summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsolpeth <>2020-07-26 23:37:00 (GMT)
committerhdiff <hdiff@hdiff.luite.com>2020-07-26 23:37:00 (GMT)
commit6a34325817453a52d191983799f983e9605ce870 (patch)
treed590ff45f37df1d3234733bf3bb06a059ea417c2
parent408014f3f923370194e604e0b5416490800aa46b (diff)
version 0.6.6HEAD0.6.6master
-rw-r--r--AnsiColor.hs2
-rw-r--r--Cabal2Ebuild.hs55
-rw-r--r--Error.hs9
-rw-r--r--HACKING.rst8
-rw-r--r--HackPort/GlobalFlags.hs5
-rw-r--r--Main.hs2
-rw-r--r--Merge.hs193
-rw-r--r--Merge/Dependencies.hs47
-rw-r--r--Merge/Utils.hs142
-rw-r--r--Portage/Cabal.hs55
-rw-r--r--Portage/Dependency/Types.hs38
-rw-r--r--Portage/EBuild.hs52
-rw-r--r--Portage/EBuild/CabalFeature.hs5
-rw-r--r--Portage/EMeta.hs29
-rw-r--r--Portage/GHCCore.hs76
-rw-r--r--Portage/Metadata.hs101
-rw-r--r--Portage/Overlay.hs11
-rw-r--r--Portage/PackageId.hs94
-rw-r--r--Portage/Tables.hs14
-rw-r--r--Portage/Version.hs63
-rw-r--r--README.rst5
-rw-r--r--Status.hs2
-rw-r--r--cabal/.docker/validate-7.10.3.dockerfile78
-rw-r--r--cabal/.docker/validate-7.6.3.dockerfile79
-rw-r--r--cabal/.docker/validate-7.8.4.dockerfile80
-rw-r--r--cabal/.docker/validate-8.0.2.dockerfile69
-rw-r--r--cabal/.docker/validate-8.10.1.dockerfile76
-rw-r--r--cabal/.docker/validate-8.2.2.dockerfile78
-rw-r--r--cabal/.docker/validate-8.4.4.dockerfile76
-rw-r--r--cabal/.docker/validate-8.6.5.dockerfile76
-rw-r--r--cabal/.docker/validate-8.8.3.dockerfile76
-rw-r--r--cabal/.docker/validate-old.dockerfile72
-rw-r--r--cabal/.docker/validate.dockerfile.zinza89
-rw-r--r--cabal/.dockerignore2
-rw-r--r--cabal/.readthedocs.yml9
-rw-r--r--cabal/.travis.yml177
-rw-r--r--cabal/CONTRIBUTING.md16
-rw-r--r--cabal/Cabal/Cabal-QuickCheck/Cabal-QuickCheck.cabal24
-rw-r--r--cabal/Cabal/Cabal-QuickCheck/src/Test/QuickCheck/GenericArbitrary.hs49
-rw-r--r--cabal/Cabal/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs513
-rw-r--r--cabal/Cabal/Cabal-described/Cabal-described.cabal26
-rw-r--r--cabal/Cabal/Cabal-described/src/Distribution/Described.hs577
-rw-r--r--cabal/Cabal/Cabal-described/src/Distribution/Utils/CharSet.hs242
-rw-r--r--cabal/Cabal/Cabal-described/src/Distribution/Utils/GrammarRegex.hs215
-rw-r--r--cabal/Cabal/Cabal-tree-diff/Cabal-tree-diff.cabal21
-rw-r--r--cabal/Cabal/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs135
-rw-r--r--cabal/Cabal/Cabal-tree-diff/src/Data/TreeDiff/Instances/CabalLanguage.hs17
-rw-r--r--cabal/Cabal/Cabal-tree-diff/src/Data/TreeDiff/Instances/CabalSPDX.hs28
-rw-r--r--cabal/Cabal/Cabal-tree-diff/src/Data/TreeDiff/Instances/CabalVersion.hs14
-rw-r--r--cabal/Cabal/Cabal.cabal133
-rw-r--r--cabal/Cabal/ChangeLog.md50
-rw-r--r--cabal/Cabal/Distribution/Backpack.hs7
-rw-r--r--cabal/Cabal/Distribution/Backpack/ComponentsGraph.hs35
-rw-r--r--cabal/Cabal/Distribution/Backpack/Configure.hs9
-rw-r--r--cabal/Cabal/Distribution/Backpack/ConfiguredComponent.hs62
-rw-r--r--cabal/Cabal/Distribution/Backpack/Id.hs9
-rw-r--r--cabal/Cabal/Distribution/Backpack/LinkedComponent.hs22
-rw-r--r--cabal/Cabal/Distribution/Backpack/ModuleShape.hs4
-rw-r--r--cabal/Cabal/Distribution/Backpack/ReadyComponent.hs17
-rw-r--r--cabal/Cabal/Distribution/Backpack/UnifyM.hs15
-rw-r--r--cabal/Cabal/Distribution/CabalSpecVersion.hs88
-rw-r--r--cabal/Cabal/Distribution/Compat/Async.hs2
-rw-r--r--cabal/Cabal/Distribution/Compat/Binary.hs16
-rw-r--r--cabal/Cabal/Distribution/Compat/CharParsing.hs9
-rw-r--r--cabal/Cabal/Distribution/Compat/CopyFile.hs18
-rw-r--r--cabal/Cabal/Distribution/Compat/CreatePipe.hs16
-rw-r--r--cabal/Cabal/Distribution/Compat/DList.hs9
-rw-r--r--cabal/Cabal/Distribution/Compat/Environment.hs2
-rw-r--r--cabal/Cabal/Distribution/Compat/Exception.hs14
-rw-r--r--cabal/Cabal/Distribution/Compat/GetShortPathName.hs4
-rw-r--r--cabal/Cabal/Distribution/Compat/Graph.hs36
-rw-r--r--cabal/Cabal/Distribution/Compat/Internal/TempFile.hs42
-rw-r--r--cabal/Cabal/Distribution/Compat/Lens.hs1
-rw-r--r--cabal/Cabal/Distribution/Compat/NonEmptySet.hs155
-rw-r--r--cabal/Cabal/Distribution/Compat/Prelude.hs128
-rw-r--r--cabal/Cabal/Distribution/Compat/Process.hs82
-rw-r--r--[-rwxr-xr-x]cabal/Cabal/Distribution/Compat/ResponseFile.hs135
-rw-r--r--cabal/Cabal/Distribution/Compat/Semigroup.hs11
-rw-r--r--cabal/Cabal/Distribution/Compat/Time.hs14
-rw-r--r--cabal/Cabal/Distribution/Compat/Typeable.hs18
-rw-r--r--cabal/Cabal/Distribution/Compiler.hs16
-rw-r--r--cabal/Cabal/Distribution/FieldGrammar.hs6
-rw-r--r--cabal/Cabal/Distribution/FieldGrammar/Class.hs71
-rw-r--r--cabal/Cabal/Distribution/FieldGrammar/FieldDescrs.hs20
-rw-r--r--cabal/Cabal/Distribution/FieldGrammar/Newtypes.hs (renamed from cabal/Cabal/Distribution/Parsec/Newtypes.hs)163
-rw-r--r--cabal/Cabal/Distribution/FieldGrammar/Parsec.hs41
-rw-r--r--cabal/Cabal/Distribution/FieldGrammar/Pretty.hs7
-rw-r--r--cabal/Cabal/Distribution/Fields/ConfVar.hs12
-rw-r--r--cabal/Cabal/Distribution/Fields/Field.hs2
-rw-r--r--cabal/Cabal/Distribution/Fields/ParseResult.hs13
-rw-r--r--cabal/Cabal/Distribution/Fields/Parser.hs1
-rw-r--r--cabal/Cabal/Distribution/Fields/Pretty.hs32
-rw-r--r--cabal/Cabal/Distribution/InstalledPackageInfo.hs19
-rw-r--r--cabal/Cabal/Distribution/License.hs2
-rw-r--r--cabal/Cabal/Distribution/Make.hs2
-rw-r--r--cabal/Cabal/Distribution/ModuleName.hs129
-rw-r--r--cabal/Cabal/Distribution/PackageDescription.hs190
-rw-r--r--cabal/Cabal/Distribution/PackageDescription/Check.hs354
-rw-r--r--cabal/Cabal/Distribution/PackageDescription/Configuration.hs114
-rw-r--r--cabal/Cabal/Distribution/PackageDescription/FieldGrammar.hs239
-rw-r--r--cabal/Cabal/Distribution/PackageDescription/Parsec.hs191
-rw-r--r--cabal/Cabal/Distribution/PackageDescription/PrettyPrint.hs104
-rw-r--r--cabal/Cabal/Distribution/PackageDescription/Quirks.hs23
-rw-r--r--cabal/Cabal/Distribution/Parsec.hs138
-rw-r--r--cabal/Cabal/Distribution/Parsec/Warning.hs7
-rw-r--r--cabal/Cabal/Distribution/Pretty.hs4
-rw-r--r--cabal/Cabal/Distribution/SPDX/License.hs1
-rw-r--r--cabal/Cabal/Distribution/SPDX/LicenseExceptionId.hs61
-rw-r--r--cabal/Cabal/Distribution/SPDX/LicenseExpression.hs3
-rw-r--r--cabal/Cabal/Distribution/SPDX/LicenseId.hs599
-rw-r--r--cabal/Cabal/Distribution/SPDX/LicenseListVersion.hs3
-rw-r--r--cabal/Cabal/Distribution/SPDX/LicenseReference.hs1
-rw-r--r--cabal/Cabal/Distribution/Simple.hs98
-rw-r--r--cabal/Cabal/Distribution/Simple/Bench.hs1
-rw-r--r--cabal/Cabal/Distribution/Simple/Build.hs15
-rw-r--r--cabal/Cabal/Distribution/Simple/Build/Macros.hs162
-rw-r--r--cabal/Cabal/Distribution/Simple/Build/Macros/Z.hs140
-rw-r--r--cabal/Cabal/Distribution/Simple/BuildPaths.hs2
-rw-r--r--cabal/Cabal/Distribution/Simple/BuildTarget.hs13
-rw-r--r--cabal/Cabal/Distribution/Simple/BuildToolDepends.hs3
-rw-r--r--cabal/Cabal/Distribution/Simple/Command.hs7
-rw-r--r--cabal/Cabal/Distribution/Simple/Compiler.hs47
-rw-r--r--cabal/Cabal/Distribution/Simple/Configure.hs270
-rw-r--r--cabal/Cabal/Distribution/Simple/Doctest.hs4
-rw-r--r--cabal/Cabal/Distribution/Simple/Flag.hs10
-rw-r--r--cabal/Cabal/Distribution/Simple/GHC.hs65
-rw-r--r--cabal/Cabal/Distribution/Simple/GHC/EnvironmentParser.hs2
-rw-r--r--cabal/Cabal/Distribution/Simple/GHC/Internal.hs73
-rw-r--r--cabal/Cabal/Distribution/Simple/GHCJS.hs37
-rw-r--r--cabal/Cabal/Distribution/Simple/Glob.hs16
-rw-r--r--cabal/Cabal/Distribution/Simple/Haddock.hs44
-rw-r--r--cabal/Cabal/Distribution/Simple/HaskellSuite.hs19
-rw-r--r--cabal/Cabal/Distribution/Simple/InstallDirs.hs11
-rw-r--r--cabal/Cabal/Distribution/Simple/InstallDirs/Internal.hs7
-rw-r--r--cabal/Cabal/Distribution/Simple/LocalBuildInfo.hs2
-rw-r--r--cabal/Cabal/Distribution/Simple/PackageIndex.hs15
-rw-r--r--cabal/Cabal/Distribution/Simple/PreProcess.hs15
-rw-r--r--cabal/Cabal/Distribution/Simple/Program.hs1
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/Builtin.hs3
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/Db.hs25
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/Find.hs14
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/GHC.hs33
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/HcPkg.hs95
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/Hpc.hs3
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/Run.hs84
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/Script.hs12
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/Types.hs5
-rw-r--r--cabal/Cabal/Distribution/Simple/Register.hs7
-rw-r--r--cabal/Cabal/Distribution/Simple/Setup.hs66
-rw-r--r--cabal/Cabal/Distribution/Simple/ShowBuildInfo.hs5
-rw-r--r--cabal/Cabal/Distribution/Simple/SrcDist.hs265
-rw-r--r--cabal/Cabal/Distribution/Simple/Test.hs1
-rw-r--r--cabal/Cabal/Distribution/Simple/Test/ExeV10.hs60
-rw-r--r--cabal/Cabal/Distribution/Simple/Test/LibV09.hs28
-rw-r--r--cabal/Cabal/Distribution/Simple/Test/Log.hs2
-rw-r--r--cabal/Cabal/Distribution/Simple/UHC.hs18
-rw-r--r--cabal/Cabal/Distribution/Simple/Utils.hs267
-rw-r--r--cabal/Cabal/Distribution/System.hs13
-rw-r--r--cabal/Cabal/Distribution/Types/AbiDependency.hs4
-rw-r--r--cabal/Cabal/Distribution/Types/AbiHash.hs4
-rw-r--r--cabal/Cabal/Distribution/Types/Benchmark.hs2
-rw-r--r--cabal/Cabal/Distribution/Types/BenchmarkInterface.hs2
-rw-r--r--cabal/Cabal/Distribution/Types/BenchmarkType.hs5
-rw-r--r--cabal/Cabal/Distribution/Types/BuildInfo.hs6
-rw-r--r--cabal/Cabal/Distribution/Types/BuildType.hs3
-rw-r--r--cabal/Cabal/Distribution/Types/ComponentId.hs1
-rw-r--r--cabal/Cabal/Distribution/Types/ComponentLocalBuildInfo.hs6
-rw-r--r--cabal/Cabal/Distribution/Types/ComponentName.hs1
-rw-r--r--cabal/Cabal/Distribution/Types/ComponentRequestedSpec.hs5
-rw-r--r--cabal/Cabal/Distribution/Types/CondTree.hs12
-rw-r--r--cabal/Cabal/Distribution/Types/Condition.hs2
-rw-r--r--cabal/Cabal/Distribution/Types/ConfVar.hs3
-rw-r--r--cabal/Cabal/Distribution/Types/Dependency.hs184
-rw-r--r--cabal/Cabal/Distribution/Types/DependencyMap.hs33
-rw-r--r--cabal/Cabal/Distribution/Types/ExeDependency.hs12
-rw-r--r--cabal/Cabal/Distribution/Types/Executable.hs2
-rw-r--r--cabal/Cabal/Distribution/Types/ExecutableScope.hs3
-rw-r--r--cabal/Cabal/Distribution/Types/ExposedModule.hs5
-rw-r--r--cabal/Cabal/Distribution/Types/Flag.hs119
-rw-r--r--cabal/Cabal/Distribution/Types/ForeignLib.hs8
-rw-r--r--cabal/Cabal/Distribution/Types/ForeignLibOption.hs3
-rw-r--r--cabal/Cabal/Distribution/Types/ForeignLibType.hs3
-rw-r--r--cabal/Cabal/Distribution/Types/GenericPackageDescription.hs53
-rw-r--r--cabal/Cabal/Distribution/Types/GenericPackageDescription/Lens.hs37
-rw-r--r--cabal/Cabal/Distribution/Types/GivenComponent.hs2
-rw-r--r--cabal/Cabal/Distribution/Types/IncludeRenaming.hs5
-rw-r--r--cabal/Cabal/Distribution/Types/InstalledPackageInfo.hs21
-rw-r--r--cabal/Cabal/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs124
-rw-r--r--cabal/Cabal/Distribution/Types/InstalledPackageInfo/Lens.hs20
-rw-r--r--cabal/Cabal/Distribution/Types/LegacyExeDependency.hs9
-rw-r--r--cabal/Cabal/Distribution/Types/Library.hs2
-rw-r--r--cabal/Cabal/Distribution/Types/LibraryName.hs1
-rw-r--r--cabal/Cabal/Distribution/Types/LibraryVisibility.hs3
-rw-r--r--cabal/Cabal/Distribution/Types/LocalBuildInfo.hs4
-rw-r--r--cabal/Cabal/Distribution/Types/Mixin.hs67
-rw-r--r--cabal/Cabal/Distribution/Types/Module.hs1
-rw-r--r--cabal/Cabal/Distribution/Types/ModuleReexport.hs5
-rw-r--r--cabal/Cabal/Distribution/Types/ModuleRenaming.hs3
-rw-r--r--cabal/Cabal/Distribution/Types/MungedPackageId.hs1
-rw-r--r--cabal/Cabal/Distribution/Types/MungedPackageName.hs1
-rw-r--r--cabal/Cabal/Distribution/Types/PackageDescription.hs76
-rw-r--r--cabal/Cabal/Distribution/Types/PackageDescription/Lens.hs94
-rw-r--r--cabal/Cabal/Distribution/Types/PackageId.hs7
-rw-r--r--cabal/Cabal/Distribution/Types/PackageName.hs18
-rw-r--r--cabal/Cabal/Distribution/Types/PackageVersionConstraint.hs61
-rw-r--r--cabal/Cabal/Distribution/Types/PkgconfigDependency.hs6
-rw-r--r--cabal/Cabal/Distribution/Types/PkgconfigName.hs9
-rw-r--r--cabal/Cabal/Distribution/Types/PkgconfigVersion.hs14
-rw-r--r--cabal/Cabal/Distribution/Types/PkgconfigVersionRange.hs37
-rw-r--r--cabal/Cabal/Distribution/Types/SetupBuildInfo.hs2
-rw-r--r--cabal/Cabal/Distribution/Types/SourceRepo.hs63
-rw-r--r--cabal/Cabal/Distribution/Types/TestSuite.hs1
-rw-r--r--cabal/Cabal/Distribution/Types/TestSuiteInterface.hs1
-rw-r--r--cabal/Cabal/Distribution/Types/TestType.hs4
-rw-r--r--cabal/Cabal/Distribution/Types/UnitId.hs11
-rw-r--r--cabal/Cabal/Distribution/Types/UnqualComponentName.hs11
-rw-r--r--cabal/Cabal/Distribution/Types/Version.hs1
-rw-r--r--cabal/Cabal/Distribution/Types/VersionInterval.hs26
-rw-r--r--cabal/Cabal/Distribution/Types/VersionRange.hs51
-rw-r--r--cabal/Cabal/Distribution/Types/VersionRange/Internal.hs213
-rw-r--r--cabal/Cabal/Distribution/Utils/Generic.hs64
-rw-r--r--cabal/Cabal/Distribution/Utils/IOData.hs91
-rw-r--r--cabal/Cabal/Distribution/Utils/LogProgress.hs6
-rw-r--r--cabal/Cabal/Distribution/Utils/MD5.hs (renamed from cabal/Cabal/Distribution/Compat/MD5.hs)31
-rw-r--r--cabal/Cabal/Distribution/Utils/NubList.hs9
-rw-r--r--cabal/Cabal/Distribution/Utils/ShortText.hs56
-rw-r--r--cabal/Cabal/Distribution/Utils/Structured.hs472
-rw-r--r--cabal/Cabal/Distribution/Verbosity.hs129
-rw-r--r--cabal/Cabal/Distribution/Verbosity/Internal.hs8
-rw-r--r--cabal/Cabal/Distribution/Version.hs17
-rw-r--r--cabal/Cabal/Distribution/ZinzaPrelude.hs43
-rw-r--r--cabal/Cabal/LICENSE5
-rw-r--r--cabal/Cabal/Language/Haskell/Extension.hs25
-rw-r--r--cabal/Cabal/Makefile9
-rw-r--r--cabal/Cabal/doc/README.md9
-rw-r--r--cabal/Cabal/doc/buildinfo-fields-reference.rst654
-rw-r--r--cabal/Cabal/doc/cabal-commands.rst402
-rw-r--r--cabal/Cabal/doc/cabal-package.rst3335
-rw-r--r--cabal/Cabal/doc/cabal-project.rst1549
-rw-r--r--cabal/Cabal/doc/cabaldomain.py29
-rw-r--r--cabal/Cabal/doc/conf.py15
-rw-r--r--cabal/Cabal/doc/developing-packages.rst3324
-rw-r--r--cabal/Cabal/doc/file-format-changelog.rst27
-rw-r--r--cabal/Cabal/doc/getting-started.rst169
-rw-r--r--cabal/Cabal/doc/hcar/Cabal-201604.tex2
-rw-r--r--cabal/Cabal/doc/hcar/Cabal-201611.tex2
-rw-r--r--cabal/Cabal/doc/index.rst10
-rw-r--r--cabal/Cabal/doc/installing-packages.rst1723
-rw-r--r--cabal/Cabal/doc/misc.rst2
-rw-r--r--cabal/Cabal/doc/nix-integration.rst5
-rw-r--r--cabal/Cabal/doc/nix-local-build-overview.rst4
-rw-r--r--cabal/Cabal/doc/nix-local-build.rst1932
-rw-r--r--cabal/Cabal/doc/references.inc2
-rw-r--r--cabal/Cabal/doc/requirements.txt2
-rw-r--r--cabal/Cabal/doc/setup-commands.rst1422
-rw-r--r--cabal/LICENSE2
-rw-r--r--cabal/Makefile150
-rw-r--r--cabal/appveyor.yml4
-rw-r--r--cabal/boot/SPDX.LicenseExceptionId.template.hs14
-rw-r--r--cabal/boot/SPDX.LicenseId.template.hs34
-rw-r--r--cabal/boot/cabal_macros.template.h41
-rw-r--r--cabal/boot/ci-artifacts.template.yml136
-rw-r--r--cabal/boot/ci-bootstrap.template.yml64
-rw-r--r--cabal/boot/ci-linux.template.yml72
-rw-r--r--cabal/boot/ci-macos.template.yml68
-rw-r--r--cabal/boot/ci-quick-jobs.template.yml84
-rw-r--r--cabal/boot/ci-windows.template.yml84
-rw-r--r--cabal/buildinfo-reference-generator/buildinfo-reference-generator.cabal16
-rw-r--r--cabal/buildinfo-reference-generator/src/Main.hs274
-rw-r--r--cabal/buildinfo-reference-generator/template.zinza233
-rw-r--r--cabal/cabal-benchmarks/LICENSE34
-rw-r--r--cabal/cabal-benchmarks/README.md3
-rw-r--r--cabal/cabal-benchmarks/bench/CabalBenchmarks.hs14
-rw-r--r--cabal/cabal-benchmarks/cabal-benchmarks.cabal34
-rw-r--r--cabal/cabal-dev-scripts/LICENSE10
-rw-r--r--cabal/cabal-dev-scripts/cabal-dev-scripts.cabal79
-rw-r--r--cabal/cabal-dev-scripts/src/AnalyseImports.hs106
-rw-r--r--cabal/cabal-dev-scripts/src/Capture.hs31
-rw-r--r--cabal/cabal-dev-scripts/src/GenCabalInstallCabal.hs49
-rw-r--r--cabal/cabal-dev-scripts/src/GenCabalMacros.hs119
-rw-r--r--cabal/cabal-dev-scripts/src/GenSPDX.hs12
-rw-r--r--cabal/cabal-dev-scripts/src/GenSPDXExc.hs7
-rw-r--r--cabal/cabal-dev-scripts/src/GenUtils.hs16
-rw-r--r--cabal/cabal-dev-scripts/src/GenValidate.hs157
-rw-r--r--cabal/cabal-dev-scripts/src/GenValidateDockerfile.hs74
-rw-r--r--cabal/cabal-dev-scripts/src/Preprocessor.hs222
-rw-r--r--cabal/cabal-install/Distribution/Client/BuildReports/Anonymous.hs308
-rw-r--r--cabal/cabal-install/Distribution/Client/BuildReports/Lens.hs46
-rw-r--r--cabal/cabal-install/Distribution/Client/BuildReports/Storage.hs31
-rw-r--r--cabal/cabal-install/Distribution/Client/BuildReports/Types.hs156
-rw-r--r--cabal/cabal-install/Distribution/Client/BuildReports/Upload.hs17
-rw-r--r--cabal/cabal-install/Distribution/Client/Check.hs1
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdBench.hs138
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdBuild.hs109
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdClean.hs8
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdConfigure.hs67
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdErrorMessages.hs123
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdExec.hs49
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdFreeze.hs60
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdHaddock.hs87
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdInstall.hs784
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdInstall/ClientInstallFlags.hs56
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdInstall/ClientInstallTargetSelector.hs68
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdLegacy.hs24
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdListBin.hs368
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdRepl.hs252
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdRun.hs253
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdSdist.hs280
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdTest.hs142
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdUpdate.hs150
-rw-r--r--cabal/cabal-install/Distribution/Client/Compat/Directory.hs49
-rw-r--r--cabal/cabal-install/Distribution/Client/Compat/ExecutablePath.hs2
-rw-r--r--cabal/cabal-install/Distribution/Client/Compat/FilePerms.hs2
-rw-r--r--cabal/cabal-install/Distribution/Client/Compat/Orphans.hs41
-rw-r--r--cabal/cabal-install/Distribution/Client/Compat/Prelude.hs11
-rw-r--r--cabal/cabal-install/Distribution/Client/Compat/Process.hs5
-rw-r--r--cabal/cabal-install/Distribution/Client/Compat/Semaphore.hs8
-rw-r--r--cabal/cabal-install/Distribution/Client/Config.hs257
-rw-r--r--cabal/cabal-install/Distribution/Client/Configure.hs33
-rw-r--r--cabal/cabal-install/Distribution/Client/Dependency.hs161
-rw-r--r--cabal/cabal-install/Distribution/Client/Dependency/Types.hs35
-rw-r--r--cabal/cabal-install/Distribution/Client/DistDirLayout.hs41
-rw-r--r--cabal/cabal-install/Distribution/Client/Exec.hs134
-rw-r--r--cabal/cabal-install/Distribution/Client/Fetch.hs21
-rw-r--r--cabal/cabal-install/Distribution/Client/FetchUtils.hs49
-rw-r--r--cabal/cabal-install/Distribution/Client/FileMonitor.hs73
-rw-r--r--cabal/cabal-install/Distribution/Client/Freeze.hs33
-rw-r--r--cabal/cabal-install/Distribution/Client/GZipUtils.hs8
-rw-r--r--cabal/cabal-install/Distribution/Client/GenBounds.hs15
-rw-r--r--cabal/cabal-install/Distribution/Client/Get.hs62
-rw-r--r--cabal/cabal-install/Distribution/Client/Glob.hs150
-rw-r--r--cabal/cabal-install/Distribution/Client/GlobalFlags.hs128
-rw-r--r--cabal/cabal-install/Distribution/Client/Haddock.hs9
-rw-r--r--cabal/cabal-install/Distribution/Client/HashValue.hs85
-rw-r--r--cabal/cabal-install/Distribution/Client/HttpUtils.hs146
-rw-r--r--cabal/cabal-install/Distribution/Client/IndexUtils.hs494
-rw-r--r--cabal/cabal-install/Distribution/Client/IndexUtils/ActiveRepos.hs174
-rw-r--r--cabal/cabal-install/Distribution/Client/IndexUtils/IndexState.hs138
-rw-r--r--cabal/cabal-install/Distribution/Client/IndexUtils/Timestamp.hs111
-rw-r--r--cabal/cabal-install/Distribution/Client/Init.hs1290
-rw-r--r--cabal/cabal-install/Distribution/Client/Init/Command.hs730
-rw-r--r--cabal/cabal-install/Distribution/Client/Init/Defaults.hs41
-rw-r--r--cabal/cabal-install/Distribution/Client/Init/FileCreators.hs650
-rw-r--r--cabal/cabal-install/Distribution/Client/Init/Heuristics.hs25
-rw-r--r--cabal/cabal-install/Distribution/Client/Init/Licenses.hs12
-rw-r--r--cabal/cabal-install/Distribution/Client/Init/Prompt.hs145
-rw-r--r--cabal/cabal-install/Distribution/Client/Init/Types.hs39
-rw-r--r--cabal/cabal-install/Distribution/Client/Init/Utils.hs38
-rw-r--r--cabal/cabal-install/Distribution/Client/Install.hs207
-rw-r--r--cabal/cabal-install/Distribution/Client/InstallPlan.hs75
-rw-r--r--cabal/cabal-install/Distribution/Client/InstallSymlink.hs113
-rw-r--r--cabal/cabal-install/Distribution/Client/JobControl.hs7
-rw-r--r--cabal/cabal-install/Distribution/Client/List.hs204
-rw-r--r--cabal/cabal-install/Distribution/Client/Manpage.hs47
-rw-r--r--cabal/cabal-install/Distribution/Client/ManpageFlags.hs40
-rw-r--r--cabal/cabal-install/Distribution/Client/Nix.hs26
-rw-r--r--cabal/cabal-install/Distribution/Client/NixStyleOptions.hs85
-rw-r--r--cabal/cabal-install/Distribution/Client/Outdated.hs53
-rw-r--r--cabal/cabal-install/Distribution/Client/PackageHash.hs174
-rw-r--r--cabal/cabal-install/Distribution/Client/PackageUtils.hs38
-rw-r--r--cabal/cabal-install/Distribution/Client/ParseUtils.hs18
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectBuilding.hs69
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectBuilding/Types.hs8
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectConfig.hs121
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectConfig/Legacy.hs283
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectConfig/Types.hs51
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectFlags.hs60
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectOrchestration.hs213
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectPlanOutput.hs52
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectPlanning.hs230
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectPlanning/Types.hs24
-rw-r--r--cabal/cabal-install/Distribution/Client/RebuildMonad.hs3
-rw-r--r--cabal/cabal-install/Distribution/Client/Reconfigure.hs66
-rw-r--r--cabal/cabal-install/Distribution/Client/Run.hs12
-rw-r--r--cabal/cabal-install/Distribution/Client/Sandbox.hs789
-rw-r--r--cabal/cabal-install/Distribution/Client/Sandbox/Index.hs285
-rw-r--r--cabal/cabal-install/Distribution/Client/Sandbox/PackageEnvironment.hs353
-rw-r--r--cabal/cabal-install/Distribution/Client/Sandbox/Timestamp.hs273
-rw-r--r--cabal/cabal-install/Distribution/Client/Sandbox/Types.hs65
-rw-r--r--cabal/cabal-install/Distribution/Client/SavedFlags.hs12
-rw-r--r--cabal/cabal-install/Distribution/Client/Security/DNS.hs10
-rw-r--r--cabal/cabal-install/Distribution/Client/Security/HTTP.hs81
-rw-r--r--cabal/cabal-install/Distribution/Client/Setup.hs808
-rw-r--r--cabal/cabal-install/Distribution/Client/SetupWrapper.hs58
-rw-r--r--cabal/cabal-install/Distribution/Client/SolverInstallPlan.hs77
-rw-r--r--cabal/cabal-install/Distribution/Client/SourceFiles.hs29
-rw-r--r--cabal/cabal-install/Distribution/Client/SrcDist.hs232
-rw-r--r--cabal/cabal-install/Distribution/Client/Store.hs13
-rw-r--r--cabal/cabal-install/Distribution/Client/Tar.hs6
-rw-r--r--cabal/cabal-install/Distribution/Client/TargetProblem.hs55
-rw-r--r--cabal/cabal-install/Distribution/Client/TargetSelector.hs140
-rw-r--r--cabal/cabal-install/Distribution/Client/Targets.hs201
-rw-r--r--cabal/cabal-install/Distribution/Client/Types.hs618
-rw-r--r--cabal/cabal-install/Distribution/Client/Types/AllowNewer.hs241
-rw-r--r--cabal/cabal-install/Distribution/Client/Types/BuildResults.hs59
-rw-r--r--cabal/cabal-install/Distribution/Client/Types/ConfiguredId.hs83
-rw-r--r--cabal/cabal-install/Distribution/Client/Types/ConfiguredPackage.hs86
-rw-r--r--cabal/cabal-install/Distribution/Client/Types/Credentials.hs9
-rw-r--r--cabal/cabal-install/Distribution/Client/Types/InstallMethod.hs32
-rw-r--r--cabal/cabal-install/Distribution/Client/Types/OverwritePolicy.hs28
-rw-r--r--cabal/cabal-install/Distribution/Client/Types/PackageLocation.hs50
-rw-r--r--cabal/cabal-install/Distribution/Client/Types/PackageSpecifier.hs55
-rw-r--r--cabal/cabal-install/Distribution/Client/Types/ReadyPackage.hs31
-rw-r--r--cabal/cabal-install/Distribution/Client/Types/Repo.hs184
-rw-r--r--cabal/cabal-install/Distribution/Client/Types/RepoName.hs45
-rw-r--r--cabal/cabal-install/Distribution/Client/Types/SourcePackageDb.hs23
-rw-r--r--cabal/cabal-install/Distribution/Client/Types/SourceRepo.hs (renamed from cabal/cabal-install/Distribution/Client/SourceRepo.hs)38
-rw-r--r--cabal/cabal-install/Distribution/Client/Types/WriteGhcEnvironmentFilesPolicy.hs20
-rw-r--r--cabal/cabal-install/Distribution/Client/Update.hs35
-rw-r--r--cabal/cabal-install/Distribution/Client/Upload.hs39
-rw-r--r--cabal/cabal-install/Distribution/Client/Utils.hs25
-rw-r--r--cabal/cabal-install/Distribution/Client/Utils/Assertion.hs4
-rw-r--r--cabal/cabal-install/Distribution/Client/Utils/Json.hs13
-rw-r--r--cabal/cabal-install/Distribution/Client/VCS.hs167
-rw-r--r--cabal/cabal-install/Distribution/Client/Win32SelfUpgrade.hs9
-rw-r--r--cabal/cabal-install/Distribution/Client/World.hs71
-rw-r--r--cabal/cabal-install/Distribution/Deprecated/ParseUtils.hs259
-rw-r--r--cabal/cabal-install/Distribution/Deprecated/Text.hs409
-rw-r--r--cabal/cabal-install/Distribution/Deprecated/ViewAsFieldDescr.hs2
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular.hs1
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Assignment.hs11
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Builder.hs14
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/ConfiguredConversion.hs2
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/ConflictSet.hs104
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Dependency.hs81
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Explore.hs202
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Index.hs24
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/IndexConversion.hs233
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/LabeledGraph.hs5
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Linking.hs8
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Message.hs125
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Package.hs17
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Preference.hs10
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/RetryLog.hs3
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Solver.hs16
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Tree.hs2
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Validate.hs127
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Version.hs9
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/ComponentDeps.hs19
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/ConstraintSource.hs5
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/DependencyResolver.hs3
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/Flag.hs2
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/InstSolverPackage.hs10
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/InstalledPreference.hs2
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/OptionalStanza.hs7
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/PackageConstraint.hs37
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/PackageIndex.hs28
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/PackagePath.hs19
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/PkgConfigDb.hs3
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/Progress.hs2
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/ResolverPackage.hs6
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/Settings.hs36
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/SolverId.hs6
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/SolverPackage.hs6
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/SourcePackage.hs23
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/Variable.hs2
-rw-r--r--cabal/cabal-install/LICENSE5
-rw-r--r--cabal/cabal-install/Setup.hs64
-rwxr-xr-xcabal/cabal-install/bootstrap.sh33
-rw-r--r--cabal/cabal-install/cabal-install.cabal79
-rw-r--r--cabal/cabal-install/cabal-install.cabal.dev (renamed from cabal/cabal-install/cabal-install.cabal.pp)602
-rw-r--r--cabal/cabal-install/cabal-install.cabal.prod397
-rw-r--r--cabal/cabal-install/cabal-install.cabal.zinza616
-rw-r--r--cabal/cabal-install/changelog36
-rw-r--r--cabal/cabal-install/main/Main.hs429
-rw-r--r--cabal/cabal-install/solver-dsl/UnitTests/Distribution/Solver/Modular/DSL.hs291
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2.hs277
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/targets/complex/q/q.cabal3
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/targets/simple/app/Main.hs (renamed from cabal/cabal-testsuite/PackageTests/Sandbox/Sources/q/LICENSE)0
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/targets/simple/p.cabal5
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/targets/simple/q/Q.hs (renamed from cabal/cabal-testsuite/PackageTests/Sandbox/Sources/p/LICENSE)0
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/targets/simple/q/q.cabal1
-rw-r--r--cabal/cabal-install/tests/UnitTests.hs14
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/ArbitraryInstances.hs451
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/BuildReport.hs32
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/Described.hs37
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/DescribedInstances.hs316
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/FileMonitor.hs35
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/GZipUtils.hs11
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/GenericInstances.hs10
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/Get.hs18
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/Glob.hs136
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/IndexUtils/Timestamp.hs19
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/Init/FileCreators.hs184
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/InstallPlan.hs18
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/JobControl.hs30
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs354
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/Sandbox.hs28
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/Sandbox/Timestamp.hs63
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/Tar.hs15
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/Targets.hs24
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/TreeDiffInstances.hs77
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/VCS.hs100
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL/TestCaseUtils.hs13
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/MemoryUsage.hs27
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck.hs133
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs468
-rw-r--r--cabal/cabal-testsuite/LICENSE5
-rw-r--r--cabal/cabal-testsuite/PackageTests/Ambiguity/reexport/reexport.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Ambiguity/setup-package-import.cabal.out3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Ambiguity/setup-reexport.cabal.out4
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutoconfBadPaths/cabal.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/Package/my.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/Package/setup.cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/Package/setup.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/AutogenModules.cabal6
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/setup.cabal.out4
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/setup.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/setup.test.hs8
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Fail1/Fail1.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Fail1/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Fail2/Fail2.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Fail2/setup.cabal.out3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Fail2/setup.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Fail3/Fail3.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Fail3/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes1/Includes1.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes1/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/Includes2.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/Includes2.cabal.fail2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/cabal-internal.out4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/exe/exe.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/mylib/mylib.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/mysql/mysql.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/postgresql/postgresql.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.cabal.out15
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-internal-fail.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-internal.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/src/src.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes3/Includes3.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes3/repo/exe-0.1.0.0/exe.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes3/repo/indef-0.1.0.0/indef.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes3/repo/sigs-0.1.0.0/sigs.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-fail.cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.cabal.out5
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes3/setup-internal.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes3/setup-internal.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes4/Includes4.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes4/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes5/Includes5.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes5/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Indef1/Indef1.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Indef2/Indef2.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Indef2/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Reexport1/p/p.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Reexport2/Reexport2.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Reexport2/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/T4447/T4447.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/T4447/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/T4754/p.cabal4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/T4754/setup.cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/T4754/setup.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/T5634/T5634.cabal5
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/T5634/setup.cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/T5634/setup.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/TemplateHaskell/bkpth.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/TemplateHaskell/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/BenchmarkExeV10/my.cabal4
-rw-r--r--cabal/cabal-testsuite/PackageTests/BenchmarkExeV10/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/BenchmarkOptions/BenchmarkOptions.cabal4
-rw-r--r--cabal/cabal-testsuite/PackageTests/BenchmarkOptions/setup.cabal.out5
-rw-r--r--cabal/cabal-testsuite/PackageTests/BenchmarkStanza/my.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/BenchmarkStanza/setup.cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/BenchmarkStanza/setup.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/DepCycle/setup.cabal.out5
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/DepCycle/setup.out4
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary0/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary1/cabal.out5
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary1/my.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary1/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary2/setup.cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary3/setup.cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/SameDepsAllRound/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/TargetSpecificDeps1/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/TargetSpecificDeps2/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/TargetSpecificDeps3/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildTargetErrors/BuildTargetErrors.cabal4
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildToolDependsInternalMissing/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildTools/Foreign/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildTools/Internal/cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildTools/Internal/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/CMain/my.cabal3
-rw-r--r--cabal/cabal-testsuite/PackageTests/CMain/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/COnlyMain/my.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/COnlyMain/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/CabalMacros/Mdl.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/CabalMacros/my.cabal16
-rw-r--r--cabal/cabal-testsuite/PackageTests/CabalMacros/setup.cabal.out15
-rw-r--r--cabal/cabal-testsuite/PackageTests/CabalMacros/setup.out15
-rw-r--r--cabal/cabal-testsuite/PackageTests/CabalMacros/setup.test.hs18
-rw-r--r--cabal/cabal-testsuite/PackageTests/CaretOperator/my.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/DifferentGhcOptions/cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/CmmSources/cabal.out13
-rw-r--r--cabal/cabal-testsuite/PackageTests/CmmSources/cabal.project1
-rw-r--r--cabal/cabal-testsuite/PackageTests/CmmSources/cabal.test.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/CmmSources/cbits/HeapPrim.cmm6
-rw-r--r--cabal/cabal-testsuite/PackageTests/CmmSources/cmmexperiment.cabal27
-rw-r--r--cabal/cabal-testsuite/PackageTests/CmmSources/demo/Main.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/CmmSources/setup.out7
-rw-r--r--cabal/cabal-testsuite/PackageTests/CmmSources/setup.test.hs7
-rw-r--r--cabal/cabal-testsuite/PackageTests/CmmSources/src/Demo.hs37
-rw-r--r--cabal/cabal-testsuite/PackageTests/Configure/cabal.out8
-rw-r--r--cabal/cabal-testsuite/PackageTests/Configure/cabal.project2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Configure/cabal.test.hs10
-rw-r--r--cabal/cabal-testsuite/PackageTests/Configure/setup.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/ConfigureComponent/Exe/setup.cabal.out8
-rw-r--r--cabal/cabal-testsuite/PackageTests/ConfigureComponent/SubLib/setup-explicit-fail.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/ConfigureComponent/SubLib/setup-explicit.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/CopyComponent/Exe/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/CopyComponent/Lib/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomDep/sandbox.out5
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomDep/sandbox.test.hs22
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomPlain/setup.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomPreProcess/Setup.hs14
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomPreProcess/cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomPreProcess/cabal.project2
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomPreProcess/cabal.test.hs13
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomPreProcess/internal-preprocessor-test.cabal3
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomPreProcess/setup.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/DeterministicAr/my.cabal3
-rw-r--r--cabal/cabal-testsuite/PackageTests/DeterministicAr/setup-default-ar.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/DeterministicAr/setup-old-ar-without-at-args.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/DuplicateModuleName/setup.cabal.out9
-rw-r--r--cabal/cabal-testsuite/PackageTests/EmptyLib/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/T4049/UseLib.c9
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/T4049/csrc/MyForeignLibWrapper.c23
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/T4049/my-foreign-lib.cabal19
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/T4049/sandbox.out12
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/T4049/sandbox.test.hs20
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/T4049/src/MyForeignLib/Hello.hs10
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/T4049/src/MyForeignLib/SomeBindings.hsc10
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/sandbox-ghc-pkg.out16
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/sandbox-ghc-pkg.test.hs12
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/sandbox-hc-pkg.out16
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/sandbox-hc-pkg.test.hs26
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/sandbox-path.out16
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/sandbox-path.test.hs8
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/sandbox.out16
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/sandbox.test.hs7
-rw-r--r--cabal/cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/Freeze/freeze.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Freeze/my.cabal5
-rw-r--r--cabal/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Haddock/my.cabal3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Haddock/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/HaddockNewline/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/Executable/foo.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/Executable/setup-static.cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/Library/foolib/foolib.cabal3
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/Library/setup.cabal.out3
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/Library/setup.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/p/p.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/sandbox-shadow.out18
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/sandbox-shadow.test.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/sandbox.out17
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/sandbox.test.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/setup-gen-pkg-config.cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/setup-gen-script.cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/setup.cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalVersions/BuildDependsBad/setup.cabal.out8
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/setup.cabal.out3
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/setup.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsBad/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/setup.cabal.out3
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalVersions/BuildToolDependsExtra/setup.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalVersions/BuildToolsBad/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/setup.cabal.out3
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalVersions/BuildToolsExtra/setup.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Macros/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Manpage/cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Manpage/cabal.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/Failing/cabal.out8
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/Failing/cabal.project (renamed from cabal/cabal-testsuite/PackageTests/MultipleLibraries/cabal.project)0
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/Failing/cabal.test.hs (renamed from cabal/cabal-testsuite/PackageTests/MultipleLibraries/cabal.test.hs)0
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/Failing/d/d.cabal (renamed from cabal/cabal-testsuite/PackageTests/MultipleLibraries/d/d.cabal)0
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/Failing/p/p.cabal (renamed from cabal/cabal-testsuite/PackageTests/MultipleLibraries/p/p.cabal)0
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/Successful/cabal.out14
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/Successful/cabal.project4
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/Successful/cabal.test.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/Successful/pkg-abc/Main.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/Successful/pkg-abc/pkg-abc.cabal10
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/Successful/pkg-def/pkg-def.cabal14
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/Successful/pkg-def/publib/PkgDef.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/Successful/pkg-def/src/PkgDef.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083Post/cabal.out15
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083Post/cabal.project4
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083Post/cabal.test.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083Post/pkg-abc/exe/Main.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083Post/pkg-abc/pkg-abc.cabal19
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083Post/pkg-abc/pkg-def/PkgDef.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083Post/pkg-def/pkg-def.cabal17
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083Post/pkg-def/publib/PkgDef.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083Post/pkg-def/src/PkgDef.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083PostMixin/cabal.out16
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083PostMixin/cabal.project4
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083PostMixin/cabal.test.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083PostMixin/pkg-abc/exe/Main.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083PostMixin/pkg-abc/pkg-abc.cabal20
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083PostMixin/pkg-abc/pkg-def/PkgDef.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083PostMixin/pkg-def/pkg-def.cabal17
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083PostMixin/pkg-def/publib/PkgDef.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083PostMixin/pkg-def/src/PkgDef.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083Pre/cabal.out14
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083Pre/cabal.project4
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083Pre/cabal.test.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083Pre/pkg-abc/exe/Main.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083Pre/pkg-abc/pkg-abc.cabal19
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083Pre/pkg-abc/pkg-def/PkgDef.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083Pre/pkg-def/pkg-def.cabal17
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083Pre/pkg-def/publib/PkgDef.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083Pre/pkg-def/src/PkgDef.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083PreMixin/cabal.out14
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083PreMixin/cabal.project4
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083PreMixin/cabal.test.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083PreMixin/pkg-abc/exe/Main.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083PreMixin/pkg-abc/pkg-abc.cabal20
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083PreMixin/pkg-abc/pkg-def/PkgDef.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083PreMixin/pkg-def/pkg-def.cabal17
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083PreMixin/pkg-def/publib/PkgDef.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6083PreMixin/pkg-def/src/PkgDef.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6894/Bar.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6894/Foo.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6894/cabal.out15
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6894/cabal.project1
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6894/cabal.test.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6894/issue.cabal13
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6894/setup.cabal.out8
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6894/setup.out8
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/T6894/setup.test.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/MultipleLibraries/cabal.out12
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Script/script.hs22
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewConfigure/LocalConfigOverwrite/cabal.out27
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewConfigure/LocalConfigOverwrite/cabal.test.hs19
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewConfigure/LocalConfigOverwrite/foo.project1
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewConfigure/LocalConfigOverwrite/foo.project.local (renamed from cabal/cabal-testsuite/PackageTests/Sandbox/MultipleSources/q/LICENSE)0
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/DeterministicTrivial/deterministic.test.hs8
-rw-r--r--cabal/cabal-testsuite/PackageTests/OrderFlags/my.cabal3
-rw-r--r--cabal/cabal-testsuite/PackageTests/OrderFlags/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Outdated/my.cabal4
-rw-r--r--cabal/cabal-testsuite/PackageTests/PathsModule/Executable/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/PathsModule/Library/my.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/PathsModule/Library/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/PreProcess/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/PreProcessExtraSources/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/QuasiQuotes/dynamic/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/QuasiQuotes/profiling/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/QuasiQuotes/vanilla/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReexportedModules/p/p.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReexportedModules/p/p.cabal.fail-ambiguous2
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReexportedModules/p/p.cabal.fail-missing2
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReexportedModules/p/p.cabal.fail-other2
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReexportedModules/setup-fail-ambiguous.cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReexportedModules/setup-fail-missing.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReexportedModules/setup-fail-other.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReexportedModules/setup.cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T2755/setup.cabal.out3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T2971/setup.cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T2971a/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3199/Cabal/Cabal.cabal8
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3199/Main.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3199/Setup.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3199/sandbox.out8
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3199/sandbox.test.hs11
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3199/test-3199.cabal27
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3294/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3436/Cabal-1.2/Cabal.cabal8
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3436/Cabal-1.2/CabalMessage.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3436/Cabal-2.0/Cabal.cabal8
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3436/Cabal-2.0/CabalMessage.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3436/cabal.out9
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3436/cabal.project1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3436/custom-setup/Setup.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3436/custom-setup/custom-setup.cabal9
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3436/sandbox.out22
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3436/sandbox.test.hs21
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3847/T3847.cabal4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3847/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4025/T4025.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4025/setup.cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4025/setup.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4270/T4270.cabal4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4270/setup.cabal.out5
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4291/dependee/dependee.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4291/depender/depender.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4291/setup.cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4449/setup.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5309/cabal.out6
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5309/memoized-tcm/costMatrix.h2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5318/sdist-list-sources.out5
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5318/sdist-list-sources.test.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5677/cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5677/prog/prog.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5677/prog/program.hs (renamed from cabal/cabal-testsuite/PackageTests/Regression/T5677/prog/prog.hs)0
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T6125/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T6853/cabal.out8
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T6853/cabal.project1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T6853/cabal.test.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T6853/pkg-foo/Foo.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T6853/pkg-foo/pkg-foo.cabal17
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReplCSources/Lib.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReplCSources/cabal-csrc-repl.cabal8
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReplCSources/cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReplCSources/cabal.project1
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReplCSources/cabal.test.hs9
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReplCSources/foo.c1
-rw-r--r--cabal/cabal-testsuite/PackageTests/SDist/T5195/cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/SDist/T5195/cabal.test.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/SPDX/cabal-old-build.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/SPDX/cabal-old-build.test.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/SPDX/my.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/MultipleSources/cabal.out12
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/MultipleSources/cabal.test.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/MultipleSources/p/LICENSE0
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/MultipleSources/p/Setup.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/MultipleSources/p/p.cabal11
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/MultipleSources/q/Setup.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/MultipleSources/q/q.cabal11
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/Reinstall/p/Main.hs7
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/Reinstall/p/p.cabal8
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/Reinstall/q/Q.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/Reinstall/q/Q.hs.in24
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/Reinstall/q/q.cabal8
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/Reinstall/sandbox.out15
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/Reinstall/sandbox.test.hs9
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/Sources/p/Setup.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/Sources/p/p.cabal11
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/Sources/q/Setup.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/Sources/q/q.cabal11
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/Sources/sandbox.out15
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/Sources/sandbox.test.hs7
-rw-r--r--cabal/cabal-testsuite/PackageTests/SimpleDefault/my.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/TemplateHaskell/dynamic/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/TemplateHaskell/profiling/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/TemplateHaskell/vanilla/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestNameCollision/setup.cabal.out6
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestOptions/TestOptions.cabal4
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestOptions/setup.cabal.out5
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestStanza/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/cabal.out4
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/my.cabal5
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/setup-no-markup.cabal.out5
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/setup-no-tix.cabal.out5
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestSuiteTests/LibV09/LibV09.cabal4
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestSuiteTests/LibV09/setup-deadlock.cabal.out5
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestSuiteTests/LibV09/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/UniqueIPID/setup.cabal.out2
-rw-r--r--cabal/cabal-testsuite/cabal-testsuite.cabal32
-rw-r--r--cabal/cabal-testsuite/main/cabal-tests.hs2
-rw-r--r--cabal/cabal-testsuite/src/Test/Cabal/CheckArMetadata.hs (renamed from cabal/cabal-testsuite/Test/Cabal/CheckArMetadata.hs)0
-rw-r--r--cabal/cabal-testsuite/src/Test/Cabal/Monad.hs (renamed from cabal/cabal-testsuite/Test/Cabal/Monad.hs)107
-rw-r--r--cabal/cabal-testsuite/src/Test/Cabal/OutputNormalizer.hs79
-rw-r--r--cabal/cabal-testsuite/src/Test/Cabal/Plan.hs (renamed from cabal/cabal-testsuite/Test/Cabal/Plan.hs)0
-rw-r--r--cabal/cabal-testsuite/src/Test/Cabal/Prelude.hs (renamed from cabal/cabal-testsuite/Test/Cabal/Prelude.hs)194
-rw-r--r--cabal/cabal-testsuite/src/Test/Cabal/Run.hs (renamed from cabal/cabal-testsuite/Test/Cabal/Run.hs)35
-rw-r--r--cabal/cabal-testsuite/src/Test/Cabal/Script.hs (renamed from cabal/cabal-testsuite/Test/Cabal/Script.hs)2
-rw-r--r--cabal/cabal-testsuite/src/Test/Cabal/Server.hs (renamed from cabal/cabal-testsuite/Test/Cabal/Server.hs)0
-rw-r--r--cabal/cabal-testsuite/src/Test/Cabal/Workdir.hs (renamed from cabal/cabal-testsuite/Test/Cabal/Workdir.hs)0
-rw-r--r--cabal/cabal.project5
-rw-r--r--cabal/cabal.project.buildinfo10
-rw-r--r--cabal/cabal.project.release11
-rw-r--r--cabal/cabal.project.validate11
-rw-r--r--cabal/cabal.project.validate.libonly5
-rw-r--r--cabal/cabal.project.weeder14
-rw-r--r--cabal/changelog.d/Cabal-QuickCheck4
-rw-r--r--cabal/changelog.d/Cabal-tree-diff3
-rw-r--r--cabal/changelog.d/PerCompilerFlavor-functor3
-rw-r--r--cabal/changelog.d/active-repositories14
-rw-r--r--cabal/changelog.d/added-tests11
-rw-r--r--cabal/changelog.d/backported43
-rw-r--r--cabal/changelog.d/build-reports3
-rw-r--r--cabal/changelog.d/cabal-init19
-rw-r--r--cabal/changelog.d/cabal-list5
-rw-r--r--cabal/changelog.d/cabal-project-local-tilde3
-rw-r--r--cabal/changelog.d/cabal-sdist32
-rw-r--r--cabal/changelog.d/cabal-spec-3.49
-rw-r--r--cabal/changelog.d/cabal-testsuite8
-rw-r--r--cabal/changelog.d/cabalInstallVersion3
-rw-r--r--cabal/changelog.d/changelog3
-rw-r--r--cabal/changelog.d/ci24
-rw-r--r--cabal/changelog.d/code-organization16
-rw-r--r--cabal/changelog.d/config2
-rw-r--r--cabal/changelog.d/copyright2
-rw-r--r--cabal/changelog.d/dependency16
-rw-r--r--cabal/changelog.d/described8
-rw-r--r--cabal/changelog.d/documentation4
-rw-r--r--cabal/changelog.d/expose-all-unfoldings9
-rw-r--r--cabal/changelog.d/flag-assignment3
-rw-r--r--cabal/changelog.d/ghc-8.1218
-rw-r--r--cabal/changelog.d/ghci-fix8
-rw-r--r--cabal/changelog.d/help-remove-new-aliases3
-rw-r--r--cabal/changelog.d/index-state5
-rw-r--r--cabal/changelog.d/install-prints-destination3
-rw-r--r--cabal/changelog.d/install-sha2563
-rw-r--r--cabal/changelog.d/issue-47464
-rw-r--r--cabal/changelog.d/issue-52244
-rw-r--r--cabal/changelog.d/issue-55554
-rw-r--r--cabal/changelog.d/issue-558612
-rw-r--r--cabal/changelog.d/issue-597314
-rw-r--r--cabal/changelog.d/issue-608323
-rw-r--r--cabal/changelog.d/issue-62104
-rw-r--r--cabal/changelog.d/issue-62813
-rw-r--r--cabal/changelog.d/issue-62883
-rw-r--r--cabal/changelog.d/issue-63694
-rw-r--r--cabal/changelog.d/issue-63934
-rw-r--r--cabal/changelog.d/issue-64324
-rw-r--r--cabal/changelog.d/issue-64853
-rw-r--r--cabal/changelog.d/issue-656513
-rw-r--r--cabal/changelog.d/issue-65754
-rw-r--r--cabal/changelog.d/issue-65896
-rw-r--r--cabal/changelog.d/issue-661011
-rw-r--r--cabal/changelog.d/issue-66224
-rw-r--r--cabal/changelog.d/issue-669113
-rw-r--r--cabal/changelog.d/issue-671016
-rw-r--r--cabal/changelog.d/issue-672911
-rw-r--r--cabal/changelog.d/issue-67393
-rw-r--r--cabal/changelog.d/issue-68044
-rw-r--r--cabal/changelog.d/issue-68053
-rw-r--r--cabal/changelog.d/issue-680711
-rw-r--r--cabal/changelog.d/issue-68094
-rw-r--r--cabal/changelog.d/issue-68564
-rw-r--r--cabal/changelog.d/issue-68694
-rw-r--r--cabal/changelog.d/linux-androideabi9
-rw-r--r--cabal/changelog.d/man-command3
-rw-r--r--cabal/changelog.d/others10
-rw-r--r--cabal/changelog.d/parser-benchmark2
-rw-r--r--cabal/changelog.d/pr-68783
-rw-r--r--cabal/changelog.d/pr-69292
-rw-r--r--cabal/changelog.d/public-libs2
-rw-r--r--cabal/changelog.d/public-libs-solver13
-rw-r--r--cabal/changelog.d/refactor-packagedescription-module9
-rw-r--r--cabal/changelog.d/remove-sandbox11
-rw-r--r--cabal/changelog.d/remove-text11
-rw-r--r--cabal/changelog.d/rewriteFileLBS3
-rw-r--r--cabal/changelog.d/spdx3
-rw-r--r--cabal/changelog.d/specVersion-type3
-rw-r--r--cabal/changelog.d/symlinking-windows11
-rw-r--r--cabal/changelog.d/use-process-jobs23
-rw-r--r--cabal/changelog.d/utf83
-rw-r--r--cabal/changelog.d/version-range-parser2
-rw-r--r--cabal/changelog.d/version-type10
-rw-r--r--cabal/changelog.d/versions-exact2
-rw-r--r--cabal/changelog.d/weeder2
-rw-r--r--cabal/generics-sop-lens.hs4
-rw-r--r--cabal/license-list-data/exceptions-3.9.json466
-rw-r--r--cabal/license-list-data/licenses-3.9.json5297
-rw-r--r--cabal/release-checklist.md1
-rw-r--r--cabal/release-notes/Cabal-3.4.0.0.md147
-rw-r--r--cabal/release-notes/cabal-install-3.4.0.0.md235
-rw-r--r--cabal/solver-benchmarks/HackageBenchmark.hs77
-rw-r--r--cabal/solver-benchmarks/LICENSE5
-rw-r--r--cabal/solver-benchmarks/solver-benchmarks.cabal6
-rw-r--r--cabal/tests/UnitTests/Distribution/Client/Init/goldens/generateCabalFile/exe-only.cabal16
-rw-r--r--cabal/tests/UnitTests/Distribution/Client/Init/goldens/generateCabalFile/lib-exe-and-test.cabal29
-rw-r--r--cabal/tests/fixtures/init/exe-only-golden.cabal20
-rw-r--r--cabal/tests/fixtures/init/lib-and-exe-golden.cabal31
-rw-r--r--cabal/tests/fixtures/init/lib-exe-and-test-golden.cabal43
-rw-r--r--cabal/tests/fixtures/init/lib-exe-and-test-with-comments-golden.cabal110
-rw-r--r--cabal/travis-common.sh8
-rwxr-xr-xcabal/travis-deploy.sh2
-rwxr-xr-xcabal/travis-install.sh4
-rwxr-xr-xcabal/travis-meta.sh4
-rwxr-xr-xcabal/travis-script.sh6
-rw-r--r--cabal/travis/binaries/.travis.yml4
-rw-r--r--cabal/validate.dockerfile48
-rwxr-xr-xcabal/validate.sh434
-rw-r--r--cabal/weeder.dhall9
-rw-r--r--hackage-security/.travis.yml130
-rw-r--r--hackage-security/example-client/example-client.cabal4
-rw-r--r--hackage-security/hackage-repo-tool/ChangeLog.md4
-rw-r--r--hackage-security/hackage-repo-tool/README.md98
-rw-r--r--hackage-security/hackage-repo-tool/hackage-repo-tool.cabal52
-rw-r--r--hackage-security/hackage-root-tool/hackage-root-tool.cabal2
-rw-r--r--hackage-security/hackage-security-HTTP/hackage-security-HTTP.cabal2
-rw-r--r--hackage-security/hackage-security-curl/hackage-security-curl.cabal4
-rw-r--r--hackage-security/hackage-security-http-client/hackage-security-http-client.cabal4
-rw-r--r--hackage-security/hackage-security/ChangeLog.md6
-rw-r--r--hackage-security/hackage-security/hackage-security.cabal16
-rw-r--r--hackage-security/hackage-security/src/Hackage/Security/TUF/Patterns.hs9
-rw-r--r--hackage-security/hackage-security/src/Hackage/Security/Util/IO.hs4
-rw-r--r--hackport.cabal267
-rw-r--r--tests/Merge/UtilsSpec.hs120
-rw-r--r--tests/Merge/UtilsSpec.hs~53
-rw-r--r--tests/Portage/CabalSpec.hs69
-rw-r--r--tests/Portage/Dependency/PrintSpec.hs327
-rw-r--r--tests/Portage/EBuildSpec.hs29
-rw-r--r--tests/Portage/GHCCoreSpec.hs23
-rw-r--r--tests/Portage/MetadataSpec.hs80
-rw-r--r--tests/Portage/PackageIdSpec.hs69
-rw-r--r--tests/Portage/VersionSpec.hs27
-rw-r--r--tests/QuickCheck/Instances.hs44
-rw-r--r--tests/Spec.hs1
-rw-r--r--tests/doctests.hs12
999 files changed, 41232 insertions, 23368 deletions
diff --git a/AnsiColor.hs b/AnsiColor.hs
index dfe3e16..ffcd037 100644
--- a/AnsiColor.hs
+++ b/AnsiColor.hs
@@ -26,7 +26,7 @@ data Color = Black
esc :: [String] -> String
esc [] = ""
-esc xs = "\ESC[" ++ (concat . intersperse ";" $ xs) ++ "m"
+esc xs = "\ESC[" ++ (intercalate ";" xs) ++ "m"
col :: Color -> Bool -> Color -> [String]
col fg bf bg = show (fromEnum fg + 30) : bf' [show (fromEnum bg + 40)]
diff --git a/Cabal2Ebuild.hs b/Cabal2Ebuild.hs
index e5bb8a3..9ae3265 100644
--- a/Cabal2Ebuild.hs
+++ b/Cabal2Ebuild.hs
@@ -1,16 +1,16 @@
--- A program for generating a Gentoo ebuild from a .cabal file
---
--- Author : Duncan Coutts <dcoutts@gentoo.org>
---
--- Created: 21 July 2005
---
--- Copyright (C) 2005 Duncan Coutts
---
+{-|
+Module : Cabal2Ebuild
+Copyright : (C) 2005, Duncan Coutts
+License : GPL-2+
+Maintainer : haskell@gentoo.org
+
+A program for generating a Gentoo ebuild from a .cabal file
+-}
-- This library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; either version 2
-- of the License, or (at your option) any later version.
---
+
-- This library is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
@@ -22,14 +22,17 @@ module Cabal2Ebuild
,convertDependency) where
import qualified Distribution.PackageDescription as Cabal
- (PackageDescription(..), license)
-import qualified Distribution.Package as Cabal (PackageIdentifier(..)
+ ( PackageDescription(..), license)
+import qualified Distribution.Package as Cabal ( PackageIdentifier(..)
, Dependency(..))
-import qualified Distribution.Version as Cabal (VersionRange, cataVersionRange, normaliseVersionRange
- , wildcardUpperBound, majorUpperBound)
+import qualified Distribution.Version as Cabal ( VersionRange
+ , cataVersionRange, normaliseVersionRange
+ , majorUpperBound, mkVersion )
import Distribution.Version (VersionRangeF(..))
import Distribution.Pretty (prettyShow)
+import qualified Distribution.Utils.ShortText as ST
+
import Data.Char (isUpper)
import Data.Maybe
@@ -43,16 +46,19 @@ import qualified Portage.EBuild as E
import qualified Portage.Overlay as O
import Portage.Version
+-- | Generate a 'Portage.EBuild' from a 'Portage.Category' and a 'Cabal.PackageDescription'.
cabal2ebuild :: Portage.Category -> Cabal.PackageDescription -> Portage.EBuild
cabal2ebuild cat pkg = Portage.ebuildTemplate {
E.name = Portage.cabal_pn_to_PN cabal_pn,
E.category = prettyShow cat,
E.hackage_name= cabalPkgName,
E.version = prettyShow (Cabal.pkgVersion (Cabal.package pkg)),
- E.description = if null (Cabal.synopsis pkg) then Cabal.description pkg
- else Cabal.synopsis pkg,
- E.long_desc = if null (Cabal.description pkg) then Cabal.synopsis pkg
- else Cabal.description pkg,
+ E.description = ST.fromShortText $ if ST.null (Cabal.synopsis pkg)
+ then Cabal.description pkg
+ else Cabal.synopsis pkg,
+ E.long_desc = ST.fromShortText $ if ST.null (Cabal.description pkg)
+ then Cabal.synopsis pkg
+ else Cabal.description pkg,
E.homepage = thisHomepage,
E.license = Portage.convertLicense $ Cabal.license pkg,
E.slot = (E.slot E.ebuildTemplate) ++ (if hasLibs then "/${PV}" else ""),
@@ -74,13 +80,15 @@ cabal2ebuild cat pkg = Portage.ebuildTemplate {
cabalPkgName = prettyShow cabal_pn
hasLibs = isJust (Cabal.library pkg)
hasTests = (not . null) (Cabal.testSuites pkg)
- thisHomepage = if (null $ Cabal.homepage pkg)
+ thisHomepage = if (ST.null $ Cabal.homepage pkg)
then E.homepage E.ebuildTemplate
- else Cabal.homepage pkg
+ else ST.fromShortText $ Cabal.homepage pkg
+-- | Map 'convertDependency' over ['Cabal.Dependency'].
convertDependencies :: O.Overlay -> Portage.Category -> [Cabal.Dependency] -> [Dependency]
convertDependencies overlay category = map (convertDependency overlay category)
+-- | Convert 'Cabal.Dependency' into 'Dependency'.
convertDependency :: O.Overlay -> Portage.Category -> Cabal.Dependency -> Dependency
convertDependency overlay category (Cabal.Dependency pname versionRange _lib)
= convert versionRange
@@ -95,16 +103,15 @@ convertDependency overlay category (Cabal.Dependency pname versionRange _lib)
convert :: Cabal.VersionRange -> Dependency
convert = Cabal.cataVersionRange alg . Cabal.normaliseVersionRange
where
- alg AnyVersionF = mk_p $ DRange ZeroB InfinityB
alg (ThisVersionF v) = mk_p $ DExact $ p_v v
alg (LaterVersionF v) = mk_p $ DRange (StrictLB $ p_v v) InfinityB
alg (EarlierVersionF v) = mk_p $ DRange ZeroB $ StrictUB $ p_v v
- alg (OrLaterVersionF v) = mk_p $ DRange (NonstrictLB $ p_v v) InfinityB
+ alg (OrLaterVersionF v) = if v == Cabal.mkVersion [0] -- any version
+ then mk_p $ DRange ZeroB InfinityB
+ else mk_p $ DRange (NonstrictLB $ p_v v)
+ InfinityB
alg (OrEarlierVersionF v) = mk_p $ DRange ZeroB $ NonstrictUB $ p_v v
- alg (WildcardVersionF v) = mk_p $ DRange (NonstrictLB $ p_v v)
- $ StrictUB $ p_v $ Cabal.wildcardUpperBound v
alg (MajorBoundVersionF v) = mk_p $ DRange (NonstrictLB $ p_v v)
$ StrictUB $ p_v $ Cabal.majorUpperBound v
alg (UnionVersionRangesF v1 v2) = DependAnyOf [v1, v2]
alg (IntersectVersionRangesF v1 v2) = DependAllOf [v1, v2]
- alg (VersionRangeParensF v) = v
diff --git a/Error.hs b/Error.hs
index 4529005..1a92cc7 100644
--- a/Error.hs
+++ b/Error.hs
@@ -5,6 +5,7 @@ module Error (HackPortError(..), throwEx, catchEx, hackPortShowError) where
import Data.Typeable
import Control.Exception.Extensible as EE
+-- | Type holding all of the 'HackPortError' constructors.
data HackPortError
= ArgumentError String
| ConnectionFailed String String
@@ -26,16 +27,22 @@ data HackPortError
-- | WrongCacheVersion
-- | InvalidCache
| InvalidServer String
- deriving (Typeable, Show)
+ deriving (Typeable
+ , Show
+ , Eq -- ^ needed for spec test-suite
+ )
instance Exception HackPortError where
+-- | Throw a 'HackPortError'.
throwEx :: HackPortError -> IO a
throwEx = EE.throw
+-- | Catch a 'HackPortError'.
catchEx :: IO a -> (HackPortError -> IO a) -> IO a
catchEx = EE.catch
+-- | Show the error string for a given 'HackPortError'.
hackPortShowError :: HackPortError -> String
hackPortShowError err = case err of
ArgumentError str -> "Argument error: "++str
diff --git a/HACKING.rst b/HACKING.rst
index 986854e..db73232 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -140,8 +140,9 @@ First, create a tag of your new ``HackPort`` version:
The ``-s`` option signs the tag with your GnuPG key, if you wish to do
this.
-Next, run the ‘mk_release_tarball.bash’ script. ``cabal sdist`` does not
-build the submodules, which is why we need to use this script instead.
+Next, run the ‘mk_release_tarball.bash’ script. This is similar to ``cabal sdist``
+except that it also strips out unnecessary files and creates a tarball
+from the latest tag rather than ``HEAD``.
Assuming everything builds correctly and you are a designated
``HackPort`` maintainer on Hackage, you can publish the ``HackPort``
@@ -163,6 +164,3 @@ TODO
- Include section explaining how to determine and add the list of bundled
libraries for a given GHC version to ``HackPort``.
-
-
-
diff --git a/HackPort/GlobalFlags.hs b/HackPort/GlobalFlags.hs
index 9fc364c..18f3129 100644
--- a/HackPort/GlobalFlags.hs
+++ b/HackPort/GlobalFlags.hs
@@ -17,6 +17,7 @@ import System.FilePath ((</>))
import qualified Overlays
+-- | Type containing global flags.
data GlobalFlags =
GlobalFlags { globalVersion :: DSS.Flag Bool
, globalNumericVersion :: DSS.Flag Bool
@@ -24,6 +25,7 @@ data GlobalFlags =
, globalPathToPortage :: DSS.Flag (Maybe FilePath)
}
+-- | Default 'GlobalFlags'.
defaultGlobalFlags :: GlobalFlags
defaultGlobalFlags =
GlobalFlags { globalVersion = DSS.Flag False
@@ -32,8 +34,9 @@ defaultGlobalFlags =
, globalPathToPortage = DSS.Flag Nothing
}
+-- | Default remote repository. Defaults to [hackage](hackage.haskell.org).
defaultRemoteRepo :: DCT.RemoteRepo
-defaultRemoteRepo = DCC.addInfoForKnownRepos $ (DCT.emptyRemoteRepo name) { DCT.remoteRepoURI = uri }
+defaultRemoteRepo = DCC.addInfoForKnownRepos $ (DCT.emptyRemoteRepo (DCT.RepoName name)) { DCT.remoteRepoURI = uri }
where
Just uri = NU.parseURI "https://hackage.haskell.org/"
name = "hackage.haskell.org"
diff --git a/Main.hs b/Main.hs
index fa63224..bf9afd2 100644
--- a/Main.hs
+++ b/Main.hs
@@ -116,7 +116,7 @@ listAction flags extraArgs globalFlags = do
overlay <- Overlay.loadLazy overlayPath
let pkgs | null extraArgs = CabalInstall.allPackages index
| otherwise = concatMap (concatMap snd . CabalInstall.searchByNameSubstring index) extraArgs
- normalized = map (normalizeCabalPackageId . CabalInstall.packageInfoId) pkgs
+ normalized = map (normalizeCabalPackageId . CabalInstall.srcpkgPackageId) pkgs
let decorated = map (\p -> (Overlay.inOverlay overlay p, p)) normalized
mapM_ (putStrLn . pretty) decorated
where
diff --git a/Merge.hs b/Merge.hs
index de02ea6..5d90d73 100644
--- a/Merge.hs
+++ b/Merge.hs
@@ -1,3 +1,10 @@
+{-|
+Module : Merge
+License : GPL-3+
+Maintainer : haskell@gentoo.org
+
+Core functionality of the @merge@ command of @HackPort@.
+-}
module Merge
( merge
, mergeGenericPackageDescription
@@ -5,9 +12,10 @@ module Merge
import Control.Monad
import Control.Exception
-import qualified Data.ByteString.Lazy.Char8 as BL
-import qualified Data.ByteString.Builder as BL (stringUtf8, toLazyByteString)
+import qualified Data.Text as T
+import qualified Data.Text.IO as T
import Data.Function (on)
+import qualified Data.Map.Strict as Map
import Data.Maybe
import qualified Data.List as L
import qualified Data.Set as S
@@ -29,7 +37,6 @@ import Distribution.Simple.Utils
import Distribution.Client.IndexUtils ( getSourcePackages )
import qualified Distribution.Client.GlobalFlags as CabalInstall
import Distribution.Client.Types
-
-- others
import qualified Data.List.Split as DLS
import System.Directory ( getCurrentDirectory
@@ -39,10 +46,10 @@ import System.Directory ( getCurrentDirectory
, listDirectory
)
import System.Process (system)
-import System.FilePath ((</>))
-import qualified System.FilePath as SF
+import System.FilePath ((</>),(<.>))
import System.Exit
+import qualified AnsiColor as A
import qualified Cabal2Ebuild as C2E
import qualified Portage.EBuild as E
import qualified Portage.EMeta as EM
@@ -60,48 +67,43 @@ import qualified Portage.Use as Portage
import qualified Portage.GHCCore as GHCCore
import qualified Merge.Dependencies as Merge
-
-(<.>) :: String -> String -> String
-a <.> b = a ++ '.':b
+import qualified Merge.Utils as Merge
{-
Requested features:
* Add files to git?
-}
-readPackageString :: [String]
- -> Either HackPortError ( Maybe Portage.Category
- , Cabal.PackageName
- , Maybe Portage.Version
- )
-readPackageString args = do
- packageString <-
- case args of
- [] -> Left (ArgumentError "Need an argument, [category/]package[-version]")
- [pkg] -> return pkg
- _ -> Left (ArgumentError ("Too many arguments: " ++ unwords args))
- case Portage.parseFriendlyPackage packageString of
- Right v@(_,_,Nothing) -> return v
- -- we only allow versions we can convert into cabal versions
- Right v@(_,_,Just (Portage.Version _ Nothing [] 0)) -> return v
- Left e -> Left $ ArgumentError $ "Could not parse [category/]package[-version]: "
- ++ packageString ++ "\nParsec error: " ++ e
- _ -> Left $ ArgumentError $ "Could not parse [category/]package[-version]: "
- ++ packageString
+-- | Call @diff@ between two ebuilds.
+diffEbuilds :: FilePath -> Portage.PackageId -> Portage.PackageId -> IO ()
+diffEbuilds fp a b = do _ <- system $ "diff -u --color=auto "
+ ++ fp </> Portage.packageIdToFilePath a ++ " "
+ ++ fp </> Portage.packageIdToFilePath b
+ exitSuccess
-- | Given a list of available packages, and maybe a preferred version,
-- return the available package with that version. Latest version is chosen
-- if no preference.
resolveVersion :: [UnresolvedSourcePackage] -> Maybe Cabal.Version -> Maybe UnresolvedSourcePackage
-resolveVersion avails Nothing = Just $ L.maximumBy (comparing (Cabal.pkgVersion . CabalInstall.packageInfoId)) avails
+resolveVersion avails Nothing = Just $ L.maximumBy (comparing (Cabal.pkgVersion . CabalInstall.srcpkgPackageId)) avails
resolveVersion avails (Just ver) = listToMaybe (filter match avails)
where
- match avail = ver == Cabal.pkgVersion (CabalInstall.packageInfoId avail)
-
+ match avail = ver == Cabal.pkgVersion (CabalInstall.srcpkgPackageId avail)
+
+-- | This function is executed by the @merge@ command of @HackPort@.
+-- Its functionality is as follows:
+--
+-- 1. Feed user input to 'readPackageString'
+-- 2. Look for a matching package on the @hackage@ database
+-- 3. Run 'mergeGenericPackageDescription' with the supplied information
+-- 4. Generate a coloured diff between the old and new ebuilds.
+--
+-- Various information is printed in between these steps depending on the
+-- 'Verbosity'.
merge :: Verbosity -> CabalInstall.RepoContext -> [String] -> FilePath -> Maybe String -> IO ()
merge verbosity repoContext args overlayPath users_cabal_flags = do
(m_category, user_pName, m_version) <-
- case readPackageString args of
+ case Merge.readPackageString args of
Left err -> throwEx err
Right (c,p,m_v) ->
case m_v of
@@ -126,12 +128,12 @@ merge verbosity repoContext args overlayPath users_cabal_flags = do
case map snd (CabalInstall.searchByName index user_pname_str) of
[] -> throwEx (PackageNotFound user_pname_str)
[pkg] -> return pkg
- pkgs -> do let cabal_pkg_to_pn pkg = Cabal.unPackageName $ Cabal.pkgName (CabalInstall.packageInfoId pkg)
+ pkgs -> do let cabal_pkg_to_pn pkg = Cabal.unPackageName $ Cabal.pkgName (CabalInstall.srcpkgPackageId pkg)
names = map (cabal_pkg_to_pn . L.head) pkgs
notice verbosity $ "Ambiguous names: " ++ L.intercalate ", " names
forM_ pkgs $ \ps ->
do let p_name = (cabal_pkg_to_pn . L.head) ps
- notice verbosity $ p_name ++ ": " ++ (L.intercalate ", " $ map (prettyShow . Cabal.pkgVersion . CabalInstall.packageInfoId) ps)
+ notice verbosity $ p_name ++ ": " ++ (L.intercalate ", " $ map (prettyShow . Cabal.pkgVersion . CabalInstall.srcpkgPackageId) ps)
return $ concat pkgs
-- select a single package taking into account the user specified version
@@ -140,74 +142,35 @@ merge verbosity repoContext args overlayPath users_cabal_flags = do
Nothing -> do
putStrLn "No such version for that package, available versions:"
forM_ availablePkgs $ \ avail ->
- putStrLn (prettyShow . CabalInstall.packageInfoId $ avail)
+ putStrLn (prettyShow . CabalInstall.srcpkgPackageId $ avail)
throwEx (ArgumentError "no such version for that package")
Just avail -> return avail
-- print some info
info verbosity "Selecting package:"
forM_ availablePkgs $ \ avail -> do
- let match_text | CabalInstall.packageInfoId avail == CabalInstall.packageInfoId selectedPkg = "* "
+ let match_text | CabalInstall.srcpkgPackageId avail == CabalInstall.srcpkgPackageId selectedPkg = "* "
| otherwise = "- "
- info verbosity $ match_text ++ (prettyShow . CabalInstall.packageInfoId $ avail)
+ info verbosity $ match_text ++ (prettyShow . CabalInstall.srcpkgPackageId $ avail)
- let cabal_pkgId = CabalInstall.packageInfoId selectedPkg
+ let cabal_pkgId = CabalInstall.srcpkgPackageId selectedPkg
norm_pkgName = Cabal.packageName (Portage.normalizeCabalPackageId cabal_pkgId)
cat <- maybe (Portage.resolveCategory verbosity overlay norm_pkgName) return m_category
- mergeGenericPackageDescription verbosity overlayPath cat (CabalInstall.packageDescription selectedPkg) True users_cabal_flags
+ mergeGenericPackageDescription verbosity overlayPath cat (CabalInstall.srcpkgDescription selectedPkg) True users_cabal_flags
-- Maybe generate a diff
let pkgPath = overlayPath </> (Portage.unCategory cat) </> (Cabal.unPackageName norm_pkgName)
newPkgId = Portage.fromCabalPackageId cat cabal_pkgId
pkgDir <- listDirectory pkgPath
- case getPreviousPackageId pkgDir newPkgId of
+ case Merge.getPreviousPackageId pkgDir newPkgId of
Just validPkg -> do info verbosity "Generating a diff..."
diffEbuilds overlayPath validPkg newPkgId
_ -> info verbosity "Nothing to diff!"
-
--- | Call diff between two ebuilds.
-diffEbuilds :: FilePath -> Portage.PackageId -> Portage.PackageId -> IO ()
-diffEbuilds fp a b = do _ <- system $ "diff -u --color=auto "
- ++ fp </> Portage.packageIdToFilePath a ++ " "
- ++ fp </> Portage.packageIdToFilePath b
- exitSuccess
-
--- | Maybe return a PackageId of the next highest version for a given
--- package, relative to the provided PackageId.
-getPreviousPackageId :: [FilePath] -- ^ list of ebuilds for given package
- -> Portage.PackageId -- ^ new PackageId
- -> Maybe Portage.PackageId -- ^ maybe PackageId of previous version
-getPreviousPackageId pkgDir newPkgId = do
- let pkgIds = reverse
- . L.sortOn (Portage.pkgVersion)
- . filter (<newPkgId)
- $ mapMaybe (Portage.filePathToPackageId (Portage.category . Portage.packageId $ newPkgId))
- $ SF.dropExtension <$> filter (\fp -> SF.takeExtension fp == ".ebuild") pkgDir
- case pkgIds of
- x:_ -> Just x
- _ -> Nothing
-
-first_just_of :: [Maybe a] -> Maybe a
-first_just_of = msum
-
--- Gentoo allows underscore ('_') names in IUSE only for
--- USE_EXPAND values. If it's not a user-specified rename mangle
--- it into a hyphen ('-').
-mangle_iuse :: String -> String
-mangle_iuse = drop_prefix . map f
- where f '_' = '-'
- f c = c
-
--- | Remove "with" or "use" prefixes from flag names.
-drop_prefix :: String -> String
-drop_prefix x
- | take 5 x `elem` ["with_","with-"] = drop 5 x
- | take 4 x `elem` ["use_","use-"] = drop 4 x
- | otherwise = x
-- used to be FlagAssignment in Cabal but now it's an opaque type
type CabalFlags = [(Cabal.FlagName, Bool)]
+-- | Generate an ebuild from a 'Cabal.GenericPackageDescription'.
mergeGenericPackageDescription :: Verbosity -> FilePath -> Portage.Category -> Cabal.GenericPackageDescription -> Bool -> Maybe String -> IO ()
mergeGenericPackageDescription verbosity overlayPath cat pkgGenericDesc fetch users_cabal_flags = do
overlay <- Overlay.loadLazy overlayPath
@@ -215,7 +178,7 @@ mergeGenericPackageDescription verbosity overlayPath cat pkgGenericDesc fetch us
merged_PN = Portage.cabal_pn_to_PN merged_cabal_pkg_name
pkgdir = overlayPath </> Portage.unCategory cat </> merged_PN
existing_meta <- EM.findExistingMeta pkgdir
- let requested_cabal_flags = first_just_of [users_cabal_flags, EM.cabal_flags existing_meta]
+ let requested_cabal_flags = Merge.first_just_of [users_cabal_flags, EM.cabal_flags existing_meta]
-- accepts things, like: "cabal_flag:iuse_name", "+cabal_flag", "-cabal_flag"
read_fas :: Maybe String -> (CabalFlags, [(String, String)])
@@ -264,7 +227,7 @@ mergeGenericPackageDescription verbosity overlayPath cat pkgGenericDesc fetch us
pkgDesc = Merge.RetroPackageDescription pkgDesc0 accepted_deps
cabal_flag_descs = Cabal.genPackageFlags pkgGenericDesc
all_flags = map Cabal.flagName cabal_flag_descs
- make_fas :: [Cabal.Flag] -> [CabalFlags]
+ make_fas :: [Cabal.PackageFlag] -> [CabalFlags]
make_fas [] = [[]]
make_fas (f:rest) = [ (fn, is_enabled) : fas
| fas <- make_fas rest
@@ -286,7 +249,7 @@ mergeGenericPackageDescription verbosity overlayPath cat pkgGenericDesc fetch us
cfn_to_iuse :: String -> String
cfn_to_iuse cfn =
case lookup cfn cf_to_iuse_rename of
- Nothing -> mangle_iuse cfn
+ Nothing -> Merge.mangle_iuse cfn
Just ein -> ein
-- key idea is to generate all possible list of flags
deps1 :: [(CabalFlags, Merge.EDep)]
@@ -439,6 +402,9 @@ mergeGenericPackageDescription verbosity overlayPath cat pkgGenericDesc fetch us
norm_pkgName = Cabal.packageName (Portage.normalizeCabalPackageId cabal_pkgId)
fetchDigestAndCheck verbosity (overlayPath </> prettyShow cat </> prettyShow norm_pkgName)
+-- | Run various @repoman@ commands in the directory of the newly-generated ebuild.
+-- This will ensure well-formed ebuilds and @metadata.xml@, and will update (if possible)
+-- the @Manifest@ file.
fetchDigestAndCheck :: Verbosity
-> FilePath -- ^ directory of ebuild
-> IO ()
@@ -461,33 +427,44 @@ withWorkingDirectory newDir action = do
(\_ -> setCurrentDirectory oldDir)
(\_ -> action)
--- "amd64" -> "~amd64"
-to_unstable :: String -> String
-to_unstable kw =
- case kw of
- '~':_ -> kw
- '-':_ -> kw
- _ -> '~':kw
-
--- | Generate a list of tuples containing Cabal flag names and descriptions
-metaFlags :: [Cabal.Flag] -> [(String, String)]
-metaFlags flags = zip (mangle_iuse . Cabal.unFlagName . Cabal.flagName <$> flags) (Cabal.flagDescription <$> flags)
-
-mergeEbuild :: Verbosity -> EM.EMeta -> FilePath -> E.EBuild -> [Cabal.Flag] -> IO ()
+-- | Write the ebuild (and sometimes a new @metadata.xml@) to its directory.
+mergeEbuild :: Verbosity -> EM.EMeta -> FilePath -> E.EBuild -> [Cabal.PackageFlag] -> IO ()
mergeEbuild verbosity existing_meta pkgdir ebuild flags = do
let edir = pkgdir
elocal = E.name ebuild ++"-"++ E.version ebuild <.> "ebuild"
epath = edir </> elocal
emeta = "metadata.xml"
mpath = edir </> emeta
- default_meta = BL.toLazyByteString . BL.stringUtf8
- $ Portage.makeDefaultMetadata (E.long_desc ebuild)
- $ metaFlags flags
+ yet_meta <- doesFileExist mpath
+ -- If there is an existing @metadata.xml@, read it in as a 'T.Text'.
+ -- Otherwise return 'T.empty'. We only use this once more to directly
+ -- compare to @default_meta@ before writing it.
+ current_meta <- if yet_meta
+ then T.readFile mpath
+ else return T.empty
+ -- Either create an object of the 'Portage.Metadata' type from a valid @current_meta@,
+ -- or supply a default minimal metadata object. Note the difference to @current_meta@:
+ -- @current_meta@ is of type 'T.Text', @current_meta'@ is of type 'Portage.Metadata'.
+ let current_meta' = fromMaybe Portage.makeMinimalMetadata
+ (Portage.pureMetadataFromFile current_meta)
+ -- Create the @metadata.xml@ string, adding new USE flags (if any) to those of
+ -- the existing @metadata.xml@. If an existing flag has a new and old description,
+ -- the new one takes precedence.
+ default_meta = Portage.makeDefaultMetadata (E.long_desc ebuild)
+ $ Merge.metaFlags flags `Map.union`
+ Portage.metadataUseFlags current_meta'
+ -- Create a 'Map.Map' of USE flags with updated descriptions.
+ new_flags = Map.differenceWith (\new old -> if (new /= old)
+ then Just $ old ++ A.bold (" -> " ++ new)
+ else Nothing)
+ (Merge.metaFlags flags)
+ $ Portage.metadataUseFlags current_meta'
+
createDirectoryIfMissing True edir
now <- TC.getCurrentTime
let (existing_keywords, existing_license, existing_description) = (EM.keywords existing_meta, EM.license existing_meta, EM.description existing_meta)
- new_keywords = maybe (E.keywords ebuild) (map to_unstable) existing_keywords
+ new_keywords = maybe (E.keywords ebuild) (map Merge.to_unstable) existing_keywords
new_license = either (\err -> maybe (Left err)
Right
existing_license)
@@ -504,12 +481,14 @@ mergeEbuild verbosity existing_meta pkgdir ebuild flags = do
notice verbosity $ "Current license: " ++ show existing_license ++ " -> " ++ show new_license
notice verbosity $ "Writing " ++ elocal
- length s_ebuild' `seq` BL.writeFile epath (BL.pack s_ebuild')
+ length s_ebuild' `seq` T.writeFile epath (T.pack s_ebuild')
- yet_meta <- doesFileExist mpath
- if not yet_meta -- TODO: add --force-meta-rewrite to opts
- then do notice verbosity $ "Writing " ++ emeta
- BL.writeFile mpath default_meta
- else do current_meta <- BL.readFile mpath
- when (current_meta /= default_meta) $
- notice verbosity $ "Default and current " ++ emeta ++ " differ."
+ when (current_meta /= default_meta) $ do
+ notice verbosity $ A.bold $ "Default and current " ++ emeta ++ " differ."
+ if (new_flags /= Map.empty)
+ then notice verbosity $ "New or updated USE flags:\n" ++
+ (unlines $ Portage.prettyPrintFlagsHuman new_flags)
+ else notice verbosity "No new USE flags."
+
+ notice verbosity $ "Writing " ++ emeta
+ T.writeFile mpath default_meta
diff --git a/Merge/Dependencies.hs b/Merge/Dependencies.hs
index 44771e8..6e1a0e6 100644
--- a/Merge/Dependencies.hs
+++ b/Merge/Dependencies.hs
@@ -1,7 +1,11 @@
-{-# LANGUAGE CPP #-}
+{-|
+Module : Merge.Dependencies
+License : GPL-3+
+Maintainer : haskell@gentoo.org
-{- | Merge a package from hackage to an ebuild.
- -}
+Merge a package from @hackage@ to an ebuild.
+-}
+{-# LANGUAGE CPP #-}
module Merge.Dependencies
( EDep(..)
, RetroPackageDescription(..)
@@ -13,15 +17,14 @@ module Merge.Dependencies
import Data.Maybe ( isJust, isNothing )
import Data.Monoid ( Monoid, mempty )
import qualified Data.List as L
-import qualified Data.Set as S
+import qualified Data.Set as S
+import qualified Distribution.CabalSpecVersion as Cabal
+import qualified Distribution.Compat.NonEmptySet as NES
import qualified Distribution.Package as Cabal
import qualified Distribution.PackageDescription as Cabal
import qualified Distribution.Version as Cabal
import qualified Distribution.Pretty as Cabal
-import qualified Distribution.Types.ExeDependency as Cabal
-import qualified Distribution.Types.LegacyExeDependency as Cabal
-import qualified Distribution.Types.PkgconfigDependency as Cabal
import qualified Distribution.Compiler as Cabal
@@ -42,7 +45,7 @@ import Debug.Trace ( trace )
import Data.Semigroup (Semigroup(..))
#endif
--- | Dependencies of an ebuild
+-- | Dependencies of an ebuild.
data EDep = EDep
{
rdep :: Portage.Dependency,
@@ -52,25 +55,23 @@ data EDep = EDep
}
deriving (Show, Eq, Ord)
--- | Cabal-1 style PackageDescription, with a top-level buildDepends function
+-- | Cabal-1 style 'Cabal.PackageDescription', with a top-level 'buildDepends' function.
data RetroPackageDescription = RetroPackageDescription {
packageDescription :: Cabal.PackageDescription,
buildDepends :: [Cabal.Dependency]
} deriving (Show)
--- | Construct a RetroPackageDescription using exeAndLibDeps for the buildDepends.
+-- | Construct a 'RetroPackageDescription' using 'exeAndLibDeps' for the 'buildDepends'.
mkRetroPD :: Cabal.PackageDescription -> RetroPackageDescription
mkRetroPD pd = RetroPackageDescription { packageDescription = pd, buildDepends = exeAndLibDeps pd }
--- | extract only the build dependencies for libraries and executables for a given package.
+-- | Extract only the build dependencies for libraries and executables for a given package.
exeAndLibDeps :: Cabal.PackageDescription -> [Cabal.Dependency]
-exeAndLibDeps pkg = L.union
- (concat
- $ map Cabal.targetBuildDepends
- $ map Cabal.buildInfo (Cabal.executables pkg))
- (concat
- $ map Cabal.targetBuildDepends
- $ map Cabal.libBuildInfo (Cabal.allLibraries pkg))
+exeAndLibDeps pkg = concatMap (Cabal.targetBuildDepends . Cabal.buildInfo)
+ (Cabal.executables pkg)
+ `L.union`
+ concatMap (Cabal.targetBuildDepends . Cabal.libBuildInfo)
+ (Cabal.allLibraries pkg)
#if MIN_VERSION_base(4,9,0)
instance Semigroup EDep where
@@ -99,6 +100,7 @@ instance Monoid EDep where
}
#endif
+-- | Resolve package dependencies from a 'RetroPackageDescription' into an 'EDep'.
resolveDependencies :: Portage.Overlay -> RetroPackageDescription -> Cabal.CompilerInfo
-> [Cabal.PackageName] -> Cabal.PackageName
-> EDep
@@ -193,7 +195,7 @@ setupDependencies overlay pkg ghc_package_names merged_cabal_pkg_name = deps
testDependencies :: Portage.Overlay -> Cabal.PackageDescription -> [Cabal.PackageName] -> Cabal.PackageName -> [Portage.Dependency]
testDependencies overlay pkg ghc_package_names merged_cabal_pkg_name = deps
- where cabalDeps = concat $ map Cabal.targetBuildDepends $ map Cabal.testBuildInfo (Cabal.testSuites pkg)
+ where cabalDeps = concatMap (Cabal.targetBuildDepends . Cabal.testBuildInfo) (Cabal.testSuites pkg)
cabalDeps' = fst $ Portage.partition_depends ghc_package_names merged_cabal_pkg_name cabalDeps
deps = C2E.convertDependencies overlay (Portage.Category "dev-haskell") cabalDeps'
@@ -219,10 +221,11 @@ cabalDependency overlay pkg ~(Cabal.CompilerInfo {
C2E.convertDependency overlay
(Portage.Category "dev-haskell")
(Cabal.Dependency (Cabal.mkPackageName "Cabal")
- finalCabalDep (S.singleton Cabal.defaultLibName))
+ finalCabalDep (NES.singleton Cabal.defaultLibName))
where
versionNumbers = Cabal.versionNumbers cabal_version
- userCabalVersion = Cabal.orLaterVersion (Cabal.specVersion pkg)
+ userCabalVersion = Cabal.orLaterVersion $ Cabal.mkVersion
+ $ Cabal.cabalSpecToVersionDigits $ Cabal.specVersion pkg
shippedCabalVersion = GHCCore.cabalFromGHC versionNumbers
shippedCabalDep = maybe Cabal.anyVersion Cabal.orLaterVersion shippedCabalVersion
finalCabalDep = Cabal.simplifyVersionRange
@@ -429,7 +432,7 @@ buildToolsProvided = ["hsc2hs"]
hackageBuildToolsDependencies :: Portage.Overlay -> Cabal.PackageDescription -> [Portage.Dependency]
hackageBuildToolsDependencies overlay (Cabal.PackageDescription { Cabal.library = lib, Cabal.executables = exes }) =
haskellDependencies overlay $ L.nub $
- [ Cabal.Dependency pn versionRange $ S.singleton Cabal.defaultLibName
+ [ Cabal.Dependency pn versionRange $ NES.singleton Cabal.defaultLibName
| Cabal.ExeDependency pn _component versionRange <- cabalDeps
]
where
diff --git a/Merge/Utils.hs b/Merge/Utils.hs
new file mode 100644
index 0000000..af2685e
--- /dev/null
+++ b/Merge/Utils.hs
@@ -0,0 +1,142 @@
+{-|
+Module : Merge.Utils
+License : GPL-3+
+Maintainer : haskell@gentoo.org
+
+Internal helper functions for "Merge".
+-}
+module Merge.Utils
+ ( readPackageString
+ , getPreviousPackageId
+ , first_just_of
+ , drop_prefix
+ , mangle_iuse
+ , to_unstable
+ , metaFlags
+ ) where
+
+import qualified Control.Monad as M
+import Data.Maybe (mapMaybe)
+import qualified Data.List as L
+import qualified Data.Map.Strict as Map
+import qualified System.FilePath as SF
+
+import Error
+import qualified Portage.PackageId as Portage
+
+import qualified Distribution.Package as Cabal
+import qualified Distribution.PackageDescription as Cabal
+
+-- | Parse a ['String'] as a valid package string. E.g. @category\/name-1.0.0@.
+-- Return 'HackPortError' if the string to parse is invalid.
+--
+-- When the ['String'] is valid:
+--
+-- >>> readPackageString ["dev-haskell/packagename1-1.0.0"]
+-- Right (Just (Category {unCategory = "dev-haskell"}),PackageName "packagename1",Just (Version {versionNumber = [1,0,0], versionChar = Nothing, versionSuffix = [], versionRevision = 0}))
+--
+-- When the ['String'] is empty:
+--
+-- >>> readPackageString []
+-- Left ...
+readPackageString :: [String]
+ -> Either HackPortError ( Maybe Portage.Category
+ , Cabal.PackageName
+ , Maybe Portage.Version
+ )
+readPackageString args = do
+ packageString <-
+ case args of
+ [] -> Left (ArgumentError "Need an argument, [category/]package[-version]")
+ [pkg] -> return pkg
+ _ -> Left (ArgumentError ("Too many arguments: " ++ unwords args))
+ case Portage.parseFriendlyPackage packageString of
+ Right v@(_,_,Nothing) -> return v
+ -- we only allow versions we can convert into cabal versions
+ Right v@(_,_,Just (Portage.Version _ Nothing [] 0)) -> return v
+ Left e -> Left $ ArgumentError $ "Could not parse [category/]package[-version]: "
+ ++ packageString ++ "\nParsec error: " ++ e
+ _ -> Left $ ArgumentError $ "Could not parse [category/]package[-version]: "
+ ++ packageString
+
+-- | Maybe return a 'Portage.PackageId' of the next highest version for a given
+-- package, relative to the provided 'Portage.PackageId'.
+--
+-- For example:
+--
+-- >>> let ebuildDir = ["foo-bar2-3.0.1.ebuild","metadata.xml"]
+-- >>> let newPkgId = Portage.PackageId (Portage.PackageName (Portage.Category "dev-haskell") (Cabal.mkPackageName "foo-bar2")) (Portage.Version [3,0,2] Nothing [] 0 )
+--
+-- >>> getPreviousPackageId ebuildDir newPkgId
+-- Just (PackageId {packageId = PackageName {category = Category {unCategory = "dev-haskell"}, cabalPkgName = PackageName "foo-bar2"}, pkgVersion = Version {versionNumber = [3,0,1], versionChar = Nothing, versionSuffix = [], versionRevision = 0}})
+getPreviousPackageId :: [FilePath] -- ^ list of ebuilds for given package
+ -> Portage.PackageId -- ^ new PackageId
+ -> Maybe Portage.PackageId -- ^ maybe PackageId of previous version
+getPreviousPackageId pkgDir newPkgId = do
+ let pkgIds = reverse
+ . L.sortOn (Portage.pkgVersion)
+ . filter (<newPkgId)
+ $ mapMaybe (Portage.filePathToPackageId (Portage.category . Portage.packageId $ newPkgId))
+ $ SF.dropExtension <$> filter (\fp -> SF.takeExtension fp == ".ebuild") pkgDir
+ case pkgIds of
+ x:_ -> Just x
+ _ -> Nothing
+
+-- | Alias for 'msum'.
+--
+-- prop> \a -> first_just_of a == M.msum a
+first_just_of :: [Maybe a] -> Maybe a
+first_just_of = M.msum
+
+-- | Remove @with@ or @use@ prefixes from flag names.
+--
+-- >>> drop_prefix "with_conduit"
+-- "conduit"
+-- >>> drop_prefix "use-https"
+-- "https"
+-- >>> drop_prefix "no_examples"
+-- "no_examples"
+drop_prefix :: String -> String
+drop_prefix x
+ | take 5 x `elem` ["with_","with-"] = drop 5 x
+ | take 4 x `elem` ["use_","use-"] = drop 4 x
+ | otherwise = x
+
+-- | Gentoo allows underscore ('_') names in @IUSE@ only for
+-- @USE_EXPAND@ values. If it's not a user-specified rename mangle
+-- it into a hyphen ('-').
+--
+-- >>> mangle_iuse "use_remove_my_underscores"
+-- "remove-my-underscores"
+mangle_iuse :: String -> String
+mangle_iuse = drop_prefix . map f
+ where f '_' = '-'
+ f c = c
+
+-- | Convert all stable keywords to testing (unstable) keywords.
+-- Preserve arch masks (-).
+--
+-- >>> to_unstable "amd64"
+-- "~amd64"
+-- >>> to_unstable "~amd64"
+-- "~amd64"
+-- >>> to_unstable "-amd64"
+-- "-amd64"
+to_unstable :: String -> String
+to_unstable kw =
+ case kw of
+ '~':_ -> kw
+ '-':_ -> kw
+ _ -> '~':kw
+
+-- | Generate a 'Map.Map' of 'Cabal.PackageFlag' names and their descriptions.
+--
+-- For example, if we construct a singleton list holding a 'Cabal.PackageFlag' with
+-- 'Cabal.FlagName' @foo@ and 'Cabal.FlagDescription' @bar@, we should get
+-- a 'Map.Map' containing those values:
+--
+-- >>> let flags = [(Cabal.emptyFlag (Cabal.mkFlagName "foo")) {Cabal.flagDescription = "bar"}]
+-- >>> metaFlags flags
+-- fromList [("foo","bar")]
+metaFlags :: [Cabal.PackageFlag] -> Map.Map String String
+metaFlags flags = Map.fromList $ zip (mangle_iuse . Cabal.unFlagName . Cabal.flagName <$> flags) (Cabal.flagDescription <$> flags)
diff --git a/Portage/Cabal.hs b/Portage/Cabal.hs
index be97b4f..3b74889 100644
--- a/Portage/Cabal.hs
+++ b/Portage/Cabal.hs
@@ -1,3 +1,11 @@
+{-|
+Module : Portage.Cabal
+License : GPL-3+
+Maintainer : haskell@gentoo.org
+
+Utilities to extract and manipulate information from a package's @.cabal@ file,
+such as its license and dependencies.
+-}
module Portage.Cabal
( convertLicense
, partition_depends
@@ -5,19 +13,49 @@ module Portage.Cabal
import qualified Data.List as L
-import qualified Distribution.License as Cabal
-import qualified Distribution.SPDX.License as SPDX
-import qualified Distribution.Package as Cabal
-import qualified Distribution.Pretty as Cabal
+import qualified Distribution.License as Cabal
+import qualified Distribution.SPDX as SPDX
+import qualified Distribution.Package as Cabal
+import qualified Distribution.Pretty as Cabal
--- map the cabal license type to the gentoo license string format
+-- | Convert the Cabal 'SPDX.License' into the Gentoo format, as a 'String'.
+--
+-- Generally, if the license is one of the common free-software or
+-- open-source licenses, 'convertLicense' should return the license
+-- as a 'Right' 'String':
+--
+-- >>> convertLicense (SPDX.License $ SPDX.simpleLicenseExpression SPDX.GPL_3_0_or_later)
+-- Right "GPL-3+"
+--
+-- >>> convertLicense (SPDX.License $ SPDX.simpleLicenseExpression SPDX.GPL_3_0_only)
+-- Right "GPL-3"
+--
+-- If it is a more obscure license, this should alert the user by returning
+-- a 'Left' 'String':
+--
+-- >>> convertLicense (SPDX.License $ SPDX.simpleLicenseExpression SPDX.EUPL_1_1)
+-- Left ...
convertLicense :: SPDX.License -> Either String String
convertLicense l =
case Cabal.licenseFromSPDX l of
-- good ones
- Cabal.AGPL mv -> Right $ "AGPL-" ++ (maybe "3" Cabal.prettyShow mv) -- almost certainly version 3
- Cabal.GPL mv -> Right $ "GPL-" ++ (maybe "2" Cabal.prettyShow mv) -- almost certainly version 2
- Cabal.LGPL mv -> Right $ "LGPL-" ++ (maybe "2.1" Cabal.prettyShow mv) -- probably version 2.1
+ Cabal.AGPL mv -> Right $ "AGPL-" ++ case (Cabal.prettyShow <$> mv) of
+ Just "3" -> "3"
+ Just "3.0" -> "3+"
+ _ -> "3" -- almost certainly version 3
+ Cabal.GPL mv -> Right $ "GPL-" ++ case (Cabal.prettyShow <$> mv) of
+ Just "2" -> "2"
+ Just "2.0" -> "2+"
+ Just "3" -> "3"
+ Just "3.0" -> "3+"
+ _ -> "2" -- possibly version 2
+ Cabal.LGPL mv -> Right $ "LGPL-" ++ case (Cabal.prettyShow <$> mv) of
+ Just "2" -> "2"
+ -- Cabal can't handle 2.0+ properly
+ Just "2.0" -> "2"
+ Just "3" -> "3"
+ Just "3.0" -> "3+"
+ _ -> "2.1" -- probably version 2.1
Cabal.BSD2 -> Right "BSD-2"
Cabal.BSD3 -> Right "BSD"
Cabal.BSD4 -> Right "BSD-4"
@@ -32,6 +70,7 @@ convertLicense l =
Cabal.OtherLicense -> Left "(Other) Please look at license file of package and pick it manually."
Cabal.UnspecifiedLicense -> Left "(Unspecified) Please look at license file of package and pick it manually."
+-- | Extract only the dependencies which are not bundled with @GHC@.
partition_depends :: [Cabal.PackageName] -> Cabal.PackageName -> [Cabal.Dependency] -> ([Cabal.Dependency], [Cabal.Dependency])
partition_depends ghc_package_names merged_cabal_pkg_name = L.partition (not . is_internal_depend)
where is_internal_depend (Cabal.Dependency pn _vr _lib) = is_itself || is_ghc_package
diff --git a/Portage/Dependency/Types.hs b/Portage/Dependency/Types.hs
index 320936e..e36c5a9 100644
--- a/Portage/Dependency/Types.hs
+++ b/Portage/Dependency/Types.hs
@@ -1,3 +1,10 @@
+{-|
+Module : Portage.Dependency.Types
+License : GPL-3+
+Maintainer : haskell@gentoo.org
+
+Functions and types related to processing Portage dependencies.
+-}
module Portage.Dependency.Types
(
SlotDepend(..)
@@ -16,14 +23,16 @@ module Portage.Dependency.Types
import Portage.PackageId
import Portage.Use
-data SlotDepend = AnySlot -- nothing special
- | AnyBuildTimeSlot -- ':='
- | GivenSlot String -- ':slotno'
+-- | Type of SLOT dependency of a dependency.
+data SlotDepend = AnySlot -- ^ nothing special
+ | AnyBuildTimeSlot -- ^ ':='
+ | GivenSlot String -- ^ ':slotno'
deriving (Eq, Show, Ord)
-data LBound = StrictLB Version
- | NonstrictLB Version
- | ZeroB
+-- | Type of lower bound of a dependency.
+data LBound = StrictLB Version -- ^ greater than (>)
+ | NonstrictLB Version -- ^ greater than or equal to (>=)
+ | ZeroB -- ^ no lower bound
deriving (Eq, Show)
instance Ord LBound where
@@ -38,10 +47,10 @@ instance Ord LBound where
compare (NonstrictLB lv) (StrictLB rv) = case compare lv rv of
EQ -> LT
r -> r
-
-data UBound = StrictUB Version -- <
- | NonstrictUB Version -- <=
- | InfinityB
+-- | Type of upper bound of a dependency.
+data UBound = StrictUB Version -- ^ less than (<)
+ | NonstrictUB Version -- ^ less than or equal to (<=)
+ | InfinityB -- ^ no upper bound
deriving (Eq, Show)
instance Ord UBound where
@@ -57,6 +66,10 @@ instance Ord UBound where
EQ -> GT
r -> r
+-- | Type of dependency version.
+--
+-- A dependency version may either be an exact 'Version' or a
+-- version range between a given 'LBound' and 'UBound'.
data DRange = DRange LBound UBound
| DExact Version
deriving (Eq, Show, Ord)
@@ -66,7 +79,7 @@ range_is_case_of (DRange llow lup) (DRange rlow rup)
| llow >= rlow && lup <= rup = True
range_is_case_of _ _ = False
--- True if 'left' "interval" covers at least as much as the 'right' "interval"
+-- | True if left 'DRange' covers at least as much as the right 'DRange'.
range_as_broad_as :: DRange -> DRange -> Bool
range_as_broad_as (DRange llow lup) (DRange rlow rup)
| llow <= rlow && lup >= rup = True
@@ -83,7 +96,8 @@ data Dependency = DependAtom Atom
data Atom = Atom PackageName DRange DAttr deriving (Eq, Show, Ord)
--- returns 'True' if left constraint is the same as (or looser than) right
+-- | True if left 'Dependency' constraint is the same as (or looser than) right
+-- 'Dependency' constraint.
dep_as_broad_as :: Dependency -> Dependency -> Bool
dep_as_broad_as l r
-- very broad (not only on atoms) special case
diff --git a/Portage/EBuild.hs b/Portage/EBuild.hs
index 82787ef..35ecd76 100644
--- a/Portage/EBuild.hs
+++ b/Portage/EBuild.hs
@@ -1,9 +1,21 @@
+{-|
+Module : Portage.EBuild
+License : GPL-3+
+Maintainer : haskell@gentoo.org
+
+Functions and types related to interpreting and manipulating an ebuild,
+as understood by the Portage package manager.
+-}
{-# LANGUAGE CPP #-}
module Portage.EBuild
( EBuild(..)
, ebuildTemplate
, showEBuild
, src_uri
+ -- hspec exports
+ , sort_iuse
+ , drop_tdot
+ , quote
) where
import Portage.Dependency
@@ -23,6 +35,7 @@ import qualified Paths_hackport(version)
import qualified System.Locale as TC
#endif
+-- | Type representing the information contained in an @.ebuild@.
data EBuild = EBuild {
name :: String,
category :: String,
@@ -52,6 +65,7 @@ getHackportVersion :: Version -> String
getHackportVersion Version {versionBranch=(x:s)} = foldl (\y z -> y ++ "." ++ (show z)) (show x) s
getHackportVersion Version {versionBranch=[]} = ""
+-- | Generate a minimal 'EBuild' template.
ebuildTemplate :: EBuild
ebuildTemplate = EBuild {
name = "foobar",
@@ -79,6 +93,9 @@ ebuildTemplate = EBuild {
-- | Given an EBuild, give the URI to the tarball of the source code.
-- Assumes that the server is always hackage.haskell.org.
+--
+-- >>> src_uri ebuild_template
+-- "https://hackage.haskell.org/package/${P}/${P}.tar.gz"
src_uri :: EBuild -> String
src_uri e =
case my_pn e of
@@ -89,6 +106,7 @@ src_uri e =
-- package
Just _ -> "https://hackage.haskell.org/package/${MY_P}/${MY_P}.tar.gz"
+-- | Pretty-print an 'EBuild' as a 'String'.
showEBuild :: TC.UTCTime -> EBuild -> String
showEBuild now ebuild =
ss ("# Copyright 1999-" ++ this_year ++ " Gentoo Authors"). nl.
@@ -142,12 +160,19 @@ showEBuild now ebuild =
this_year = TC.formatTime TC.defaultTimeLocale "%Y" now
replace old new = L.intercalate new . LS.splitOn old
--- "+a" -> "a"
--- "b" -> "b"
+-- | Sort IUSE alphabetically
+--
+-- >>> sort_iuse ["+a","b"]
+-- ["+a","b"]
sort_iuse :: [String] -> [String]
sort_iuse = L.sortBy (compare `F.on` dropWhile ( `elem` "+"))
--- drops trailing dot
+-- | Drop trailing dot(s).
+--
+-- >>> drop_tdot "foo."
+-- "foo"
+-- >>> drop_tdot "foo..."
+-- "foo"
drop_tdot :: String -> String
drop_tdot = reverse . dropWhile (== '.') . reverse
@@ -195,6 +220,7 @@ dep_str var extra dep = ss var. sc '='. quote' (ss $ drop_leadings $ unlines ext
deps_s = tabify (dep2str indent $ PN.normalize_depend dep)
drop_leadings = dropWhile (== '\t')
+-- | Place a 'String' between quotes, and correctly handle special characters.
quote :: String -> DString
quote str = sc '"'. ss (esc str). sc '"'
where
@@ -215,18 +241,16 @@ sepBy _ [] = id
sepBy _ [x] = ss x
sepBy s (x:xs) = ss x. ss s. sepBy s xs
-getRestIfPrefix ::
- String -> -- ^ the prefix
- String -> -- ^ the string
- Maybe String
+getRestIfPrefix :: String -- ^ the prefix
+ -> String -- ^ the string
+ -> Maybe String
getRestIfPrefix (p:ps) (x:xs) = if p==x then getRestIfPrefix ps xs else Nothing
getRestIfPrefix [] rest = Just rest
getRestIfPrefix _ [] = Nothing
-subStr ::
- String -> -- ^ the search string
- String -> -- ^ the string to be searched
- Maybe (String,String) -- ^ Just (pre,post) if string is found
+subStr :: String -- ^ the search string
+ -> String -- ^ the string to be searched
+ -> Maybe (String,String) -- ^ Just (pre,post) if string is found
subStr sstr str = case getRestIfPrefix sstr str of
Nothing -> if null str then Nothing else case subStr sstr (tail str) of
Nothing -> Nothing
@@ -234,9 +258,9 @@ subStr sstr str = case getRestIfPrefix sstr str of
Just rest -> Just ([],rest)
replaceMultiVars ::
- [(String,String)] -> -- ^ pairs of variable name and content
- String -> -- ^ string to be searched
- String -- ^ the result
+ [(String,String)] -- ^ pairs of variable name and content
+ -> String -- ^ string to be searched
+ -> String -- ^ the result
replaceMultiVars [] str = str
replaceMultiVars whole@((pname,cont):rest) str = case subStr cont str of
Nothing -> replaceMultiVars rest str
diff --git a/Portage/EBuild/CabalFeature.hs b/Portage/EBuild/CabalFeature.hs
index db84ba5..273e4db 100644
--- a/Portage/EBuild/CabalFeature.hs
+++ b/Portage/EBuild/CabalFeature.hs
@@ -1,11 +1,12 @@
{-# LANGUAGE LambdaCase #-}
--- CABAL_FEATURES="..." in haskell-cabal .ebuild files
--- see haskell-cabal.eclass for details on each of those
+-- | Support for CABAL_FEATURES="..." in haskell-cabal .ebuild files.
+-- See haskell-cabal.eclass for details on each of those.
module Portage.EBuild.CabalFeature (CabalFeature(..)) where
import Portage.EBuild.Render
+-- | Type representing @CABAL_FEATURES@ in an ebuild.
data CabalFeature = Lib
| Profile
| Haddock
diff --git a/Portage/EMeta.hs b/Portage/EMeta.hs
index 3425ad8..3e5ae8b 100644
--- a/Portage/EMeta.hs
+++ b/Portage/EMeta.hs
@@ -1,3 +1,12 @@
+{-|
+Module : Portage.EMeta
+License : GPL-3+
+Maintainer : haskell@gentoo.org
+
+Functions to propagate existing ebuild information
+(such as its licence, description, switched flags etc.) to
+a new ebuild.
+-}
module Portage.EMeta
( EMeta(..)
, findExistingMeta
@@ -11,15 +20,15 @@ import System.Directory (doesDirectoryExist, getDirectoryContents)
import System.FilePath ((</>))
import Text.Printf
--- tries to extract value of variable in 'var="val"' format
--- There should be exactly one variable assignment in ebuild
--- It's a bit artificial limitation, but it's common for 'if / else' blocks
+-- | Extract a value of variable in \'var=\"val\"\' format.
+-- There should be exactly one variable assignment in the ebuild.
+-- It's a bit of an artificial limitation, but it's common for \'if / else\' blocks.
extract_quoted_string :: FilePath -> String -> String -> Maybe String
extract_quoted_string ebuild_path s_ebuild var_name =
case filter (L.isPrefixOf var_prefix . ltrim) $ lines s_ebuild of
[] -> Nothing
[kw_line] -> up_to_quote $ skip_prefix $ ltrim kw_line
- other -> bail_out $ printf "strange '%s' assignmets:\n%s" var_name (unlines other)
+ other -> bail_out $ printf "strange '%s' assignments:\n%s" var_name (unlines other)
where ltrim :: String -> String
ltrim = dropWhile isSpace
@@ -32,8 +41,8 @@ extract_quoted_string ebuild_path s_ebuild var_name =
bail_out :: String -> e
bail_out msg = error $ printf "%s:extract_quoted_string %s" ebuild_path msg
--- tries to extract value of variable in '#hackport: var: val' format
--- There should be exactly one variable assignment in ebuild.
+-- | Extract a value of variable in \'#hackport: var: val\' format.
+-- There should be exactly one variable assignment in the ebuild.
extract_hackport_var :: FilePath -> String -> String -> Maybe String
extract_hackport_var ebuild_path s_ebuild var_name =
case filter (L.isPrefixOf var_prefix) $ lines s_ebuild of
@@ -46,29 +55,35 @@ extract_hackport_var ebuild_path s_ebuild var_name =
bail_out :: String -> e
bail_out msg = error $ printf "%s:extract_hackport_var %s" ebuild_path msg
+-- | Extract the existing keywords from an ebuild.
extractKeywords :: FilePath -> String -> Maybe [String]
extractKeywords ebuild_path s_ebuild =
words `fmap ` extract_quoted_string ebuild_path s_ebuild "KEYWORDS"
+-- | Extract the existing license from an ebuild.
extractLicense :: FilePath -> String -> Maybe String
extractLicense ebuild_path s_ebuild =
extract_quoted_string ebuild_path s_ebuild "LICENSE"
+-- | Extract the existing Cabal flags from an ebuild.
extractCabalFlags :: FilePath -> String -> Maybe String
extractCabalFlags ebuild_path s_ebuild =
extract_hackport_var ebuild_path s_ebuild "flags"
+-- | Extract the existing description from an ebuild.
extractDescription :: FilePath -> String -> Maybe String
extractDescription ebuild_path s_ebuild =
extract_quoted_string ebuild_path s_ebuild "DESCRIPTION"
--- aggregated (best inferred) metadata for a new ebuild of package
+-- | Type representing the aggregated (best inferred) metadata for a
+-- new ebuild of a package.
data EMeta = EMeta { keywords :: Maybe [String]
, license :: Maybe String
, cabal_flags :: Maybe String
, description :: Maybe String
}
+-- | Find the existing package metadata from the last available ebuild.
findExistingMeta :: FilePath -> IO EMeta
findExistingMeta pkgdir =
do ebuilds <- filter (L.isSuffixOf ".ebuild") `fmap` do b <- doesDirectoryExist pkgdir
diff --git a/Portage/GHCCore.hs b/Portage/GHCCore.hs
index 1b03a3e..4714858 100644
--- a/Portage/GHCCore.hs
+++ b/Portage/GHCCore.hs
@@ -1,5 +1,10 @@
+{-|
+Module : Portage.GHCCore
+License : GPL-3+
+Maintainer : haskell@gentoo.org
--- Guess GHC version from packages depended upon.
+Guess the appropriate GHC version from packages depended upon.
+-}
module Portage.GHCCore
( minimumGHCVersionToBuildPackage
, cabalFromGHC
@@ -7,6 +12,8 @@ module Portage.GHCCore
, finalizePD
, platform
, dependencySatisfiable
+ -- hspec exports
+ , packageIsCoreInAnyGHC
) where
import qualified Distribution.Compiler as DC
@@ -21,7 +28,6 @@ import Distribution.PackageDescription.Configuration
import Distribution.Compiler (CompilerId(..), CompilerFlavor(GHC))
import Distribution.System
import Distribution.Types.ComponentRequestedSpec (defaultComponentRequestedSpec)
-import Distribution.Types.Dependency (depPkgName, depVerRange)
import Distribution.Pretty (prettyShow)
@@ -30,12 +36,19 @@ import Data.List ( nub )
import Debug.Trace
--- ghcs tried in specified order.
--- It means that first ghc in this list is a minimum default.
+-- | Try each @GHC@ version in the specified order, from left to right.
+-- The first @GHC@ version in this list is a minimum default.
ghcs :: [(DC.CompilerInfo, InstalledPackageIndex)]
ghcs = modern_ghcs
- where modern_ghcs = [ghc741, ghc742, ghc762, ghc782, ghc7101, ghc7102, ghc801, ghc802, ghc821, ghc843, ghc863, ghc865, ghc881, ghc883, ghc8101]
-
+ where modern_ghcs = [ghc741, ghc742, ghc762, ghc782, ghc7101, ghc7102, ghc801, ghc802, ghc821, ghc843, ghc863, ghc865, ghc881, ghc883, ghc884, ghc8101]
+
+-- | Maybe determine the appropriate 'Cabal.Version' of the @Cabal@ package
+-- from a given @GHC@ version.
+--
+-- >>> cabalFromGHC [8,8,3]
+-- Just (mkVersion [3,0,1,0])
+-- >>> cabalFromGHC [9,9,9,9]
+-- Nothing
cabalFromGHC :: [Int] -> Maybe Cabal.Version
cabalFromGHC ver = lookup ver table
where
@@ -52,15 +65,25 @@ cabalFromGHC ver = lookup ver table
, ([8,6,5], Cabal.mkVersion [2,4,0,1])
, ([8,8,1], Cabal.mkVersion [3,0,0,0])
, ([8,8,3], Cabal.mkVersion [3,0,1,0])
+ , ([8,8,4], Cabal.mkVersion [3,0,1,0])
, ([8,10,1], Cabal.mkVersion [3,2,0,0])
]
platform :: Platform
platform = Platform X86_64 Linux
+-- | Is the package a core dependency of a specific version of @GHC@?
+--
+-- >>> packageIsCore (mkIndex ghc883_pkgs) (Cabal.mkPackageName "binary")
+-- True
+-- >>> all (== True) ((packageIsCore (mkIndex ghc883_pkgs)) <$> (packageNamesFromPackageIndex (mkIndex ghc883_pkgs)))
+-- True
packageIsCore :: InstalledPackageIndex -> Cabal.PackageName -> Bool
packageIsCore index pn = not . null $ lookupPackageName index pn
+-- | Is the package a core dependency of any version of @GHC@?
+-- >>> packageIsCoreInAnyGHC (Cabal.mkPackageName "array")
+-- True
packageIsCoreInAnyGHC :: Cabal.PackageName -> Bool
packageIsCoreInAnyGHC pn = any (flip packageIsCore pn) (map snd ghcs)
@@ -71,7 +94,7 @@ packageIsCoreInAnyGHC pn = any (flip packageIsCore pn) (map snd ghcs)
dependencySatisfiable :: InstalledPackageIndex -> Cabal.Dependency -> Bool
dependencySatisfiable pindex dep@(Cabal.Dependency pn _rang _lib)
| Cabal.unPackageName pn == "Win32" = False -- only exists on windows, not in linux
- | not . null $ lookupDependency pindex (depPkgName dep) (depVerRange dep) = True -- the package index satisfies the dep
+ | not . null $ lookupDependency pindex (Cabal.depPkgName dep) (Cabal.depVerRange dep) = True -- the package index satisfies the dep
| packageIsCoreInAnyGHC pn = False -- some other ghcs support the dependency
| otherwise = True -- the dep is not related with core packages, accept the dep
@@ -107,6 +130,9 @@ minimumGHCVersionToBuildPackage gpd user_specified_fas =
| g@(cinfo, pix) <- ghcs
, Right (pkg_desc, picked_flags) <- return (packageBuildableWithGHCVersion gpd user_specified_fas g)]
+-- | Create an 'InstalledPackageIndex' from a ['Cabal.PackageIdentifier'].
+-- This is used to generate an index of core @GHC@ packages from the provided
+-- ['Cabal.PackageIdentifier'] functions, e.g. 'ghc883_pkgs'.
mkIndex :: [Cabal.PackageIdentifier] -> InstalledPackageIndex
mkIndex pids = fromList
[ emptyInstalledPackageInfo
@@ -125,6 +151,9 @@ ghc nrs = DC.unknownCompilerInfo c_id DC.NoAbiTag
ghc8101 :: (DC.CompilerInfo, InstalledPackageIndex)
ghc8101 = (ghc [8,10,1], mkIndex ghc8101_pkgs)
+ghc884 :: (DC.CompilerInfo, InstalledPackageIndex)
+ghc884 = (ghc [8,8,4], mkIndex ghc884_pkgs)
+
ghc883 :: (DC.CompilerInfo, InstalledPackageIndex)
ghc883 = (ghc [8,8,3], mkIndex ghc883_pkgs)
@@ -208,6 +237,39 @@ ghc8101_pkgs =
-- , p "xhtml" [3000,2,2,1]
]
+ghc884_pkgs :: [Cabal.PackageIdentifier]
+ghc884_pkgs =
+ [ p "array" [0,5,4,0]
+ , p "base" [4,13,0,0]
+ , p "binary" [0,8,7,0] -- used by libghc
+ , p "bytestring" [0,10,10,1]
+-- , p "Cabal" [3,0,1,0] package is upgradeable
+ , p "containers" [0,6,2,1]
+ , p "deepseq" [1,4,4,0] -- used by time
+ , p "directory" [1,3,6,0]
+ , p "filepath" [1,4,2,1]
+ , p "ghc-boot" [8,8,4]
+ , p "ghc-boot-th" [8,8,4]
+ , p "ghc-compact" [0,1,0,0]
+ , p "ghc-prim" [0,5,3,0]
+ , p "ghci" [8,8,4]
+-- , p "haskeline" [0,7,5,0] package is upgradeable
+ , p "hpc" [0,6,0,3] -- used by libghc
+ , p "integer-gmp" [1,0,2,0]
+ -- , p "mtl" [2,2,2] package is upgradeable(?)
+ -- , p "parsec" [3,1,14,0] package is upgradeable(?)
+ , p "pretty" [1,1,3,6]
+ , p "process" [1,6,9,0]
+ -- , p "stm" [2,5,0,0] package is upgradeable(?)
+ , p "template-haskell" [2,15,0,0] -- used by libghc
+ -- , p "terminfo" [0,4,1,4]
+ -- , p "text" [1,2,4,0] dependency of Cabal library
+ , p "time" [1,9,3,0] -- used by unix, directory, hpc, ghc. unsafe to upgrade
+ , p "transformers" [0,5,6,2] -- used by libghc
+ , p "unix" [2,7,2,2]
+-- , p "xhtml" [3000,2,2,1]
+ ]
+
ghc883_pkgs :: [Cabal.PackageIdentifier]
ghc883_pkgs =
[ p "array" [0,5,4,0]
diff --git a/Portage/Metadata.hs b/Portage/Metadata.hs
index 3a333a7..ded3a2e 100644
--- a/Portage/Metadata.hs
+++ b/Portage/Metadata.hs
@@ -1,46 +1,109 @@
+{-|
+Module : Portage.Metadata
+License : GPL-3+
+Maintainer : haskell@gentoo.org
+
+Functions and types related to @metadata.xml@ processing
+-}
module Portage.Metadata
( Metadata(..)
, metadataFromFile
+ , pureMetadataFromFile
+ , prettyPrintFlags -- exported for hspec
+ , prettyPrintFlagsHuman
, makeDefaultMetadata
+ , makeMinimalMetadata
) where
-import qualified Data.ByteString as B
+import qualified AnsiColor as A
+
+import qualified Data.Text as T
+import qualified Data.Text.IO as T
+import qualified Data.Map.Strict as Map
import Text.XML.Light
-newtype Metadata = Metadata
- { metadata_emails :: [String]
- -- , metadataMaintainers :: [String],
- -- , metadataUseFlags :: [(String,String)]
- } deriving (Show)
+-- | A data type for the Gentoo-specific @metadata.xml@ file.
+-- Currently defines functions for the maintainer email and
+-- USE flags and their descriptions.
+data Metadata = Metadata
+ { metadataEmails :: [String] -- ^ This should /always/ be [\"haskell@gentoo.org\"].
+ , metadataUseFlags :: Map.Map String String -- ^ Only /active/ USE flags, if any.
+ } deriving (Eq, Show)
+-- | Maybe return a 'Metadata' from a 'T.Text'.
+--
+-- Trying to parse an empty 'T.Text' should return 'Nothing':
+--
+-- prop> pureMetadataFromFile T.empty == Nothing
+--
+-- Parsing a @metadata.xml@ /without/ USE flags should /always/ be equivalent
+-- to 'makeMinimalMetadata', no matter the package description:
+--
+-- prop> \desc -> pureMetadataFromFile (makeDefaultMetadata desc Map.empty) == Just makeMinimalMetadata
+--
+-- Parsing a @metadata.xml@ /with/ USE flags should /always/ be equivalent
+-- to 'makeMinimalMetadata' /plus/ the supplied USE flags, no matter the
+-- package description:
+--
+-- prop> \desc -> pureMetadataFromFile (makeDefaultMetadata desc (Map.fromList [("name","description")])) == Just (makeMinimalMetadata {metadataUseFlags = Map.fromList [("name","description")] } )
+pureMetadataFromFile :: T.Text -> Maybe Metadata
+pureMetadataFromFile file = parseXMLDoc file >>= \doc -> parseMetadata doc
+
+-- | Apply 'pureMetadataFromFile' to a 'FilePath'.
metadataFromFile :: FilePath -> IO (Maybe Metadata)
-metadataFromFile fp = do
- doc <- parseXMLDoc <$> B.readFile fp
- return (doc >>= parseMetadata)
+metadataFromFile fp = pureMetadataFromFile <$> T.readFile fp
+-- | Extract the maintainer email and USE flags from a supplied XML 'Element'.
+--
+-- If we're parsing a blank 'Element' or otherwise empty @metadata.xml@:
+-- >>> parseMetadata blank_element
+-- Just (Metadata {metadataEmails = [], metadataUseFlags = fromList []})
parseMetadata :: Element -> Maybe Metadata
parseMetadata xml =
- return Metadata { metadata_emails = map strContent (findElements (unqual "email") xml) }
+ return Metadata { metadataEmails = strContent <$> findElements (unqual "email") xml
+ , metadataUseFlags =
+ -- find the flag name
+ let x = findElement (unqual "use") xml
+ y = onlyElems $ concatMap elContent x
+ z = attrVal <$> concatMap elAttribs y
+ -- find the flag description
+ a = concatMap elContent y
+ b = cdData <$> onlyText a
+ in Map.fromList $ zip z b
+ }
+
+-- | Pretty print as valid XML a list of flags and their descriptions
+-- from a given 'Map.Map'.
+prettyPrintFlags :: Map.Map String String -> [String]
+prettyPrintFlags m = (\(name,description) -> "\t\t<flag name=\"" ++ name ++
+ "\">" ++ description ++ "</flag>")
+ <$> Map.toAscList m
-formatFlags :: (String, String) -> String
-formatFlags (name, description) = "\t\t<flag name=\"" ++ name ++
- "\">" ++ description ++ "</flag>"
+-- | Pretty print a human-readable list of flags and their descriptions
+-- from a given 'Map.Map'.
+prettyPrintFlagsHuman :: Map.Map String String -> [String]
+prettyPrintFlagsHuman m = (\(name,description) -> A.bold (name ++ ": ") ++ description)
+ <$> Map.toAscList m
+
+-- | A minimal metadata for use as a fallback value.
+makeMinimalMetadata :: Metadata
+makeMinimalMetadata = Metadata { metadataEmails = ["haskell@gentoo.org"]
+ , metadataUseFlags = Map.empty
+ }
-- don't use Text.XML.Light as we like our own pretty printer
-makeDefaultMetadata :: String -> [(String, String)] -> String
+-- | Pretty print the @metadata.xml@ string.
+makeDefaultMetadata :: String -> Map.Map String String -> T.Text
makeDefaultMetadata long_description flags =
- unlines [ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ T.pack $ unlines [ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
, "<!DOCTYPE pkgmetadata SYSTEM \"http://www.gentoo.org/dtd/metadata.dtd\">"
, "<pkgmetadata>"
, "\t<maintainer type=\"project\">"
, "\t\t<email>haskell@gentoo.org</email>"
, "\t\t<name>Gentoo Haskell</name>"
, "\t</maintainer>"
- , if (formatFlags <$> flags) == [""]
- then "\t<use>\n\t</use>"
- else "\t<use>\n" ++ (unlines $ formatFlags <$> flags) ++
- "\t</use>"
+ , "\t<use>\n" ++ (unlines $ prettyPrintFlags flags) ++ "\t</use>"
, (init {- strip trailing newline-}
. unlines
. map (\l -> if l `elem` ["<longdescription>", "</longdescription>"]
diff --git a/Portage/Overlay.hs b/Portage/Overlay.hs
index c3aabf5..39ca011 100644
--- a/Portage/Overlay.hs
+++ b/Portage/Overlay.hs
@@ -40,12 +40,14 @@ instance Cabal.Package ExistingEbuild where
instance Cabal.HasUnitId ExistingEbuild where
installedUnitId _ = error "Portage.Cabal.installedUnitId: FIXME: should not be used"
+-- | Type describing an overlay.
data Overlay = Overlay {
overlayPath :: FilePath,
overlayMap :: Map Portage.PackageName [ExistingEbuild],
overlayMetadata :: Map Portage.PackageName Portage.Metadata
} deriving Show
+-- | Is 'Cabal.PackageId' found in 'Overlay'?
inOverlay :: Overlay -> Cabal.PackageId -> Bool
inOverlay overlay pkgId = not (Map.null packages)
where
@@ -106,22 +108,21 @@ filterByEmail p overlay = overlay
, overlayMap = pkgMap'
}
where
- metadataMap' = Map.filter (p . Portage.metadata_emails) (overlayMetadata overlay)
+ metadataMap' = Map.filter (p . Portage.metadataEmails) (overlayMetadata overlay)
pkgMap' = Map.intersection (overlayMap overlay) metadataMap'
--- make sure there is only one ebuild for each version number (by selecting
+-- | Make sure there is only one ebuild for each version number (by selecting
-- the highest ebuild version revision)
reduceOverlay :: Overlay -> Overlay
reduceOverlay overlay = overlay { overlayMap = Map.map reduceVersions (overlayMap overlay) }
where
versionNumbers (Portage.Version nums _ _ _) = nums
reduceVersions :: [ExistingEbuild] -> [ExistingEbuild]
- reduceVersions ebuilds = -- gah!
+ reduceVersions = -- gah!
map (maximumBy (comparing (Portage.pkgVersion . ebuildId)))
. groupBy (equating (versionNumbers . Portage.pkgVersion . ebuildId))
- . sortBy (comparing (Portage.pkgVersion . ebuildId))
- $ ebuilds
+ . sortOn (Portage.pkgVersion . ebuildId)
readOverlayByPackage :: DirectoryTree -> [(Portage.PackageName, [Portage.Version])]
readOverlayByPackage tree =
diff --git a/Portage/PackageId.hs b/Portage/PackageId.hs
index 18289c5..c4e575d 100644
--- a/Portage/PackageId.hs
+++ b/Portage/PackageId.hs
@@ -1,7 +1,11 @@
{-# LANGUAGE CPP #-}
+{-|
+Module : Portage.PackageId
+License : GPL-3+
+Maintainer : haskell@gentoo.org
--- | Portage package identifiers, which unlike Cabal ones include a category.
---
+Portage package identifiers, which unlike Cabal ones include a category.
+-}
module Portage.PackageId (
Category(..),
PackageName(..),
@@ -18,19 +22,17 @@ module Portage.PackageId (
cabal_pn_to_PN
) where
-import qualified Distribution.Package as Cabal
-
-import Distribution.Parsec (CabalParsing(..), Parsec(..), explicitEitherParsec)
import qualified Distribution.Compat.CharParsing as P
+import qualified Distribution.Package as Cabal
+import Distribution.Parsec (CabalParsing(..), Parsec(..), explicitEitherParsec)
+import Distribution.Pretty (Pretty(..), prettyShow)
import qualified Portage.Version as Portage
+import qualified Data.Char as Char
import qualified Text.PrettyPrint as Disp
-import Text.PrettyPrint ((<>))
-import qualified Data.Char as Char (isAlphaNum, toLower)
-
-import Distribution.Pretty (Pretty(..), prettyShow)
-import System.FilePath ((</>))
+import Text.PrettyPrint ((<>))
+import System.FilePath ((</>))
#if MIN_VERSION_base(4,11,0)
import Prelude hiding ((<>))
@@ -39,9 +41,11 @@ import Prelude hiding ((<>))
newtype Category = Category { unCategory :: String }
deriving (Eq, Ord, Show, Read)
+-- | Portage-style 'PackageName', containing a 'Category' and a 'Cabal.PackageName'.
data PackageName = PackageName { category :: Category, cabalPkgName :: Cabal.PackageName }
deriving (Eq, Ord, Show, Read)
+-- | Portage-style 'PackageId', containing a 'PackageName' and a 'Portage.Version'.
data PackageId = PackageId { packageId :: PackageName, pkgVersion :: Portage.Version }
deriving (Eq, Ord, Show, Read)
@@ -54,15 +58,15 @@ instance Parsec Category where
categoryChar c = Char.isAlphaNum c || c == '-'
instance Pretty PackageName where
- pretty (PackageName category name) =
- pretty category <> Disp.char '/' <> pretty name
+ pretty (PackageName cat name) =
+ pretty cat <> Disp.char '/' <> pretty name
instance Parsec PackageName where
parsec = do
- category <- parsec
+ cat <- parsec
_ <- P.char '/'
name <- parseCabalPackageName
- return $ PackageName category name
+ return $ PackageName cat name
instance Pretty PackageId where
pretty (PackageId name version) =
@@ -75,6 +79,10 @@ instance Parsec PackageId where
version <- parsec
return $ PackageId name version
+-- | Transform a 'PackageId' into a 'FilePath'.
+--
+-- >>> packageIdToFilePath (PackageId (PackageName (Category "dev-haskell") (Cabal.mkPackageName "foo-bar2")) (Portage.Version [3,0,0] (Just 'b') [Portage.RC 2] 1 ))
+-- "dev-haskell/foo-bar2/foo-bar2-3.0.0b_rc2-r1.ebuild"
packageIdToFilePath :: PackageId -> FilePath
packageIdToFilePath (PackageId (PackageName cat pn) version) =
prettyShow cat </> prettyShow pn </> prettyShow pn <-> prettyShow version <.> "ebuild"
@@ -82,12 +90,11 @@ packageIdToFilePath (PackageId (PackageName cat pn) version) =
a <-> b = a ++ '-':b
a <.> b = a ++ '.':b
--- TODO: fix the parser such that it can tolerate malformed package strings,
--- strings with ".ebuild" extensions and strings which are not in fact package
--- strings at all (e.g. metadata.xml). Then we can eliminate the string manipulation
--- present in Merge.getPreviousPackageId, which ensures this function is only fed
--- well-formed package strings, i.e <name>-<version>.
--- | Maybe generate a PackageId from a FilePath.
+-- | Maybe generate a 'PackageId' from a 'FilePath'. Note that the 'FilePath' must have its
+-- file extension stripped before being passed to 'filePathToPackageId'.
+--
+-- >>> filePathToPackageId (Category "dev-haskell") "foo-bar2-3.0.0b_rc2-r1"
+-- Just (PackageId {packageId = PackageName {category = Category {unCategory = "dev-haskell"}, cabalPkgName = PackageName "foo-bar2"}, pkgVersion = Version {versionNumber = [3,0,0], versionChar = Just 'b', versionSuffix = [RC 2], versionRevision = 1}})
filePathToPackageId :: Category -> FilePath -> Maybe PackageId
filePathToPackageId cat fp =
case explicitEitherParsec parser fp of
@@ -100,27 +107,52 @@ filePathToPackageId cat fp =
v <- parsec
return $ PackageId (PackageName cat pn) v
+-- | Create a 'PackageName' from supplied category and package name 'String's.
mkPackageName :: String -> String -> PackageName
mkPackageName cat package = PackageName (Category cat) (Cabal.mkPackageName package)
+-- | Create a 'PackageId' from a 'Category' and 'Cabal.PackageIdentifier'.
fromCabalPackageId :: Category -> Cabal.PackageIdentifier -> PackageId
-fromCabalPackageId category (Cabal.PackageIdentifier name version) =
- PackageId (PackageName category (normalizeCabalPackageName name))
+fromCabalPackageId cat (Cabal.PackageIdentifier name version) =
+ PackageId (PackageName cat (normalizeCabalPackageName name))
(Portage.fromCabalVersion version)
+-- | Convert a 'Cabal.PackageName' into lowercase. Internally uses
+-- 'cabal_pn_to_PN'.
+--
+-- >>> normalizeCabalPackageName (Cabal.mkPackageName "FooBar1")
+-- PackageName "foobar1"
normalizeCabalPackageName :: Cabal.PackageName -> Cabal.PackageName
normalizeCabalPackageName =
- Cabal.mkPackageName . map Char.toLower . Cabal.unPackageName
+ Cabal.mkPackageName . cabal_pn_to_PN
+-- | Apply 'normalizeCabalPackageName' to the 'Cabal.PackageName' of
+-- a supplied 'Cabal.PackageIdentifier'.
normalizeCabalPackageId :: Cabal.PackageIdentifier -> Cabal.PackageIdentifier
normalizeCabalPackageId (Cabal.PackageIdentifier name version) =
Cabal.PackageIdentifier (normalizeCabalPackageName name) version
+-- | Convert a 'PackageId' into a 'Maybe' 'Cabal.PackageIdentifier'.
toCabalPackageId :: PackageId -> Maybe Cabal.PackageIdentifier
toCabalPackageId (PackageId (PackageName _cat name) version) =
fmap (Cabal.PackageIdentifier name)
(Portage.toCabalVersion version)
+-- | Parse a 'String' as a package in the form of @[category\/]name[-version]@:
+--
+-- Note that we /cannot/ use the 'parsec' function to parse the 'Cabal.PackageName',
+-- since it fails the entire parse if it tries to parse a 'Version'.
+-- See 'parseCabalPackageName' below.
+--
+-- If parsing a valid package string:
+--
+-- >>> parseFriendlyPackage "category-name/package-name1-0.0.0.1a_beta2-r4"
+-- Right (Just (Category {unCategory = "category-name"}),PackageName "package-name1",Just (Version {versionNumber = [0,0,0,1], versionChar = Just 'a', versionSuffix = [Beta 2], versionRevision = 4}))
+--
+-- If malformed, return an error string:
+--
+-- >>> parseFriendlyPackage "category-name/package-name-1-0.0.0.1a_beta2-r4"
+-- Left ...
parseFriendlyPackage :: String -> Either String (Maybe Category, Cabal.PackageName, Maybe Portage.Version)
parseFriendlyPackage str = explicitEitherParsec parser str
where
@@ -136,18 +168,26 @@ parseFriendlyPackage str = explicitEitherParsec parser str
return v
return (mc, p, mv)
--- | Parse a Cabal PackageName. Note that we cannot use the @parsec@
--- method as defined in the @Parsec PackageName@ instance, since it
--- fails the entire PackageName parse if it tries to parse a version
--- number.
+-- | Parse a 'Cabal.PackageName'.
+--
+-- This parser is a replacement for 'parsecUnqualComponentName' which fails when
+-- trying to parse a 'Version'.
parseCabalPackageName :: CabalParsing m => m Cabal.PackageName
parseCabalPackageName = do
pn <- P.some . P.try $
P.choice
[ P.alphaNum
+ , P.char '+'
, P.char '-' <* P.notFollowedBy (P.some P.digit <* P.notFollowedBy P.letter)
]
return $ Cabal.mkPackageName pn
+-- | Pretty-print a lowercase 'Cabal.PackageName'.
+--
+-- Note the difference between this function and 'normalizeCabalPackageName':
+-- this function returns a 'String', the other a 'Cabal.PackageName'.
+--
+-- >>> cabal_pn_to_PN (Cabal.mkPackageName "FooBar1")
+-- "foobar1"
cabal_pn_to_PN :: Cabal.PackageName -> String
cabal_pn_to_PN = map Char.toLower . prettyShow
diff --git a/Portage/Tables.hs b/Portage/Tables.hs
index 5af0ddd..fc06a35 100644
--- a/Portage/Tables.hs
+++ b/Portage/Tables.hs
@@ -1,4 +1,10 @@
--- | Tables of portage specific convertations
+{-|
+Module : Portage.Tables
+License : GPL-3+
+Maintainer : haskell@gentoo.org
+
+Tables of Portage-specific conversions.
+-}
module Portage.Tables
( set_build_slot
) where
@@ -9,10 +15,11 @@ import Portage.PackageId
import Data.Monoid
+-- | Set the @SLOT@ for a given 'Dependency'.
set_build_slot :: Dependency -> Dependency
set_build_slot =
overAtom $ \a@(Atom pn dr (DAttr _ u)) ->
- case mconcat $ map First $ map (matches a) slottedPkgs of
+ case mconcat $ map (First . matches a) slottedPkgs of
First (Just s) -> Atom pn dr (DAttr s u)
First Nothing -> Atom pn dr (DAttr AnyBuildTimeSlot u)
where
@@ -20,6 +27,9 @@ set_build_slot =
| pn == nm = Just s
| otherwise = Nothing
+-- | List of 'PackageName's with their corresponding default 'SlotDepend's.
+--
+-- For example, dependency @QuickCheck@ has its @SLOT@ always set to @2@.
slottedPkgs :: [(PackageName, SlotDepend)]
slottedPkgs =
[ (mkPackageName "dev-haskell" "quickcheck", GivenSlot "2=")
diff --git a/Portage/Version.hs b/Portage/Version.hs
index c85fb6c..b2b1255 100644
--- a/Portage/Version.hs
+++ b/Portage/Version.hs
@@ -1,5 +1,4 @@
{-# LANGUAGE CPP #-}
-
{-|
Author : Andres Loeh <kosmikus@gentoo.org>
Stability : provisional
@@ -10,7 +9,6 @@
Shamelessly borrowed from exi, ported from Parsec to ReadP
-}
-
module Portage.Version (
Version(..),
Suffix(..),
@@ -21,26 +19,27 @@ module Portage.Version (
import qualified Distribution.Version as Cabal
-import Distribution.Pretty (Pretty(..))
+import Distribution.Pretty (Pretty(..))
-import Distribution.Parsec (Parsec(..))
+import Distribution.Parsec (Parsec(..))
import qualified Distribution.Compat.CharParsing as P
import qualified Text.PrettyPrint as Disp
-import Text.PrettyPrint ((<>))
-import qualified Data.Char as Char (isAlpha, isDigit)
-import qualified Data.List.NonEmpty as NonEmpty
+import Text.PrettyPrint ((<>))
+import qualified Data.List.NonEmpty as NE
#if MIN_VERSION_base(4,11,0)
import Prelude hiding ((<>))
#endif
-data Version = Version { versionNumber :: [Int] -- [1,42,3] ~= 1.42.3
- , versionChar :: (Maybe Char) -- optional letter
+-- | Portage-style version type.
+data Version = Version { versionNumber :: [Int] -- ^ @[1,42,3]@ ~= 1.42.3
+ , versionChar :: (Maybe Char) -- ^ optional letter
, versionSuffix :: [Suffix]
- , versionRevision :: Int -- revision, 0 means none
+ , versionRevision :: Int -- ^ revision, 0 means none
}
deriving (Eq, Ord, Show, Read)
+-- | Prints a valid Portage 'Version' string.
instance Pretty Version where
pretty (Version ver c suf rev) =
dispVer ver <> dispC c <> dispSuf suf <> dispRev rev
@@ -51,16 +50,32 @@ instance Pretty Version where
dispRev 0 = Disp.empty
dispRev n = Disp.text "-r" <> Disp.int n
+-- | 'Version' parser using 'Parsec'.
instance Parsec Version where
parsec = do
ver <- P.sepByNonEmpty digits (P.char '.')
- c <- P.optional $ P.satisfy Char.isAlpha
+ c <- P.optional P.lower
suf <- P.many parsec
rev <- P.option 0 $ P.string "-r" *> digits
- return $ Version (NonEmpty.toList ver) c suf rev
-
+ return $ Version (NE.toList ver) c suf rev
+
+-- | Check if the ebuild is a live ebuild, i.e. if its 'Version' is @9999@.
+--
-- foo-9999* is treated as live ebuild
-- Cabal-1.17.9999* as well
+--
+-- >>> let (c,s,r) = (Nothing,[],0)
+-- >>> is_live (Version [1,0,0] c s r)
+-- False
+-- >>> is_live (Version [999] c s r)
+-- False
+-- >>> is_live (Version [1,0,0,9999] c s r)
+-- True
+-- >>> is_live (Version [9999] c s r)
+-- True
+--
+-- $
+-- prop> \verNum char rev -> is_live (Version verNum char [] rev) == if length verNum >= 1 && last verNum >= 9999 then True else False
is_live :: Version -> Bool
is_live v =
case vs of
@@ -72,6 +87,7 @@ is_live v =
is_big n = n >= 9999
all_nines n = (all (== '9') . show) n
+-- | Various allowed suffixes in Portage versions.
data Suffix = Alpha Int | Beta Int | Pre Int | RC Int | P Int
deriving (Eq, Ord, Show, Read)
@@ -90,22 +106,29 @@ instance Pretty Suffix where
instance Parsec Suffix where
parsec = P.char '_'
- >> P.choice
- [ P.string "alpha" >> fmap Alpha maybeDigits
- , P.string "beta" >> fmap Beta maybeDigits
- , P.string "pre" >> fmap Pre maybeDigits
- , P.string "rc" >> fmap RC maybeDigits
- , P.string "p" >> fmap P maybeDigits
+ *> P.choice
+ [ P.string "alpha" >> fmap Alpha maybeDigits
+ , P.string "beta" >> fmap Beta maybeDigits
+ , P.try (P.string "pre") >> fmap Pre maybeDigits
+ , P.string "rc" >> fmap RC maybeDigits
+ , P.string "p" >> fmap P maybeDigits
]
where
maybeDigits = P.option 0 digits
+-- | Convert from a 'Cabal.Version' to a Portage 'Version'.
+--
+-- prop> \verNum -> fromCabalVersion (Cabal.mkVersion verNum) == Version verNum Nothing [] 0
fromCabalVersion :: Cabal.Version -> Version
fromCabalVersion cabal_version = Version (Cabal.versionNumbers cabal_version) Nothing [] 0
+-- | Convert from a Portage 'Version' to a 'Cabal.Version'.
+-- $
+-- prop> \verNum char rev -> toCabalVersion (Version verNum char [] rev) == if char == Nothing then Just (Cabal.mkVersion verNum) else Nothing
toCabalVersion :: Version -> Maybe Cabal.Version
toCabalVersion (Version nums Nothing [] _) = Just (Cabal.mkVersion nums)
toCabalVersion _ = Nothing
+-- | Parser which munches digits.
digits :: P.CharParsing m => m Int
-digits = read <$> P.munch1 Char.isDigit
+digits = read <$> P.some P.digit
diff --git a/README.rst b/README.rst
index fe1e60f..1220e71 100644
--- a/README.rst
+++ b/README.rst
@@ -1,6 +1,11 @@
Hackport
========
+.. image:: https://img.shields.io/hackage/v/hackport
+ :target: https://hackage.haskell.org/package/hackport
+.. image:: https://github.com/gentoo-haskell/hackport/workflows/Haskell%20CI/badge.svg
+ :target: https://github.com/gentoo-haskell/hackport/actions?query=workflow%3A%22Haskell+CI%22
+
About
-----
diff --git a/Status.hs b/Status.hs
index 2cbd56e..26f5210 100644
--- a/Status.hs
+++ b/Status.hs
@@ -85,7 +85,7 @@ loadHackage verbosity repoContext overlay = do
_ -> {- ambig -} Category "dev-haskell"
pkg_infos = map ( reverse . take 3 . reverse -- hackage usually has a ton of older versions
. map ((\p -> fromCabalPackageId (get_cat p) p)
- . CabalInstall.packageInfoId))
+ . CabalInstall.srcpkgPackageId))
(CabalInstall.allPackagesByName pindex)
return pkg_infos
diff --git a/cabal/.docker/validate-7.10.3.dockerfile b/cabal/.docker/validate-7.10.3.dockerfile
new file mode 100644
index 0000000..1d013f5
--- /dev/null
+++ b/cabal/.docker/validate-7.10.3.dockerfile
@@ -0,0 +1,78 @@
+FROM phadej/ghc:7.10.3-bionic
+
+# Install cabal-plan
+RUN mkdir -p /root/.cabal/bin && \
+ curl -L https://github.com/haskell-hvr/cabal-plan/releases/download/v0.6.2.0/cabal-plan-0.6.2.0-x86_64-linux.xz > cabal-plan.xz && \
+ echo "de73600b1836d3f55e32d80385acc055fd97f60eaa0ab68a755302685f5d81bc cabal-plan.xz" | sha256sum -c - && \
+ xz -d < cabal-plan.xz > /root/.cabal/bin/cabal-plan && \
+ rm -f cabal-plan.xz && \
+ chmod a+x /root/.cabal/bin/cabal-plan
+
+# Install cabal-env
+RUN curl -sL https://github.com/phadej/cabal-extras/releases/download/preview-20191225/cabal-env-snapshot-20191225-x86_64-linux.xz > cabal-env.xz && \
+ echo "1b567d529c5f627fd8c956e57ae8f0d9f11ee66d6db34b7fb0cb1c370b4edf01 cabal-env.xz" | sha256sum -c - && \
+ xz -d < cabal-env.xz > $HOME/.cabal/bin/cabal-env && \
+ rm -f cabal-env.xz && \
+ chmod a+x $HOME/.cabal/bin/cabal-env
+
+
+# Update index
+RUN cabal v2-update --index-state="2020-06-12T23:36:15Z"
+
+# We install happy, so it's in the store; we (hopefully) don't use it directly.
+RUN cabal v2-install happy --constraint 'happy ^>=1.19.12'
+
+# Install some other dependencies
+# Remove $HOME/.ghc so there aren't any environments
+RUN cabal v2-install -w ghc-7.10.3 --lib \
+ Cabal \
+ aeson \
+ async \
+ base-compat \
+ base16-bytestring \
+ base64-bytestring \
+ cryptohash-sha256 \
+ Diff \
+ echo \
+ ed25519 \
+ edit-distance \
+ HTTP \
+ lukko \
+ network \
+ optparse-applicative \
+ pretty-show \
+ regex-compat-tdfa \
+ regex-posix \
+ regex-tdfa \
+ rere \
+ statistics \
+ tar \
+ tasty \
+ tasty-golden \
+ tasty-hunit \
+ tasty-quickcheck \
+ tree-diff \
+ void \
+ zlib \
+ resolv \
+ parsec \
+ text \
+ --constraint="rere -rere-cfg" \
+ --constraint="these -assoc" \
+ --constraint="bytestring installed" \
+ --constraint="binary installed" \
+ --constraint="containers installed" \
+ --constraint="deepseq installed" \
+ --constraint="directory installed" \
+ --constraint="filepath installed" \
+ --constraint="pretty installed" \
+ --constraint="process installed" \
+ --constraint="time installed" \
+ --constraint="unix installed" \
+ --constraint="transformers installed" \
+ && rm -rf $HOME/.ghc
+
+# Validate
+WORKDIR /build
+COPY . /build
+RUN sh ./validate.sh -w ghc-7.10.3 -v
diff --git a/cabal/.docker/validate-7.6.3.dockerfile b/cabal/.docker/validate-7.6.3.dockerfile
new file mode 100644
index 0000000..f35a653
--- /dev/null
+++ b/cabal/.docker/validate-7.6.3.dockerfile
@@ -0,0 +1,79 @@
+FROM phadej/ghc:7.6.3-xenial
+
+# Install cabal-plan
+RUN mkdir -p /root/.cabal/bin && \
+ curl -L https://github.com/haskell-hvr/cabal-plan/releases/download/v0.6.2.0/cabal-plan-0.6.2.0-x86_64-linux.xz > cabal-plan.xz && \
+ echo "de73600b1836d3f55e32d80385acc055fd97f60eaa0ab68a755302685f5d81bc cabal-plan.xz" | sha256sum -c - && \
+ xz -d < cabal-plan.xz > /root/.cabal/bin/cabal-plan && \
+ rm -f cabal-plan.xz && \
+ chmod a+x /root/.cabal/bin/cabal-plan
+
+# Install cabal-env
+RUN curl -sL https://github.com/phadej/cabal-extras/releases/download/preview-20191225/cabal-env-snapshot-20191225-x86_64-linux.xz > cabal-env.xz && \
+ echo "1b567d529c5f627fd8c956e57ae8f0d9f11ee66d6db34b7fb0cb1c370b4edf01 cabal-env.xz" | sha256sum -c - && \
+ xz -d < cabal-env.xz > $HOME/.cabal/bin/cabal-env && \
+ rm -f cabal-env.xz && \
+ chmod a+x $HOME/.cabal/bin/cabal-env
+
+# We need newer compiler, to install cabal-plan
+RUN apt-get update
+RUN apt-get install -y ghc-7.6.3-dyn
+
+# Update index
+RUN cabal v2-update --index-state="2020-06-12T23:36:15Z"
+
+# We install happy, so it's in the store; we (hopefully) don't use it directly.
+RUN cabal v2-install happy --constraint 'happy ^>=1.19.12'
+
+# Install some other dependencies
+# Remove $HOME/.ghc so there aren't any environments
+RUN cabal v2-install -w ghc-7.6.3 --lib \
+ Cabal \
+ aeson \
+ async \
+ base-compat \
+ base16-bytestring \
+ base64-bytestring \
+ cryptohash-sha256 \
+ Diff \
+ echo \
+ ed25519 \
+ edit-distance \
+ HTTP \
+ lukko \
+ network \
+ optparse-applicative \
+ pretty-show \
+ regex-compat-tdfa \
+ regex-posix \
+ regex-tdfa \
+ rere \
+ statistics \
+ tar \
+ tasty \
+ tasty-golden \
+ tasty-hunit \
+ tasty-quickcheck \
+ tree-diff \
+ void \
+ zlib \
+ parsec \
+ text \
+ --constraint="rere -rere-cfg" \
+ --constraint="these -assoc" \
+ --constraint="bytestring installed" \
+ --constraint="binary installed" \
+ --constraint="containers installed" \
+ --constraint="deepseq installed" \
+ --constraint="directory installed" \
+ --constraint="filepath installed" \
+ --constraint="pretty installed" \
+ --constraint="process installed" \
+ --constraint="time installed" \
+ --constraint="unix installed" \
+ && rm -rf $HOME/.ghc
+
+# Validate
+WORKDIR /build
+COPY . /build
+RUN sh ./validate.sh --lib-only -w ghc-7.6.3 -v
diff --git a/cabal/.docker/validate-7.8.4.dockerfile b/cabal/.docker/validate-7.8.4.dockerfile
new file mode 100644
index 0000000..722228d
--- /dev/null
+++ b/cabal/.docker/validate-7.8.4.dockerfile
@@ -0,0 +1,80 @@
+FROM phadej/ghc:7.8.4-xenial
+
+# Install cabal-plan
+RUN mkdir -p /root/.cabal/bin && \
+ curl -L https://github.com/haskell-hvr/cabal-plan/releases/download/v0.6.2.0/cabal-plan-0.6.2.0-x86_64-linux.xz > cabal-plan.xz && \
+ echo "de73600b1836d3f55e32d80385acc055fd97f60eaa0ab68a755302685f5d81bc cabal-plan.xz" | sha256sum -c - && \
+ xz -d < cabal-plan.xz > /root/.cabal/bin/cabal-plan && \
+ rm -f cabal-plan.xz && \
+ chmod a+x /root/.cabal/bin/cabal-plan
+
+# Install cabal-env
+RUN curl -sL https://github.com/phadej/cabal-extras/releases/download/preview-20191225/cabal-env-snapshot-20191225-x86_64-linux.xz > cabal-env.xz && \
+ echo "1b567d529c5f627fd8c956e57ae8f0d9f11ee66d6db34b7fb0cb1c370b4edf01 cabal-env.xz" | sha256sum -c - && \
+ xz -d < cabal-env.xz > $HOME/.cabal/bin/cabal-env && \
+ rm -f cabal-env.xz && \
+ chmod a+x $HOME/.cabal/bin/cabal-env
+
+# We need newer compiler, to install cabal-plan
+RUN apt-get update
+RUN apt-get install -y ghc-7.8.4-dyn
+
+# Update index
+RUN cabal v2-update --index-state="2020-06-12T23:36:15Z"
+
+# We install happy, so it's in the store; we (hopefully) don't use it directly.
+RUN cabal v2-install happy --constraint 'happy ^>=1.19.12'
+
+# Install some other dependencies
+# Remove $HOME/.ghc so there aren't any environments
+RUN cabal v2-install -w ghc-7.8.4 --lib \
+ Cabal \
+ aeson \
+ async \
+ base-compat \
+ base16-bytestring \
+ base64-bytestring \
+ cryptohash-sha256 \
+ Diff \
+ echo \
+ ed25519 \
+ edit-distance \
+ HTTP \
+ lukko \
+ network \
+ optparse-applicative \
+ pretty-show \
+ regex-compat-tdfa \
+ regex-posix \
+ regex-tdfa \
+ rere \
+ statistics \
+ tar \
+ tasty \
+ tasty-golden \
+ tasty-hunit \
+ tasty-quickcheck \
+ tree-diff \
+ void \
+ zlib \
+ parsec \
+ text \
+ --constraint="rere -rere-cfg" \
+ --constraint="these -assoc" \
+ --constraint="bytestring installed" \
+ --constraint="binary installed" \
+ --constraint="containers installed" \
+ --constraint="deepseq installed" \
+ --constraint="directory installed" \
+ --constraint="filepath installed" \
+ --constraint="pretty installed" \
+ --constraint="process installed" \
+ --constraint="time installed" \
+ --constraint="unix installed" \
+ --constraint="transformers installed" \
+ && rm -rf $HOME/.ghc
+
+# Validate
+WORKDIR /build
+COPY . /build
+RUN sh ./validate.sh --lib-only -w ghc-7.8.4 -v
diff --git a/cabal/.docker/validate-8.0.2.dockerfile b/cabal/.docker/validate-8.0.2.dockerfile
new file mode 100644
index 0000000..aab9315
--- /dev/null
+++ b/cabal/.docker/validate-8.0.2.dockerfile
@@ -0,0 +1,69 @@
+FROM phadej/ghc:8.0.2-bionic
+
+# Install cabal-plan
+RUN mkdir -p /root/.cabal/bin && \
+ curl -L https://github.com/haskell-hvr/cabal-plan/releases/download/v0.6.2.0/cabal-plan-0.6.2.0-x86_64-linux.xz > cabal-plan.xz && \
+ echo "de73600b1836d3f55e32d80385acc055fd97f60eaa0ab68a755302685f5d81bc cabal-plan.xz" | sha256sum -c - && \
+ xz -d < cabal-plan.xz > /root/.cabal/bin/cabal-plan && \
+ rm -f cabal-plan.xz && \
+ chmod a+x /root/.cabal/bin/cabal-plan
+
+
+# Update index
+RUN cabal v2-update --index-state="2020-06-12T23:36:15Z"
+
+# We install happy, so it's in the store; we (hopefully) don't use it directly.
+RUN cabal v2-install happy --constraint 'happy ^>=1.19.12'
+
+# Install some other dependencies
+# Remove $HOME/.ghc so there aren't any environments
+RUN cabal v2-install -w ghc-8.0.2 --lib \
+ Cabal \
+ aeson \
+ async \
+ base-compat \
+ base16-bytestring \
+ base64-bytestring \
+ cryptohash-sha256 \
+ Diff \
+ echo \
+ ed25519 \
+ edit-distance \
+ HTTP \
+ lukko \
+ network \
+ optparse-applicative \
+ pretty-show \
+ regex-compat-tdfa \
+ regex-posix \
+ regex-tdfa \
+ rere \
+ statistics \
+ tar \
+ tasty \
+ tasty-golden \
+ tasty-hunit \
+ tasty-quickcheck \
+ tree-diff \
+ void \
+ zlib \
+ resolv \
+ --constraint="rere -rere-cfg" \
+ --constraint="these -assoc" \
+ --constraint="bytestring installed" \
+ --constraint="binary installed" \
+ --constraint="containers installed" \
+ --constraint="deepseq installed" \
+ --constraint="directory installed" \
+ --constraint="filepath installed" \
+ --constraint="pretty installed" \
+ --constraint="process installed" \
+ --constraint="time installed" \
+ --constraint="unix installed" \
+ --constraint="transformers installed" \
+ && rm -rf $HOME/.ghc
+
+# Validate
+WORKDIR /build
+COPY . /build
+RUN sh ./validate.sh -w ghc-8.0.2 -v
diff --git a/cabal/.docker/validate-8.10.1.dockerfile b/cabal/.docker/validate-8.10.1.dockerfile
new file mode 100644
index 0000000..4306eed
--- /dev/null
+++ b/cabal/.docker/validate-8.10.1.dockerfile
@@ -0,0 +1,76 @@
+FROM phadej/ghc:8.10.1-bionic
+
+# Install cabal-plan
+RUN mkdir -p /root/.cabal/bin && \
+ curl -L https://github.com/haskell-hvr/cabal-plan/releases/download/v0.6.2.0/cabal-plan-0.6.2.0-x86_64-linux.xz > cabal-plan.xz && \
+ echo "de73600b1836d3f55e32d80385acc055fd97f60eaa0ab68a755302685f5d81bc cabal-plan.xz" | sha256sum -c - && \
+ xz -d < cabal-plan.xz > /root/.cabal/bin/cabal-plan && \
+ rm -f cabal-plan.xz && \
+ chmod a+x /root/.cabal/bin/cabal-plan
+
+# Install cabal-env
+RUN curl -sL https://github.com/phadej/cabal-extras/releases/download/preview-20191225/cabal-env-snapshot-20191225-x86_64-linux.xz > cabal-env.xz && \
+ echo "1b567d529c5f627fd8c956e57ae8f0d9f11ee66d6db34b7fb0cb1c370b4edf01 cabal-env.xz" | sha256sum -c - && \
+ xz -d < cabal-env.xz > $HOME/.cabal/bin/cabal-env && \
+ rm -f cabal-env.xz && \
+ chmod a+x $HOME/.cabal/bin/cabal-env
+
+
+# Update index
+RUN cabal v2-update --index-state="2020-06-12T23:36:15Z"
+
+# We install happy, so it's in the store; we (hopefully) don't use it directly.
+RUN cabal v2-install happy --constraint 'happy ^>=1.19.12'
+
+# Install some other dependencies
+# Remove $HOME/.ghc so there aren't any environments
+RUN cabal v2-install -w ghc-8.10.1 --lib \
+ Cabal \
+ aeson \
+ async \
+ base-compat \
+ base16-bytestring \
+ base64-bytestring \
+ cryptohash-sha256 \
+ Diff \
+ echo \
+ ed25519 \
+ edit-distance \
+ HTTP \
+ lukko \
+ network \
+ optparse-applicative \
+ pretty-show \
+ regex-compat-tdfa \
+ regex-posix \
+ regex-tdfa \
+ rere \
+ statistics \
+ tar \
+ tasty \
+ tasty-golden \
+ tasty-hunit \
+ tasty-quickcheck \
+ tree-diff \
+ void \
+ zlib \
+ resolv \
+ --constraint="rere -rere-cfg" \
+ --constraint="these -assoc" \
+ --constraint="bytestring installed" \
+ --constraint="binary installed" \
+ --constraint="containers installed" \
+ --constraint="deepseq installed" \
+ --constraint="directory installed" \
+ --constraint="filepath installed" \
+ --constraint="pretty installed" \
+ --constraint="process installed" \
+ --constraint="time installed" \
+ --constraint="unix installed" \
+ --constraint="transformers installed" \
+ && rm -rf $HOME/.ghc
+
+# Validate
+WORKDIR /build
+COPY . /build
+RUN sh ./validate.sh -w ghc-8.10.1 -v
diff --git a/cabal/.docker/validate-8.2.2.dockerfile b/cabal/.docker/validate-8.2.2.dockerfile
new file mode 100644
index 0000000..1f0c90e
--- /dev/null
+++ b/cabal/.docker/validate-8.2.2.dockerfile
@@ -0,0 +1,78 @@
+FROM phadej/ghc:8.2.2-bionic
+
+# Install cabal-plan
+RUN mkdir -p /root/.cabal/bin && \
+ curl -L https://github.com/haskell-hvr/cabal-plan/releases/download/v0.6.2.0/cabal-plan-0.6.2.0-x86_64-linux.xz > cabal-plan.xz && \
+ echo "de73600b1836d3f55e32d80385acc055fd97f60eaa0ab68a755302685f5d81bc cabal-plan.xz" | sha256sum -c - && \
+ xz -d < cabal-plan.xz > /root/.cabal/bin/cabal-plan && \
+ rm -f cabal-plan.xz && \
+ chmod a+x /root/.cabal/bin/cabal-plan
+
+# Install cabal-env
+RUN curl -sL https://github.com/phadej/cabal-extras/releases/download/preview-20191225/cabal-env-snapshot-20191225-x86_64-linux.xz > cabal-env.xz && \
+ echo "1b567d529c5f627fd8c956e57ae8f0d9f11ee66d6db34b7fb0cb1c370b4edf01 cabal-env.xz" | sha256sum -c - && \
+ xz -d < cabal-env.xz > $HOME/.cabal/bin/cabal-env && \
+ rm -f cabal-env.xz && \
+ chmod a+x $HOME/.cabal/bin/cabal-env
+
+
+# Update index
+RUN cabal v2-update --index-state="2020-06-12T23:36:15Z"
+
+# We install happy, so it's in the store; we (hopefully) don't use it directly.
+RUN cabal v2-install happy --constraint 'happy ^>=1.19.12'
+
+# Install some other dependencies
+# Remove $HOME/.ghc so there aren't any environments
+RUN cabal v2-install -w ghc-8.2.2 --lib \
+ Cabal \
+ aeson \
+ async \
+ base-compat \
+ base16-bytestring \
+ base64-bytestring \
+ cryptohash-sha256 \
+ Diff \
+ echo \
+ ed25519 \
+ edit-distance \
+ HTTP \
+ lukko \
+ network \
+ optparse-applicative \
+ pretty-show \
+ regex-compat-tdfa \
+ regex-posix \
+ regex-tdfa \
+ rere \
+ statistics \
+ tar \
+ tasty \
+ tasty-golden \
+ tasty-hunit \
+ tasty-quickcheck \
+ tree-diff \
+ void \
+ zlib \
+ resolv \
+ parsec \
+ text \
+ --constraint="rere -rere-cfg" \
+ --constraint="these -assoc" \
+ --constraint="bytestring installed" \
+ --constraint="binary installed" \
+ --constraint="containers installed" \
+ --constraint="deepseq installed" \
+ --constraint="directory installed" \
+ --constraint="filepath installed" \
+ --constraint="pretty installed" \
+ --constraint="process installed" \
+ --constraint="time installed" \
+ --constraint="unix installed" \
+ --constraint="transformers installed" \
+ && rm -rf $HOME/.ghc
+
+# Validate
+WORKDIR /build
+COPY . /build
+RUN sh ./validate.sh -w ghc-8.2.2 -v
diff --git a/cabal/.docker/validate-8.4.4.dockerfile b/cabal/.docker/validate-8.4.4.dockerfile
new file mode 100644
index 0000000..c74f7e6
--- /dev/null
+++ b/cabal/.docker/validate-8.4.4.dockerfile
@@ -0,0 +1,76 @@
+FROM phadej/ghc:8.4.4-bionic
+
+# Install cabal-plan
+RUN mkdir -p /root/.cabal/bin && \
+ curl -L https://github.com/haskell-hvr/cabal-plan/releases/download/v0.6.2.0/cabal-plan-0.6.2.0-x86_64-linux.xz > cabal-plan.xz && \
+ echo "de73600b1836d3f55e32d80385acc055fd97f60eaa0ab68a755302685f5d81bc cabal-plan.xz" | sha256sum -c - && \
+ xz -d < cabal-plan.xz > /root/.cabal/bin/cabal-plan && \
+ rm -f cabal-plan.xz && \
+ chmod a+x /root/.cabal/bin/cabal-plan
+
+# Install cabal-env
+RUN curl -sL https://github.com/phadej/cabal-extras/releases/download/preview-20191225/cabal-env-snapshot-20191225-x86_64-linux.xz > cabal-env.xz && \
+ echo "1b567d529c5f627fd8c956e57ae8f0d9f11ee66d6db34b7fb0cb1c370b4edf01 cabal-env.xz" | sha256sum -c - && \
+ xz -d < cabal-env.xz > $HOME/.cabal/bin/cabal-env && \
+ rm -f cabal-env.xz && \
+ chmod a+x $HOME/.cabal/bin/cabal-env
+
+
+# Update index
+RUN cabal v2-update --index-state="2020-06-12T23:36:15Z"
+
+# We install happy, so it's in the store; we (hopefully) don't use it directly.
+RUN cabal v2-install happy --constraint 'happy ^>=1.19.12'
+
+# Install some other dependencies
+# Remove $HOME/.ghc so there aren't any environments
+RUN cabal v2-install -w ghc-8.4.4 --lib \
+ Cabal \
+ aeson \
+ async \
+ base-compat \
+ base16-bytestring \
+ base64-bytestring \
+ cryptohash-sha256 \
+ Diff \
+ echo \
+ ed25519 \
+ edit-distance \
+ HTTP \
+ lukko \
+ network \
+ optparse-applicative \
+ pretty-show \
+ regex-compat-tdfa \
+ regex-posix \
+ regex-tdfa \
+ rere \
+ statistics \
+ tar \
+ tasty \
+ tasty-golden \
+ tasty-hunit \
+ tasty-quickcheck \
+ tree-diff \
+ void \
+ zlib \
+ resolv \
+ --constraint="rere -rere-cfg" \
+ --constraint="these -assoc" \
+ --constraint="bytestring installed" \
+ --constraint="binary installed" \
+ --constraint="containers installed" \
+ --constraint="deepseq installed" \
+ --constraint="directory installed" \
+ --constraint="filepath installed" \
+ --constraint="pretty installed" \
+ --constraint="process installed" \
+ --constraint="time installed" \
+ --constraint="unix installed" \
+ --constraint="transformers installed" \
+ && rm -rf $HOME/.ghc
+
+# Validate
+WORKDIR /build
+COPY . /build
+RUN sh ./validate.sh -w ghc-8.4.4 -v
diff --git a/cabal/.docker/validate-8.6.5.dockerfile b/cabal/.docker/validate-8.6.5.dockerfile
new file mode 100644
index 0000000..0410bc7
--- /dev/null
+++ b/cabal/.docker/validate-8.6.5.dockerfile
@@ -0,0 +1,76 @@
+FROM phadej/ghc:8.6.5-bionic
+
+# Install cabal-plan
+RUN mkdir -p /root/.cabal/bin && \
+ curl -L https://github.com/haskell-hvr/cabal-plan/releases/download/v0.6.2.0/cabal-plan-0.6.2.0-x86_64-linux.xz > cabal-plan.xz && \
+ echo "de73600b1836d3f55e32d80385acc055fd97f60eaa0ab68a755302685f5d81bc cabal-plan.xz" | sha256sum -c - && \
+ xz -d < cabal-plan.xz > /root/.cabal/bin/cabal-plan && \
+ rm -f cabal-plan.xz && \
+ chmod a+x /root/.cabal/bin/cabal-plan
+
+# Install cabal-env
+RUN curl -sL https://github.com/phadej/cabal-extras/releases/download/preview-20191225/cabal-env-snapshot-20191225-x86_64-linux.xz > cabal-env.xz && \
+ echo "1b567d529c5f627fd8c956e57ae8f0d9f11ee66d6db34b7fb0cb1c370b4edf01 cabal-env.xz" | sha256sum -c - && \
+ xz -d < cabal-env.xz > $HOME/.cabal/bin/cabal-env && \
+ rm -f cabal-env.xz && \
+ chmod a+x $HOME/.cabal/bin/cabal-env
+
+
+# Update index
+RUN cabal v2-update --index-state="2020-06-12T23:36:15Z"
+
+# We install happy, so it's in the store; we (hopefully) don't use it directly.
+RUN cabal v2-install happy --constraint 'happy ^>=1.19.12'
+
+# Install some other dependencies
+# Remove $HOME/.ghc so there aren't any environments
+RUN cabal v2-install -w ghc-8.6.5 --lib \
+ Cabal \
+ aeson \
+ async \
+ base-compat \
+ base16-bytestring \
+ base64-bytestring \
+ cryptohash-sha256 \
+ Diff \
+ echo \
+ ed25519 \
+ edit-distance \
+ HTTP \
+ lukko \
+ network \
+ optparse-applicative \
+ pretty-show \
+ regex-compat-tdfa \
+ regex-posix \
+ regex-tdfa \
+ rere \
+ statistics \
+ tar \
+ tasty \
+ tasty-golden \
+ tasty-hunit \
+ tasty-quickcheck \
+ tree-diff \
+ void \
+ zlib \
+ resolv \
+ --constraint="rere -rere-cfg" \
+ --constraint="these -assoc" \
+ --constraint="bytestring installed" \
+ --constraint="binary installed" \
+ --constraint="containers installed" \
+ --constraint="deepseq installed" \
+ --constraint="directory installed" \
+ --constraint="filepath installed" \
+ --constraint="pretty installed" \
+ --constraint="process installed" \
+ --constraint="time installed" \
+ --constraint="unix installed" \
+ --constraint="transformers installed" \
+ && rm -rf $HOME/.ghc
+
+# Validate
+WORKDIR /build
+COPY . /build
+RUN sh ./validate.sh -w ghc-8.6.5 -v
diff --git a/cabal/.docker/validate-8.8.3.dockerfile b/cabal/.docker/validate-8.8.3.dockerfile
new file mode 100644
index 0000000..57b6091
--- /dev/null
+++ b/cabal/.docker/validate-8.8.3.dockerfile
@@ -0,0 +1,76 @@
+FROM phadej/ghc:8.8.3-bionic
+
+# Install cabal-plan
+RUN mkdir -p /root/.cabal/bin && \
+ curl -L https://github.com/haskell-hvr/cabal-plan/releases/download/v0.6.2.0/cabal-plan-0.6.2.0-x86_64-linux.xz > cabal-plan.xz && \
+ echo "de73600b1836d3f55e32d80385acc055fd97f60eaa0ab68a755302685f5d81bc cabal-plan.xz" | sha256sum -c - && \
+ xz -d < cabal-plan.xz > /root/.cabal/bin/cabal-plan && \
+ rm -f cabal-plan.xz && \
+ chmod a+x /root/.cabal/bin/cabal-plan
+
+# Install cabal-env
+RUN curl -sL https://github.com/phadej/cabal-extras/releases/download/preview-20191225/cabal-env-snapshot-20191225-x86_64-linux.xz > cabal-env.xz && \
+ echo "1b567d529c5f627fd8c956e57ae8f0d9f11ee66d6db34b7fb0cb1c370b4edf01 cabal-env.xz" | sha256sum -c - && \
+ xz -d < cabal-env.xz > $HOME/.cabal/bin/cabal-env && \
+ rm -f cabal-env.xz && \
+ chmod a+x $HOME/.cabal/bin/cabal-env
+
+
+# Update index
+RUN cabal v2-update --index-state="2020-06-12T23:36:15Z"
+
+# We install happy, so it's in the store; we (hopefully) don't use it directly.
+RUN cabal v2-install happy --constraint 'happy ^>=1.19.12'
+
+# Install some other dependencies
+# Remove $HOME/.ghc so there aren't any environments
+RUN cabal v2-install -w ghc-8.8.3 --lib \
+ Cabal \
+ aeson \
+ async \
+ base-compat \
+ base16-bytestring \
+ base64-bytestring \
+ cryptohash-sha256 \
+ Diff \
+ echo \
+ ed25519 \
+ edit-distance \
+ HTTP \
+ lukko \
+ network \
+ optparse-applicative \
+ pretty-show \
+ regex-compat-tdfa \
+ regex-posix \
+ regex-tdfa \
+ rere \
+ statistics \
+ tar \
+ tasty \
+ tasty-golden \
+ tasty-hunit \
+ tasty-quickcheck \
+ tree-diff \
+ void \
+ zlib \
+ resolv \
+ --constraint="rere -rere-cfg" \
+ --constraint="these -assoc" \
+ --constraint="bytestring installed" \
+ --constraint="binary installed" \
+ --constraint="containers installed" \
+ --constraint="deepseq installed" \
+ --constraint="directory installed" \
+ --constraint="filepath installed" \
+ --constraint="pretty installed" \
+ --constraint="process installed" \
+ --constraint="time installed" \
+ --constraint="unix installed" \
+ --constraint="transformers installed" \
+ && rm -rf $HOME/.ghc
+
+# Validate
+WORKDIR /build
+COPY . /build
+RUN sh ./validate.sh --doctest --solver-benchmarks --complete-hackage -w ghc-8.8.3 -v
diff --git a/cabal/.docker/validate-old.dockerfile b/cabal/.docker/validate-old.dockerfile
new file mode 100644
index 0000000..2971baf
--- /dev/null
+++ b/cabal/.docker/validate-old.dockerfile
@@ -0,0 +1,72 @@
+FROM phadej/ghc:8.8.3-xenial
+
+# Install cabal-plan
+RUN mkdir -p /root/.cabal/bin && \
+ curl -L https://github.com/haskell-hvr/cabal-plan/releases/download/v0.6.2.0/cabal-plan-0.6.2.0-x86_64-linux.xz > cabal-plan.xz && \
+ echo "de73600b1836d3f55e32d80385acc055fd97f60eaa0ab68a755302685f5d81bc cabal-plan.xz" | sha256sum -c - && \
+ xz -d < cabal-plan.xz > /root/.cabal/bin/cabal-plan && \
+ rm -f cabal-plan.xz && \
+ chmod a+x /root/.cabal/bin/cabal-plan
+
+# Install older compilers
+RUN apt-get update
+RUN apt-get install -y ghc-7.0.4 ghc-7.0.4-dyn ghc-7.2.2 ghc-7.2.2-dyn ghc-7.4.2 ghc-7.4.2-dyn
+
+# Update index
+RUN cabal v2-update --index-state="2020-06-12T23:36:15Z"
+
+# We install happy, so it's in the store; we (hopefully) don't use it directly.
+RUN cabal v2-install happy --constraint 'happy ^>=1.19.12'
+
+# Install some other dependencies
+# Remove $HOME/.ghc so there aren't any environments
+RUN cabal v2-install -w ghc-8.8.3 --lib \
+ Cabal \
+ aeson \
+ async \
+ base-compat \
+ base16-bytestring \
+ base64-bytestring \
+ cryptohash-sha256 \
+ Diff \
+ echo \
+ ed25519 \
+ edit-distance \
+ HTTP \
+ lukko \
+ network \
+ optparse-applicative \
+ pretty-show \
+ regex-compat-tdfa \
+ regex-posix \
+ regex-tdfa \
+ rere \
+ statistics \
+ tar \
+ tasty \
+ tasty-golden \
+ tasty-hunit \
+ tasty-quickcheck \
+ tree-diff \
+ void \
+ zlib \
+ resolv \
+ --constraint="rere -rere-cfg" \
+ --constraint="these -assoc" \
+ --constraint="bytestring installed" \
+ --constraint="binary installed" \
+ --constraint="containers installed" \
+ --constraint="deepseq installed" \
+ --constraint="directory installed" \
+ --constraint="filepath installed" \
+ --constraint="pretty installed" \
+ --constraint="process installed" \
+ --constraint="time installed" \
+ --constraint="unix installed" \
+ --constraint="transformers installed" \
+ && rm -rf $HOME/.ghc
+
+# Validate
+WORKDIR /build
+COPY . /build
+RUN sh ./validate.sh -w ghc-8.8.3 -v --lib-only --extra-hc /opt/ghc/7.0.4/bin/ghc-7.0.4 --extra-hc /opt/ghc/7.2.2/bin/ghc-7.2.2 --extra-hc /opt/ghc/7.4.2/bin/ghc-7.4.2
diff --git a/cabal/.docker/validate.dockerfile.zinza b/cabal/.docker/validate.dockerfile.zinza
new file mode 100644
index 0000000..c2c1724
--- /dev/null
+++ b/cabal/.docker/validate.dockerfile.zinza
@@ -0,0 +1,89 @@
+FROM phadej/ghc:{{ image }}
+
+# Install cabal-plan
+RUN mkdir -p /root/.cabal/bin && \
+ curl -L https://github.com/haskell-hvr/cabal-plan/releases/download/v0.6.2.0/cabal-plan-0.6.2.0-x86_64-linux.xz > cabal-plan.xz && \
+ echo "de73600b1836d3f55e32d80385acc055fd97f60eaa0ab68a755302685f5d81bc cabal-plan.xz" | sha256sum -c - && \
+ xz -d < cabal-plan.xz > /root/.cabal/bin/cabal-plan && \
+ rm -f cabal-plan.xz && \
+ chmod a+x /root/.cabal/bin/cabal-plan
+
+# Install cabal-env
+RUN curl -sL https://github.com/phadej/cabal-extras/releases/download/preview-20191225/cabal-env-snapshot-20191225-x86_64-linux.xz > cabal-env.xz && \
+ echo "1b567d529c5f627fd8c956e57ae8f0d9f11ee66d6db34b7fb0cb1c370b4edf01 cabal-env.xz" | sha256sum -c - && \
+ xz -d < cabal-env.xz > $HOME/.cabal/bin/cabal-env && \
+ rm -f cabal-env.xz && \
+ chmod a+x $HOME/.cabal/bin/cabal-env
+
+{% if needsDynamic %}
+# We need newer compiler, to install cabal-plan
+RUN apt-get update
+RUN apt-get install -y {{ ghc }}-dyn
+{% endif %}
+
+# Update index
+RUN cabal v2-update --index-state="2020-06-12T23:36:15Z"
+
+# We install happy, so it's in the store; we (hopefully) don't use it directly.
+RUN cabal v2-install happy --constraint 'happy ^>=1.19.12'
+
+# Install some other dependencies
+# Remove $HOME/.ghc so there aren't any environments
+RUN cabal v2-install -w {{ ghc }} --lib \
+ Cabal \
+ aeson \
+ async \
+ base-compat \
+ base16-bytestring \
+ base64-bytestring \
+ cryptohash-sha256 \
+ Diff \
+ echo \
+ ed25519 \
+ edit-distance \
+ HTTP \
+ lukko \
+ network \
+ optparse-applicative \
+ pretty-show \
+ regex-compat-tdfa \
+ regex-posix \
+ regex-tdfa \
+ rere \
+ statistics \
+ tar \
+ tasty \
+ tasty-golden \
+ tasty-hunit \
+ tasty-quickcheck \
+ tree-diff \
+ void \
+ zlib \
+{% if client %}
+ resolv \
+{% endif %}
+{% if parsecCompat %}
+ parsec \
+ text \
+{% endif %}
+ --constraint="rere -rere-cfg" \
+ --constraint="these -assoc" \
+ --constraint="bytestring installed" \
+ --constraint="binary installed" \
+ --constraint="containers installed" \
+ --constraint="deepseq installed" \
+ --constraint="directory installed" \
+ --constraint="filepath installed" \
+ --constraint="pretty installed" \
+ --constraint="process installed" \
+ --constraint="time installed" \
+ --constraint="unix installed" \
+{% if hasTransformers %}
+ --constraint="transformers installed" \
+{% endif %}
+ && rm -rf $HOME/.ghc
+
+# Validate
+WORKDIR /build
+COPY . /build
+RUN sh ./validate.sh {{ args }} -w {{ ghc }} -v
diff --git a/cabal/.dockerignore b/cabal/.dockerignore
index 47c984d..024a5f8 100644
--- a/cabal/.dockerignore
+++ b/cabal/.dockerignore
@@ -3,6 +3,8 @@
cabal.project.local
.ghc.environment.*
+.docker/
+
**/.hpc
**/*.hi
**/*.o
diff --git a/cabal/.readthedocs.yml b/cabal/.readthedocs.yml
new file mode 100644
index 0000000..2660528
--- /dev/null
+++ b/cabal/.readthedocs.yml
@@ -0,0 +1,9 @@
+version: 2
+
+sphinx:
+ configuration: Cabal/doc/conf.py
+
+python:
+ version: 3.7
+ install:
+ - requirements: Cabal/doc/requirements.txt
diff --git a/cabal/.travis.yml b/cabal/.travis.yml
deleted file mode 100644
index c6f4732..0000000
--- a/cabal/.travis.yml
+++ /dev/null
@@ -1,177 +0,0 @@
-# NB: don't set `language: haskell` here
-# We specify language: c, so it doesn't default to e.g. ruby
-language: c
-
-dist: xenial
-
-# This sets the default config for each job to use full VMs.
-# The VMs have 2 cores and 8 gigs of ram. Larger VMs are also available.
-sudo: true
-
-# We whitelist branches, as we don't really need to build dev-branches.
-# Except if those branches are in a fork.
-# Remember to add release branches, both here and to appveyor.yml.
-if: branch IN (master, 3.0, 2.4, 2.2, 2.0, 1.24, 1.22, 1.20, 1.18) OR repo != haskell/cabal
-
-# The following enables several GHC versions to be tested; often it's enough to
-# test only against the last release in a major GHC version. Feel free to omit
-# lines listings versions you don't need/want testing for.
-#
-# NB: If you test the same GHC version/OS combo multiple times with
-# SCRIPT=script (e.g., see PARSEC=YES below), you MUST supply a
-# TAGSUFFIX to help travis/upload.sh disambiguate the matrix entry.
-matrix:
- include:
- - env: GHCVER=8.4.4 SCRIPT=meta BUILDER=none
- os: linux
- sudo: required
- # These don't have -dyn/-prof whitelisted yet, so we have to
- # do the old-style installation
- # NB: TEST_OTHER_VERSIONS doesn't work with USE_GOLD=YES.
- - env: GHCVER=7.6.3 SCRIPT=script CABAL_LIB_ONLY=YES TEST_OTHER_VERSIONS=YES
- os: linux
- sudo: required
- - env: GHCVER=7.8.4 SCRIPT=script CABAL_LIB_ONLY=YES TEST_OTHER_VERSIONS=YES
- os: linux
- sudo: required
- # Ugh, we'd like to drop 'sudo: required' and use the
- # apt plugin for the next two
- # but the GCE instance we get has more memory, which makes
- # a big difference
- - env: GHCVER=7.10.3 SCRIPT=script USE_GOLD=YES
- os: linux
- sudo: required
- - env: GHCVER=8.0.2 SCRIPT=script USE_GOLD=YES TEST_SOLVER_BENCHMARKS=YES
- sudo: required
- os: linux
- - env: GHCVER=8.2.2 SCRIPT=script USE_GOLD=YES
- os: linux
- sudo: required
- - env: GHCVER=8.4.4 SCRIPT=script USE_GOLD=YES DEPLOY_DOCS=YES
- os: linux
- sudo: required
- - env: GHCVER=8.6.5 SCRIPT=script USE_GOLD=YES
- os: linux
- sudo: required
- #- env: GHCVER=8.8.1 SCRIPT=script USE_GOLD=YES
- # os: linux
- # sudo: required
-
- - env: GHCVER=8.4.4 SCRIPT=solver-debug-flags USE_GOLD=YES
- sudo: required
- os: linux
- - env: GHCVER=8.4.4 SCRIPT=script DEBUG_EXPENSIVE_ASSERTIONS=YES TAGSUFFIX="-fdebug-expensive-assertions" USE_GOLD=YES
- os: linux
- sudo: required
- - env: GHCVER=8.0.2 SCRIPT=bootstrap USE_GOLD=YES
- sudo: required
- os: linux
- - env: GHCVER=8.4.4 SCRIPT=bootstrap USE_GOLD=YES
- sudo: required
- os: linux
-
- # We axed GHC 7.6 and earlier because it's not worth the trouble to
- # make older GHC work with clang's cpp. See
- # https://ghc.haskell.org/trac/ghc/ticket/8493
- - env: GHCVER=7.8.4 SCRIPT=script CABAL_LIB_ONLY=YES
- os: osx
- # Keep this synced with travis/upload.sh
- osx_image: xcode6.4 # We need 10.10
-
- # TODO: We might want to specify OSX version
- # https://docs.travis-ci.com/user/osx-ci-environment/#OS-X-Version
- - env: GHCVER=7.10.3 SCRIPT=script
- os: osx
- - env: GHCVER=8.0.2 SCRIPT=script
- os: osx
- - env: GHCVER=8.0.2 SCRIPT=bootstrap
- os: osx
-
- # It's been long known that CI with
- # Stack does not work so it's disabled until further notice
- # to reduce latency and avoid wasting CI slots for no reason.
- #
- #- env: GHCVER=via-stack SCRIPT=stack STACK_CONFIG=stack.yaml
- # os: linux
- #
- # See https://github.com/haskell/cabal/pull/4667#issuecomment-321036564
- # for why failures are allowed.
- #
- # OSX jobs timeout often, so they can fail
- allow_failures:
- # - env: GHCVER=via-stack SCRIPT=stack STACK_CONFIG=stack.yaml
- - env: GHCVER=7.10.3 SCRIPT=script
- os: osx
- - env: GHCVER=8.0.2 SCRIPT=script
- os: osx
-
- # TODO add PARSEC_BUNDLED=YES when it's so
- # It seems pointless to run head if we're going to ignore the results.
- #- GHCVER=head
-
- # Marks the build result as soon as all the non-"allow_failures" jobs finish, based on their results
- # while the remaining `allow_failures` jobs continue to run.
- fast_finish: true
-
-# Note: the distinction between `before_install` and `install` is not important.
-before_install:
- - export PATH=/opt/ghc/$GHCVER/bin:$PATH
- - export PATH=$HOME/.ghc-install/$GHCVER/bin:$PATH
- - export PATH=$HOME/bin:$PATH
- - export PATH=$HOME/.cabal/bin:$PATH
- - export PATH=$HOME/.local/bin:$PATH
- - export PATH=/opt/cabal/2.4/bin:$PATH
- - if [ "$USE_GOLD" = "YES" ]; then sudo update-alternatives --install "/usr/bin/ld" "ld" "/usr/bin/ld.gold" 20; fi
- - if [ "$USE_GOLD" = "YES" ]; then sudo update-alternatives --install "/usr/bin/ld" "ld" "/usr/bin/ld.bfd" 10; fi
- - ld -v
- - ./travis-install.sh
-
-install:
- # We intentionally do not install anything before trying to build Cabal because
- # it should build with each supported GHC version out-of-the-box.
-
-# Here starts the actual work to be performed for the package under test; any
-# command which exits with a non-zero exit code causes the build to fail. Using
-# ./dist/setup/setup here instead of cabal-install to avoid breakage when the
-# build config format changed.
-script:
- - rm -rf dist-newstyle
- - ./travis-${SCRIPT}.sh -j2
-
-cache:
- directories:
- - $HOME/.cabal/packages
- - $HOME/.cabal/store
- - $HOME/.cabal/bin
-
- - $HOME/.stack/bin
- - $HOME/.stack/precompiled
- - $HOME/.stack/programs
- - $HOME/.stack/setup-exe-cache
- - $HOME/.stack/snapshots
-
-# We remove the index because it churns quite a bit and we don't want
-# to pay the cost of repeatedly caching it even though we don't care
-# about most changing packages.
-before_cache:
- - rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log
- - rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index*
- - rm -fv $HOME/.cabal/packages/hackage.haskell.org/01-index*
- - rm -fv $HOME/.cabal/packages/hackage.haskell.org/*.json
- # avoid clashing or stale locks being cached
- - rm -rfv $HOME/.cabal/packages/hackage.haskell.org/hackage-security-lock
-
-# Deploy Haddocks to the haskell/cabal-website repo.
-after_success:
- # Set up deployment to the haskell/cabal-website repo.
- # NB: these commands MUST be in .travis.yml, otherwise the secret key can be
- # leaked! See https://github.com/travis-ci/travis.rb/issues/423.
- # umask to get the permissions to be 600.
- - if [ "x$TRAVIS_REPO_SLUG" = "xhaskell/cabal" -a "x$TRAVIS_PULL_REQUEST" = "xfalse" -a "x$TRAVIS_BRANCH" = "xmaster" -a "x$DEPLOY_DOCS" = "xYES" ]; then (umask 177 && openssl aes-256-cbc -K $encrypted_edaf6551664d_key -iv $encrypted_edaf6551664d_iv -in id_rsa_cabal_website.aes256.enc -out ~/.ssh/id_rsa -d); fi
- - ./travis-deploy.sh
-
-notifications:
- irc:
- if: repo = haskell/cabal
- channels:
- - "chat.freenode.net##haskell-cabal"
diff --git a/cabal/CONTRIBUTING.md b/cabal/CONTRIBUTING.md
index 8b311fc..a387adf 100644
--- a/cabal/CONTRIBUTING.md
+++ b/cabal/CONTRIBUTING.md
@@ -4,12 +4,12 @@ Building Cabal for hacking
--------------------------
The current recommended way of developing Cabal is to use the
-`new-build` feature which [shipped in cabal-install-1.24](http://blog.ezyang.com/2016/05/announcing-cabal-new-build-nix-style-local-builds/). Assuming
+`v2-build` feature which [shipped in cabal-install-1.24](http://blog.ezyang.com/2016/05/announcing-cabal-new-build-nix-style-local-builds/). Assuming
that you have a sufficiently recent cabal-install (see above),
it is sufficient to run:
~~~~
-cabal new-build cabal
+cabal v2-build cabal
~~~~
To build a local, development copy of cabal-install. The location
@@ -21,9 +21,9 @@ to find the binary (or just run `find -type f -executable -name cabal`).
Here are some other useful variations on the commands:
~~~~
-cabal new-build Cabal # build library only
-cabal new-build Cabal:unit-tests # build Cabal's unit test suite
-cabal new-build cabal-tests # etc...
+cabal v2-build Cabal # build library only
+cabal v2-build Cabal:unit-tests # build Cabal's unit test suite
+cabal v2-build cabal-tests # etc...
~~~~
**Dogfooding HEAD.**
@@ -45,7 +45,7 @@ and `~/cabal-dev`, and you have a release copy of cabal installed at
~~~~
cd ~/cabal-prod
-/opt/cabal/2.4/bin/cabal new-build cabal
+/opt/cabal/2.4/bin/cabal v2-build cabal
~~~~
This will produce a cabal binary (see also: [Where are my build products?](http://cabal.readthedocs.io/en/latest/nix-local-build.html#where-are-my-build-products)
@@ -54,7 +54,7 @@ and then use it to build your development copy:
~~~~
cd ~/cabal-dev
-cabal new-build cabal
+cabal v2-build cabal
~~~~
Running tests
@@ -112,7 +112,7 @@ If none of these let you reproduce, there might be some race condition
or continuous integration breakage; please file a bug.
**Running tests locally.**
-To run tests locally with `new-build`, you will need to know the
+To run tests locally with `v2-build`, you will need to know the
name of the test suite you want. Cabal and cabal-install have
several. Also, you'll want to read [Where are my build products?](http://cabal.readthedocs.io/en/latest/nix-local-build.html#where-are-my-build-products)
diff --git a/cabal/Cabal/Cabal-QuickCheck/Cabal-QuickCheck.cabal b/cabal/Cabal/Cabal-QuickCheck/Cabal-QuickCheck.cabal
new file mode 100644
index 0000000..8f392d1
--- /dev/null
+++ b/cabal/Cabal/Cabal-QuickCheck/Cabal-QuickCheck.cabal
@@ -0,0 +1,24 @@
+cabal-version: 2.2
+name: Cabal-QuickCheck
+version: 3.3.0.0
+synopsis: QuickCheck instances for types in Cabal
+category: Testing
+description:
+ Provides QuickCheck Arbitrary instances for some types in Cabal
+
+library
+ default-language: Haskell2010
+ hs-source-dirs: src
+ ghc-options: -Wall
+ build-depends:
+ , base
+ , bytestring
+ , Cabal ^>=3.3.0.0
+ , QuickCheck ^>=2.13.2 || ^>=2.14
+
+ if !impl(ghc >= 8.0)
+ build-depends: semigroups
+
+ exposed-modules:
+ Test.QuickCheck.GenericArbitrary
+ Test.QuickCheck.Instances.Cabal
diff --git a/cabal/Cabal/Cabal-QuickCheck/src/Test/QuickCheck/GenericArbitrary.hs b/cabal/Cabal/Cabal-QuickCheck/src/Test/QuickCheck/GenericArbitrary.hs
new file mode 100644
index 0000000..fdfe817
--- /dev/null
+++ b/cabal/Cabal/Cabal-QuickCheck/src/Test/QuickCheck/GenericArbitrary.hs
@@ -0,0 +1,49 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeOperators #-}
+module Test.QuickCheck.GenericArbitrary (
+ genericArbitrary,
+ GArbitrary,
+) where
+
+import GHC.Generics
+import Test.QuickCheck
+
+#if !MIN_VERSION_base(4,8,0)
+import Control.Applicative (pure, (<$>), (<*>))
+#endif
+
+-- Generic arbitary for non-recursive types
+genericArbitrary :: (Generic a, GArbitrary (Rep a)) => Gen a
+genericArbitrary = fmap to garbitrary
+
+class GArbitrary f where
+ garbitrary :: Gen (f ())
+
+class GArbitrarySum f where
+ garbitrarySum :: [Gen (f ())]
+
+class GArbitraryProd f where
+ garbitraryProd :: Gen (f ())
+
+instance (GArbitrarySum f, i ~ D) => GArbitrary (M1 i c f) where
+ garbitrary = fmap M1 (oneof garbitrarySum)
+
+instance (GArbitraryProd f, i ~ C) => GArbitrarySum (M1 i c f) where
+ garbitrarySum = [fmap M1 garbitraryProd]
+
+instance (GArbitrarySum f, GArbitrarySum g) => GArbitrarySum (f :+: g) where
+ garbitrarySum = map (fmap L1) garbitrarySum ++ map (fmap R1) garbitrarySum
+
+instance (GArbitraryProd f, i ~ S) => GArbitraryProd (M1 i c f) where
+ garbitraryProd = fmap M1 garbitraryProd
+
+instance GArbitraryProd U1 where
+ garbitraryProd = pure U1
+
+instance (GArbitraryProd f, GArbitraryProd g) => GArbitraryProd (f :*: g) where
+ garbitraryProd = (:*:) <$> garbitraryProd <*> garbitraryProd
+
+instance (Arbitrary a) => GArbitraryProd (K1 i a) where
+ garbitraryProd = fmap K1 arbitrary
diff --git a/cabal/Cabal/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs b/cabal/Cabal/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs
new file mode 100644
index 0000000..9c107ce
--- /dev/null
+++ b/cabal/Cabal/Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs
@@ -0,0 +1,513 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE TypeOperators #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+module Test.QuickCheck.Instances.Cabal () where
+
+import Control.Applicative (liftA2)
+import Data.Char (isAlphaNum, isDigit)
+import Data.List (intercalate, isPrefixOf)
+import Data.List.NonEmpty (NonEmpty (..))
+import Distribution.Utils.Generic (lowercase)
+import Test.QuickCheck
+
+import Distribution.CabalSpecVersion
+import Distribution.Compat.NonEmptySet (NonEmptySet)
+import Distribution.Compiler
+import Distribution.FieldGrammar.Newtypes
+import Distribution.ModuleName
+import Distribution.Simple.Compiler (DebugInfoLevel (..), OptimisationLevel (..), PackageDB (..), ProfDetailLevel (..), knownProfDetailLevels)
+import Distribution.Simple.Flag (Flag (..))
+import Distribution.Simple.InstallDirs
+import Distribution.Simple.Setup (HaddockTarget (..), TestShowDetails (..))
+import Distribution.SPDX
+import Distribution.System
+import Distribution.Types.Dependency
+import Distribution.Types.Flag (FlagAssignment, FlagName, mkFlagAssignment, mkFlagName, unFlagAssignment)
+import Distribution.Types.IncludeRenaming
+import Distribution.Types.LibraryName
+import Distribution.Types.LibraryVisibility
+import Distribution.Types.Mixin
+import Distribution.Types.ModuleRenaming
+import Distribution.Types.PackageId
+import Distribution.Types.PackageName
+import Distribution.Types.PackageVersionConstraint
+import Distribution.Types.PkgconfigVersion
+import Distribution.Types.PkgconfigVersionRange
+import Distribution.Types.SourceRepo
+import Distribution.Types.UnqualComponentName
+import Distribution.Types.VersionRange.Internal
+import Distribution.Utils.NubList
+import Distribution.Verbosity
+import Distribution.Version
+
+import Test.QuickCheck.GenericArbitrary
+
+import qualified Data.ByteString.Char8 as BS8
+import qualified Distribution.Compat.NonEmptySet as NES
+
+#if !MIN_VERSION_base(4,8,0)
+import Control.Applicative (pure, (<$>), (<*>))
+#endif
+
+-------------------------------------------------------------------------------
+-- CabalSpecVersion
+-------------------------------------------------------------------------------
+
+instance Arbitrary CabalSpecVersion where
+ arbitrary = arbitraryBoundedEnum
+
+instance Arbitrary SpecVersion where
+ arbitrary = fmap SpecVersion arbitrary
+
+-------------------------------------------------------------------------------
+-- PackageName and PackageIdentifier
+-------------------------------------------------------------------------------
+
+instance Arbitrary PackageName where
+ arbitrary = mkPackageName . intercalate "-" <$> shortListOf1 2 nameComponent
+ where
+ nameComponent = shortListOf1 5 (elements packageChars)
+ `suchThat` (not . all isDigit)
+ packageChars = filter isAlphaNum ['\0'..'\127']
+
+instance Arbitrary PackageIdentifier where
+ arbitrary = PackageIdentifier <$> arbitrary <*> arbitrary
+
+ shrink (PackageIdentifier pn vr) = uncurry PackageIdentifier <$> shrink (pn, vr)
+
+-------------------------------------------------------------------------------
+-- Version
+-------------------------------------------------------------------------------
+
+-- | Does *NOT* generate 'nullVersion'
+instance Arbitrary Version where
+ arbitrary = do
+ branch <- smallListOf1 $
+ frequency [(3, return 0)
+ ,(3, return 1)
+ ,(2, return 2)
+ ,(2, return 3)
+ ,(1, return 0xfffd)
+ ,(1, return 0xfffe) -- max fitting into packed W64
+ ,(1, return 0xffff)
+ ,(1, return 999999998)
+ ,(1, return 999999999)
+ ,(1, return 0x10000)]
+ return (mkVersion branch)
+ where
+ smallListOf1 = scale (\n -> min 6 (n `div` 3)) . listOf1
+
+ shrink ver = [ mkVersion ns | ns <- shrink (versionNumbers ver)
+ , not (null ns) ]
+
+instance Arbitrary VersionRange where
+ arbitrary = sized verRangeExp
+ where
+ verRangeExp n = frequency $
+ [ (2, return anyVersion)
+ , (1, fmap thisVersion arbitrary)
+ , (1, fmap laterVersion arbitrary)
+ , (1, fmap orLaterVersion arbitrary)
+ , (1, fmap orLaterVersion' arbitrary)
+ , (1, fmap earlierVersion arbitrary)
+ , (1, fmap orEarlierVersion arbitrary)
+ , (1, fmap orEarlierVersion' arbitrary)
+ , (1, fmap withinVersion arbitraryV)
+ , (1, fmap majorBoundVersion arbitrary)
+ ] ++ if n == 0 then [] else
+ [ (2, liftA2 unionVersionRanges verRangeExp2 verRangeExp2)
+ , (2, liftA2 intersectVersionRanges verRangeExp2 verRangeExp2)
+ ]
+ where
+ verRangeExp2 = verRangeExp (n `div` 2)
+
+ arbitraryV :: Gen Version
+ arbitraryV = arbitrary `suchThat` \v -> all (< 999999999) (versionNumbers v)
+
+ orLaterVersion' v =
+ unionVersionRanges (LaterVersion v) (ThisVersion v)
+ orEarlierVersion' v =
+ unionVersionRanges (EarlierVersion v) (ThisVersion v)
+
+ shrink (ThisVersion v) = map ThisVersion (shrink v)
+ shrink (LaterVersion v) = map LaterVersion (shrink v)
+ shrink (EarlierVersion v) = map EarlierVersion (shrink v)
+ shrink (OrLaterVersion v) = LaterVersion v : map OrLaterVersion (shrink v)
+ shrink (OrEarlierVersion v) = EarlierVersion v : map OrEarlierVersion (shrink v)
+ shrink (MajorBoundVersion v) = map MajorBoundVersion (shrink v)
+ shrink (UnionVersionRanges a b) = a : b : map (uncurry UnionVersionRanges) (shrink (a, b))
+ shrink (IntersectVersionRanges a b) = a : b : map (uncurry IntersectVersionRanges) (shrink (a, b))
+
+-- | Generating VersionIntervals
+--
+-- This is a tad tricky as VersionIntervals is an abstract type, so we first
+-- make a local type for generating the internal representation. Then we check
+-- that this lets us construct valid 'VersionIntervals'.
+--
+
+instance Arbitrary VersionIntervals where
+ arbitrary = fmap mkVersionIntervals' arbitrary
+ where
+ mkVersionIntervals' :: [(Version, Bound)] -> VersionIntervals
+ mkVersionIntervals' = mkVersionIntervals . go version0
+ where
+ go :: Version -> [(Version, Bound)] -> [VersionInterval]
+ go _ [] = []
+ go v [(lv, lb)] =
+ [(LowerBound (addVersion lv v) lb, NoUpperBound)]
+ go v ((lv, lb) : (uv, ub) : rest) =
+ (LowerBound lv' lb, UpperBound uv' ub) : go uv' rest
+ where
+ lv' = addVersion v lv
+ uv' = addVersion lv' uv
+
+ addVersion :: Version -> Version -> Version
+ addVersion xs ys = mkVersion $ z (versionNumbers xs) (versionNumbers ys)
+ where
+ z [] ys' = ys'
+ z xs' [] = xs'
+ z (x : xs') (y : ys') = x + y : z xs' ys'
+
+instance Arbitrary Bound where
+ arbitrary = elements [ExclusiveBound, InclusiveBound]
+
+-------------------------------------------------------------------------------
+-- Backpack
+-------------------------------------------------------------------------------
+
+instance Arbitrary Mixin where
+ arbitrary = normaliseMixin <$> genericArbitrary
+ shrink = fmap normaliseMixin . genericShrink
+
+instance Arbitrary IncludeRenaming where
+ arbitrary = genericArbitrary
+ shrink = genericShrink
+
+instance Arbitrary ModuleRenaming where
+ arbitrary = genericArbitrary
+ shrink = genericShrink
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+
+instance Arbitrary LibraryVisibility where
+ arbitrary = elements [LibraryVisibilityPrivate, LibraryVisibilityPublic]
+
+ shrink LibraryVisibilityPublic = [LibraryVisibilityPrivate]
+ shrink LibraryVisibilityPrivate = []
+
+-------------------------------------------------------------------------------
+-- ModuleName
+-------------------------------------------------------------------------------
+
+instance Arbitrary ModuleName where
+ arbitrary = fromString . intercalate "." <$> shortListOf1 4 comp where
+ comp = (:) <$> elements upper <*> shortListOf1 10 (elements moduleChar)
+ upper = ['A'..'Z']
+ moduleChar = [ c | c <- ['\0' .. '\255'], isAlphaNum c || c `elem` "_'" ]
+
+-------------------------------------------------------------------------------
+-- Dependency
+-------------------------------------------------------------------------------
+
+instance Arbitrary Dependency where
+ arbitrary = mkDependency
+ <$> arbitrary
+ <*> arbitrary
+ <*> (arbitrary `suchThat` const True) -- should be (not . null)
+
+ shrink (Dependency pn vr lb) =
+ [ mkDependency pn' vr' lb'
+ | (pn', vr', lb') <- shrink (pn, vr, lb)
+ ]
+
+-------------------------------------------------------------------------------
+-- PackageVersionConstraint
+-------------------------------------------------------------------------------
+
+instance Arbitrary PackageVersionConstraint where
+ arbitrary = PackageVersionConstraint
+ <$> arbitrary
+ <*> arbitrary
+
+ shrink (PackageVersionConstraint pn vr) =
+ [ PackageVersionConstraint pn' vr'
+ | (pn', vr') <- shrink (pn, vr)
+ ]
+
+-------------------------------------------------------------------------------
+-- System
+-------------------------------------------------------------------------------
+
+instance Arbitrary OS where
+ arbitrary = elements knownOSs
+
+instance Arbitrary Arch where
+ arbitrary = elements knownArches
+
+instance Arbitrary Platform where
+ arbitrary = Platform <$> arbitrary <*> arbitrary
+
+-------------------------------------------------------------------------------
+-- Various names
+-------------------------------------------------------------------------------
+
+instance Arbitrary UnqualComponentName where
+ -- same rules as package names
+ arbitrary = packageNameToUnqualComponentName <$> arbitrary
+
+instance Arbitrary LibraryName where
+ arbitrary = oneof
+ [ LSubLibName <$> arbitrary
+ , pure LMainLibName
+ ]
+
+ shrink (LSubLibName _) = [LMainLibName]
+ shrink _ = []
+
+-------------------------------------------------------------------------------
+-- option flags
+-------------------------------------------------------------------------------
+
+instance Arbitrary a => Arbitrary (Flag a) where
+ arbitrary = arbitrary1
+
+ shrink NoFlag = []
+ shrink (Flag x) = NoFlag : [ Flag x' | x' <- shrink x ]
+
+instance Arbitrary1 Flag where
+ liftArbitrary genA = sized $ \sz ->
+ if sz <= 0
+ then pure NoFlag
+ else frequency [ (1, pure NoFlag)
+ , (3, Flag <$> genA) ]
+
+-------------------------------------------------------------------------------
+-- GPD flags
+-------------------------------------------------------------------------------
+
+instance Arbitrary FlagName where
+ arbitrary = mkFlagName <$> frequency
+ [ (20, flagident)
+ -- special nasty cases
+ , (1, pure "none")
+ , (1, pure "any")
+ ]
+ where
+ flagident = lowercase <$> shortListOf1 5 (elements flagChars)
+ `suchThat` (("-" /=) . take 1)
+ flagChars = "-_" ++ ['a'..'z']
+
+instance Arbitrary FlagAssignment where
+ arbitrary = mkFlagAssignment <$> arbitrary
+ shrink x = mkFlagAssignment <$> shrink (unFlagAssignment x)
+
+-------------------------------------------------------------------------------
+-- Verbosity
+-------------------------------------------------------------------------------
+
+instance Arbitrary Verbosity where
+ arbitrary = do
+ v <- elements [minBound..maxBound]
+ -- verbose markoutput is left out on purpose
+ flags <- listOf $ elements
+ [ verboseCallSite
+ , verboseCallStack
+ , verboseNoWrap
+ , verboseTimestamp
+ , verboseStderr
+ ]
+ return (foldr ($) v flags)
+
+-------------------------------------------------------------------------------
+-- SourceRepo
+-------------------------------------------------------------------------------
+
+instance Arbitrary RepoType where
+ arbitrary = elements (KnownRepoType <$> knownRepoTypes)
+
+instance Arbitrary RepoKind where
+ arbitrary = elements [RepoHead, RepoThis]
+
+-------------------------------------------------------------------------------
+-- SPDX
+-------------------------------------------------------------------------------
+
+instance Arbitrary LicenseId where
+ arbitrary = elements $ licenseIdList currentLicenseListVersion
+
+instance Arbitrary LicenseExceptionId where
+ arbitrary = elements $ licenseExceptionIdList currentLicenseListVersion
+
+currentLicenseListVersion :: LicenseListVersion
+currentLicenseListVersion = cabalSpecVersionToSPDXListVersion cabalSpecLatest
+
+instance Arbitrary LicenseRef where
+ arbitrary = mkLicenseRef' <$> ids' <*> ids
+ where
+ ids = listOf1 $ elements $ ['a'..'z'] ++ ['A' .. 'Z'] ++ ['0'..'9'] ++ "_-"
+ ids' = oneof [ pure Nothing, Just <$> ids ]
+
+instance Arbitrary SimpleLicenseExpression where
+ arbitrary = oneof
+ [ ELicenseId <$> arbitrary
+ , ELicenseIdPlus <$> arbitrary
+ , ELicenseRef <$> arbitrary
+ ]
+
+instance Arbitrary LicenseExpression where
+ arbitrary = sized arb
+ where
+ arb n
+ | n <= 0 = ELicense <$> arbitrary <*> pure Nothing
+ | otherwise = oneof
+ [ ELicense <$> arbitrary <*> arbitrary
+ , EAnd <$> arbA <*> arbB
+ , EOr <$> arbA <*> arbB
+ ]
+ where
+ m = n `div` 2
+ arbA = arb m
+ arbB = arb (n - m)
+
+ shrink (EAnd a b) = a : b : map (uncurry EAnd) (shrink (a, b))
+ shrink (EOr a b) = a : b : map (uncurry EOr) (shrink (a, b))
+ shrink _ = []
+
+-------------------------------------------------------------------------------
+-- Compiler
+-------------------------------------------------------------------------------
+
+instance Arbitrary CompilerFlavor where
+ arbitrary = elements knownCompilerFlavors
+
+instance Arbitrary CompilerId where
+ arbitrary = genericArbitrary
+ shrink = genericShrink
+
+instance Arbitrary ProfDetailLevel where
+ arbitrary = elements [ d | (_,_,d) <- knownProfDetailLevels ]
+
+instance Arbitrary OptimisationLevel where
+ arbitrary = elements [minBound..maxBound]
+
+instance Arbitrary DebugInfoLevel where
+ arbitrary = elements [minBound..maxBound]
+
+-------------------------------------------------------------------------------
+-- NonEmptySet
+-------------------------------------------------------------------------------
+
+instance (Arbitrary a, Ord a) => Arbitrary (NonEmptySet a) where
+ arbitrary = mk <$> arbitrary <*> arbitrary where
+ mk x xs = NES.fromNonEmpty (x :| xs)
+
+ shrink nes = case NES.toNonEmpty nes of
+ x :| xs -> map mk (shrink (x, xs))
+ where
+ mk (x,xs) = NES.fromNonEmpty (x :| xs)
+
+-------------------------------------------------------------------------------
+-- NubList
+-------------------------------------------------------------------------------
+
+instance (Arbitrary a, Ord a) => Arbitrary (NubList a) where
+ arbitrary = toNubList <$> arbitrary
+ shrink xs = [ toNubList [] | (not . null) (fromNubList xs) ]
+ -- try empty, otherwise don't shrink as it can loop
+
+-------------------------------------------------------------------------------
+-- InstallDirs
+-------------------------------------------------------------------------------
+
+instance Arbitrary a => Arbitrary (InstallDirs a) where
+ arbitrary = InstallDirs
+ <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary -- 4
+ <*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary -- 8
+ <*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary -- 12
+ <*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary -- 16
+
+instance Arbitrary PathTemplate where
+ arbitrary = toPathTemplate <$> arbitraryShortToken
+ shrink t = [ toPathTemplate s
+ | s <- shrink (fromPathTemplate t)
+ , not (null s) ]
+
+-------------------------------------------------------------------------------
+-- Pkgconfig
+-------------------------------------------------------------------------------
+
+instance Arbitrary PkgconfigVersion where
+ arbitrary = PkgconfigVersion . BS8.pack . dropDash . concat <$> listOf1 elems where
+ elems = frequency
+ [ (2, pure ".")
+ , (1, pure "-")
+ , (5, listOf1 $ elements ['0' .. '9'])
+ , (1, listOf1 $ elements ['A' .. 'Z'])
+ , (1, listOf1 $ elements ['a' .. 'z'])
+ ]
+
+ -- disallow versions starting with dash
+ dropDash = notEmpty . dropWhile (== '-')
+ notEmpty x
+ | null x = "0"
+ | otherwise = x
+
+instance Arbitrary PkgconfigVersionRange where
+ arbitrary = sized verRangeExp
+ where
+ verRangeExp n = frequency $
+ [ (2, return PcAnyVersion)
+ , (1, fmap PcThisVersion arbitrary)
+ , (1, fmap PcLaterVersion arbitrary)
+ , (1, fmap PcOrLaterVersion arbitrary)
+ , (1, fmap orLaterVersion' arbitrary)
+ , (1, fmap PcEarlierVersion arbitrary)
+ , (1, fmap PcOrEarlierVersion arbitrary)
+ , (1, fmap orEarlierVersion' arbitrary)
+ ] ++ if n == 0 then [] else
+ [ (2, liftA2 PcUnionVersionRanges verRangeExp2 verRangeExp2)
+ , (2, liftA2 PcIntersectVersionRanges verRangeExp2 verRangeExp2)
+ ]
+ where
+ verRangeExp2 = verRangeExp (n `div` 2)
+
+ orLaterVersion' v =
+ PcUnionVersionRanges (PcLaterVersion v) (PcThisVersion v)
+ orEarlierVersion' v =
+ PcUnionVersionRanges (PcEarlierVersion v) (PcThisVersion v)
+
+-------------------------------------------------------------------------------
+-- Setup
+-------------------------------------------------------------------------------
+
+instance Arbitrary HaddockTarget where
+ arbitrary = elements [ForHackage, ForDevelopment]
+
+instance Arbitrary TestShowDetails where
+ arbitrary = arbitraryBoundedEnum
+
+-------------------------------------------------------------------------------
+-- PackageDB
+-------------------------------------------------------------------------------
+
+instance Arbitrary PackageDB where
+ arbitrary = oneof [ pure GlobalPackageDB
+ , pure UserPackageDB
+ , SpecificPackageDB <$> arbitraryShortToken
+ ]
+
+
+-------------------------------------------------------------------------------
+-- Helpers
+-------------------------------------------------------------------------------
+
+shortListOf1 :: Int -> Gen a -> Gen [a]
+shortListOf1 bound gen = sized $ \n -> do
+ k <- choose (1, 1 `max` ((n `div` 2) `min` bound))
+ vectorOf k gen
+
+arbitraryShortToken :: Gen String
+arbitraryShortToken =
+ shortListOf1 5 (choose ('#', '~')) `suchThat` (not . ("[]" `isPrefixOf`))
diff --git a/cabal/Cabal/Cabal-described/Cabal-described.cabal b/cabal/Cabal/Cabal-described/Cabal-described.cabal
new file mode 100644
index 0000000..09ba1c8
--- /dev/null
+++ b/cabal/Cabal/Cabal-described/Cabal-described.cabal
@@ -0,0 +1,26 @@
+cabal-version: 2.2
+name: Cabal-described
+version: 3.3.0.0
+synopsis: Described functionality for types in Cabal
+category: Testing, Parsec
+description: Provides rere bindings
+
+library
+ default-language: Haskell2010
+ hs-source-dirs: src
+ ghc-options: -Wall
+ build-depends:
+ , base
+ , Cabal ^>=3.3.0.0
+ , containers
+ , pretty
+ , QuickCheck
+ , rere ^>=0.1
+ , tasty
+ , tasty-quickcheck
+ , transformers
+
+ exposed-modules:
+ Distribution.Described
+ Distribution.Utils.CharSet
+ Distribution.Utils.GrammarRegex
diff --git a/cabal/Cabal/Cabal-described/src/Distribution/Described.hs b/cabal/Cabal/Cabal-described/src/Distribution/Described.hs
new file mode 100644
index 0000000..d095040
--- /dev/null
+++ b/cabal/Cabal/Cabal-described/src/Distribution/Described.hs
@@ -0,0 +1,577 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+module Distribution.Described (
+ Described (..),
+ describeDoc,
+ -- * Regular expressions
+ GrammarRegex (..),
+ reEps,
+ reChar,
+ reChars,
+ reMunchCS,
+ reMunch1CS,
+ -- * Variables
+ reVar0,
+ reVar1,
+ -- * Special expressions
+ reDot,
+ reComma,
+ reSpacedComma,
+ reHsString,
+ reUnqualComponent,
+ -- *
+ describeFlagAssignmentNonEmpty,
+ -- * Lists
+ reSpacedList,
+ reCommaList,
+ reCommaNonEmpty,
+ reOptCommaList,
+ -- * Character Sets
+ csChar,
+ csAlpha,
+ csAlphaNum,
+ csUpper,
+ csNotSpace,
+ csNotSpaceOrComma,
+ -- * tasty
+ testDescribed,
+ ) where
+
+import Prelude
+ (Bool (..), Char, Either (..), Enum (..), Eq (..), Ord (..), Show (..), String, elem, fmap, foldr, id, map, maybe, otherwise, return, undefined, ($),
+ (.))
+
+import Data.Functor.Identity (Identity (..))
+import Data.Maybe (fromMaybe)
+import Data.Proxy (Proxy (..))
+import Data.String (IsString (..))
+import Data.Typeable (Typeable, typeOf)
+import Data.Void (Void, vacuous)
+import Test.QuickCheck (Arbitrary (..), Property, counterexample)
+import Test.Tasty (TestTree, testGroup)
+import Test.Tasty.QuickCheck (testProperty)
+
+import Distribution.Compat.Semigroup (Semigroup (..))
+import Distribution.Parsec (Parsec, eitherParsec)
+import Distribution.Pretty (Pretty, prettyShow)
+
+import qualified Distribution.Utils.CharSet as CS
+import qualified RERE as RE
+import qualified RERE.CharSet as RE
+import qualified Text.PrettyPrint as PP
+
+import Distribution.Utils.GrammarRegex
+
+-- Types
+import Distribution.Compat.Newtype
+import Distribution.Compiler (CompilerFlavor, CompilerId, knownCompilerFlavors)
+import Distribution.FieldGrammar.Newtypes
+import Distribution.ModuleName (ModuleName)
+import Distribution.System (Arch, OS, knownArches, knownOSs)
+import Distribution.Types.AbiDependency (AbiDependency)
+import Distribution.Types.AbiHash (AbiHash)
+import Distribution.Types.BenchmarkType (BenchmarkType)
+import Distribution.Types.BuildType (BuildType)
+import Distribution.Types.Dependency (Dependency)
+import Distribution.Types.ExecutableScope (ExecutableScope)
+import Distribution.Types.ExeDependency (ExeDependency)
+import Distribution.Types.ExposedModule (ExposedModule)
+import Distribution.Types.Flag (FlagAssignment, FlagName)
+import Distribution.Types.ForeignLib (LibVersionInfo)
+import Distribution.Types.ForeignLibOption (ForeignLibOption)
+import Distribution.Types.ForeignLibType (ForeignLibType)
+import Distribution.Types.IncludeRenaming (IncludeRenaming)
+import Distribution.Types.LegacyExeDependency (LegacyExeDependency)
+import Distribution.Types.LibraryVisibility (LibraryVisibility)
+import Distribution.Types.Mixin (Mixin)
+import Distribution.Types.ModuleReexport (ModuleReexport)
+import Distribution.Types.ModuleRenaming (ModuleRenaming)
+import Distribution.Types.MungedPackageName (MungedPackageName)
+import Distribution.Types.PackageId (PackageIdentifier)
+import Distribution.Types.PackageName (PackageName)
+import Distribution.Types.PackageVersionConstraint (PackageVersionConstraint)
+import Distribution.Types.PkgconfigDependency (PkgconfigDependency)
+import Distribution.Types.SourceRepo (RepoType)
+import Distribution.Types.TestType (TestType)
+import Distribution.Types.UnitId (UnitId)
+import Distribution.Types.UnqualComponentName (UnqualComponentName)
+import Distribution.Verbosity (Verbosity)
+import Distribution.Version (Version, VersionRange)
+import Language.Haskell.Extension (Extension, Language)
+
+-- | Class describing the pretty/parsec format of a.
+class (Pretty a, Parsec a) => Described a where
+ -- | A pretty document of "regex" describing the field format
+ describe :: proxy a -> GrammarRegex void
+
+-- | Pretty-print description.
+--
+-- >>> describeDoc ([] :: [Bool])
+-- \left\{ \mathop{\mathord{``}\mathtt{True}\mathord{"}}\mid\mathop{\mathord{``}\mathtt{False}\mathord{"}} \right\}
+--
+describeDoc :: Described a => proxy a -> PP.Doc
+describeDoc p = regexDoc (describe p)
+
+instance Described Bool where
+ describe _ = REUnion ["True", "False"]
+
+instance Described a => Described (Identity a) where
+ describe _ = describe ([] :: [a])
+
+-------------------------------------------------------------------------------
+-- Lists
+------------------------------------------------------------------------------
+
+reSpacedList :: GrammarRegex a -> GrammarRegex a
+reSpacedList = REMunch RESpaces1
+
+reCommaList :: GrammarRegex a -> GrammarRegex a
+reCommaList = RECommaList
+
+reCommaNonEmpty :: GrammarRegex a -> GrammarRegex a
+reCommaNonEmpty = RECommaNonEmpty
+
+reOptCommaList :: GrammarRegex a -> GrammarRegex a
+reOptCommaList = REOptCommaList
+
+-------------------------------------------------------------------------------
+-- Specific grammars
+-------------------------------------------------------------------------------
+
+reHsString :: GrammarRegex a
+reHsString = RENamed "hs-string" impl where
+ impl = reChar '"' <> REMunch reEps (REUnion [strChar, escChar]) <> reChar '"'
+ strChar = RECharSet $ CS.difference CS.universe (CS.fromList "\"\\")
+
+ escChar = REUnion
+ [ "\\&"
+ , "\\\\"
+ , REUnion ["\\n", RENamed "escapes" "\\n"] -- TODO
+ , "\\" <> RECharSet "0123456789"
+ , "\\o" <> RECharSet "01234567"
+ , "\\x" <> RECharSet "0123456789abcdefABCDEF"
+ , REUnion ["\\^@", RENamed "control" "\\^@"] -- TODO
+ , REUnion ["\\NUL", RENamed "ascii" "\\NUL"] -- TODO
+ ]
+
+reUnqualComponent :: GrammarRegex a
+reUnqualComponent = RENamed "unqual-name" $
+ REMunch1 (reChar '-') component
+ where
+ component
+ = REMunch reEps (RECharSet csAlphaNum)
+ -- currently the parser accepts "csAlphaNum `difference` "0123456789"
+ -- which is larger set than CS.alpha
+ --
+ -- Hackage rejects non ANSI names, so it's not so relevant.
+ <> RECharSet CS.alpha
+ <> REMunch reEps (RECharSet csAlphaNum)
+
+reDot :: GrammarRegex a
+reDot = reChar '.'
+
+reComma :: GrammarRegex a
+reComma = reChar ','
+
+reSpacedComma :: GrammarRegex a
+reSpacedComma = RESpaces <> reComma <> RESpaces
+
+-------------------------------------------------------------------------------
+-- Character sets
+-------------------------------------------------------------------------------
+
+csChar :: Char -> CS.CharSet
+csChar = CS.singleton
+
+csAlpha :: CS.CharSet
+csAlpha = CS.alpha
+
+csAlphaNum :: CS.CharSet
+csAlphaNum = CS.alphanum
+
+csUpper :: CS.CharSet
+csUpper = CS.upper
+
+csNotSpace :: CS.CharSet
+csNotSpace = CS.difference CS.universe $ CS.singleton ' '
+
+csNotSpaceOrComma :: CS.CharSet
+csNotSpaceOrComma = CS.difference csNotSpace $ CS.singleton ','
+
+-------------------------------------------------------------------------------
+-- Special
+-------------------------------------------------------------------------------
+
+describeFlagAssignmentNonEmpty :: GrammarRegex void
+describeFlagAssignmentNonEmpty = REMunch1 RESpaces1 $
+ REUnion [fromString "+", fromString "-"] <> describe (Proxy :: Proxy FlagName)
+
+-------------------------------------------------------------------------------
+-- Conversion
+-------------------------------------------------------------------------------
+
+convert :: GrammarRegex Void -> RE.RE Void
+convert = go id . vacuous where
+ go :: Ord b => (a -> b) -> GrammarRegex a -> RE.RE b
+ go f (REAppend rs) = foldr (\r acc -> go f r <> acc) RE.Eps rs
+ go f (REUnion rs) = foldr (\r acc -> go f r RE.\/ acc) RE.Null rs
+ go _ (RECharSet cs) = RE.Ch (convertCS cs)
+ go _ (REString str) = RE.string_ str
+
+ go f (REMunch sep r) = RE.Eps RE.\/ r' <> RE.star_ (sep' <> r') where
+ sep' = go f sep
+ r' = go f r
+ go f (REMunch1 sep r) = r' <> RE.star_ (sep' <> r') where
+ sep' = go f sep
+ r' = go f r
+ go f (REMunchR n sep r)
+ | n <= 0 = RE.Eps
+ | otherwise = RE.Eps RE.\/ r' <> go' (pred n)
+ where
+ sep' = go f sep
+ r' = go f r
+
+ go' m | m <= 0 = RE.Eps
+ | otherwise = RE.Eps RE.\/ sep' <> r' <> go' (pred m)
+
+ go f (REOpt r) = RE.Eps RE.\/ go f r
+
+ go f (REVar a) = RE.Var (f a)
+ go f (RENamed _ r) = go f r
+ go f (RERec n r) = RE.fix_ (fromString n)
+ (go (maybe RE.B (RE.F . f)) r)
+
+ go _ RESpaces = RE.Eps RE.\/ RE.ch_ ' ' RE.\/ " " RE.\/ "\n"
+ go _ RESpaces1 = RE.ch_ ' ' RE.\/ " " RE.\/ "\n"
+
+ go f (RECommaList r) = go f (expandedCommaList r)
+ go f (RECommaNonEmpty r)= go f (expandedCommaNonEmpty r)
+ go f (REOptCommaList r) = go f (expandedOptCommaList r)
+
+ go _ RETodo = RE.Null
+
+expandedCommaList :: GrammarRegex a -> GrammarRegex a
+expandedCommaList = REUnion . expandedCommaList'
+
+expandedCommaNonEmpty :: GrammarRegex a -> GrammarRegex a
+expandedCommaNonEmpty r = REUnion
+ [ REMunch1 reSpacedComma r
+ , reComma <> RESpaces <> REMunch1 reSpacedComma r
+ , REMunch1 reSpacedComma r <> RESpaces <> reComma
+ ]
+
+expandedCommaList' :: GrammarRegex a -> [GrammarRegex a]
+expandedCommaList' r =
+ [ REMunch reSpacedComma r
+ , reComma <> RESpaces <> REMunch1 reSpacedComma r
+ , REMunch1 reSpacedComma r <> RESpaces <> reComma
+ ]
+
+expandedOptCommaList :: GrammarRegex a -> GrammarRegex a
+expandedOptCommaList r = REUnion $ reSpacedList r : expandedCommaList' r
+
+convertCS :: CS.CharSet -> RE.CharSet
+convertCS = RE.fromIntervalList . CS.toIntervalList
+
+-------------------------------------------------------------------------------
+-- tasty
+-------------------------------------------------------------------------------
+
+testDescribed
+ :: forall a. (Arbitrary a, Described a, Typeable a, Eq a, Show a)
+ => Proxy a
+ -> TestTree
+testDescribed _ = testGroup name
+ [ testProperty "parsec" propParsec
+ , testProperty "pretty" propPretty
+ , testProperty "roundtrip" propRoundtrip
+ ]
+ where
+ name = show (typeOf (undefined :: a))
+
+ propParsec :: Ex a -> Property
+ propParsec (Example str) = counterexample (show res) $ case res of
+ Right _ -> True
+ Left _ -> False
+ where
+ res :: Either String a
+ res = eitherParsec str
+
+ rr :: RE.RE Void
+ rr = convert $ describe (Proxy :: Proxy a)
+
+ propPretty :: a -> Property
+ propPretty x = counterexample str $ RE.matchR rr str
+ where
+ str = prettyShow x
+
+ propRoundtrip :: a -> Property
+ propRoundtrip x = counterexample (show (res, str)) $ case res of
+ Right y -> x == y
+ Left _ -> False
+ where
+ str = prettyShow x
+ res = eitherParsec str
+
+newtype Ex a = Example String
+ deriving (Show)
+
+instance Described a => Arbitrary (Ex a) where
+ arbitrary
+ = fmap Example
+ $ fromMaybe (return "")
+ $ RE.generate 10 5
+ $ convert $ describe (Proxy :: Proxy a)
+
+ shrink (Example s)
+ | '\n' `elem` s = [ Example $ map (\c -> if c == '\n' then ' ' else c) s ]
+ | otherwise = []
+
+-------------------------------------------------------------------------------
+-- Instances
+-------------------------------------------------------------------------------
+
+instance Described AbiDependency where
+ describe _ =
+ describe (Proxy :: Proxy UnitId) <>
+ reChar '=' <>
+ describe (Proxy :: Proxy AbiHash)
+
+instance Described AbiHash where
+ describe _ = reMunchCS csAlphaNum
+
+instance Described Arch where
+ describe _ = REUnion
+ [ fromString (prettyShow arch)
+ | arch <- knownArches
+ ]
+
+instance Described BenchmarkType where
+ describe _ = "exitcode-stdio-1.0"
+
+instance Described BuildType where
+ describe _ = REUnion ["Simple","Configure","Custom","Make","Default"]
+
+instance Described CompilerFlavor where
+ describe _ = REUnion
+ [ fromString (prettyShow c)
+ | c <- knownCompilerFlavors
+ ]
+
+instance Described CompilerId where
+ describe _ =
+ describe (Proxy :: Proxy CompilerFlavor)
+ <> fromString "-"
+ <> describe (Proxy :: Proxy Version)
+
+instance Described Dependency where
+ describe _ = REAppend
+ [ RENamed "pkg-name" (describe (Proxy :: Proxy PackageName))
+ , REOpt $
+ reChar ':'
+ <> REUnion
+ [ reUnqualComponent
+ , REAppend
+ [ reChar '{'
+ , RESpaces
+ -- no leading or trailing comma
+ , REMunch1 reSpacedComma reUnqualComponent
+ , RESpaces
+ , reChar '}'
+ ]
+ ]
+
+ , REOpt $ RESpaces <> vr
+ ]
+ where
+ vr = RENamed "version-range" (describe (Proxy :: Proxy VersionRange))
+
+instance Described ExecutableScope where
+ describe _ = REUnion ["public","private"]
+
+instance Described ExeDependency where
+ describe _ = RETodo
+
+instance Described ExposedModule where
+ describe _ = RETodo
+
+instance Described Extension where
+ describe _ = RETodo
+
+instance Described FlagAssignment where
+ describe _ = REMunch RESpaces1 $
+ REUnion [fromString "+", fromString "-"] <> describe (Proxy :: Proxy FlagName)
+
+instance Described FlagName where
+ describe _ = lead <> rest where
+ lead = RECharSet $ csAlphaNum <> fromString "_"
+ rest = reMunchCS $ csAlphaNum <> fromString "_-"
+
+instance Described ForeignLibOption where
+ describe _ = "standalone"
+
+instance Described ForeignLibType where
+ describe _ = REUnion ["native-shared","native-static"]
+
+instance Described IncludeRenaming where
+ describe _ = mr <> REOpt (RESpaces <> "requires" <> RESpaces1 <> mr)
+ where
+ mr = describe (Proxy :: Proxy ModuleRenaming)
+
+instance Described Language where
+ describe _ = REUnion ["Haskell98", "Haskell2010"]
+
+instance Described LegacyExeDependency where
+ describe _ = RETodo
+
+instance Described LibraryVisibility where
+ describe _ = REUnion ["public","private"]
+
+instance Described LibVersionInfo where
+ describe _ = reDigits <> REOpt (reChar ':' <> reDigits <> REOpt (reChar ':' <> reDigits)) where
+ reDigits = reChars ['0'..'9']
+
+instance Described Mixin where
+ describe _ =
+ RENamed "package-name" (describe (Proxy :: Proxy PackageName)) <>
+ REOpt (reChar ':' <> RENamed "library-name" (describe (Proxy :: Proxy UnqualComponentName))) <>
+ REOpt (RESpaces1 <> describe (Proxy :: Proxy IncludeRenaming))
+
+instance Described ModuleName where
+ describe _ = REMunch1 (reChar '.') component where
+ component = RECharSet csUpper <> REMunch reEps (REUnion [RECharSet csAlphaNum, RECharSet (fromString "_'")])
+
+instance Described ModuleReexport where
+ describe _ = RETodo
+
+instance Described ModuleRenaming where
+ describe _ = REUnion
+ [ reEps
+ , "hiding" <> RESpaces <> bp (REMunch reSpacedComma mn)
+ , bp (REMunch reSpacedComma entry)
+ ]
+ where
+ bp r = "(" <> RESpaces <> r <> RESpaces <> ")"
+ mn = RENamed "module-name" $ describe (Proxy :: Proxy ModuleName)
+
+ entry = mn <> REOpt (RESpaces1 <> "as" <> RESpaces1 <> mn)
+
+instance Described MungedPackageName where
+ describe _ = RETodo
+
+instance Described OS where
+ describe _ = REUnion
+ [ fromString (prettyShow os)
+ | os <- knownOSs
+ ]
+
+instance Described PackageIdentifier where
+ describe _ = describe (Proxy :: Proxy PackageName) <> fromString "-" <> describe (Proxy :: Proxy Version)
+
+instance Described PackageName where
+ describe _ = reUnqualComponent
+
+instance Described PackageVersionConstraint where
+ describe _ = describe (Proxy :: Proxy PackageName) <> REUnion
+ [ fromString "-" <> describe (Proxy :: Proxy Version)
+ , RESpaces <> describe (Proxy :: Proxy VersionRange)
+ ]
+
+instance Described PkgconfigDependency where
+ describe _ = RETodo
+
+instance Described RepoType where
+ describe _ = reMunch1CS $ csAlphaNum <> csChar '_' <> csChar '-'
+
+instance Described TestType where
+ describe _ = REUnion ["exitcode-stdio-1.0", "detailed-0.9"]
+
+instance Described Verbosity where
+ describe _ = REUnion
+ [ REUnion ["0", "1", "2", "3"]
+ , REUnion ["silent", "normal", "verbose", "debug", "deafening"]
+ <> REMunch reEps (RESpaces <> "+" <>
+ -- markoutput is left out on purpose
+ REUnion ["callsite", "callstack", "nowrap", "timestamp", "stderr", "stdout" ])
+ ]
+
+instance Described Version where
+ describe _ = REMunch1 reDot reDigits where
+ reDigits = REUnion
+ [ reChar '0'
+ , reChars ['1'..'9'] <> REMunchR 8 reEps (reChars ['0'..'9'])
+ ]
+
+instance Described VersionRange where
+ describe _ = RERec "version-range" $ REUnion
+ [ "==" <> RESpaces <> ver
+ , ">" <> RESpaces <> ver
+ , "<" <> RESpaces <> ver
+ , "<=" <> RESpaces <> ver
+ , ">=" <> RESpaces <> ver
+ , "^>=" <> RESpaces <> ver
+
+ -- ==0.1.*
+ , "==" <> RESpaces <> wildVer
+
+ , reVar0 <> RESpaces <> "||" <> RESpaces <> reVar0
+ , reVar0 <> RESpaces <> "&&" <> RESpaces <> reVar0
+ , "(" <> RESpaces <> reVar0 <> RESpaces <> ")"
+
+ -- == { 0.1.2 }
+ -- silly haddock: ^>= { 0.1.2, 3.4.5 }
+ , "==" <> RESpaces <> verSet
+ , "^>=" <> RESpaces <> verSet
+ ]
+ where
+ ver' = describe (Proxy :: Proxy Version)
+ ver = RENamed "version" ver'
+ wildVer = ver' <> ".*"
+ verSet = "{" <> RESpaces <> REMunch1 reSpacedComma ver <> RESpaces <> "}"
+
+instance Described UnitId where
+ describe _ = reMunch1CS $ csAlphaNum <> csChar '-' <> csChar '_' <> csChar '.' <> csChar '+'
+
+instance Described UnqualComponentName where
+ describe _ = reUnqualComponent
+
+-------------------------------------------------------------------------------
+-- Instances: Newtypes
+-------------------------------------------------------------------------------
+
+class Sep sep => DescribeSep sep where
+ describeSep :: Proxy sep -> GrammarRegex a -> GrammarRegex a
+
+instance DescribeSep CommaVCat where describeSep _ = reCommaList
+instance DescribeSep CommaFSep where describeSep _ = reCommaList
+instance DescribeSep VCat where describeSep _ = reCommaList
+instance DescribeSep FSep where describeSep _ = reOptCommaList
+instance DescribeSep NoCommaFSep where describeSep _ = reSpacedList
+
+instance (Newtype a b, DescribeSep sep, Described b) => Described (List sep b a) where
+ describe _ = describeSep (Proxy :: Proxy sep) (describe (Proxy :: Proxy b))
+
+instance (Newtype a b, Ord a, DescribeSep sep, Described b) => Described (Set' sep b a) where
+ describe _ = describeSep (Proxy :: Proxy sep) (describe (Proxy :: Proxy b))
+
+instance Described Token where
+ describe _ = REUnion [reHsString, reMunch1CS csNotSpaceOrComma]
+
+instance Described Token' where
+ describe _ = REUnion [reHsString, reMunch1CS csNotSpace]
+
+instance Described a => Described (MQuoted a) where
+ -- TODO: this is simplification
+ describe _ = describe ([] :: [a])
+
+instance Described SpecVersion where
+ describe _ = "3.4" -- :)
+
+instance Described SpecLicense where
+ describe _ = RETodo
+
+instance Described TestedWith where
+ describe _ = RETodo
+
+instance Described FilePathNT where
+ describe _ = describe ([] :: [Token])
diff --git a/cabal/Cabal/Cabal-described/src/Distribution/Utils/CharSet.hs b/cabal/Cabal/Cabal-described/src/Distribution/Utils/CharSet.hs
new file mode 100644
index 0000000..c5c906d
--- /dev/null
+++ b/cabal/Cabal/Cabal-described/src/Distribution/Utils/CharSet.hs
@@ -0,0 +1,242 @@
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE CPP #-}
+-- | Sets of characters.
+--
+-- Using this is more efficint than 'RE.Type.Alt':ng individual characters.
+module Distribution.Utils.CharSet (
+ -- * Set of characters
+ CharSet,
+ -- * Construction
+ empty,
+ universe,
+ singleton,
+ insert,
+ union,
+ intersection,
+ complement,
+ difference,
+ -- * Query
+ size,
+ null,
+ member,
+ -- * Conversions
+ fromList,
+ toList,
+ fromIntervalList,
+ toIntervalList,
+ -- * Special lists
+ alpha,
+ alphanum,
+ upper,
+ ) where
+
+import Data.Char (chr, isAlpha, isAlphaNum, isUpper, ord)
+import Data.List (foldl', sortBy)
+import Data.Monoid (Monoid (..))
+import Data.String (IsString (..))
+import Distribution.Compat.Semigroup (Semigroup (..))
+import Prelude
+ (Bool (..), Bounded (..), Char, Enum (..), Eq (..), Int, Maybe (..), Num (..), Ord (..), Show (..), String, concatMap, flip, fst, otherwise, showParen,
+ showString, uncurry, ($), (.))
+
+#if MIN_VERSION_containers(0,5,0)
+import qualified Data.IntMap.Strict as IM
+#else
+import qualified Data.IntMap as IM
+#endif
+
+-- | A set of 'Char's.
+--
+-- We use range set, which works great with 'Char'.
+newtype CharSet = CS { unCS :: IM.IntMap Int }
+ deriving (Eq, Ord)
+
+instance IsString CharSet where
+ fromString = fromList
+
+instance Show CharSet where
+ showsPrec d cs
+ | size cs < 20
+ = showsPrec d (toList cs)
+ | otherwise
+ = showParen (d > 10)
+ $ showString "CS "
+ . showsPrec 11 (unCS cs)
+
+instance Semigroup CharSet where
+ (<>) = union
+
+instance Monoid CharSet where
+ mempty = empty
+ mappend = (<>)
+
+-- | Empty character set.
+empty :: CharSet
+empty = CS IM.empty
+
+-- | universe
+universe :: CharSet
+universe = CS $ IM.singleton 0 0x10ffff
+
+-- | Check whether 'CharSet' is 'empty'.
+null :: CharSet -> Bool
+null (CS cs) = IM.null cs
+
+-- | Size of 'CharSet'
+--
+-- >>> size $ fromIntervalList [('a','f'), ('0','9')]
+-- 16
+--
+-- >>> length $ toList $ fromIntervalList [('a','f'), ('0','9')]
+-- 16
+--
+size :: CharSet -> Int
+size (CS m) = foldl' (\ !acc (lo, hi) -> acc + (hi - lo) + 1) 0 (IM.toList m)
+
+-- | Singleton character set.
+singleton :: Char -> CharSet
+singleton c = CS (IM.singleton (ord c) (ord c))
+
+-- | Test whether character is in the set.
+member :: Char -> CharSet -> Bool
+#if MIN_VERSION_containers(0,5,0)
+member c (CS m) = case IM.lookupLE i m of
+ Nothing -> False
+ Just (_, hi) -> i <= hi
+ where
+#else
+member c (CS m) = go (IM.toList m)
+ where
+ go [] = False
+ go ((x,y):zs) = (x <= i && i <= y) || go zs
+#endif
+ i = ord c
+
+-- | Insert 'Char' into 'CharSet'.
+insert :: Char -> CharSet -> CharSet
+insert c (CS m) = normalise (IM.insert (ord c) (ord c) m)
+
+-- | Union of two 'CharSet's.
+union :: CharSet -> CharSet -> CharSet
+union (CS xs) (CS ys) = normalise (IM.unionWith max xs ys)
+
+-- | Intersection of two 'CharSet's
+intersection :: CharSet -> CharSet -> CharSet
+intersection (CS xs) (CS ys) = CS $
+ IM.fromList (intersectRangeList (IM.toList xs) (IM.toList ys))
+
+-- | Compute the intersection.
+intersectRangeList :: Ord a => [(a, a)] -> [(a, a)] -> [(a, a)]
+intersectRangeList aset@((x,y):as) bset@((u,v):bs)
+ | y < u = intersectRangeList as bset
+ | v < x = intersectRangeList aset bs
+ | y < v = (max x u, y) : intersectRangeList as bset
+ | otherwise = (max x u, v) : intersectRangeList aset bs
+intersectRangeList _ [] = []
+intersectRangeList [] _ = []
+
+-- | Complement of a CharSet
+complement :: CharSet -> CharSet
+complement (CS xs) = CS $ IM.fromList $ complementRangeList (IM.toList xs)
+
+-- | Compute the complement intersected with @[x,)@ assuming @x<u@.
+complementRangeList' :: Int -> [(Int, Int)] -> [(Int, Int)]
+complementRangeList' x ((u,v):s) = (x,pred u) : complementRangeList'' v s
+complementRangeList' x [] = [(x,0x10ffff)]
+
+-- | Compute the complement intersected with @(x,)@.
+complementRangeList'' :: Int -> [(Int, Int)] -> [(Int, Int)]
+complementRangeList'' x s
+ | x == 0x10ffff = []
+ | otherwise = complementRangeList' (succ x) s
+
+-- | Compute the complement.
+--
+-- Note: we treat Ints as codepoints, i.e minBound is 0, and maxBound is 0x10ffff
+complementRangeList :: [(Int, Int)] -> [(Int, Int)]
+complementRangeList s@((x,y):s')
+ | x == 0 = complementRangeList'' y s'
+ | otherwise = complementRangeList' 0 s
+complementRangeList [] = [(0, 0x10ffff)]
+
+-- | Difference of two 'CharSet's.
+difference :: CharSet -> CharSet -> CharSet
+difference xs ys = intersection xs (complement ys)
+
+-- | Make 'CharSet' from a list of characters, i.e. 'String'.
+fromList :: String -> CharSet
+fromList = normalise . foldl' (\ acc c -> IM.insert (ord c) (ord c) acc) IM.empty
+
+-- | Convert 'CharSet' to a list of characters i.e. 'String'.
+toList :: CharSet -> String
+toList = concatMap (uncurry enumFromTo) . toIntervalList
+
+-- | Convert to interval list
+--
+-- >>> toIntervalList $ union "01234" "56789"
+-- [('0','9')]
+--
+toIntervalList :: CharSet -> [(Char, Char)]
+toIntervalList (CS m) = [ (chr lo, chr hi) | (lo, hi) <- IM.toList m ]
+
+-- | Convert from interval pairs.
+--
+-- >>> fromIntervalList []
+-- ""
+--
+-- >>> fromIntervalList [('a','f'), ('0','9')]
+-- "0123456789abcdef"
+--
+-- >>> fromIntervalList [('Z','A')]
+-- ""
+--
+fromIntervalList :: [(Char,Char)] -> CharSet
+fromIntervalList xs = normalise' $ sortBy (\a b -> compare (fst a) (fst b))
+ [ (ord lo, ord hi)
+ | (lo, hi) <- xs
+ , lo <= hi
+ ]
+
+-------------------------------------------------------------------------------
+-- Normalisation
+-------------------------------------------------------------------------------
+
+normalise :: IM.IntMap Int -> CharSet
+normalise = normalise'. IM.toList
+
+normalise' :: [(Int,Int)] -> CharSet
+normalise' = CS . IM.fromList . go where
+ go :: [(Int,Int)] -> [(Int,Int)]
+ go [] = []
+ go ((x,y):zs) = go' x y zs
+
+ go' :: Int -> Int -> [(Int, Int)] -> [(Int, Int)]
+ go' lo hi [] = [(lo, hi)]
+ go' lo hi ws0@((u,v):ws)
+ | u <= succ hi = go' lo (max v hi) ws
+ | otherwise = (lo,hi) : go ws0
+
+-------------------------------------------------------------------------------
+-- Alpha Numeric character list
+-------------------------------------------------------------------------------
+
+-- Computing this takes some time,
+-- but they are not used in-non testing in Cabal's normal operation.
+
+-- | Note: this set varies depending on @base@ version.
+--
+alpha :: CharSet
+alpha = foldl' (flip insert) empty [ c | c <- [ minBound .. maxBound ], isAlpha c ]
+{-# NOINLINE alpha #-}
+
+-- | Note: this set varies depending on @base@ version.
+--
+alphanum :: CharSet
+alphanum = foldl' (flip insert) empty [ c | c <- [ minBound .. maxBound ], isAlphaNum c ]
+{-# NOINLINE alphanum #-}
+
+-- | Note: this set varies depending on @base@ version.
+--
+upper :: CharSet
+upper = foldl' (flip insert) empty [ c | c <- [ minBound .. maxBound ], isUpper c ]
+{-# NOINLINE upper #-}
diff --git a/cabal/Cabal/Cabal-described/src/Distribution/Utils/GrammarRegex.hs b/cabal/Cabal/Cabal-described/src/Distribution/Utils/GrammarRegex.hs
new file mode 100644
index 0000000..d355848
--- /dev/null
+++ b/cabal/Cabal/Cabal-described/src/Distribution/Utils/GrammarRegex.hs
@@ -0,0 +1,215 @@
+{-# LANGUAGE DeriveFoldable #-}
+{-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE DeriveTraversable #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+module Distribution.Utils.GrammarRegex (
+ -- * Regular expressions
+ GrammarRegex (..),
+ reEps,
+ reChar,
+ reChars,
+ reMunchCS,
+ reMunch1CS,
+ -- * Variables
+ reVar0,
+ reVar1,
+ -- * Pretty-printing
+ regexDoc,
+ ) where
+
+import Data.Char (isAlphaNum, isControl, ord)
+import Data.Foldable (Foldable)
+import Data.Maybe (fromMaybe)
+import Data.Monoid (Monoid (..))
+import Data.String (IsString (..))
+import Data.Traversable (Traversable)
+import Data.Void (Void, vacuous)
+import Distribution.Compat.Semigroup (Semigroup (..))
+import Prelude (Bool (..), Char, Eq (..), Functor, Int, Maybe (..), Ord (..), Show, String, fmap, length, map, otherwise, ($), (++), (.))
+
+import qualified Distribution.Utils.CharSet as CS
+import qualified Text.PrettyPrint as PP
+
+(<<>>) :: PP.Doc -> PP.Doc -> PP.Doc
+(<<>>) = (PP.<>)
+
+-------------------------------------------------------------------------------
+-- GrammarRegex
+-------------------------------------------------------------------------------
+
+-- | Recursive regular expressions tuned for 'Described' use-case.
+data GrammarRegex a
+ = REAppend [GrammarRegex a] -- ^ append @ab@
+ | REUnion [GrammarRegex a] -- ^ union @a|b@
+
+ -- repetition
+ | REMunch (GrammarRegex a) (GrammarRegex a) -- ^ star @a*@, with a separator
+ | REMunch1 (GrammarRegex a) (GrammarRegex a) -- ^ plus @a+@, with a separator
+ | REMunchR Int (GrammarRegex a) (GrammarRegex a) -- ^ 1-n, with a separator
+ | REOpt (GrammarRegex a) -- ^ optional @r?@
+
+ | REString String -- ^ literal string @abcd@
+ | RECharSet CS.CharSet -- ^ charset @[:alnum:]@
+ | REVar a -- ^ variable
+ | RENamed String (GrammarRegex a) -- ^ named expression
+ | RERec String (GrammarRegex (Maybe a)) -- ^ recursive expressions
+
+ -- cabal syntax specifics
+ | RESpaces -- ^ zero-or-more spaces
+ | RESpaces1 -- ^ one-or-more spaces
+ | RECommaList (GrammarRegex a) -- ^ comma list (note, leading or trailing commas)
+ | RECommaNonEmpty (GrammarRegex a) -- ^ comma non-empty list (note, leading or trailing commas)
+ | REOptCommaList (GrammarRegex a) -- ^ opt comma list
+
+ | RETodo -- ^ unspecified
+ deriving (Eq, Ord, Show, Functor, Foldable, Traversable)
+
+-------------------------------------------------------------------------------
+-- Instances
+-------------------------------------------------------------------------------
+
+instance IsString (GrammarRegex a) where
+ fromString = REString
+
+instance Semigroup (GrammarRegex a) where
+ x <> y = REAppend (unAppend x ++ unAppend y) where
+ unAppend (REAppend rs) = rs
+ unAppend r = [r]
+
+instance Monoid (GrammarRegex a) where
+ mempty = REAppend []
+ mappend = (<>)
+
+-------------------------------------------------------------------------------
+-- Smart constructors
+-------------------------------------------------------------------------------
+
+reEps :: GrammarRegex a
+reEps = REAppend []
+
+reChar :: Char -> GrammarRegex a
+reChar = RECharSet . CS.singleton
+
+reChars :: [Char] -> GrammarRegex a
+reChars = RECharSet . CS.fromList
+
+reMunch1CS :: CS.CharSet -> GrammarRegex a
+reMunch1CS = REMunch1 reEps . RECharSet
+
+reMunchCS :: CS.CharSet -> GrammarRegex a
+reMunchCS = REMunch reEps . RECharSet
+
+-------------------------------------------------------------------------------
+-- Variables
+-------------------------------------------------------------------------------
+
+reVar0 :: GrammarRegex (Maybe a)
+reVar0 = REVar Nothing
+
+reVar1 :: GrammarRegex (Maybe (Maybe a))
+reVar1 = REVar (Just Nothing)
+
+-------------------------------------------------------------------------------
+-- Pretty-printing
+-------------------------------------------------------------------------------
+
+-- |
+--
+-- >>> regexDoc $ REString "True"
+-- \mathop{\mathord{``}\mathtt{True}\mathord{"}}
+--
+-- Note: we don't simplify regexps yet:
+--
+-- >>> regexDoc $ REString "foo" <> REString "bar"
+-- \mathop{\mathord{``}\mathtt{foo}\mathord{"}}\mathop{\mathord{``}\mathtt{bar}\mathord{"}}
+--
+regexDoc :: GrammarRegex Void -> PP.Doc
+regexDoc = go 0 . vacuous where
+ go :: Int -> GrammarRegex PP.Doc -> PP.Doc
+ go _ (REAppend []) = ""
+ go d (REAppend rs) = parensIf (d > 2) $ PP.hcat (map (go 2) rs)
+ go d (REUnion [r]) = go d r
+ go _ (REUnion rs) = PP.hsep
+ [ "\\left\\{"
+ , if length rs < 4
+ then PP.hcat (PP.punctuate (PP.text "\\mid") (map (go 0) rs))
+ else "\\begin{gathered}" <<>>
+ PP.hcat (PP.punctuate "\\\\" (map (go 0) rs)) <<>>
+ "\\end{gathered}"
+ , "\\right\\}" ]
+
+ go d (REMunch sep r) = parensIf (d > 3) $
+ PP.text "{" <<>> go 4 r <<>> PP.text "}^\\ast_{" <<>> go 4 sep <<>> PP.text "}"
+ go d (REMunch1 sep r) = parensIf (d > 3) $
+ PP.text "{" <<>> go 4 r <<>> PP.text "}^+_{" <<>> go 4 sep <<>> PP.text "}"
+ go d (REMunchR n sep r) = parensIf (d > 3) $
+ PP.text "{" <<>> go 4 r <<>> PP.text "}^{\\in [0\\ldots" <<>> PP.int n <<>> "]}_{" <<>> go 4 sep <<>> PP.text "}"
+ go d (REOpt r) = parensIf (d > 3) $
+ PP.text "{" <<>> go 4 r <<>> PP.text "}^?"
+
+ go _ (REString s) = PP.text "\\mathop{\\mathord{``}\\mathtt{" <<>> PP.hcat (map charDoc s) <<>> PP.text "}\\mathord{\"}}"
+ go _ (RECharSet cs) = charsetDoc cs
+
+ go _ RESpaces = "\\circ"
+ go _ RESpaces1 = "\\bullet"
+
+ go _ (RECommaList r) =
+ "\\mathrm{commalist}" <<>> go 4 r
+ go _ (RECommaNonEmpty r) =
+ "\\mathrm{commanonempty}" <<>> go 4 r
+ go _ (REOptCommaList r) =
+ "\\mathrm{optcommalist}" <<>> go 4 r
+
+ go _ (REVar a) = a
+ go _ (RENamed n _) = terminalDoc n
+ go d (RERec n r) = parensIf (d > 0) $
+ "\\mathbf{fix}\\;" <<>> n' <<>> "\\;\\mathbf{in}\\;" <<>>
+ go 0 (fmap (fromMaybe n') r)
+ where
+ n' = terminalDoc n
+
+ go _ RETodo = PP.text "\\mathsf{\\color{red}{TODO}}"
+
+ parensIf :: Bool -> PP.Doc -> PP.Doc
+ parensIf True d = PP.text "\\left(" <<>> d <<>> PP.text "\\right)"
+ parensIf False d = d
+
+terminalDoc :: String -> PP.Doc
+terminalDoc s = PP.text "\\mathop{\\mathit{" <<>> PP.hcat (map charDoc s) <<>> PP.text "}}"
+
+charDoc :: Char -> PP.Doc
+charDoc ' ' = PP.text "\\ "
+charDoc '{' = PP.text "\\{"
+charDoc '}' = PP.text "\\}"
+charDoc '\\' = PP.text "\\text{\\\\}"
+charDoc c
+ | isAlphaNum c = PP.char c
+ | isControl c = PP.int (ord c) -- TODO: some syntax
+ | otherwise = PP.text ("\\text{" ++ c : "}")
+
+inquotes :: PP.Doc -> PP.Doc
+inquotes d = "\\mathop{\\mathord{``}" <<>> d <<>> "\\mathord{\"}}"
+
+mathtt :: PP.Doc -> PP.Doc
+mathtt d = "\\mathtt{" <<>> d <<>> "}"
+
+charsetDoc :: CS.CharSet -> PP.Doc
+charsetDoc acs
+ | acs == CS.alpha = terminalDoc "alpha"
+ | acs == CS.alphanum = terminalDoc "alpha-num"
+ | acs == CS.upper = terminalDoc "upper"
+charsetDoc acs = case CS.toIntervalList acs of
+ [] -> "\\emptyset"
+ [(x,y)] | x == y -> inquotes $ mathtt $ charDoc x
+ rs
+ | CS.size acs <= CS.size notAcs
+ -> PP.brackets $ PP.hcat $ map rangeDoc rs
+ | otherwise
+ -> PP.braces $ PP.brackets (PP.hcat $ map rangeDoc (CS.toIntervalList notAcs)) <<>> PP.text "^c"
+ where
+ notAcs = CS.complement acs
+
+ rangeDoc :: (Char, Char) -> PP.Doc
+ rangeDoc (x, y) | x == y = inquotes (mathtt $ charDoc x)
+ | otherwise = inquotes (mathtt $ charDoc x) <<>> PP.text "\\cdots" <<>> inquotes (mathtt $ charDoc y)
diff --git a/cabal/Cabal/Cabal-tree-diff/Cabal-tree-diff.cabal b/cabal/Cabal/Cabal-tree-diff/Cabal-tree-diff.cabal
new file mode 100644
index 0000000..dd47507
--- /dev/null
+++ b/cabal/Cabal/Cabal-tree-diff/Cabal-tree-diff.cabal
@@ -0,0 +1,21 @@
+cabal-version: 2.2
+name: Cabal-tree-diff
+version: 3.3.0.0
+synopsis: QuickCheck instances for types in Cabal
+category: Testing
+description: Provides tree-diff ToExpr instances for some types in Cabal
+
+library
+ default-language: Haskell2010
+ hs-source-dirs: src
+ ghc-options: -Wall
+ build-depends:
+ , base
+ , Cabal ^>=3.3.0.0
+ , tree-diff ^>=0.1
+
+ exposed-modules: Data.TreeDiff.Instances.Cabal
+ other-modules:
+ Data.TreeDiff.Instances.CabalLanguage
+ Data.TreeDiff.Instances.CabalSPDX
+ Data.TreeDiff.Instances.CabalVersion
diff --git a/cabal/Cabal/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs b/cabal/Cabal/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs
new file mode 100644
index 0000000..999c03f
--- /dev/null
+++ b/cabal/Cabal/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs
@@ -0,0 +1,135 @@
+{-# LANGUAGE CPP #-}
+#if __GLASGOW_HASKELL__ >= 800
+{-# OPTIONS_GHC -freduction-depth=0 #-}
+#else
+{-# OPTIONS_GHC -fcontext-stack=151 #-}
+#endif
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+module Data.TreeDiff.Instances.Cabal () where
+
+import Data.TreeDiff
+
+import Data.TreeDiff.Instances.CabalLanguage ()
+import Data.TreeDiff.Instances.CabalSPDX ()
+import Data.TreeDiff.Instances.CabalVersion ()
+
+-------------------------------------------------------------------------------
+
+import Distribution.Backpack (OpenModule, OpenUnitId)
+import Distribution.CabalSpecVersion (CabalSpecVersion)
+import Distribution.Compiler (CompilerFlavor, CompilerId, PerCompilerFlavor)
+import Distribution.InstalledPackageInfo (AbiDependency, ExposedModule, InstalledPackageInfo)
+import Distribution.ModuleName (ModuleName)
+import Distribution.PackageDescription
+import Distribution.Simple.Compiler (DebugInfoLevel, OptimisationLevel, ProfDetailLevel)
+import Distribution.Simple.Flag (Flag)
+import Distribution.Simple.InstallDirs
+import Distribution.Simple.InstallDirs.Internal
+import Distribution.Simple.Setup (HaddockTarget, TestShowDetails)
+import Distribution.System
+import Distribution.Types.AbiHash (AbiHash)
+import Distribution.Types.ComponentId (ComponentId)
+import Distribution.Types.IncludeRenaming (IncludeRenaming)
+import Distribution.Types.Mixin
+import Distribution.Types.ModuleReexport
+import Distribution.Types.ModuleRenaming
+import Distribution.Types.PackageVersionConstraint
+import Distribution.Types.PkgconfigName (PkgconfigName)
+import Distribution.Types.PkgconfigVersion (PkgconfigVersion)
+import Distribution.Types.PkgconfigVersionRange (PkgconfigVersionRange)
+import Distribution.Types.UnitId (DefUnitId, UnitId)
+import Distribution.Utils.NubList (NubList)
+import Distribution.Utils.ShortText (ShortText, fromShortText)
+import Distribution.Verbosity
+import Distribution.Verbosity.Internal
+
+import qualified Distribution.Compat.NonEmptySet as NES
+
+-------------------------------------------------------------------------------
+-- instances
+-------------------------------------------------------------------------------
+
+instance (Eq a, Show a) => ToExpr (Condition a) where toExpr = defaultExprViaShow
+instance (Show a, ToExpr b, ToExpr c, Show b, Show c, Eq a, Eq c, Eq b) => ToExpr (CondTree a b c)
+instance (Show a, ToExpr b, ToExpr c, Show b, Show c, Eq a, Eq c, Eq b) => ToExpr (CondBranch a b c)
+instance (ToExpr a) => ToExpr (NubList a)
+instance (ToExpr a) => ToExpr (Flag a)
+instance ToExpr a => ToExpr (NES.NonEmptySet a) where
+ toExpr xs = App "NonEmptySet.fromNonEmpty" [toExpr $ NES.toNonEmpty xs]
+
+instance ToExpr a => ToExpr (PerCompilerFlavor a)
+
+instance ToExpr Dependency where
+ toExpr d@(Dependency pn vr cs)
+ | cs == mainLibSet = App "Dependency" [toExpr pn, toExpr vr, App "mainLibSet" []]
+ | otherwise = genericToExpr d
+
+instance ToExpr AbiDependency
+instance ToExpr AbiHash
+instance ToExpr Arch
+instance ToExpr Benchmark
+instance ToExpr BenchmarkInterface
+instance ToExpr BenchmarkType
+instance ToExpr BuildInfo
+instance ToExpr BuildType
+instance ToExpr CabalSpecVersion
+instance ToExpr CompilerFlavor
+instance ToExpr CompilerId
+instance ToExpr ComponentId
+instance ToExpr DebugInfoLevel
+instance ToExpr DefUnitId
+instance ToExpr ExeDependency
+instance ToExpr Executable
+instance ToExpr ExecutableScope
+instance ToExpr ExposedModule
+instance ToExpr FlagAssignment
+instance ToExpr FlagName
+instance ToExpr ForeignLib
+instance ToExpr ForeignLibOption
+instance ToExpr ForeignLibType
+instance ToExpr GenericPackageDescription
+instance ToExpr HaddockTarget
+instance ToExpr IncludeRenaming
+instance ToExpr InstalledPackageInfo
+instance ToExpr KnownRepoType
+instance ToExpr LegacyExeDependency
+instance ToExpr LibVersionInfo
+instance ToExpr Library
+instance ToExpr LibraryName
+instance ToExpr LibraryVisibility
+instance ToExpr Mixin
+instance ToExpr ModuleName
+instance ToExpr ModuleReexport
+instance ToExpr ModuleRenaming
+instance ToExpr OS
+instance ToExpr OpenModule
+instance ToExpr OpenUnitId
+instance ToExpr OptimisationLevel
+instance ToExpr PackageDescription
+instance ToExpr PackageFlag
+instance ToExpr PackageIdentifier
+instance ToExpr PackageName
+instance ToExpr PackageVersionConstraint
+instance ToExpr PathComponent
+instance ToExpr PathTemplate
+instance ToExpr PathTemplateVariable
+instance ToExpr PkgconfigDependency
+instance ToExpr PkgconfigName
+instance ToExpr PkgconfigVersion
+instance ToExpr PkgconfigVersionRange
+instance ToExpr ProfDetailLevel
+instance ToExpr RepoKind
+instance ToExpr RepoType
+instance ToExpr SetupBuildInfo
+instance ToExpr SourceRepo
+instance ToExpr TestShowDetails
+instance ToExpr TestSuite
+instance ToExpr TestSuiteInterface
+instance ToExpr TestType
+instance ToExpr UnitId
+instance ToExpr UnqualComponentName
+instance ToExpr Verbosity
+instance ToExpr VerbosityFlag
+instance ToExpr VerbosityLevel
+
+instance ToExpr ShortText where toExpr = toExpr . fromShortText
diff --git a/cabal/Cabal/Cabal-tree-diff/src/Data/TreeDiff/Instances/CabalLanguage.hs b/cabal/Cabal/Cabal-tree-diff/src/Data/TreeDiff/Instances/CabalLanguage.hs
new file mode 100644
index 0000000..8f38707
--- /dev/null
+++ b/cabal/Cabal/Cabal-tree-diff/src/Data/TreeDiff/Instances/CabalLanguage.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE CPP #-}
+#if __GLASGOW_HASKELL__ >= 800
+{-# OPTIONS_GHC -freduction-depth=0 #-}
+#else
+{-# OPTIONS_GHC -fcontext-stack=151 #-}
+#endif
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+module Data.TreeDiff.Instances.CabalLanguage () where
+
+import Data.TreeDiff
+import Language.Haskell.Extension (Extension, KnownExtension, Language)
+
+-- These are big enums, so they are in separate file.
+--
+instance ToExpr Extension
+instance ToExpr KnownExtension
+instance ToExpr Language
diff --git a/cabal/Cabal/Cabal-tree-diff/src/Data/TreeDiff/Instances/CabalSPDX.hs b/cabal/Cabal/Cabal-tree-diff/src/Data/TreeDiff/Instances/CabalSPDX.hs
new file mode 100644
index 0000000..edf5c01
--- /dev/null
+++ b/cabal/Cabal/Cabal-tree-diff/src/Data/TreeDiff/Instances/CabalSPDX.hs
@@ -0,0 +1,28 @@
+{-# LANGUAGE CPP #-}
+#if __GLASGOW_HASKELL__ >= 800
+{-# OPTIONS_GHC -freduction-depth=0 #-}
+#else
+{-# OPTIONS_GHC -fcontext-stack=151 #-}
+#endif
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+module Data.TreeDiff.Instances.CabalSPDX () where
+
+import Data.TreeDiff
+import Distribution.License (License)
+
+import Data.TreeDiff.Instances.CabalVersion ()
+
+import qualified Distribution.SPDX as SPDX
+
+-- 'License' almost belongs here.
+
+instance ToExpr License
+
+-- Generics instance is too heavy
+instance ToExpr SPDX.LicenseId where toExpr = defaultExprViaShow
+instance ToExpr SPDX.LicenseExceptionId where toExpr = defaultExprViaShow
+
+instance ToExpr SPDX.License
+instance ToExpr SPDX.LicenseExpression
+instance ToExpr SPDX.LicenseRef
+instance ToExpr SPDX.SimpleLicenseExpression
diff --git a/cabal/Cabal/Cabal-tree-diff/src/Data/TreeDiff/Instances/CabalVersion.hs b/cabal/Cabal/Cabal-tree-diff/src/Data/TreeDiff/Instances/CabalVersion.hs
new file mode 100644
index 0000000..8d6acf0
--- /dev/null
+++ b/cabal/Cabal/Cabal-tree-diff/src/Data/TreeDiff/Instances/CabalVersion.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE CPP #-}
+#if __GLASGOW_HASKELL__ >= 800
+{-# OPTIONS_GHC -freduction-depth=0 #-}
+#else
+{-# OPTIONS_GHC -fcontext-stack=151 #-}
+#endif
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+module Data.TreeDiff.Instances.CabalVersion where
+
+import Data.TreeDiff
+import Distribution.Version (Version, VersionRange, versionNumbers)
+
+instance ToExpr Version where toExpr v = App "mkVersion" [toExpr $ versionNumbers v]
+instance ToExpr VersionRange
diff --git a/cabal/Cabal/Cabal.cabal b/cabal/Cabal/Cabal.cabal
index 2b2365f..72c0902 100644
--- a/cabal/Cabal/Cabal.cabal
+++ b/cabal/Cabal/Cabal.cabal
@@ -1,7 +1,7 @@
cabal-version: >=1.10
name: Cabal
-version: 3.1.0.0
-copyright: 2003-2019, Cabal Development Team (see AUTHORS file)
+version: 3.3.0.0
+copyright: 2003-2020, Cabal Development Team (see AUTHORS file)
license: BSD3
license-file: LICENSE
author: Cabal Development Team <cabal-devel@haskell.org>
@@ -35,6 +35,8 @@ extra-source-files:
-- BEGIN gen-extra-source-files
tests/ParserTests/errors/MiniAgda.cabal
tests/ParserTests/errors/MiniAgda.errors
+ tests/ParserTests/errors/anynone.cabal
+ tests/ParserTests/errors/anynone.errors
tests/ParserTests/errors/big-version.cabal
tests/ParserTests/errors/big-version.errors
tests/ParserTests/errors/common1.cabal
@@ -110,6 +112,9 @@ extra-source-files:
tests/ParserTests/regressions/Octree-0.5.cabal
tests/ParserTests/regressions/Octree-0.5.expr
tests/ParserTests/regressions/Octree-0.5.format
+ tests/ParserTests/regressions/anynone.cabal
+ tests/ParserTests/regressions/anynone.expr
+ tests/ParserTests/regressions/anynone.format
tests/ParserTests/regressions/assoc-cpp-options.cabal
tests/ParserTests/regressions/assoc-cpp-options.check
tests/ParserTests/regressions/bad-glob-syntax.cabal
@@ -151,6 +156,9 @@ extra-source-files:
tests/ParserTests/regressions/ghc-option-j.check
tests/ParserTests/regressions/haddock-api-2.18.1-check.cabal
tests/ParserTests/regressions/haddock-api-2.18.1-check.check
+ tests/ParserTests/regressions/hasktorch.cabal
+ tests/ParserTests/regressions/hasktorch.expr
+ tests/ParserTests/regressions/hasktorch.format
tests/ParserTests/regressions/hidden-main-lib.cabal
tests/ParserTests/regressions/hidden-main-lib.expr
tests/ParserTests/regressions/hidden-main-lib.format
@@ -169,6 +177,30 @@ extra-source-files:
tests/ParserTests/regressions/issue-5846.cabal
tests/ParserTests/regressions/issue-5846.expr
tests/ParserTests/regressions/issue-5846.format
+ tests/ParserTests/regressions/issue-6083-a.cabal
+ tests/ParserTests/regressions/issue-6083-a.expr
+ tests/ParserTests/regressions/issue-6083-a.format
+ tests/ParserTests/regressions/issue-6083-b.cabal
+ tests/ParserTests/regressions/issue-6083-b.expr
+ tests/ParserTests/regressions/issue-6083-b.format
+ tests/ParserTests/regressions/issue-6083-c.cabal
+ tests/ParserTests/regressions/issue-6083-c.expr
+ tests/ParserTests/regressions/issue-6083-c.format
+ tests/ParserTests/regressions/issue-6083-pkg-pkg.cabal
+ tests/ParserTests/regressions/issue-6083-pkg-pkg.expr
+ tests/ParserTests/regressions/issue-6083-pkg-pkg.format
+ tests/ParserTests/regressions/issue-6288-a.cabal
+ tests/ParserTests/regressions/issue-6288-a.check
+ tests/ParserTests/regressions/issue-6288-b.cabal
+ tests/ParserTests/regressions/issue-6288-b.check
+ tests/ParserTests/regressions/issue-6288-c.cabal
+ tests/ParserTests/regressions/issue-6288-c.check
+ tests/ParserTests/regressions/issue-6288-d.cabal
+ tests/ParserTests/regressions/issue-6288-d.check
+ tests/ParserTests/regressions/issue-6288-e.cabal
+ tests/ParserTests/regressions/issue-6288-e.check
+ tests/ParserTests/regressions/issue-6288-f.cabal
+ tests/ParserTests/regressions/issue-6288-f.check
tests/ParserTests/regressions/issue-774.cabal
tests/ParserTests/regressions/issue-774.check
tests/ParserTests/regressions/issue-774.expr
@@ -197,6 +229,9 @@ extra-source-files:
tests/ParserTests/regressions/mixin-3.cabal
tests/ParserTests/regressions/mixin-3.expr
tests/ParserTests/regressions/mixin-3.format
+ tests/ParserTests/regressions/monad-param.cabal
+ tests/ParserTests/regressions/monad-param.expr
+ tests/ParserTests/regressions/monad-param.format
tests/ParserTests/regressions/multiple-libs-2.cabal
tests/ParserTests/regressions/multiple-libs-2.check
tests/ParserTests/regressions/multiple-libs-2.expr
@@ -212,6 +247,10 @@ extra-source-files:
tests/ParserTests/regressions/pre-1.6-glob.check
tests/ParserTests/regressions/pre-2.4-globstar.cabal
tests/ParserTests/regressions/pre-2.4-globstar.check
+ tests/ParserTests/regressions/public-multilib-1.cabal
+ tests/ParserTests/regressions/public-multilib-1.check
+ tests/ParserTests/regressions/public-multilib-2.cabal
+ tests/ParserTests/regressions/public-multilib-2.check
tests/ParserTests/regressions/shake.cabal
tests/ParserTests/regressions/shake.expr
tests/ParserTests/regressions/shake.format
@@ -243,6 +282,10 @@ extra-source-files:
tests/ParserTests/warnings/nbsp.cabal
tests/ParserTests/warnings/newsyntax.cabal
tests/ParserTests/warnings/oldsyntax.cabal
+ tests/ParserTests/warnings/operator.cabal
+ tests/ParserTests/warnings/specversion-a.cabal
+ tests/ParserTests/warnings/specversion-b.cabal
+ tests/ParserTests/warnings/specversion-c.cabal
tests/ParserTests/warnings/subsection.cabal
tests/ParserTests/warnings/tab.cabal
tests/ParserTests/warnings/trailingfield.cabal
@@ -250,6 +293,7 @@ extra-source-files:
tests/ParserTests/warnings/unknownsection.cabal
tests/ParserTests/warnings/utf8.cabal
tests/ParserTests/warnings/versiontag.cabal
+ tests/ParserTests/warnings/wildcard.cabal
tests/cbits/rpmvercmp.c
tests/hackage/check.sh
tests/hackage/download.sh
@@ -276,7 +320,7 @@ library
filepath >= 1.3.0.1 && < 1.5,
pretty >= 1.1.1 && < 1.2,
process >= 1.1.0.2 && < 1.7,
- time >= 1.4.0.1 && < 1.10
+ time >= 1.4.0.1 && < 1.11
if flag(bundled-binary-generic)
build-depends: binary >= 0.5.1.1 && < 0.7
@@ -288,16 +332,21 @@ library
else
build-depends: unix >= 2.6.0.0 && < 2.8
- ghc-options: -Wall -fno-ignore-asserts -fwarn-tabs
+ ghc-options: -Wall -fno-ignore-asserts -fwarn-tabs -fwarn-incomplete-uni-patterns
if impl(ghc >= 8.0)
ghc-options: -Wcompat -Wnoncanonical-monad-instances
- -Wnoncanonical-monadfail-instances
+
+ if impl(ghc <8.8)
+ ghc-options: -Wnoncanonical-monadfail-instances
if !impl(ghc >= 8.0)
-- at least one of lib:Cabal's dependency (i.e. `parsec`)
-- already depends on `fail` and `semigroups` transitively
build-depends: fail == 4.9.*, semigroups >= 0.18.3 && < 0.20
+ if !impl(ghc >= 7.10)
+ build-depends: void >= 0.7.3 && < 0.8
+
if !impl(ghc >= 7.8)
-- semigroups depends on tagged.
build-depends: tagged >=0.8.6 && <0.9
@@ -317,6 +366,8 @@ library
Distribution.Utils.IOData
Distribution.Utils.LogProgress
Distribution.Utils.MapAccum
+ Distribution.Utils.MD5
+ Distribution.Utils.Structured
Distribution.Compat.CreatePipe
Distribution.Compat.Directory
Distribution.Compat.Environment
@@ -325,11 +376,14 @@ library
Distribution.Compat.Graph
Distribution.Compat.Internal.TempFile
Distribution.Compat.Newtype
+ Distribution.Compat.NonEmptySet
Distribution.Compat.ResponseFile
Distribution.Compat.Prelude.Internal
+ Distribution.Compat.Process
Distribution.Compat.Semigroup
Distribution.Compat.Stack
Distribution.Compat.Time
+ Distribution.Compat.Typeable
Distribution.Compat.DList
Distribution.Compiler
Distribution.InstalledPackageInfo
@@ -496,6 +550,7 @@ library
Distribution.FieldGrammar
Distribution.FieldGrammar.Class
Distribution.FieldGrammar.FieldDescrs
+ Distribution.FieldGrammar.Newtypes
Distribution.FieldGrammar.Parsec
Distribution.FieldGrammar.Pretty
Distribution.PackageDescription.FieldGrammar
@@ -503,7 +558,6 @@ library
Distribution.PackageDescription.Quirks
Distribution.Parsec
Distribution.Parsec.Error
- Distribution.Parsec.Newtypes
Distribution.Parsec.Position
Distribution.Parsec.Warning
Distribution.Parsec.FieldLineStream
@@ -545,17 +599,18 @@ library
Distribution.Compat.Async
Distribution.Compat.CopyFile
Distribution.Compat.GetShortPathName
- Distribution.Compat.MD5
Distribution.Compat.MonadFail
Distribution.Compat.Prelude
Distribution.Compat.SnocList
Distribution.GetOpt
Distribution.Lex
Distribution.Utils.String
+ Distribution.Simple.Build.Macros.Z
Distribution.Simple.GHC.EnvironmentParser
Distribution.Simple.GHC.Internal
Distribution.Simple.GHC.ImplInfo
Distribution.Simple.Utils.Json
+ Distribution.ZinzaPrelude
Paths_Cabal
if flag(bundled-binary-generic)
@@ -601,9 +656,11 @@ test-suite unit-tests
other-modules:
Test.Laws
Test.QuickCheck.Utils
+ UnitTests.Distribution.CabalSpecVersion
UnitTests.Distribution.Compat.CreatePipe
UnitTests.Distribution.Compat.Graph
UnitTests.Distribution.Compat.Time
+ UnitTests.Distribution.Described
UnitTests.Distribution.Simple.Glob
UnitTests.Distribution.Simple.Program.GHC
UnitTests.Distribution.Simple.Program.Internal
@@ -611,34 +668,61 @@ test-suite unit-tests
UnitTests.Distribution.SPDX
UnitTests.Distribution.System
UnitTests.Distribution.Types.GenericPackageDescription
+ UnitTests.Distribution.Utils.CharSet
UnitTests.Distribution.Utils.Generic
UnitTests.Distribution.Utils.NubList
UnitTests.Distribution.Utils.ShortText
+ UnitTests.Distribution.Utils.Structured
UnitTests.Distribution.Version
UnitTests.Distribution.PkgconfigVersion
+ UnitTests.Orphans
+
+ -- Cabal-quickcheck
+ hs-source-dirs: Cabal-QuickCheck/src
+ other-modules:
+ Test.QuickCheck.GenericArbitrary
+ Test.QuickCheck.Instances.Cabal
+
+ -- Cabal-described
+ hs-source-dirs: Cabal-described/src
+ other-modules:
+ Distribution.Described
+ Distribution.Utils.CharSet
+ Distribution.Utils.GrammarRegex
+
main-is: UnitTests.hs
build-depends:
array,
+ async >= 2.2.2 && <2.3,
base,
binary,
bytestring,
containers,
+ deepseq,
directory,
filepath,
integer-logarithms >= 1.0.2 && <1.1,
- tasty >= 1.2.3 && < 1.3,
+ pretty,
+ rere >=0.1 && <0.2,
+ tagged,
+ tasty >= 1.2.3 && < 1.4,
tasty-hunit,
tasty-quickcheck,
- tagged,
temporary,
text,
- pretty,
+ transformers,
Diff >=0.4 && <0.5,
- QuickCheck >= 2.13.2 && < 2.14,
+ QuickCheck >= 2.14 && < 2.15,
Cabal
ghc-options: -Wall
default-language: Haskell2010
+ if !impl(ghc >= 7.10)
+ build-depends: void
+
+ if !impl(ghc >= 8.0)
+ build-depends: semigroups
+
test-suite parser-tests
type: exitcode-stdio-1.0
hs-source-dirs: tests
@@ -649,7 +733,7 @@ test-suite parser-tests
bytestring,
directory,
filepath,
- tasty >= 1.2.3 && < 1.3,
+ tasty >= 1.2.3 && < 1.4,
tasty-hunit,
tasty-quickcheck,
tasty-golden >=2.3.1.1 && <2.4,
@@ -659,16 +743,17 @@ test-suite parser-tests
default-language: Haskell2010
if !impl(ghc >= 8.0)
- build-depends: semigroups
+ build-depends: semigroups
if impl(ghc >= 7.8)
build-depends:
tree-diff >= 0.1 && <0.2
+ hs-source-dirs: Cabal-tree-diff/src
other-modules:
- Instances.TreeDiff
- Instances.TreeDiff.Language
- Instances.TreeDiff.SPDX
- Instances.TreeDiff.Version
+ Data.TreeDiff.Instances.Cabal
+ Data.TreeDiff.Instances.CabalLanguage
+ Data.TreeDiff.Instances.CabalSPDX
+ Data.TreeDiff.Instances.CabalVersion
test-suite check-tests
type: exitcode-stdio-1.0
@@ -679,7 +764,7 @@ test-suite check-tests
bytestring,
directory,
filepath,
- tasty >= 1.2.3 && < 1.3,
+ tasty >= 1.2.3 && < 1.4,
tasty-golden >=2.3.1.1 && <2.4,
Diff >=0.4 && <0.5,
Cabal
@@ -725,6 +810,7 @@ test-suite hackage-tests
build-depends:
base-compat >=0.11.0 && <0.12,
base-orphans >=0.6 && <0.9,
+ clock >=0.8 && <0.9,
optparse-applicative >=0.13.2.0 && <0.16,
stm >=2.4.5.0 && <2.6,
tar >=0.5.0.3 && <0.6
@@ -732,11 +818,12 @@ test-suite hackage-tests
if impl(ghc >= 7.8)
build-depends:
tree-diff >= 0.1 && <0.2
+ hs-source-dirs: Cabal-tree-diff/src
other-modules:
- Instances.TreeDiff
- Instances.TreeDiff.Language
- Instances.TreeDiff.SPDX
- Instances.TreeDiff.Version
+ Data.TreeDiff.Instances.Cabal
+ Data.TreeDiff.Instances.CabalLanguage
+ Data.TreeDiff.Instances.CabalSPDX
+ Data.TreeDiff.Instances.CabalVersion
ghc-options: -Wall -rtsopts -threaded
default-extensions: CPP
@@ -753,7 +840,7 @@ test-suite rpmvercmp
bytestring
build-depends:
- tasty >= 1.2.3 && < 1.3,
+ tasty >= 1.2.3 && < 1.4,
tasty-hunit,
tasty-quickcheck,
QuickCheck
diff --git a/cabal/Cabal/ChangeLog.md b/cabal/Cabal/ChangeLog.md
index 5e8d823..f2ab542 100644
--- a/cabal/Cabal/ChangeLog.md
+++ b/cabal/Cabal/ChangeLog.md
@@ -1,9 +1,41 @@
-# 3.1.0.0 (current development version)
+# 3.2.0.0 [Herbert Valerio Riedel](mailto:hvr@gnu.org) April 2020
+ * Change free text `String` fields to use `ShortText` in package description
+ and installed package info.
+ * Split `Distribution.Types.Flag` and `Distribution.Types.ConfVar`
+ `Distribution.Types.GenericPackageDescription`.
+ * Add GHC-8.10 support, including new extensions to
+ `Language.Haskell.Extension`.
+ * Use more `NonEmpty` instead of ordinary lists.
+ * Add `Distribution.Utils.Structured` for fingeprinting `Binary` blobs.
+ * Add `null`, `length` and `unsafeFromUTF8BS` to `Distribution.Utils.ShortText`.
+ * Refactor `Distribution.Utils.IOData` module.
+ * Rename `Distribution.Compat.MD5` to `Distribution.Utils.MD5`.
+ * Add `safeHead`, `safeTail`, `safeLast` to `Distribution.Utils.Generic`.
+ * Add `unsnoc` and `unsnocNE` to `Distribution.Utils.Generic`.
+ * Add `Set'` modifier to `Distribution.Parsec.Newtypes`.
+ * Add `Distribution.Compat.Async`.
+
+# 3.0.2.0 [Herbert Valerio Riedel](mailto:hvr@gnu.org) April 2020
+ * Disallow spaces around colon `:` in Dependency `build-depends` syntax
+ ([#6538](https://github.com/haskell/cabal/pull/6538)).
+ * Make `configure` accept any `pkg-config --modversion` output
+ ([#6541](https://github.com/haskell/cabal/pull/6541)).
+
+# 3.0.1.0 [Herbert Valerio Riedel](mailto:hvr@gnu.org) April 2020
+ * Add GHC-8.8 flags to `normaliseGhcFlags`
+ ([#6379](https://github.com/haskell/cabal/pull/6379)).
+ * Typo fixes
+ ([#6372](https://github.com/haskell/cabal/pull/6372)).
+ * Limit version number parts to contain at most 9 digits
+ ([#6386](https://github.com/haskell/cabal/pull/6386)).
+ * Fix boundless sublibrary dependency parse failure
+ ([#5846](https://github.com/haskell/cabal/issues/5846)).
* `cabal check` verifies `cpp-options` more pedantically, allowing only
options starting with `-D` and `-U`.
- * TODO
-
- ----
+ * Don’t rebuild world when new ghc flags that affect how error
+ messages are presented is specified.
+ * Fix dropExeExtension behaviour on Windows
+ ([#6287](https://github.com/haskell/cabal/pull/6287)).
# 3.0.0.0 [Mikhail Glushenkov](mailto:mikhail.glushenkov@gmail.com) August 2019
* The 3.0 migration guide gives advice on adapting Custom setup
@@ -133,7 +165,7 @@
[#784](https://github.com/haskell/cabal/issues/784),
[#5057](https://github.com/haskell/cabal/issues/5057)).
* Wildcard syntax errors (misplaced `*`, etc), wildcards that
- refer to missing directoies, and wildcards that do not match
+ refer to missing directories, and wildcards that do not match
anything are now all detected by `cabal check`.
* Wildcard ('globbing') functions have been moved from
`Distribution.Simple.Utils` to `Distribution.Simple.Glob` and
@@ -594,7 +626,7 @@
* Support for finding installed packages for hugs
* Cabal version macros now have proper parenthesis
* Reverted change to filter out deps of non-buildable components
- * Fix for registering implace when using a specific package db
+ * Fix for registering inplace when using a specific package db
* Fix mismatch between $os and $arch path template variables
* Fix for finding ar.exe on Windows, always pick ghc's version
* Fix for intra-package dependencies with ghc-6.12
@@ -756,7 +788,7 @@
# 1.2.0 [Duncan Coutts](mailto:duncan.coutts@worc.ox.ac.uk) Sept 2007
* To be included in GHC 6.8.x
* New configurations feature
- * Can make haddock docs link to hilighted sources (with hscolour)
+ * Can make haddock docs link to highlighted sources (with hscolour)
* New flag to allow linking to haddock docs on the web
* Supports pkg-config
* New field `build-tools` for tool dependencies
@@ -796,7 +828,7 @@
* Released with GHC 6.6
* Added support for hoogle
- * Allow profiling and normal builds of libs to be chosen indepentantly
+ * Allow profiling and normal builds of libs to be chosen independently
* Default installation directories on Win32 changed
* Register haddock docs with ghc-pkg
* Get haddock to make hyperlinks to dependent package docs
@@ -876,7 +908,7 @@
* Lots of bug fixes
* spaces can sometimes be used instead of commas
* A user manual has appeared (Thanks, ross!)
- * for ghc 6.4, configures versionsed depends properly
+ * for ghc 6.4, configures versioned depends properly
* more features to `./setup haddock`
----
diff --git a/cabal/Cabal/Distribution/Backpack.hs b/cabal/Cabal/Distribution/Backpack.hs
index bf02a5e..e763286 100644
--- a/cabal/Cabal/Distribution/Backpack.hs
+++ b/cabal/Cabal/Distribution/Backpack.hs
@@ -98,7 +98,7 @@ data OpenUnitId
-- TODO: cache holes?
instance Binary OpenUnitId
-
+instance Structured OpenUnitId
instance NFData OpenUnitId where
rnf (IndefFullUnitId cid subst) = rnf cid `seq` rnf subst
rnf (DefiniteUnitId uid) = rnf uid
@@ -117,7 +117,7 @@ instance Pretty OpenUnitId where
--Right (DefiniteUnitId (DefUnitId {unDefUnitId = UnitId "foobar"}))
--
-- >>> eitherParsec "foo[Str=text-1.2.3:Data.Text.Text]" :: Either String OpenUnitId
--- Right (IndefFullUnitId (ComponentId "foo") (fromList [(ModuleName ["Str"],OpenModule (DefiniteUnitId (DefUnitId {unDefUnitId = UnitId "text-1.2.3"})) (ModuleName ["Data","Text","Text"]))]))
+-- Right (IndefFullUnitId (ComponentId "foo") (fromList [(ModuleName "Str",OpenModule (DefiniteUnitId (DefUnitId {unDefUnitId = UnitId "text-1.2.3"})) (ModuleName "Data.Text.Text"))]))
--
instance Parsec OpenUnitId where
parsec = P.try parseOpenUnitId <|> fmap DefiniteUnitId parsec
@@ -165,6 +165,7 @@ data OpenModule
deriving (Generic, Read, Show, Eq, Ord, Typeable, Data)
instance Binary OpenModule
+instance Structured OpenModule
instance NFData OpenModule where
rnf (OpenModule uid mod_name) = rnf uid `seq` rnf mod_name
@@ -179,7 +180,7 @@ instance Pretty OpenModule where
-- |
--
-- >>> eitherParsec "Includes2-0.1.0.0-inplace-mysql:Database.MySQL" :: Either String OpenModule
--- Right (OpenModule (DefiniteUnitId (DefUnitId {unDefUnitId = UnitId "Includes2-0.1.0.0-inplace-mysql"})) (ModuleName ["Database","MySQL"]))
+-- Right (OpenModule (DefiniteUnitId (DefUnitId {unDefUnitId = UnitId "Includes2-0.1.0.0-inplace-mysql"})) (ModuleName "Database.MySQL"))
--
instance Parsec OpenModule where
parsec = parsecModuleVar <|> parsecOpenModule
diff --git a/cabal/Cabal/Distribution/Backpack/ComponentsGraph.hs b/cabal/Cabal/Distribution/Backpack/ComponentsGraph.hs
index aab90dd..656fc22 100644
--- a/cabal/Cabal/Distribution/Backpack/ComponentsGraph.hs
+++ b/cabal/Cabal/Distribution/Backpack/ComponentsGraph.hs
@@ -12,13 +12,13 @@ import Prelude ()
import Distribution.Compat.Prelude
import Distribution.Package
-import Distribution.PackageDescription as PD hiding (Flag)
+import Distribution.PackageDescription
import Distribution.Simple.BuildToolDepends
import Distribution.Simple.LocalBuildInfo
import Distribution.Types.ComponentRequestedSpec
-import Distribution.Types.UnqualComponentName
import Distribution.Compat.Graph (Graph, Node(..))
import qualified Distribution.Compat.Graph as Graph
+import qualified Distribution.Compat.NonEmptySet as NES
import Distribution.Utils.Generic
import Distribution.Pretty (pretty)
@@ -63,20 +63,18 @@ mkComponentsGraph enabled pkg_descr =
where
-- The dependencies for the given component
componentDeps component =
- (CExeName <$> getAllInternalToolDependencies pkg_descr bi)
-
- ++ [ if pkgname == packageName pkg_descr
- then CLibName LMainLibName
- else CLibName (LSubLibName toolname)
- | Dependency pkgname _ _ <- targetBuildDepends bi
- , let toolname = packageNameToUnqualComponentName pkgname
- , toolname `elem` internalPkgDeps ]
+ toolDependencies ++ libDependencies
where
bi = componentBuildInfo component
- internalPkgDeps = map (conv . libName) (allLibraries pkg_descr)
- conv LMainLibName = packageNameToUnqualComponentName $ packageName pkg_descr
- conv (LSubLibName s) = s
+ toolDependencies = CExeName <$> getAllInternalToolDependencies pkg_descr bi
+
+ libDependencies = do
+ Dependency pkgname _ lns <- targetBuildDepends bi
+ guard (pkgname == packageName pkg_descr)
+
+ ln <- NES.toList lns
+ return (CLibName ln)
-- | Given the package description and a 'PackageDescription' (used
-- to determine if a package name is internal or not), sort the
@@ -90,9 +88,10 @@ componentsGraphToList =
map (\(N c _ cs) -> (c, cs)) . Graph.revTopSort
-- | Error message when there is a cycle; takes the SCC of components.
-componentCycleMsg :: [ComponentName] -> Doc
-componentCycleMsg cnames =
- text $ "Components in the package depend on each other in a cyclic way:\n "
- ++ intercalate " depends on "
+componentCycleMsg :: PackageIdentifier -> [ComponentName] -> Doc
+componentCycleMsg pn cnames =
+ text "Components in the package" <+> pretty pn <+> text "depend on each other in a cyclic way:"
+ $$
+ text (intercalate " depends on "
[ "'" ++ showComponentName cname ++ "'"
- | cname <- cnames ++ maybeToList (safeHead cnames) ]
+ | cname <- cnames ++ maybeToList (safeHead cnames) ])
diff --git a/cabal/Cabal/Distribution/Backpack/Configure.hs b/cabal/Cabal/Distribution/Backpack/Configure.hs
index 927570f..e2a7594 100644
--- a/cabal/Cabal/Distribution/Backpack/Configure.hs
+++ b/cabal/Cabal/Distribution/Backpack/Configure.hs
@@ -27,14 +27,14 @@ import Distribution.Backpack.ReadyComponent
import Distribution.Backpack.ComponentsGraph
import Distribution.Backpack.Id
-import Distribution.Simple.Compiler hiding (Flag)
+import Distribution.Simple.Compiler
import Distribution.Package
import qualified Distribution.InstalledPackageInfo as Installed
import Distribution.InstalledPackageInfo (InstalledPackageInfo
,emptyInstalledPackageInfo)
import qualified Distribution.Simple.PackageIndex as PackageIndex
import Distribution.Simple.PackageIndex (InstalledPackageIndex)
-import Distribution.PackageDescription as PD hiding (Flag)
+import Distribution.PackageDescription
import Distribution.ModuleName
import Distribution.Simple.Setup as Setup
import Distribution.Simple.LocalBuildInfo
@@ -78,7 +78,7 @@ configureComponentLocalBuildInfos
-- NB: In single component mode, this returns a *single* component.
-- In this graph, the graph is NOT closed.
graph0 <- case mkComponentsGraph enabled pkg_descr of
- Left ccycle -> dieProgress (componentCycleMsg ccycle)
+ Left ccycle -> dieProgress (componentCycleMsg (package pkg_descr) ccycle)
Right g -> return (componentsGraphToList g)
infoProgress $ hang (text "Source component graph:") 4
(dispComponentsWithDeps graph0)
@@ -162,7 +162,8 @@ toComponentLocalBuildInfos
. map Right
$ graph
combined_graph = Graph.unionRight external_graph internal_graph
- Just local_graph = Graph.closure combined_graph (map nodeKey graph)
+ local_graph = fromMaybe (error "toComponentLocalBuildInfos: closure returned Nothing")
+ $ Graph.closure combined_graph (map nodeKey graph)
-- The database of transitively reachable installed packages that the
-- external components the package (as a whole) depends on. This will be
-- used in several ways:
diff --git a/cabal/Cabal/Distribution/Backpack/ConfiguredComponent.hs b/cabal/Cabal/Distribution/Backpack/ConfiguredComponent.hs
index 79a678b..69178e0 100644
--- a/cabal/Cabal/Distribution/Backpack/ConfiguredComponent.hs
+++ b/cabal/Cabal/Distribution/Backpack/ConfiguredComponent.hs
@@ -21,6 +21,7 @@ import Distribution.Compat.Prelude hiding ((<>))
import Distribution.Backpack.Id
+import Distribution.CabalSpecVersion
import Distribution.Types.AnnotatedId
import Distribution.Types.Dependency
import Distribution.Types.ExeDependency
@@ -31,23 +32,23 @@ import Distribution.Types.PackageName
import Distribution.Types.Mixin
import Distribution.Types.ComponentName
import Distribution.Types.LibraryName
-import Distribution.Types.UnqualComponentName
import Distribution.Types.ComponentInclude
import Distribution.Package
-import Distribution.PackageDescription as PD hiding (Flag)
+import Distribution.PackageDescription
import Distribution.Simple.BuildToolDepends
import Distribution.Simple.Setup as Setup
import Distribution.Simple.LocalBuildInfo
-import Distribution.Version
import Distribution.Utils.LogProgress
import Distribution.Utils.MapAccum
import Distribution.Utils.Generic
import Control.Monad
import qualified Data.Set as Set
+import qualified Distribution.Compat.NonEmptySet as NonEmptySet
import qualified Data.Map as Map
import Distribution.Pretty
-import Text.PrettyPrint
+import Text.PrettyPrint (Doc, hang, text, vcat, hsep, quotes, ($$))
+import qualified Text.PrettyPrint as PP
-- | A configured component, we know exactly what its 'ComponentId' is,
-- and the 'ComponentId's of the things it depends on.
@@ -111,13 +112,12 @@ mkConfiguredComponent
mkConfiguredComponent pkg_descr this_cid lib_deps exe_deps component = do
-- Resolve each @mixins@ into the actual dependency
-- from @lib_deps@.
- explicit_includes <- forM (mixins bi) $ \(Mixin name rns) -> do
- let keys = fixFakePkgName pkg_descr name
- aid <- case Map.lookup keys deps_map of
+ explicit_includes <- forM (mixins bi) $ \(Mixin pn ln rns) -> do
+ aid <- case Map.lookup (pn, CLibName ln) deps_map of
Nothing ->
dieProgress $
- text "Mix-in refers to non-existent package" <+>
- quotes (pretty name) $$
+ text "Mix-in refers to non-existent library" <+>
+ quotes (pretty pn <<>> prettyLN ln) $$
text "(did you forget to add the package to build-depends?)"
Just r -> return r
return ComponentInclude {
@@ -149,9 +149,17 @@ mkConfiguredComponent pkg_descr this_cid lib_deps exe_deps component = do
cc_includes = explicit_includes ++ implicit_includes
}
where
+ bi :: BuildInfo
bi = componentBuildInfo component
+
+ prettyLN :: LibraryName -> Doc
+ prettyLN LMainLibName = PP.empty
+ prettyLN (LSubLibName n) = PP.colon <<>> pretty n
+
+ deps_map :: Map (PackageName, ComponentName) (AnnotatedId ComponentId)
deps_map = Map.fromList [ ((packageName dep, ann_cname dep), dep)
| dep <- lib_deps ]
+
is_public = componentName component == CLibName LMainLibName
type ConfiguredComponentMap =
@@ -169,27 +177,21 @@ toConfiguredComponent pkg_descr this_cid lib_dep_map exe_dep_map component = do
if newPackageDepsBehaviour pkg_descr
then fmap concat $ forM (targetBuildDepends bi) $
\(Dependency name _ sublibs) -> do
- -- The package name still needs fixing in case of legacy
- -- sublibrary dependency syntax
- let (pn, _) = fixFakePkgName pkg_descr name
- pkg <- case Map.lookup pn lib_dep_map of
+ pkg <- case Map.lookup name lib_dep_map of
Nothing ->
dieProgress $
text "Dependency on unbuildable" <+>
- text "package" <+> pretty pn
+ text "package" <+> pretty name
Just p -> return p
-- Return all library components
- forM (Set.toList sublibs) $ \lib ->
+ forM (NonEmptySet.toList sublibs) $ \lib ->
let comp = CLibName lib in
- case Map.lookup (CLibName $ LSubLibName $
- packageNameToUnqualComponentName name) pkg
- <|> Map.lookup comp pkg
- of
+ case Map.lookup comp pkg of
Nothing ->
dieProgress $
text "Dependency on unbuildable" <+>
text (showLibraryName lib) <+>
- text "from" <+> pretty pn
+ text "from" <+> pretty name
Just v -> return v
else return old_style_lib_deps
mkConfiguredComponent
@@ -292,8 +294,8 @@ toConfiguredComponents
m component
return (extendConfiguredComponentMap cc m, cc)
-newPackageDepsBehaviourMinVersion :: Version
-newPackageDepsBehaviourMinVersion = mkVersion [1,7,1]
+newPackageDepsBehaviourMinVersion :: CabalSpecVersion
+newPackageDepsBehaviourMinVersion = CabalSpecV1_8
-- In older cabal versions, there was only one set of package dependencies for
@@ -304,19 +306,3 @@ newPackageDepsBehaviourMinVersion = mkVersion [1,7,1]
newPackageDepsBehaviour :: PackageDescription -> Bool
newPackageDepsBehaviour pkg =
specVersion pkg >= newPackageDepsBehaviourMinVersion
-
--- | 'build-depends:' stanzas are currently ambiguous as the external packages
--- and internal libraries are specified the same. For now, we assume internal
--- libraries shadow, and this function disambiguates accordingly, but soon the
--- underlying ambiguity will be addressed.
--- Multiple public libraries (cabal 3.0) added an unambiguous way of specifying
--- sublibraries, but we still have to support the old syntax for bc reasons.
-fixFakePkgName :: PackageDescription -> PackageName -> (PackageName, ComponentName)
-fixFakePkgName pkg_descr pn =
- if subLibName `elem` internalLibraries
- then (packageName pkg_descr, CLibName (LSubLibName subLibName))
- else (pn, CLibName LMainLibName )
- where
- subLibName = packageNameToUnqualComponentName pn
- internalLibraries = mapMaybe (libraryNameString . libName)
- (allLibraries pkg_descr)
diff --git a/cabal/Cabal/Distribution/Backpack/Id.hs b/cabal/Cabal/Distribution/Backpack/Id.hs
index b5e14a6..b304d40 100644
--- a/cabal/Cabal/Distribution/Backpack/Id.hs
+++ b/cabal/Cabal/Distribution/Backpack/Id.hs
@@ -11,13 +11,12 @@ import Prelude ()
import Distribution.Compat.Prelude
import Distribution.Types.UnqualComponentName
-import Distribution.Simple.Compiler hiding (Flag)
-import Distribution.PackageDescription as PD hiding (Flag)
+import Distribution.Simple.Compiler
+import Distribution.PackageDescription
import Distribution.Simple.Setup as Setup
import qualified Distribution.Simple.InstallDirs as InstallDirs
import Distribution.Simple.LocalBuildInfo
import Distribution.Types.ComponentId
-import Distribution.Types.PackageId
import Distribution.Types.UnitId
import Distribution.Types.MungedPackageName
import Distribution.Utils.Base62
@@ -125,8 +124,8 @@ computeCompatPackageKey
-> UnitId
-> String
computeCompatPackageKey comp pkg_name pkg_version uid
- | not (packageKeySupported comp) =
- prettyShow pkg_name ++ "-" ++ prettyShow pkg_version
+ | not (packageKeySupported comp || unitIdSupported comp)
+ = prettyShow pkg_name ++ "-" ++ prettyShow pkg_version
| not (unifiedIPIDRequired comp) =
let str = unUnitId uid -- assume no Backpack support
mb_verbatim_key
diff --git a/cabal/Cabal/Distribution/Backpack/LinkedComponent.hs b/cabal/Cabal/Distribution/Backpack/LinkedComponent.hs
index 1ead8f0..dd5bc0b 100644
--- a/cabal/Cabal/Distribution/Backpack/LinkedComponent.hs
+++ b/cabal/Cabal/Distribution/Backpack/LinkedComponent.hs
@@ -29,13 +29,14 @@ import Distribution.Utils.MapAccum
import Distribution.Types.AnnotatedId
import Distribution.Types.ComponentName
+import Distribution.Types.ModuleReexport
import Distribution.Types.ModuleRenaming
import Distribution.Types.IncludeRenaming
import Distribution.Types.ComponentInclude
import Distribution.Types.ComponentId
import Distribution.Types.PackageId
import Distribution.Package
-import Distribution.PackageDescription as PD hiding (Flag)
+import Distribution.PackageDescription
import Distribution.ModuleName
import Distribution.Simple.LocalBuildInfo
import Distribution.Verbosity
@@ -43,11 +44,8 @@ import Distribution.Utils.LogProgress
import qualified Data.Set as Set
import qualified Data.Map as Map
-import Data.Traversable
- ( mapM )
import Distribution.Pretty (pretty)
-import Text.PrettyPrint
-import Data.Either
+import Text.PrettyPrint (Doc, hang, text, vcat, ($+$), hsep, quotes)
-- | A linked component is a component that has been mix-in linked, at
-- which point we have determined how all the dependencies of the
@@ -187,19 +185,19 @@ toLinkedComponent verbosity db this_pid pkg_map ConfiguredComponent {
m_u <- convertModule (OpenModule this_uid m)
return (Map.singleton m [WithSource (from m) m_u], Map.empty)
-- Handle 'exposed-modules'
- exposed_mod_shapes_u <- mapM (convertMod FromExposedModules) src_provs
+ exposed_mod_shapes_u <- traverse (convertMod FromExposedModules) src_provs
-- Handle 'other-modules'
- other_mod_shapes_u <- mapM (convertMod FromOtherModules) src_hidden
+ other_mod_shapes_u <- traverse (convertMod FromOtherModules) src_hidden
-- Handle 'signatures'
let convertReq :: ModuleName -> UnifyM s (ModuleScopeU s)
convertReq req = do
req_u <- convertModule (OpenModuleVar req)
return (Map.empty, Map.singleton req [WithSource (FromSignatures req) req_u])
- req_shapes_u <- mapM convertReq src_reqs
+ req_shapes_u <- traverse convertReq src_reqs
-- Handle 'mixins'
- (incl_shapes_u, all_includes_u) <- fmap unzip (mapM convertInclude unlinked_includes)
+ (incl_shapes_u, all_includes_u) <- fmap unzip (traverse convertInclude unlinked_includes)
failIfErrs -- Prevent error cascade
-- Mix-in link everything! mixLink is the real workhorse.
@@ -208,7 +206,7 @@ toLinkedComponent verbosity db this_pid pkg_map ConfiguredComponent {
++ req_shapes_u
++ incl_shapes_u
- -- src_reqs_u <- mapM convertReq src_reqs
+ -- src_reqs_u <- traverse convertReq src_reqs
-- Read out all the final results by converting back
-- into a pure representation.
let convertIncludeU (ComponentInclude dep_aid rns i) = do
@@ -220,8 +218,8 @@ toLinkedComponent verbosity db this_pid pkg_map ConfiguredComponent {
})
shape <- convertModuleScopeU shape_u
let (includes_u, sig_includes_u) = partitionEithers all_includes_u
- incls <- mapM convertIncludeU includes_u
- sig_incls <- mapM convertIncludeU sig_includes_u
+ incls <- traverse convertIncludeU includes_u
+ sig_incls <- traverse convertIncludeU sig_includes_u
return (shape, incls, sig_incls)
let isNotLib (CLib _) = False
diff --git a/cabal/Cabal/Distribution/Backpack/ModuleShape.hs b/cabal/Cabal/Distribution/Backpack/ModuleShape.hs
index e2f7158..d186277 100644
--- a/cabal/Cabal/Distribution/Backpack/ModuleShape.hs
+++ b/cabal/Cabal/Distribution/Backpack/ModuleShape.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
-- | See <https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst>
module Distribution.Backpack.ModuleShape (
@@ -29,9 +30,10 @@ data ModuleShape = ModuleShape {
modShapeProvides :: OpenModuleSubst,
modShapeRequires :: Set ModuleName
}
- deriving (Eq, Show, Generic)
+ deriving (Eq, Show, Generic, Typeable)
instance Binary ModuleShape
+instance Structured ModuleShape
instance ModSubst ModuleShape where
modSubst subst (ModuleShape provs reqs)
diff --git a/cabal/Cabal/Distribution/Backpack/ReadyComponent.hs b/cabal/Cabal/Distribution/Backpack/ReadyComponent.hs
index 950a643..1064776 100644
--- a/cabal/Cabal/Distribution/Backpack/ReadyComponent.hs
+++ b/cabal/Cabal/Distribution/Backpack/ReadyComponent.hs
@@ -39,9 +39,6 @@ import Distribution.ModuleName
import Distribution.Package
import Distribution.Simple.Utils
-import qualified Control.Applicative as A
-import qualified Data.Traversable as T
-
import Control.Monad
import Text.PrettyPrint
import qualified Data.Map as Map
@@ -198,14 +195,14 @@ instance Functor InstM where
fmap f (InstM m) = InstM $ \s -> let (x, s') = m s
in (f x, s')
-instance A.Applicative InstM where
+instance Applicative InstM where
pure a = InstM $ \s -> (a, s)
InstM f <*> InstM x = InstM $ \s -> let (f', s') = f s
(x', s'') = x s'
in (f' x', s'')
instance Monad InstM where
- return = A.pure
+ return = pure
InstM m >>= f = InstM $ \s -> let (x, s') = m s
in runInstM (f x) s'
@@ -259,20 +256,20 @@ toReadyComponents pid_map subst0 comps
-> InstM (Maybe ReadyComponent)
instantiateComponent uid cid insts
| Just lc <- Map.lookup cid cmap = do
- provides <- T.mapM (substModule insts) (modShapeProvides (lc_shape lc))
+ provides <- traverse (substModule insts) (modShapeProvides (lc_shape lc))
-- NB: lc_sig_includes is omitted here, because we don't
-- need them to build
includes <- forM (lc_includes lc) $ \ci -> do
uid' <- substUnitId insts (ci_id ci)
return ci { ci_ann_id = fmap (const uid') (ci_ann_id ci) }
- exe_deps <- mapM (substExeDep insts) (lc_exe_deps lc)
+ exe_deps <- traverse (substExeDep insts) (lc_exe_deps lc)
s <- InstM $ \s -> (s, s)
let getDep (Module dep_def_uid _)
| let dep_uid = unDefUnitId dep_def_uid
-- Lose DefUnitId invariant for rc_depends
= [(dep_uid,
fromMaybe err_pid $
- Map.lookup dep_uid pid_map A.<|>
+ Map.lookup dep_uid pid_map <|>
fmap rc_munged_id (join (Map.lookup dep_uid s)))]
where
err_pid = MungedPackageId
@@ -313,7 +310,7 @@ toReadyComponents pid_map subst0 comps
substSubst :: Map ModuleName Module
-> Map ModuleName OpenModule
-> InstM (Map ModuleName Module)
- substSubst subst insts = T.mapM (substModule subst) insts
+ substSubst subst insts = traverse (substModule subst) insts
substModule :: Map ModuleName Module -> OpenModule -> InstM Module
substModule subst (OpenModuleVar mod_name)
@@ -346,7 +343,7 @@ toReadyComponents pid_map subst0 comps
then do uid' <- substUnitId Map.empty (ci_id ci)
return $ ci { ci_ann_id = fmap (const (DefiniteUnitId uid')) (ci_ann_id ci) }
else return ci
- exe_deps <- mapM (substExeDep Map.empty) (lc_exe_deps lc)
+ exe_deps <- traverse (substExeDep Map.empty) (lc_exe_deps lc)
let indefc = IndefiniteComponent {
indefc_requires = map fst (lc_insts lc),
indefc_provides = modShapeProvides (lc_shape lc),
diff --git a/cabal/Cabal/Distribution/Backpack/UnifyM.hs b/cabal/Cabal/Distribution/Backpack/UnifyM.hs
index 2d2e559..396354e 100644
--- a/cabal/Cabal/Distribution/Backpack/UnifyM.hs
+++ b/cabal/Cabal/Distribution/Backpack/UnifyM.hs
@@ -60,7 +60,7 @@ import Distribution.Pretty
import Distribution.Types.IncludeRenaming
import Distribution.Types.ComponentInclude
import Distribution.Types.AnnotatedId
-import Distribution.Types.ComponentName
+import Distribution.Types.ModuleRenaming
import Distribution.Verbosity
import Data.STRef
@@ -70,7 +70,6 @@ import qualified Data.Map as Map
import qualified Data.Set as Set
import Data.IntMap (IntMap)
import qualified Data.IntMap as IntMap
-import qualified Data.Traversable as T
import Text.PrettyPrint
-- TODO: more detailed trace output on high verbosity would probably
@@ -321,7 +320,7 @@ convertUnitId' _ (DefiniteUnitId uid) =
convertUnitId' stk (IndefFullUnitId cid insts) = do
fs <- fmap unify_uniq getUnifEnv
x <- liftST $ UnionFind.fresh (error "convertUnitId") -- tie the knot later
- insts_u <- T.forM insts $ convertModule' (extendMuEnv stk x)
+ insts_u <- for insts $ convertModule' (extendMuEnv stk x)
u <- readUnifRef fs
writeUnifRef fs (u+1)
y <- liftST $ UnionFind.fresh (UnitIdU u cid insts_u)
@@ -359,11 +358,11 @@ type ModuleSubstU s = Map ModuleName (ModuleU s)
-- | Conversion of 'ModuleSubst' to 'ModuleSubstU'
convertModuleSubst :: Map ModuleName OpenModule -> UnifyM s (Map ModuleName (ModuleU s))
-convertModuleSubst = T.mapM convertModule
+convertModuleSubst = traverse convertModule
-- | Conversion of 'ModuleSubstU' to 'ModuleSubst'
convertModuleSubstU :: ModuleSubstU s -> UnifyM s OpenModuleSubst
-convertModuleSubstU = T.mapM convertModuleU
+convertModuleSubstU = traverse convertModuleU
-----------------------------------------------------------------------
-- Conversion from the unifiable data types
@@ -400,7 +399,7 @@ convertUnitIdU' stk uid_u = do
failWith (text "Unsupported mutually recursive unit identifier")
-- return (UnitIdVar i)
Nothing -> do
- insts <- T.forM insts_u $ convertModuleU' (extendMooEnv stk u)
+ insts <- for insts_u $ convertModuleU' (extendMooEnv stk u)
return (IndefFullUnitId cid insts)
convertModuleU' :: MooEnv -> ModuleU s -> UnifyM s OpenModule
@@ -615,11 +614,11 @@ convertModuleScopeU (provs_u, reqs_u) = do
-- | Convert a 'ModuleProvides' to a 'ModuleProvidesU'
convertModuleProvides :: ModuleProvides -> UnifyM s (ModuleProvidesU s)
-convertModuleProvides = T.mapM (mapM (T.mapM convertModule))
+convertModuleProvides = traverse (traverse (traverse convertModule))
-- | Convert a 'ModuleProvidesU' to a 'ModuleProvides'
convertModuleProvidesU :: ModuleProvidesU s -> UnifyM s ModuleProvides
-convertModuleProvidesU = T.mapM (mapM (T.mapM convertModuleU))
+convertModuleProvidesU = traverse (traverse (traverse convertModuleU))
convertModuleRequires :: ModuleRequires -> UnifyM s (ModuleRequiresU s)
convertModuleRequires = convertModuleProvides
diff --git a/cabal/Cabal/Distribution/CabalSpecVersion.hs b/cabal/Cabal/Distribution/CabalSpecVersion.hs
index b1f8c2f..8fc89c4 100644
--- a/cabal/Cabal/Distribution/CabalSpecVersion.hs
+++ b/cabal/Cabal/Distribution/CabalSpecVersion.hs
@@ -26,14 +26,19 @@ data CabalSpecVersion
| CabalSpecV2_2
| CabalSpecV2_4
| CabalSpecV3_0
- | CabalSpecV3_2
+ -- 3.2: no changes
+ | CabalSpecV3_4
deriving (Eq, Ord, Show, Read, Enum, Bounded, Typeable, Data, Generic)
+instance Binary CabalSpecVersion
+instance Structured CabalSpecVersion
+instance NFData CabalSpecVersion where rnf = genericRnf
+
-- | Show cabal spec version, but not the way in the .cabal files
--
-- @since 3.0.0.0
showCabalSpecVersion :: CabalSpecVersion -> String
-showCabalSpecVersion CabalSpecV3_2 = "3.2"
+showCabalSpecVersion CabalSpecV3_4 = "3.4"
showCabalSpecVersion CabalSpecV3_0 = "3.0"
showCabalSpecVersion CabalSpecV2_4 = "2.4"
showCabalSpecVersion CabalSpecV2_2 = "2.2"
@@ -51,26 +56,69 @@ showCabalSpecVersion CabalSpecV1_2 = "1.2"
showCabalSpecVersion CabalSpecV1_0 = "1.0"
cabalSpecLatest :: CabalSpecVersion
-cabalSpecLatest = CabalSpecV3_2
+cabalSpecLatest = CabalSpecV3_4
-cabalSpecFromVersionDigits :: [Int] -> CabalSpecVersion
+-- | Parse 'CabalSpecVersion' from version digits.
+--
+-- It may fail if for recent versions the version is not exact.
+--
+cabalSpecFromVersionDigits :: [Int] -> Maybe CabalSpecVersion
cabalSpecFromVersionDigits v
- | v >= [3,1] = CabalSpecV3_2
- | v >= [2,5] = CabalSpecV3_0
- | v >= [2,3] = CabalSpecV2_4
- | v >= [2,1] = CabalSpecV2_2
- | v >= [1,25] = CabalSpecV2_0
- | v >= [1,23] = CabalSpecV1_24
- | v >= [1,21] = CabalSpecV1_22
- | v >= [1,19] = CabalSpecV1_20
- | v >= [1,17] = CabalSpecV1_18
- | v >= [1,11] = CabalSpecV1_12
- | v >= [1,9] = CabalSpecV1_10
- | v >= [1,7] = CabalSpecV1_8
- | v >= [1,5] = CabalSpecV1_6
- | v >= [1,3] = CabalSpecV1_4
- | v >= [1,1] = CabalSpecV1_2
- | otherwise = CabalSpecV1_0
+ | v == [3,4] = Just CabalSpecV3_4
+ | v == [3,0] = Just CabalSpecV3_0
+ | v == [2,4] = Just CabalSpecV2_4
+ | v == [2,2] = Just CabalSpecV2_2
+ | v == [2,0] = Just CabalSpecV2_0
+ | v >= [1,25] = Nothing
+ | v >= [1,23] = Just CabalSpecV1_24
+ | v >= [1,21] = Just CabalSpecV1_22
+ | v >= [1,19] = Just CabalSpecV1_20
+ | v >= [1,17] = Just CabalSpecV1_18
+ | v >= [1,11] = Just CabalSpecV1_12
+ | v >= [1,9] = Just CabalSpecV1_10
+ | v >= [1,7] = Just CabalSpecV1_8
+ | v >= [1,5] = Just CabalSpecV1_6
+ | v >= [1,3] = Just CabalSpecV1_4
+ | v >= [1,1] = Just CabalSpecV1_2
+ | otherwise = Just CabalSpecV1_0
+
+-- | @since 3.4.0.0
+cabalSpecToVersionDigits :: CabalSpecVersion -> [Int]
+cabalSpecToVersionDigits CabalSpecV3_4 = [3,4]
+cabalSpecToVersionDigits CabalSpecV3_0 = [3,0]
+cabalSpecToVersionDigits CabalSpecV2_4 = [2,4]
+cabalSpecToVersionDigits CabalSpecV2_2 = [2,2]
+cabalSpecToVersionDigits CabalSpecV2_0 = [2,0]
+cabalSpecToVersionDigits CabalSpecV1_24 = [1,24]
+cabalSpecToVersionDigits CabalSpecV1_22 = [1,22]
+cabalSpecToVersionDigits CabalSpecV1_20 = [1,20]
+cabalSpecToVersionDigits CabalSpecV1_18 = [1,18]
+cabalSpecToVersionDigits CabalSpecV1_12 = [1,12]
+cabalSpecToVersionDigits CabalSpecV1_10 = [1,10]
+cabalSpecToVersionDigits CabalSpecV1_8 = [1,8]
+cabalSpecToVersionDigits CabalSpecV1_6 = [1,6]
+cabalSpecToVersionDigits CabalSpecV1_4 = [1,4]
+cabalSpecToVersionDigits CabalSpecV1_2 = [1,2]
+cabalSpecToVersionDigits CabalSpecV1_0 = [1,0]
+
+-- | What is the minimum Cabal library version which knows how handle
+-- this spec version.
+--
+-- /Note:/ this is a point where we could decouple cabal-spec and Cabal
+-- versions, if we ever want that.
+--
+-- >>> cabalSpecMinimumLibraryVersion CabalSpecV3_0
+-- [2,5]
+--
+-- >>> cabalSpecMinimumLibraryVersion CabalSpecV2_4
+-- [2,3]
+--
+-- @since 3.4.0.0
+cabalSpecMinimumLibraryVersion :: CabalSpecVersion -> [Int]
+cabalSpecMinimumLibraryVersion CabalSpecV1_0 = [1,0]
+cabalSpecMinimumLibraryVersion csv = case cabalSpecToVersionDigits (pred csv) of
+ [x,y] -> [x, y+1]
+ xs -> xs
specHasCommonStanzas :: CabalSpecVersion -> HasCommonStanzas
specHasCommonStanzas v =
diff --git a/cabal/Cabal/Distribution/Compat/Async.hs b/cabal/Cabal/Distribution/Compat/Async.hs
index a0b36ca..a264497 100644
--- a/cabal/Cabal/Distribution/Compat/Async.hs
+++ b/cabal/Cabal/Distribution/Compat/Async.hs
@@ -6,6 +6,8 @@
-- Copyright (c) 2012, Simon Marlow
-- Licensed under BSD-3-Clause
--
+-- @since 3.2.0.0
+--
module Distribution.Compat.Async (
AsyncM,
withAsync, waitCatch,
diff --git a/cabal/Cabal/Distribution/Compat/Binary.hs b/cabal/Cabal/Distribution/Compat/Binary.hs
index 5bd22db..6f5d7fe 100644
--- a/cabal/Cabal/Distribution/Compat/Binary.hs
+++ b/cabal/Cabal/Distribution/Compat/Binary.hs
@@ -18,12 +18,7 @@ module Distribution.Compat.Binary
#endif
) where
-import Control.Exception (catch, evaluate)
-#if __GLASGOW_HASKELL__ >= 711
-import Control.Exception (pattern ErrorCall)
-#else
-import Control.Exception (ErrorCall(..))
-#endif
+import Control.Exception (ErrorCall (..), catch, evaluate)
import Data.ByteString.Lazy (ByteString)
#if __GLASGOW_HASKELL__ >= 708 || MIN_VERSION_binary(0,7,0)
@@ -67,5 +62,10 @@ encodeFile f = BSL.writeFile f . encode
decodeOrFailIO :: Binary a => ByteString -> IO (Either String a)
decodeOrFailIO bs =
- catch (evaluate (decode bs) >>= return . Right)
- $ \(ErrorCall str) -> return $ Left str
+ catch (evaluate (decode bs) >>= return . Right) handler
+ where
+#if MIN_VERSION_base(4,9,0)
+ handler (ErrorCallWithLocation str _) = return $ Left str
+#else
+ handler (ErrorCall str) = return $ Left str
+#endif
diff --git a/cabal/Cabal/Distribution/Compat/CharParsing.hs b/cabal/Cabal/Distribution/Compat/CharParsing.hs
index a6460f2..688343d 100644
--- a/cabal/Cabal/Distribution/Compat/CharParsing.hs
+++ b/cabal/Cabal/Distribution/Compat/CharParsing.hs
@@ -38,6 +38,7 @@ module Distribution.Compat.CharParsing
, CharParsing(..)
-- * Cabal additions
, integral
+ , signedIntegral
, munch1
, munch
, skipSpaces1
@@ -331,6 +332,14 @@ integral = toNumber <$> some d <?> "integral"
f _ = error "panic! integral"
{-# INLINE integral #-}
+-- | Accepts negative (starting with @-@) and positive (without sign) integral
+-- numbers.
+--
+-- @since 3.4.0.0
+signedIntegral :: (CharParsing m, Integral a) => m a
+signedIntegral = negate <$ char '-' <*> integral <|> integral
+{-# INLINE signedIntegral #-}
+
-- | Greedily munch characters while predicate holds.
-- Require at least one character.
munch1 :: CharParsing m => (Char -> Bool) -> m String
diff --git a/cabal/Cabal/Distribution/Compat/CopyFile.hs b/cabal/Cabal/Distribution/Compat/CopyFile.hs
index 341975c..7a9762f 100644
--- a/cabal/Cabal/Distribution/Compat/CopyFile.hs
+++ b/cabal/Cabal/Distribution/Compat/CopyFile.hs
@@ -14,13 +14,11 @@ module Distribution.Compat.CopyFile (
import Prelude ()
import Distribution.Compat.Prelude
-import Distribution.Compat.Exception
-
#ifndef mingw32_HOST_OS
import Distribution.Compat.Internal.TempFile
import Control.Exception
- ( bracketOnError, throwIO )
+ ( bracketOnError )
import qualified Data.ByteString.Lazy as BSL
import System.IO.Error
( ioeSetLocation )
@@ -43,8 +41,6 @@ import Foreign.C
#else /* else mingw32_HOST_OS */
-import Control.Exception
- ( throwIO )
import qualified Data.ByteString.Lazy as BSL
import System.IO.Error
( ioeSetLocation )
@@ -69,16 +65,16 @@ import System.IO
import qualified System.Win32.File as Win32 ( copyFile )
#endif /* mingw32_HOST_OS */
-copyOrdinaryFile, copyExecutableFile :: FilePath -> FilePath -> NoCallStackIO ()
+copyOrdinaryFile, copyExecutableFile :: FilePath -> FilePath -> IO ()
copyOrdinaryFile src dest = copyFile src dest >> setFileOrdinary dest
copyExecutableFile src dest = copyFile src dest >> setFileExecutable dest
-setFileOrdinary, setFileExecutable, setDirOrdinary :: FilePath -> NoCallStackIO ()
+setFileOrdinary, setFileExecutable, setDirOrdinary :: FilePath -> IO ()
#ifndef mingw32_HOST_OS
setFileOrdinary path = setFileMode path 0o644 -- file perms -rw-r--r--
setFileExecutable path = setFileMode path 0o755 -- file perms -rwxr-xr-x
-setFileMode :: FilePath -> FileMode -> NoCallStackIO ()
+setFileMode :: FilePath -> FileMode -> IO ()
setFileMode name m =
withFilePath name $ \s -> do
throwErrnoPathIfMinus1_ "setFileMode" name (c_chmod s m)
@@ -91,7 +87,7 @@ setDirOrdinary = setFileExecutable
-- | Copies a file to a new destination.
-- Often you should use `copyFileChanged` instead.
-copyFile :: FilePath -> FilePath -> NoCallStackIO ()
+copyFile :: FilePath -> FilePath -> IO ()
copyFile fromFPath toFPath =
copy
`catchIO` (\ioe -> throwIO (ioeSetLocation ioe "copyFile"))
@@ -229,7 +225,7 @@ emptyToCurDir path = path
-- | Like `copyFile`, but does not touch the target if source and destination
-- are already byte-identical. This is recommended as it is useful for
-- time-stamp based recompilation avoidance.
-copyFileChanged :: FilePath -> FilePath -> NoCallStackIO ()
+copyFileChanged :: FilePath -> FilePath -> IO ()
copyFileChanged src dest = do
equal <- filesEqual src dest
unless equal $ copyFile src dest
@@ -237,7 +233,7 @@ copyFileChanged src dest = do
-- | Checks if two files are byte-identical.
-- Returns False if either of the files do not exist or if files
-- are of different size.
-filesEqual :: FilePath -> FilePath -> NoCallStackIO Bool
+filesEqual :: FilePath -> FilePath -> IO Bool
filesEqual f1 f2 = do
ex1 <- doesFileExist f1
ex2 <- doesFileExist f2
diff --git a/cabal/Cabal/Distribution/Compat/CreatePipe.hs b/cabal/Cabal/Distribution/Compat/CreatePipe.hs
index b9e3267..f3b18fa 100644
--- a/cabal/Cabal/Distribution/Compat/CreatePipe.hs
+++ b/cabal/Cabal/Distribution/Compat/CreatePipe.hs
@@ -4,7 +4,10 @@
module Distribution.Compat.CreatePipe (createPipe) where
-import System.IO (Handle, hSetEncoding, localeEncoding)
+#if MIN_VERSION_process(1,2,1)
+import System.Process (createPipe)
+#else
+import System.IO (Handle, hSetBinaryMode)
import Prelude ()
import Distribution.Compat.Prelude
@@ -40,11 +43,11 @@ createPipe = do
return (readfd, writefd)
(do readh <- fdToHandle readfd ReadMode
writeh <- fdToHandle writefd WriteMode
- hSetEncoding readh localeEncoding
- hSetEncoding writeh localeEncoding
+ hSetBinaryMode readh True
+ hSetBinaryMode writeh True
return (readh, writeh)) `onException` (close readfd >> close writefd)
where
- fdToHandle :: CInt -> IOMode -> NoCallStackIO Handle
+ fdToHandle :: CInt -> IOMode -> IO Handle
fdToHandle fd mode = do
(fd', deviceType) <- mkFD fd mode (Just (Stream, 0, 0)) False False
mkHandleFromFD fd' deviceType "" mode False Nothing
@@ -69,9 +72,10 @@ createPipe = do
(readfd, writefd) <- Posix.createPipe
readh <- fdToHandle readfd
writeh <- fdToHandle writefd
- hSetEncoding readh localeEncoding
- hSetEncoding writeh localeEncoding
+ hSetBinaryMode readh True
+ hSetBinaryMode writeh True
return (readh, writeh)
where
_ = callStack
#endif
+#endif
diff --git a/cabal/Cabal/Distribution/Compat/DList.hs b/cabal/Cabal/Distribution/Compat/DList.hs
index 55a1b8c..d326420 100644
--- a/cabal/Cabal/Distribution/Compat/DList.hs
+++ b/cabal/Cabal/Distribution/Compat/DList.hs
@@ -12,6 +12,7 @@
module Distribution.Compat.DList (
DList,
runDList,
+ empty,
singleton,
fromList,
toList,
@@ -19,7 +20,7 @@ module Distribution.Compat.DList (
) where
import Prelude ()
-import Distribution.Compat.Prelude hiding (toList)
+import Distribution.Compat.Prelude hiding (toList, empty)
-- | Difference list.
newtype DList a = DList ([a] -> [a])
@@ -31,6 +32,10 @@ runDList (DList run) = run []
singleton :: a -> DList a
singleton a = DList (a:)
+-- | @since 3.4.0.0
+empty :: DList a
+empty = DList id
+
fromList :: [a] -> DList a
fromList as = DList (as ++)
@@ -41,7 +46,7 @@ snoc :: DList a -> a -> DList a
snoc xs x = xs <> singleton x
instance Monoid (DList a) where
- mempty = DList id
+ mempty = empty
mappend = (<>)
instance Semigroup (DList a) where
diff --git a/cabal/Cabal/Distribution/Compat/Environment.hs b/cabal/Cabal/Distribution/Compat/Environment.hs
index 8c64e68..cc26ccf 100644
--- a/cabal/Cabal/Distribution/Compat/Environment.hs
+++ b/cabal/Cabal/Distribution/Compat/Environment.hs
@@ -39,7 +39,7 @@ import Foreign.C.Error (throwErrnoIfMinus1_)
import System.Posix.Internals ( withFilePath )
#endif /* mingw32_HOST_OS */
-getEnvironment :: NoCallStackIO [(String, String)]
+getEnvironment :: IO [(String, String)]
#ifdef mingw32_HOST_OS
-- On Windows, the names of environment variables are case-insensitive, but are
-- often given in mixed-case (e.g. "PATH" is "Path"), so we have to normalise
diff --git a/cabal/Cabal/Distribution/Compat/Exception.hs b/cabal/Cabal/Distribution/Compat/Exception.hs
index c7a4ccd..b3b0282 100644
--- a/cabal/Cabal/Distribution/Compat/Exception.hs
+++ b/cabal/Cabal/Distribution/Compat/Exception.hs
@@ -6,22 +6,32 @@ module Distribution.Compat.Exception (
displayException,
) where
+#ifdef MIN_VERSION_base
+#define MINVER_base_48 MIN_VERSION_base(4,8,0)
+#else
+#define MINVER_base_48 (__GLASGOW_HASKELL__ >= 710)
+#endif
+
import System.Exit
import qualified Control.Exception as Exception
-#if __GLASGOW_HASKELL__ >= 710
+
+#if MINVER_base_48
import Control.Exception (displayException)
#endif
+-- | Try 'IOException'.
tryIO :: IO a -> IO (Either Exception.IOException a)
tryIO = Exception.try
+-- | Catch 'IOException'.
catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
catchIO = Exception.catch
+-- | Catch 'ExitCode'
catchExit :: IO a -> (ExitCode -> IO a) -> IO a
catchExit = Exception.catch
-#if __GLASGOW_HASKELL__ < 710
+#if !MINVER_base_48
displayException :: Exception.Exception e => e -> String
displayException = show
#endif
diff --git a/cabal/Cabal/Distribution/Compat/GetShortPathName.hs b/cabal/Cabal/Distribution/Compat/GetShortPathName.hs
index eebad98..baf402c 100644
--- a/cabal/Cabal/Distribution/Compat/GetShortPathName.hs
+++ b/cabal/Cabal/Distribution/Compat/GetShortPathName.hs
@@ -40,7 +40,7 @@ foreign import WINAPI unsafe "windows.h GetShortPathNameW"
-- will always return the required buffer size for a
-- specified lpszLongPath.
--
-getShortPathName :: FilePath -> NoCallStackIO FilePath
+getShortPathName :: FilePath -> IO FilePath
getShortPathName path =
Win32.withTString path $ \c_path -> do
c_len <- Win32.failIfZero "GetShortPathName #1 failed!" $
@@ -53,7 +53,7 @@ getShortPathName path =
#else
-getShortPathName :: FilePath -> NoCallStackIO FilePath
+getShortPathName :: FilePath -> IO FilePath
getShortPathName path = return path
#endif
diff --git a/cabal/Cabal/Distribution/Compat/Graph.hs b/cabal/Cabal/Distribution/Compat/Graph.hs
index dce3c6c..a326b0c 100644
--- a/cabal/Cabal/Distribution/Compat/Graph.hs
+++ b/cabal/Cabal/Distribution/Compat/Graph.hs
@@ -1,9 +1,10 @@
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
-{-# LANGUAGE BangPatterns #-}
-----------------------------------------------------------------------------
-- |
-- Module : Distribution.Compat.Graph
@@ -83,20 +84,20 @@ module Distribution.Compat.Graph (
nodeValue,
) where
+import Distribution.Compat.Prelude hiding (empty, lookup, null, toList)
import Prelude ()
-import qualified Distribution.Compat.Prelude as Prelude
-import Distribution.Compat.Prelude hiding (lookup, null, empty, toList)
-import Data.Graph (SCC(..))
-import qualified Data.Graph as G
+import Data.Array ((!))
+import Data.Graph (SCC (..))
+import Distribution.Utils.Structured (Structure (..), Structured (..))
-import qualified Data.Map.Strict as Map
-import qualified Data.Set as Set
-import qualified Data.Array as Array
-import Data.Array ((!))
-import qualified Data.Tree as Tree
-import Data.Either (partitionEithers)
-import qualified Data.Foldable as Foldable
+import qualified Data.Array as Array
+import qualified Data.Foldable as Foldable
+import qualified Data.Graph as G
+import qualified Data.Map.Strict as Map
+import qualified Data.Set as Set
+import qualified Data.Tree as Tree
+import qualified Distribution.Compat.Prelude as Prelude
-- | A graph of nodes @a@. The nodes are expected to have instance
-- of class 'IsNode'.
@@ -129,6 +130,9 @@ instance (IsNode a, Binary a, Show (Key a)) => Binary (Graph a) where
put x = put (toList x)
get = fmap fromDistinctList get
+instance Structured a => Structured (Graph a) where
+ structure p = Nominal (typeRep p) 0 "Graph" [structure (Proxy :: Proxy a)]
+
instance (Eq (Key a), Eq a) => Eq (Graph a) where
g1 == g2 = graphMap g1 == graphMap g2
diff --git a/cabal/Cabal/Distribution/Compat/Internal/TempFile.hs b/cabal/Cabal/Distribution/Compat/Internal/TempFile.hs
index dee86eb..bf967ec 100644
--- a/cabal/Cabal/Distribution/Compat/Internal/TempFile.hs
+++ b/cabal/Cabal/Distribution/Compat/Internal/TempFile.hs
@@ -10,16 +10,21 @@ module Distribution.Compat.Internal.TempFile (
import Distribution.Compat.Exception
import System.FilePath ((</>))
-import Foreign.C (CInt, eEXIST, getErrno, errnoToIOError)
import System.IO (Handle, openTempFile, openBinaryTempFile)
+#if defined(__IO_MANAGER_WINIO__)
+import System.IO (openBinaryTempFileWithDefaultPermissions)
+#else
+import Control.Exception (onException)
import Data.Bits ((.|.))
-import System.Posix.Internals (c_open, c_close, o_CREAT, o_EXCL, o_RDWR,
- o_BINARY, o_NONBLOCK, o_NOCTTY,
- withFilePath, c_getpid)
-import System.IO.Error (isAlreadyExistsError)
+import Foreign.C (CInt, eEXIST, getErrno, errnoToIOError)
import GHC.IO.Handle.FD (fdToHandle)
-import Control.Exception (onException)
+import System.Posix.Internals (c_open, c_close, o_EXCL, o_BINARY, withFilePath,
+ o_CREAT, o_RDWR, o_NONBLOCK, o_NOCTTY)
+#endif
+
+import System.Posix.Internals (c_getpid)
+import System.IO.Error (isAlreadyExistsError)
#if defined(mingw32_HOST_OS) || defined(ghcjs_HOST_OS)
import System.Directory ( createDirectory )
@@ -36,10 +41,17 @@ import qualified System.Posix
-- TODO: This file should probably be removed.
-- This is a copy/paste of the openBinaryTempFile definition, but
--- if uses 666 rather than 600 for the permissions. The base library
--- needs to be changed to make this better.
+-- it uses 666 rather than 600 for the permissions. Newer versions
+-- of base have a new function with this behavior which we use on
+-- Windows when the new IO manager is used.
openNewBinaryFile :: FilePath -> String -> IO (FilePath, Handle)
openNewBinaryFile dir template = do
+ -- This method can't be used under WINIO. Also the current implementation has
+ -- thread safety issues depending on which GHC is used. On newer GHC's let's
+ -- use the built in one.
+#if defined(__IO_MANAGER_WINIO__)
+ openBinaryTempFileWithDefaultPermissions dir template
+#else
pid <- c_getpid
findTempName pid
where
@@ -88,6 +100,12 @@ openNewBinaryFile dir template = do
| last a == pathSeparator = a ++ b
| otherwise = a ++ [pathSeparator] ++ b
+-- FIXME: Copied from GHC.Handle
+std_flags, output_flags, rw_flags :: CInt
+std_flags = o_NONBLOCK .|. o_NOCTTY
+output_flags = std_flags .|. o_CREAT
+rw_flags = output_flags .|. o_RDWR
+
-- FIXME: Should use System.FilePath library
pathSeparator :: Char
#ifdef mingw32_HOST_OS
@@ -95,12 +113,8 @@ pathSeparator = '\\'
#else
pathSeparator = '/'
#endif
-
--- FIXME: Copied from GHC.Handle
-std_flags, output_flags, rw_flags :: CInt
-std_flags = o_NONBLOCK .|. o_NOCTTY
-output_flags = std_flags .|. o_CREAT
-rw_flags = output_flags .|. o_RDWR
+-- /* __IO_MANAGER_WINIO__ */
+#endif
createTempDirectory :: FilePath -> String -> IO FilePath
createTempDirectory dir template = do
diff --git a/cabal/Cabal/Distribution/Compat/Lens.hs b/cabal/Cabal/Distribution/Compat/Lens.hs
index 748c23d..2ea10e6 100644
--- a/cabal/Cabal/Distribution/Compat/Lens.hs
+++ b/cabal/Cabal/Distribution/Compat/Lens.hs
@@ -50,7 +50,6 @@ module Distribution.Compat.Lens (
import Prelude()
import Distribution.Compat.Prelude
-import Control.Applicative (Const (..))
import Control.Monad.State.Class (MonadState (..), gets, modify)
import qualified Distribution.Compat.DList as DList
diff --git a/cabal/Cabal/Distribution/Compat/NonEmptySet.hs b/cabal/Cabal/Distribution/Compat/NonEmptySet.hs
new file mode 100644
index 0000000..54a4ece
--- /dev/null
+++ b/cabal/Cabal/Distribution/Compat/NonEmptySet.hs
@@ -0,0 +1,155 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+module Distribution.Compat.NonEmptySet (
+ NonEmptySet,
+ -- * Construction
+ singleton,
+ -- * Insertion
+ insert,
+ -- * Deletion
+ delete,
+ -- * Conversions
+ toNonEmpty,
+ fromNonEmpty,
+ toList,
+ toSet,
+ -- * Query
+ member,
+ -- * Map
+ map,
+) where
+
+import Prelude (Bool (..), Eq, Maybe (..), Ord (..), Read, Show (..), String, error, otherwise, return, showParen, showString, ($), (++), (.))
+
+import Control.DeepSeq (NFData (..))
+import Data.Data (Data)
+import Data.List.NonEmpty (NonEmpty (..))
+import Data.Semigroup (Semigroup (..))
+import Data.Typeable (Typeable)
+
+import qualified Data.Foldable as F
+import qualified Data.Set as Set
+
+import Distribution.Compat.Binary (Binary (..))
+import Distribution.Utils.Structured
+
+#if MIN_VERSION_binary(0,6,0)
+import Control.Applicative (empty)
+#else
+import Control.Monad (fail)
+#endif
+
+-- | @since 3.4.0.0
+newtype NonEmptySet a = NES (Set.Set a)
+ deriving (Eq, Ord, Typeable, Data, Read)
+
+-------------------------------------------------------------------------------
+-- Instances
+-------------------------------------------------------------------------------
+
+instance Show a => Show (NonEmptySet a) where
+ showsPrec d s = showParen (d > 10)
+ $ showString "fromNonEmpty "
+ . showsPrec 11 (toNonEmpty s)
+
+instance Binary a => Binary (NonEmptySet a) where
+ put (NES s) = put s
+ get = do
+ xs <- get
+ if Set.null xs
+#if MIN_VERSION_binary(0,6,0)
+ then empty
+#else
+ then fail "NonEmptySet: empty"
+#endif
+ else return (NES xs)
+
+instance Structured a => Structured (NonEmptySet a) where
+ structure = containerStructure
+
+instance NFData a => NFData (NonEmptySet a) where
+ rnf (NES x) = rnf x
+
+-- | Note: there aren't @Monoid@ instance.
+instance Ord a => Semigroup (NonEmptySet a) where
+ NES x <> NES y = NES (Set.union x y)
+
+instance F.Foldable NonEmptySet where
+ foldMap f (NES s) = F.foldMap f s
+ foldr f z (NES s) = F.foldr f z s
+
+#if MIN_VERSION_base(4,8,0)
+ toList = toList
+ null _ = False
+ length (NES s) = F.length s
+#endif
+
+-------------------------------------------------------------------------------
+-- Constructors
+-------------------------------------------------------------------------------
+
+singleton :: a -> NonEmptySet a
+singleton = NES . Set.singleton
+
+-------------------------------------------------------------------------------
+-- Insertion
+-------------------------------------------------------------------------------
+
+insert :: Ord a => a -> NonEmptySet a -> NonEmptySet a
+insert x (NES xs) = NES (Set.insert x xs)
+
+-------------------------------------------------------------------------------
+-- Deletion
+-------------------------------------------------------------------------------
+
+delete :: Ord a => a -> NonEmptySet a -> Maybe (NonEmptySet a)
+delete x (NES xs)
+ | Set.null res = Nothing
+ | otherwise = Just (NES xs)
+ where
+ res = Set.delete x xs
+
+-------------------------------------------------------------------------------
+-- Conversions
+-------------------------------------------------------------------------------
+
+fromNonEmpty :: Ord a => NonEmpty a -> NonEmptySet a
+fromNonEmpty (x :| xs) = NES (Set.fromList (x : xs))
+
+toNonEmpty :: NonEmptySet a -> NonEmpty a
+toNonEmpty (NES s) = case Set.toList s of
+ [] -> panic "toNonEmpty"
+ x:xs -> x :| xs
+
+toList :: NonEmptySet a -> [a]
+toList (NES s) = Set.toList s
+
+toSet :: NonEmptySet a -> Set.Set a
+toSet (NES s) = s
+
+-------------------------------------------------------------------------------
+-- Query
+-------------------------------------------------------------------------------
+
+member :: Ord a => a -> NonEmptySet a -> Bool
+member x (NES xs) = Set.member x xs
+
+-------------------------------------------------------------------------------
+-- Map
+-------------------------------------------------------------------------------
+
+map
+ :: ( Ord b
+#if !MIN_VERSION_containers(0,5,2)
+ , Ord a
+#endif
+ )
+ => (a -> b) -> NonEmptySet a -> NonEmptySet b
+map f (NES x) = NES (Set.map f x)
+
+-------------------------------------------------------------------------------
+-- Internal
+-------------------------------------------------------------------------------
+
+panic :: String -> a
+panic msg = error $ "NonEmptySet invariant violated: " ++ msg
diff --git a/cabal/Cabal/Distribution/Compat/Prelude.hs b/cabal/Cabal/Distribution/Compat/Prelude.hs
index e71ec19..edc7eb3 100644
--- a/cabal/Cabal/Distribution/Compat/Prelude.hs
+++ b/cabal/Cabal/Distribution/Compat/Prelude.hs
@@ -1,7 +1,8 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE Trustworthy #-}
+{-# LANGUAGE TypeOperators #-}
#ifdef MIN_VERSION_base
#define MINVER_base_411 MIN_VERSION_base(4,11,0)
@@ -33,21 +34,27 @@ module Distribution.Compat.Prelude (
-- * Common type-classes
Semigroup (..),
gmappend, gmempty,
- Typeable,
+ Typeable, TypeRep, typeRep,
Data,
Generic,
NFData (..), genericRnf,
Binary (..),
+ Structured,
Alternative (..),
MonadPlus (..),
IsString (..),
-- * Some types
- IO, NoCallStackIO,
Map,
Set,
+ NonEmptySet,
Identity (..),
Proxy (..),
+ Const (..),
+ Void,
+
+ -- * Data.Either
+ partitionEithers,
-- * Data.Maybe
catMaybes, mapMaybe,
@@ -61,6 +68,7 @@ module Distribution.Compat.Prelude (
intercalate, intersperse,
sort, sortBy,
nub, nubBy,
+ partition,
-- * Data.List.NonEmpty
NonEmpty((:|)), foldl1, foldr1,
@@ -78,6 +86,12 @@ module Distribution.Compat.Prelude (
Traversable, traverse, sequenceA,
for,
+ -- * Data.Function
+ on,
+
+ -- * Data.Ord
+ comparing,
+
-- * Control.Arrow
first,
@@ -86,26 +100,49 @@ module Distribution.Compat.Prelude (
unless, when,
ap, void,
foldM, filterM,
+ join, guard,
+
+ -- * Control.Exception
+ catch, throwIO, evaluate,
+ Exception (..), IOException, SomeException (..),
+#if !MINVER_base_48
+ displayException,
+#endif
+ tryIO, catchIO, catchExit,
+
+ -- * Control.DeepSeq
+ deepseq, force,
-- * Data.Char
isSpace, isDigit, isUpper, isAlpha, isAlphaNum,
chr, ord,
toLower, toUpper,
+ -- * Data.Void
+ absurd, vacuous,
+
-- * Data.Word & Data.Int
Word,
Word8, Word16, Word32, Word64,
Int8, Int16, Int32, Int64,
-- * Text.PrettyPrint
- (<<>>),
+ (<<>>), (Disp.<+>),
+
+ -- * System.Exit
+ ExitCode (..),
+ exitWith, exitSuccess, exitFailure,
-- * Text.Read
readMaybe,
+
+ -- * Debug.Trace (as deprecated functions)
+ trace, traceShow, traceShowId,
) where
+
-- We also could hide few partial function
import Prelude as BasePrelude hiding
- ( IO, mapM, mapM_, sequence, null, length, foldr, any, all, head, tail, last, init
+ ( mapM, mapM_, sequence, null, length, foldr, any, all, head, tail, last, init
-- partial functions
, read
, foldr1, foldl1
@@ -122,53 +159,57 @@ import Prelude as BasePrelude hiding
#endif
)
+-- AMP
#if !MINVER_base_48
import Control.Applicative (Applicative (..), (<$), (<$>))
-import Distribution.Compat.Semigroup (Monoid (..))
import Data.Foldable (toList)
+import Distribution.Compat.Semigroup (Monoid (..))
#else
-import Data.Foldable (length, null, Foldable(toList))
+import Data.Foldable (Foldable (toList), length, null)
#endif
-import Data.Foldable (Foldable (foldMap, foldr), find, foldl', for_, traverse_, any, all)
-import Data.Traversable (Traversable (traverse, sequenceA), for)
+import Data.Foldable (Foldable (foldMap, foldr), all, any, find, foldl', for_, traverse_)
+import Data.Traversable (Traversable (sequenceA, traverse), for)
+
import qualified Data.Foldable
+-- Extra exports
import Control.Applicative (Alternative (..))
-import Control.DeepSeq (NFData (..))
+import Control.Applicative (Const (..))
+import Control.Arrow (first)
+import Control.DeepSeq (NFData (..), deepseq, force)
+import Control.Exception (Exception (..), IOException, SomeException (..), catch, evaluate, throwIO)
+import Control.Monad (MonadPlus (..), ap, filterM, foldM, guard, join, liftM, liftM2, unless, void, when)
+import Data.Char (chr, isAlpha, isAlphaNum, isDigit, isSpace, isUpper, ord, toLower, toUpper)
import Data.Data (Data)
-import Data.Typeable (Typeable)
-import Distribution.Compat.Binary (Binary (..))
-import Distribution.Compat.Semigroup (Semigroup (..), gmappend, gmempty)
-import GHC.Generics (Generic, Rep(..),
- V1, U1(U1), K1(unK1), M1(unM1),
- (:*:)((:*:)), (:+:)(L1,R1))
-
+import Data.Either (partitionEithers)
+import Data.Function (on)
import Data.Functor.Identity (Identity (..))
+import Data.Int (Int16, Int32, Int64, Int8)
+import Data.List (intercalate, intersperse, isPrefixOf, isSuffixOf, nub, nubBy, partition, sort, sortBy, unfoldr)
+import Data.List.NonEmpty (NonEmpty ((:|)), head, init, last, tail)
import Data.Map (Map)
+import Data.Maybe (catMaybes, fromMaybe, isJust, isNothing, listToMaybe, mapMaybe, maybeToList)
+import Data.Ord (comparing)
import Data.Proxy (Proxy (..))
import Data.Set (Set)
-
-import Control.Arrow (first)
-import Control.Monad hiding (mapM)
-import Data.Char
-import Data.List (intercalate, intersperse, isPrefixOf,
- isSuffixOf, nub, nubBy, sort, sortBy,
- unfoldr)
-import Data.List.NonEmpty (NonEmpty((:|)), head, tail, init, last)
-import Data.Maybe
import Data.String (IsString (..))
-import Data.Int
-import Data.Word
+import Data.Void (Void, absurd, vacuous)
+import Data.Word (Word, Word16, Word32, Word64, Word8)
+import Distribution.Compat.Binary (Binary (..))
+import Distribution.Compat.Semigroup (Semigroup (..), gmappend, gmempty)
+import Distribution.Compat.Typeable (TypeRep, Typeable, typeRep)
+import GHC.Generics ((:*:) ((:*:)), (:+:) (L1, R1), Generic, K1 (unK1), M1 (unM1), Rep (..), U1 (U1), V1)
+import System.Exit (ExitCode (..), exitFailure, exitSuccess, exitWith)
import Text.Read (readMaybe)
import qualified Text.PrettyPrint as Disp
-import qualified Prelude as OrigPrelude
-import Distribution.Compat.Stack
+import Distribution.Compat.Exception
+import Distribution.Compat.NonEmptySet (NonEmptySet)
+import Distribution.Utils.Structured (Structured)
-type IO a = WithCallStack (OrigPrelude.IO a)
-type NoCallStackIO a = OrigPrelude.IO a
+import qualified Debug.Trace
-- | New name for 'Text.PrettyPrint.<>'
(<<>>) :: Disp.Doc -> Disp.Doc -> Disp.Doc
@@ -254,3 +295,22 @@ foldr1 = Data.Foldable.foldr1
{-# INLINE foldl1 #-}
foldl1 :: (a -> a -> a) -> NonEmpty a -> a
foldl1 = Data.Foldable.foldl1
+
+-------------------------------------------------------------------------------
+-- Trace
+-------------------------------------------------------------------------------
+
+-- Functions from Debug.Trace
+-- but with DEPRECATED pragma, so -Werror will scream on them.
+
+trace :: String -> a -> a
+trace = Debug.Trace.trace
+{-# DEPRECATED trace "Don't leave me in the code" #-}
+
+traceShowId :: Show a => a -> a
+traceShowId x = Debug.Trace.traceShow x x
+{-# DEPRECATED traceShowId "Don't leave me in the code" #-}
+
+traceShow :: Show a => a -> b -> b
+traceShow = Debug.Trace.traceShow
+{-# DEPRECATED traceShow "Don't leave me in the code" #-}
diff --git a/cabal/Cabal/Distribution/Compat/Process.hs b/cabal/Cabal/Distribution/Compat/Process.hs
new file mode 100644
index 0000000..0862a9f
--- /dev/null
+++ b/cabal/Cabal/Distribution/Compat/Process.hs
@@ -0,0 +1,82 @@
+{-# LANGUAGE CPP #-}
+module Distribution.Compat.Process (
+ -- * Redefined functions
+ createProcess,
+ runInteractiveProcess,
+ rawSystem,
+ -- * Additions
+ enableProcessJobs,
+ ) where
+
+import System.Exit (ExitCode (..))
+import System.IO (Handle)
+
+import System.Process (CreateProcess, ProcessHandle)
+import qualified System.Process as Process
+
+#if MIN_VERSION_process(1,2,0)
+import System.Process (waitForProcess)
+#endif
+
+-------------------------------------------------------------------------------
+-- enableProcessJobs
+-------------------------------------------------------------------------------
+
+-- | Enable process jobs to ensure accurate determination of process completion
+-- in the presence of @exec(3)@ on Windows.
+--
+-- Unfortunately the process job support is badly broken in @process@ releases
+-- prior to 1.6.8, so we disable it in these versions, despite the fact that
+-- this means we may see sporatic build failures without jobs.
+enableProcessJobs :: CreateProcess -> CreateProcess
+#ifdef MIN_VERSION_process
+#if MIN_VERSION_process(1,6,8)
+enableProcessJobs cp = cp {Process.use_process_jobs = True}
+#else
+enableProcessJobs cp = cp
+#endif
+#else
+enableProcessJobs cp = cp
+#endif
+
+-------------------------------------------------------------------------------
+-- process redefinitions
+-------------------------------------------------------------------------------
+
+-- | 'System.Process.createProcess' with process jobs enabled when appropriate.
+-- See 'enableProcessJobs'.
+createProcess :: CreateProcess
+ -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
+createProcess = Process.createProcess . enableProcessJobs
+
+-- | 'System.Process.rawSystem' with process jobs enabled when appropriate.
+-- See 'enableProcessJobs'.
+rawSystem :: String -> [String] -> IO ExitCode
+rawSystem cmd args = do
+#if MIN_VERSION_process(1,2,0)
+ (_,_,_,p) <- createProcess (Process.proc cmd args) { Process.delegate_ctlc = True }
+ waitForProcess p
+#else
+ -- With very old 'process', just do its rawSystem
+ Process.rawSystem cmd args
+#endif
+
+-- | 'System.Process.runInteractiveProcess' with process jobs enabled when
+-- appropriate. See 'enableProcessJobs'.
+runInteractiveProcess
+ :: FilePath -- ^ Filename of the executable (see 'RawCommand' for details)
+ -> [String] -- ^ Arguments to pass to the executable
+ -> Maybe FilePath -- ^ Optional path to the working directory
+ -> Maybe [(String,String)] -- ^ Optional environment (otherwise inherit)
+ -> IO (Handle,Handle,Handle,ProcessHandle)
+runInteractiveProcess cmd args mb_cwd mb_env = do
+ (mb_in, mb_out, mb_err, p) <-
+ createProcess (Process.proc cmd args)
+ { Process.std_in = Process.CreatePipe,
+ Process.std_out = Process.CreatePipe,
+ Process.std_err = Process.CreatePipe,
+ Process.env = mb_env,
+ Process.cwd = mb_cwd }
+ return (fromJust mb_in, fromJust mb_out, fromJust mb_err, p)
+ where
+ fromJust = maybe (error "runInteractiveProcess: fromJust") id
diff --git a/cabal/Cabal/Distribution/Compat/ResponseFile.hs b/cabal/Cabal/Distribution/Compat/ResponseFile.hs
index 5ddfe57..db0a929 100755..100644
--- a/cabal/Cabal/Distribution/Compat/ResponseFile.hs
+++ b/cabal/Cabal/Distribution/Compat/ResponseFile.hs
@@ -1,68 +1,67 @@
-{-# LANGUAGE CPP, RankNTypes, FlexibleContexts #-}
-
--- Compatibility layer for GHC.ResponseFile
--- Implementation from base 4.12.0 is used.
--- http://hackage.haskell.org/package/base-4.12.0.0/src/LICENSE
-module Distribution.Compat.ResponseFile (expandResponse) where
-
-import Prelude (mapM)
-import Distribution.Compat.Prelude
-
-import System.Exit
-import System.FilePath
-import System.IO (hPutStrLn, stderr)
-import System.IO.Error
-
-#if MIN_VERSION_base(4,12,0)
-import GHC.ResponseFile (unescapeArgs)
-#else
-
-unescapeArgs :: String -> [String]
-unescapeArgs = filter (not . null) . unescape
-
-data Quoting = NoneQ | SngQ | DblQ
-
-unescape :: String -> [String]
-unescape args = reverse . map reverse $ go args NoneQ False [] []
- where
- -- n.b., the order of these cases matters; these are cribbed from gcc
- -- case 1: end of input
- go [] _q _bs a as = a:as
- -- case 2: back-slash escape in progress
- go (c:cs) q True a as = go cs q False (c:a) as
- -- case 3: no back-slash escape in progress, but got a back-slash
- go (c:cs) q False a as
- | '\\' == c = go cs q True a as
- -- case 4: single-quote escaping in progress
- go (c:cs) SngQ False a as
- | '\'' == c = go cs NoneQ False a as
- | otherwise = go cs SngQ False (c:a) as
- -- case 5: double-quote escaping in progress
- go (c:cs) DblQ False a as
- | '"' == c = go cs NoneQ False a as
- | otherwise = go cs DblQ False (c:a) as
- -- case 6: no escaping is in progress
- go (c:cs) NoneQ False a as
- | isSpace c = go cs NoneQ False [] (a:as)
- | '\'' == c = go cs SngQ False a as
- | '"' == c = go cs DblQ False a as
- | otherwise = go cs NoneQ False (c:a) as
-
-#endif
-
-expandResponse :: [String] -> IO [String]
-expandResponse = go recursionLimit "."
- where
- recursionLimit = 100
-
- go :: Int -> FilePath -> [String] -> IO [String]
- go n dir
- | n >= 0 = fmap concat . mapM (expand n dir)
- | otherwise = const $ hPutStrLn stderr "Error: response file recursion limit exceeded." >> exitFailure
-
- expand :: Int -> FilePath -> String -> IO [String]
- expand n dir arg@('@':f) = readRecursively n (dir </> f) `catchIOError` (const $ print "?" >> return [arg])
- expand _n _dir x = return [x]
-
- readRecursively :: Int -> FilePath -> IO [String]
- readRecursively n f = go (n - 1) (takeDirectory f) =<< unescapeArgs <$> readFile f
+{-# LANGUAGE CPP, RankNTypes, FlexibleContexts #-}
+
+-- Compatibility layer for GHC.ResponseFile
+-- Implementation from base 4.12.0 is used.
+-- http://hackage.haskell.org/package/base-4.12.0.0/src/LICENSE
+module Distribution.Compat.ResponseFile (expandResponse) where
+
+import Distribution.Compat.Prelude
+import Prelude ()
+
+import System.FilePath
+import System.IO (hPutStrLn, stderr)
+import System.IO.Error
+
+#if MIN_VERSION_base(4,12,0)
+import GHC.ResponseFile (unescapeArgs)
+#else
+
+unescapeArgs :: String -> [String]
+unescapeArgs = filter (not . null) . unescape
+
+data Quoting = NoneQ | SngQ | DblQ
+
+unescape :: String -> [String]
+unescape args = reverse . map reverse $ go args NoneQ False [] []
+ where
+ -- n.b., the order of these cases matters; these are cribbed from gcc
+ -- case 1: end of input
+ go [] _q _bs a as = a:as
+ -- case 2: back-slash escape in progress
+ go (c:cs) q True a as = go cs q False (c:a) as
+ -- case 3: no back-slash escape in progress, but got a back-slash
+ go (c:cs) q False a as
+ | '\\' == c = go cs q True a as
+ -- case 4: single-quote escaping in progress
+ go (c:cs) SngQ False a as
+ | '\'' == c = go cs NoneQ False a as
+ | otherwise = go cs SngQ False (c:a) as
+ -- case 5: double-quote escaping in progress
+ go (c:cs) DblQ False a as
+ | '"' == c = go cs NoneQ False a as
+ | otherwise = go cs DblQ False (c:a) as
+ -- case 6: no escaping is in progress
+ go (c:cs) NoneQ False a as
+ | isSpace c = go cs NoneQ False [] (a:as)
+ | '\'' == c = go cs SngQ False a as
+ | '"' == c = go cs DblQ False a as
+ | otherwise = go cs NoneQ False (c:a) as
+
+#endif
+
+expandResponse :: [String] -> IO [String]
+expandResponse = go recursionLimit "."
+ where
+ recursionLimit = 100
+
+ go :: Int -> FilePath -> [String] -> IO [String]
+ go n dir
+ | n >= 0 = fmap concat . traverse (expand n dir)
+ | otherwise = const $ hPutStrLn stderr "Error: response file recursion limit exceeded." >> exitFailure
+
+ expand :: Int -> FilePath -> String -> IO [String]
+ expand n dir arg@('@':f) = readRecursively n (dir </> f) `catchIOError` (const $ print "?" >> return [arg])
+ expand _n _dir x = return [x]
+
+ readRecursively :: Int -> FilePath -> IO [String]
+ readRecursively n f = go (n - 1) (takeDirectory f) =<< unescapeArgs <$> readFile f
diff --git a/cabal/Cabal/Distribution/Compat/Semigroup.hs b/cabal/Cabal/Distribution/Compat/Semigroup.hs
index f8ffa95..947eaa5 100644
--- a/cabal/Cabal/Distribution/Compat/Semigroup.hs
+++ b/cabal/Cabal/Distribution/Compat/Semigroup.hs
@@ -1,4 +1,5 @@
{-# LANGUAGE CPP #-}
+{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
@@ -21,6 +22,8 @@ module Distribution.Compat.Semigroup
) where
import Distribution.Compat.Binary (Binary)
+import Distribution.Utils.Structured (Structured)
+import Data.Typeable (Typeable)
import GHC.Generics
-- Data.Semigroup is available since GHC 8.0/base-4.9 in `base`
@@ -38,7 +41,9 @@ instance Semigroup (First' a) where
-- | A copy of 'Data.Semigroup.Last'.
newtype Last' a = Last' { getLast' :: a }
- deriving (Eq, Ord, Read, Show, Binary)
+ deriving (Eq, Ord, Read, Show, Generic, Binary, Typeable)
+
+instance Structured a => Structured (Last' a)
instance Semigroup (Last' a) where
_ <> b = b
@@ -49,7 +54,9 @@ instance Functor Last' where
-- | A wrapper around 'Maybe', providing the 'Semigroup' and 'Monoid' instances
-- implemented for 'Maybe' since @base-4.11@.
newtype Option' a = Option' { getOption' :: Maybe a }
- deriving (Eq, Ord, Read, Show, Binary, Functor)
+ deriving (Eq, Ord, Read, Show, Binary, Generic, Functor, Typeable)
+
+instance Structured a => Structured (Option' a)
instance Semigroup a => Semigroup (Option' a) where
Option' (Just a) <> Option' (Just b) = Option' (Just (a <> b))
diff --git a/cabal/Cabal/Distribution/Compat/Time.hs b/cabal/Cabal/Distribution/Compat/Time.hs
index 6cd02f7..ef73b4f 100644
--- a/cabal/Cabal/Distribution/Compat/Time.hs
+++ b/cabal/Cabal/Distribution/Compat/Time.hs
@@ -1,4 +1,6 @@
{-# LANGUAGE CPP #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE FlexibleContexts #-}
@@ -55,7 +57,9 @@ import System.Posix.Files ( modificationTime )
-- | An opaque type representing a file's modification time, represented
-- internally as a 64-bit unsigned integer in the Windows UTC format.
newtype ModTime = ModTime Word64
- deriving (Binary, Bounded, Eq, Ord)
+ deriving (Binary, Generic, Bounded, Eq, Ord, Typeable)
+
+instance Structured ModTime
instance Show ModTime where
show (ModTime x) = show x
@@ -68,7 +72,7 @@ instance Read ModTime where
--
-- This is a modified version of the code originally written for Shake by Neil
-- Mitchell. See module Development.Shake.FileInfo.
-getModTime :: FilePath -> NoCallStackIO ModTime
+getModTime :: FilePath -> IO ModTime
#if defined mingw32_HOST_OS
@@ -106,7 +110,7 @@ getModTime path = allocaBytes size_WIN32_FILE_ATTRIBUTE_DATA $ \info -> do
foreign import CALLCONV "windows.h GetFileAttributesExW"
c_getFileAttributesEx :: LPCTSTR -> Int32 -> LPVOID -> Prelude.IO BOOL
-getFileAttributesEx :: String -> LPVOID -> NoCallStackIO BOOL
+getFileAttributesEx :: String -> LPVOID -> IO BOOL
getFileAttributesEx path lpFileInformation =
withTString path $ \c_path ->
c_getFileAttributesEx c_path getFileExInfoStandard lpFileInformation
@@ -150,14 +154,14 @@ posixTimeToModTime p = ModTime $ (ceiling $ p * 1e7) -- 100 ns precision
+ (secToUnixEpoch * windowsTick)
-- | Return age of given file in days.
-getFileAge :: FilePath -> NoCallStackIO Double
+getFileAge :: FilePath -> IO Double
getFileAge file = do
t0 <- getModificationTime file
t1 <- getCurrentTime
return $ realToFrac (t1 `diffUTCTime` t0) / realToFrac posixDayLength
-- | Return the current time as 'ModTime'.
-getCurTime :: NoCallStackIO ModTime
+getCurTime :: IO ModTime
getCurTime = posixTimeToModTime `fmap` getPOSIXTime -- Uses 'gettimeofday'.
-- | Based on code written by Neil Mitchell for Shake. See
diff --git a/cabal/Cabal/Distribution/Compat/Typeable.hs b/cabal/Cabal/Distribution/Compat/Typeable.hs
new file mode 100644
index 0000000..808d044
--- /dev/null
+++ b/cabal/Cabal/Distribution/Compat/Typeable.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+module Distribution.Compat.Typeable (
+ Typeable,
+ TypeRep,
+ typeRep,
+ ) where
+
+#if MIN_VERSION_base(4,7,0)
+import Data.Typeable (Typeable, TypeRep, typeRep)
+#else
+import Data.Typeable (Typeable, TypeRep, typeOf)
+#endif
+
+#if !MIN_VERSION_base(4,7,0)
+typeRep :: forall a proxy. Typeable a => proxy a -> TypeRep
+typeRep _ = typeOf (undefined :: a)
+#endif
diff --git a/cabal/Cabal/Distribution/Compiler.hs b/cabal/Cabal/Distribution/Compiler.hs
index 1195df8..ba16488 100644
--- a/cabal/Cabal/Distribution/Compiler.hs
+++ b/cabal/Cabal/Distribution/Compiler.hs
@@ -1,5 +1,8 @@
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE DeriveFoldable #-}
+{-# LANGUAGE DeriveTraversable #-}
-----------------------------------------------------------------------------
-- |
@@ -66,7 +69,7 @@ data CompilerFlavor =
deriving (Generic, Show, Read, Eq, Ord, Typeable, Data)
instance Binary CompilerFlavor
-
+instance Structured CompilerFlavor
instance NFData CompilerFlavor where rnf = genericRnf
knownCompilerFlavors :: [CompilerFlavor]
@@ -122,9 +125,11 @@ defaultCompilerFlavor = case buildCompilerFlavor of
-- Cabal parses only @ghc-options@ and @ghcjs-options@, others are omitted.
--
data PerCompilerFlavor v = PerCompilerFlavor v v
- deriving (Generic, Show, Read, Eq, Typeable, Data)
+ deriving (Generic, Show, Read, Eq, Typeable, Data, Functor, Foldable
+ , Traversable)
instance Binary a => Binary (PerCompilerFlavor a)
+instance Structured a => Structured (PerCompilerFlavor a)
instance NFData a => NFData (PerCompilerFlavor a)
perCompilerFlavorToList :: PerCompilerFlavor v -> [(CompilerFlavor, v)]
@@ -143,10 +148,10 @@ instance (Semigroup a, Monoid a) => Monoid (PerCompilerFlavor a) where
-- ------------------------------------------------------------
data CompilerId = CompilerId CompilerFlavor Version
- deriving (Eq, Generic, Ord, Read, Show)
+ deriving (Eq, Generic, Ord, Read, Show, Typeable)
instance Binary CompilerId
-
+instance Structured CompilerId
instance NFData CompilerId where rnf = genericRnf
instance Pretty CompilerId where
@@ -192,9 +197,10 @@ instance Binary CompilerInfo
data AbiTag
= NoAbiTag
| AbiTag String
- deriving (Eq, Generic, Show, Read)
+ deriving (Eq, Generic, Show, Read, Typeable)
instance Binary AbiTag
+instance Structured AbiTag
instance Pretty AbiTag where
pretty NoAbiTag = Disp.empty
diff --git a/cabal/Cabal/Distribution/FieldGrammar.hs b/cabal/Cabal/Distribution/FieldGrammar.hs
index b6dc656..c30de94 100644
--- a/cabal/Cabal/Distribution/FieldGrammar.hs
+++ b/cabal/Cabal/Distribution/FieldGrammar.hs
@@ -25,6 +25,9 @@ module Distribution.FieldGrammar (
takeFields,
runFieldParser,
runFieldParser',
+ defaultFreeTextFieldDefST,
+ -- * Newtypes
+ module Distribution.FieldGrammar.Newtypes,
) where
import Distribution.Compat.Prelude
@@ -33,10 +36,11 @@ import Prelude ()
import qualified Data.Map.Strict as Map
import Distribution.FieldGrammar.Class
+import Distribution.FieldGrammar.Newtypes
import Distribution.FieldGrammar.Parsec
import Distribution.FieldGrammar.Pretty
import Distribution.Fields.Field
-import Distribution.Utils.Generic (spanMaybe)
+import Distribution.Utils.Generic (spanMaybe)
type ParsecFieldGrammar' a = ParsecFieldGrammar a a
type PrettyFieldGrammar' a = PrettyFieldGrammar a a
diff --git a/cabal/Cabal/Distribution/FieldGrammar/Class.hs b/cabal/Cabal/Distribution/FieldGrammar/Class.hs
index f08566a..e696512 100644
--- a/cabal/Cabal/Distribution/FieldGrammar/Class.hs
+++ b/cabal/Cabal/Distribution/FieldGrammar/Class.hs
@@ -1,20 +1,31 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+#if __GLASGOW_HASKELL__ >= 800
+{-# LANGUAGE UndecidableSuperClasses #-}
+#else
+{-# LANGUAGE UndecidableInstances #-}
+#endif
module Distribution.FieldGrammar.Class (
FieldGrammar (..),
uniqueField,
optionalField,
optionalFieldDef,
monoidalField,
- ) where
+ defaultFreeTextFieldDefST,
+) where
import Distribution.Compat.Lens
import Distribution.Compat.Prelude
import Prelude ()
-import Distribution.CabalSpecVersion (CabalSpecVersion)
-import Distribution.Compat.Newtype (Newtype)
+import Distribution.CabalSpecVersion (CabalSpecVersion)
+import Distribution.Compat.Newtype (Newtype)
+import Distribution.FieldGrammar.Newtypes
import Distribution.Fields.Field
-import Distribution.Parsec (Parsec)
-import Distribution.Pretty (Pretty)
+import Distribution.Utils.ShortText
-- | 'FieldGrammar' is parametrised by
--
@@ -25,13 +36,17 @@ import Distribution.Pretty (Pretty)
--
-- /Note:/ We'd like to have @forall s. Applicative (f s)@ context.
--
-class FieldGrammar g where
+class
+ ( c SpecVersion, c TestedWith, c SpecLicense, c Token, c Token', c FilePathNT
+ )
+ => FieldGrammar c g | g -> c
+ where
-- | Unfocus, zoom out, /blur/ 'FieldGrammar'.
- blurFieldGrammar :: ALens' a b -> g b c -> g a c
+ blurFieldGrammar :: ALens' a b -> g b d -> g a d
-- | Field which should be defined, exactly once.
uniqueFieldAla
- :: (Parsec b, Pretty b, Newtype a b)
+ :: (c b, Newtype a b)
=> FieldName -- ^ field name
-> (a -> b) -- ^ 'Newtype' pack
-> ALens' s a -- ^ lens into the field
@@ -46,7 +61,7 @@ class FieldGrammar g where
-- | Optional field.
optionalFieldAla
- :: (Parsec b, Pretty b, Newtype a b)
+ :: (c b, Newtype a b)
=> FieldName -- ^ field name
-> (a -> b) -- ^ 'pack'
-> ALens' s (Maybe a) -- ^ lens into the field
@@ -54,7 +69,7 @@ class FieldGrammar g where
-- | Optional field with default value.
optionalFieldDefAla
- :: (Parsec b, Pretty b, Newtype a b, Eq a)
+ :: (c b, Newtype a b, Eq a)
=> FieldName -- ^ field name
-> (a -> b) -- ^ 'Newtype' pack
-> ALens' s a -- ^ @'Lens'' s a@: lens into the field
@@ -79,6 +94,12 @@ class FieldGrammar g where
-> ALens' s String -- ^ lens into the field
-> g s String
+ -- | @since 3.2.0.0
+ freeTextFieldDefST
+ :: FieldName
+ -> ALens' s ShortText -- ^ lens into the field
+ -> g s ShortText
+
-- | Monoidal field.
--
-- Values are combined with 'mappend'.
@@ -86,7 +107,7 @@ class FieldGrammar g where
-- /Note:/ 'optionalFieldAla' is a @monoidalField@ with 'Last' monoid.
--
monoidalFieldAla
- :: (Parsec b, Pretty b, Monoid a, Newtype a b)
+ :: (c b, Monoid a, Newtype a b)
=> FieldName -- ^ field name
-> (a -> b) -- ^ 'pack'
-> ALens' s a -- ^ lens into the field
@@ -127,33 +148,45 @@ class FieldGrammar g where
-- | Field which can be defined at most once.
uniqueField
- :: (FieldGrammar g, Parsec a, Pretty a)
+ :: (FieldGrammar c g, c (Identity a))
=> FieldName -- ^ field name
-> ALens' s a -- ^ lens into the field
-> g s a
-uniqueField fn = uniqueFieldAla fn Identity
+uniqueField fn l = uniqueFieldAla fn Identity l
-- | Field which can be defined at most once.
optionalField
- :: (FieldGrammar g, Parsec a, Pretty a)
+ :: (FieldGrammar c g, c (Identity a))
=> FieldName -- ^ field name
-> ALens' s (Maybe a) -- ^ lens into the field
-> g s (Maybe a)
-optionalField fn = optionalFieldAla fn Identity
+optionalField fn l = optionalFieldAla fn Identity l
-- | Optional field with default value.
optionalFieldDef
- :: (FieldGrammar g, Functor (g s), Parsec a, Pretty a, Eq a)
+ :: (FieldGrammar c g, Functor (g s), c (Identity a), Eq a)
=> FieldName -- ^ field name
-> ALens' s a -- ^ @'Lens'' s a@: lens into the field
-> a -- ^ default value
-> g s a
-optionalFieldDef fn = optionalFieldDefAla fn Identity
+optionalFieldDef fn l x = optionalFieldDefAla fn Identity l x
-- | Field which can be define multiple times, and the results are @mappend@ed.
monoidalField
- :: (FieldGrammar g, Parsec a, Pretty a, Monoid a)
+ :: (FieldGrammar c g, c (Identity a), Monoid a)
=> FieldName -- ^ field name
-> ALens' s a -- ^ lens into the field
-> g s a
-monoidalField fn = monoidalFieldAla fn Identity
+monoidalField fn l = monoidalFieldAla fn Identity l
+
+-- | Default implementation for 'freeTextFieldDefST'.
+defaultFreeTextFieldDefST
+ :: (Functor (g s), FieldGrammar c g)
+ => FieldName
+ -> ALens' s ShortText -- ^ lens into the field
+ -> g s ShortText
+defaultFreeTextFieldDefST fn l =
+ toShortText <$> freeTextFieldDef fn (cloneLens l . st)
+ where
+ st :: Lens' ShortText String
+ st f s = toShortText <$> f (fromShortText s)
diff --git a/cabal/Cabal/Distribution/FieldGrammar/FieldDescrs.hs b/cabal/Cabal/Distribution/FieldGrammar/FieldDescrs.hs
index 351f753..c027f6d 100644
--- a/cabal/Cabal/Distribution/FieldGrammar/FieldDescrs.hs
+++ b/cabal/Cabal/Distribution/FieldGrammar/FieldDescrs.hs
@@ -1,6 +1,9 @@
-{-# LANGUAGE DeriveFunctor #-}
-{-# LANGUAGE RankNTypes #-}
-{-# LANGUAGE NoMonoLocalBinds #-}
+{-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE NoMonoLocalBinds #-}
module Distribution.FieldGrammar.FieldDescrs (
FieldDescrs,
fieldDescrPretty,
@@ -15,7 +18,7 @@ import Data.List (dropWhileEnd)
import Distribution.Compat.Lens (aview, cloneLens)
import Distribution.Compat.Newtype
import Distribution.FieldGrammar
-import Distribution.Pretty (pretty, showFreeText)
+import Distribution.Pretty (Pretty (..), showFreeText)
import qualified Data.Map as Map
import qualified Distribution.Compat.CharParsing as C
@@ -46,7 +49,7 @@ fieldDescrPretty (F m) fn = pPretty <$> Map.lookup fn m
-- | Lookup a field value parser.
fieldDescrParse :: P.CabalParsing m => FieldDescrs s a -> P.FieldName -> Maybe (s -> m s)
-fieldDescrParse (F m) fn = pParse <$> Map.lookup fn m
+fieldDescrParse (F m) fn = (\f -> pParse f) <$> Map.lookup fn m
fieldDescrsToList
:: P.CabalParsing m
@@ -56,7 +59,7 @@ fieldDescrsToList = map mk . Map.toList . runF where
mk (name, SP ppr parse) = (name, ppr, parse)
-- | /Note:/ default values are printed.
-instance FieldGrammar FieldDescrs where
+instance FieldGrammar ParsecPretty FieldDescrs where
blurFieldGrammar l (F m) = F (fmap blur m) where
blur (SP f g) = SP (f . aview l) (cloneLens l g)
@@ -85,6 +88,8 @@ instance FieldGrammar FieldDescrs where
f s = showFreeText (aview l s)
g s = cloneLens l (const parsecFreeText) s
+ freeTextFieldDefST = defaultFreeTextFieldDefST
+
monoidalFieldAla fn _pack l = singletonF fn f g where
f s = pretty (pack' _pack (aview l s))
g s = cloneLens l (\x -> mappend x . unpack' _pack <$> P.parsec) s
@@ -112,3 +117,6 @@ parsecFreeText = dropDotLines <$ C.spaces <*> many C.anyChar
trim :: String -> String
trim = dropWhile isSpace . dropWhileEnd isSpace
+
+class (P.Parsec a, Pretty a) => ParsecPretty a
+instance (P.Parsec a, Pretty a) => ParsecPretty a
diff --git a/cabal/Cabal/Distribution/Parsec/Newtypes.hs b/cabal/Cabal/Distribution/FieldGrammar/Newtypes.hs
index 971cfc4..ff13ea5 100644
--- a/cabal/Cabal/Distribution/Parsec/Newtypes.hs
+++ b/cabal/Cabal/Distribution/FieldGrammar/Newtypes.hs
@@ -1,11 +1,11 @@
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeSynonymInstances #-}
-- | This module provides @newtype@ wrappers to be used with "Distribution.FieldGrammar".
-module Distribution.Parsec.Newtypes (
+module Distribution.FieldGrammar.Newtypes (
-- * List
alaList,
alaList',
@@ -18,6 +18,10 @@ module Distribution.Parsec.Newtypes (
Sep (..),
-- ** Type
List,
+ -- * Set
+ alaSet,
+ alaSet',
+ Set',
-- * Version & License
SpecVersion (..),
TestedWith (..),
@@ -39,9 +43,10 @@ import Distribution.License (License)
import Distribution.Parsec
import Distribution.Pretty
import Distribution.Version
- (LowerBound (..), Version, VersionRange, anyVersion, asVersionIntervals, mkVersion)
-import Text.PrettyPrint (Doc, comma, fsep, punctuate, vcat, (<+>))
+ (LowerBound (..), Version, VersionRange, VersionRangeF (..), anyVersion, asVersionIntervals, cataVersionRange, mkVersion, version0, versionNumbers)
+import Text.PrettyPrint (Doc, comma, fsep, punctuate, text, vcat)
+import qualified Data.Set as Set
import qualified Distribution.Compat.CharParsing as P
import qualified Distribution.SPDX as SPDX
@@ -117,6 +122,46 @@ instance (Newtype a b, Sep sep, Parsec b) => Parsec (List sep b a) where
instance (Newtype a b, Sep sep, Pretty b) => Pretty (List sep b a) where
pretty = prettySep (Proxy :: Proxy sep) . map (pretty . (pack :: a -> b)) . unpack
+--
+-- | Like 'List', but for 'Set'.
+--
+-- @since 3.2.0.0
+newtype Set' sep b a = Set' { _getSet :: Set a }
+
+-- | 'alaSet' and 'alaSet'' are simply 'Set'' constructor, with additional phantom
+-- arguments to constraint the resulting type
+--
+-- >>> :t alaSet VCat
+-- alaSet VCat :: Set a -> Set' VCat (Identity a) a
+--
+-- >>> :t alaSet' FSep Token
+-- alaSet' FSep Token :: Set String -> Set' FSep Token String
+--
+-- >>> unpack' (alaSet' FSep Token) <$> eitherParsec "foo bar foo"
+-- Right (fromList ["bar","foo"])
+--
+-- @since 3.2.0.0
+alaSet :: sep -> Set a -> Set' sep (Identity a) a
+alaSet _ = Set'
+
+-- | More general version of 'alaSet'.
+--
+-- @since 3.2.0.0
+alaSet' :: sep -> (a -> b) -> Set a -> Set' sep b a
+alaSet' _ _ = Set'
+
+instance Newtype (Set a) (Set' sep wrapper a)
+
+instance (Newtype a b, Ord a, Sep sep, Parsec b) => Parsec (Set' sep b a) where
+ parsec = pack . Set.fromList . map (unpack :: b -> a) <$> parseSep (Proxy :: Proxy sep) parsec
+
+instance (Newtype a b, Sep sep, Pretty b) => Pretty (Set' sep b a) where
+ pretty = prettySep (Proxy :: Proxy sep) . map (pretty . (pack :: a -> b)) . Set.toList . unpack
+
+-------------------------------------------------------------------------------
+-- Identifiers
+-------------------------------------------------------------------------------
+
-- | Haskell string or @[^ ,]+@
newtype Token = Token { getToken :: String }
@@ -150,6 +195,21 @@ instance Parsec a => Parsec (MQuoted a) where
instance Pretty a => Pretty (MQuoted a) where
pretty = pretty . unpack
+-- | Filepath are parsed as 'Token'.
+newtype FilePathNT = FilePathNT { getFilePathNT :: String }
+
+instance Newtype String FilePathNT
+
+instance Parsec FilePathNT where
+ parsec = pack <$> parsecToken
+
+instance Pretty FilePathNT where
+ pretty = showFilePath . unpack
+
+-------------------------------------------------------------------------------
+-- SpecVersion
+-------------------------------------------------------------------------------
+
-- | Version range or just version, i.e. @cabal-version@ field.
--
-- There are few things to consider:
@@ -159,27 +219,87 @@ instance Pretty a => Pretty (MQuoted a) where
-- @>= 2.2@, we fail.
-- See <https://github.com/haskell/cabal/issues/4899>
--
-newtype SpecVersion = SpecVersion { getSpecVersion :: Either Version VersionRange }
+-- We have this newtype, as writing Parsec and Pretty instances
+-- for CabalSpecVersion would cause cycle in modules:
+-- Version -> CabalSpecVersion -> Parsec -> ...
+--
+newtype SpecVersion = SpecVersion { getSpecVersion :: CabalSpecVersion }
+ deriving (Eq, Show) -- instances needed for tests
-instance Newtype (Either Version VersionRange) SpecVersion
+instance Newtype CabalSpecVersion SpecVersion
instance Parsec SpecVersion where
- parsec = pack <$> parsecSpecVersion
+ parsec = do
+ e <- parsecSpecVersion
+ let ver :: Version
+ ver = either id specVersionFromRange e
+
+ digits :: [Int]
+ digits = versionNumbers ver
+
+ case cabalSpecFromVersionDigits digits of
+ Nothing -> fail $ "Unknown cabal spec version specified: " ++ prettyShow ver
+ Just csv -> do
+ -- Check some warnings:
+ case e of
+ -- example: cabal-version: 1.10
+ -- should be cabal-version: >=1.10
+ Left _v | csv < CabalSpecV1_12 -> parsecWarning PWTSpecVersion $ concat
+ [ "With 1.10 or earlier, the 'cabal-version' field must use "
+ , "range syntax rather than a simple version number. Use "
+ , "'cabal-version: >= " ++ prettyShow ver ++ "'."
+ ]
+
+ -- example: cabal-version: >=1.12
+ -- should be cabal-version: 1.12
+ Right _vr | csv >= CabalSpecV1_12 -> parsecWarning PWTSpecVersion $ concat
+ [ "Packages with 'cabal-version: 1.12' or later should specify a "
+ , "specific version of the Cabal spec of the form "
+ , "'cabal-version: x.y'. "
+ , "Use 'cabal-version: " ++ prettyShow ver ++ "'."
+ ]
+
+ -- example: cabal-version: >=1.10 && <1.12
+ -- should be cabal-version: >=1.10
+ Right vr | csv < CabalSpecV1_12
+ , not (simpleSpecVersionRangeSyntax vr) -> parsecWarning PWTSpecVersion $ concat
+ [ "It is recommended that the 'cabal-version' field only specify a "
+ , "version range of the form '>= x.y' for older cabal versions. Use "
+ , "'cabal-version: >= " ++ prettyShow ver ++ "'. "
+ , "Tools based on Cabal 1.10 and later will ignore upper bounds."
+ ]
+
+ -- otherwise no warnings
+ _ -> pure ()
+
+ return (pack csv)
where
parsecSpecVersion = Left <$> parsec <|> Right <$> range
+
range = do
vr <- parsec
if specVersionFromRange vr >= mkVersion [2,1]
then fail "cabal-version higher than 2.2 cannot be specified as a range. See https://github.com/haskell/cabal/issues/4899"
else return vr
+ specVersionFromRange :: VersionRange -> Version
+ specVersionFromRange versionRange = case asVersionIntervals versionRange of
+ [] -> version0
+ ((LowerBound version _, _):_) -> version
+
+ simpleSpecVersionRangeSyntax = cataVersionRange alg where
+ alg (OrLaterVersionF _) = True
+ alg _ = False
+
+
instance Pretty SpecVersion where
- pretty = either pretty pretty . unpack
+ pretty (SpecVersion csv)
+ | csv >= CabalSpecV1_12 = text (showCabalSpecVersion csv)
+ | otherwise = text ">=" <<>> text (showCabalSpecVersion csv)
-specVersionFromRange :: VersionRange -> Version
-specVersionFromRange versionRange = case asVersionIntervals versionRange of
- [] -> mkVersion [0]
- ((LowerBound version _, _):_) -> version
+-------------------------------------------------------------------------------
+-- SpecLicense
+-------------------------------------------------------------------------------
-- | SPDX License expression or legacy license
newtype SpecLicense = SpecLicense { getSpecLicense :: Either SPDX.License License }
@@ -196,6 +316,10 @@ instance Parsec SpecLicense where
instance Pretty SpecLicense where
pretty = either pretty pretty . unpack
+-------------------------------------------------------------------------------
+-- TestedWith
+-------------------------------------------------------------------------------
+
-- | Version range or just version
newtype TestedWith = TestedWith { getTestedWith :: (CompilerFlavor, VersionRange) }
@@ -208,21 +332,6 @@ instance Pretty TestedWith where
pretty x = case unpack x of
(compiler, vr) -> pretty compiler <+> pretty vr
--- | Filepath are parsed as 'Token'.
-newtype FilePathNT = FilePathNT { getFilePathNT :: String }
-
-instance Newtype String FilePathNT
-
-instance Parsec FilePathNT where
- parsec = pack <$> parsecToken
-
-instance Pretty FilePathNT where
- pretty = showFilePath . unpack
-
--------------------------------------------------------------------------------
--- Internal
--------------------------------------------------------------------------------
-
parsecTestedWith :: CabalParsing m => m (CompilerFlavor, VersionRange)
parsecTestedWith = do
name <- lexemeParsec
diff --git a/cabal/Cabal/Distribution/FieldGrammar/Parsec.hs b/cabal/Cabal/Distribution/FieldGrammar/Parsec.hs
index 1c81985..d0a64eb 100644
--- a/cabal/Cabal/Distribution/FieldGrammar/Parsec.hs
+++ b/cabal/Cabal/Distribution/FieldGrammar/Parsec.hs
@@ -1,6 +1,7 @@
-{-# LANGUAGE DeriveFunctor #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ScopedTypeVariables #-}
-- | This module provides a 'FieldGrammarParser', one way to parse
-- @.cabal@ -like files.
--
@@ -65,18 +66,18 @@ module Distribution.FieldGrammar.Parsec (
) where
import Data.List (dropWhileEnd)
-import Data.Ord (comparing)
import Distribution.Compat.Newtype
import Distribution.Compat.Prelude
import Distribution.Simple.Utils (fromUTF8BS)
import Prelude ()
-import qualified Data.ByteString as BS
-import qualified Data.List.NonEmpty as NE
-import qualified Data.Map.Strict as Map
-import qualified Data.Set as Set
-import qualified Text.Parsec as P
-import qualified Text.Parsec.Error as P
+import qualified Data.ByteString as BS
+import qualified Data.List.NonEmpty as NE
+import qualified Data.Map.Strict as Map
+import qualified Data.Set as Set
+import qualified Distribution.Utils.ShortText as ShortText
+import qualified Text.Parsec as P
+import qualified Text.Parsec.Error as P
import Distribution.CabalSpecVersion
import Distribution.FieldGrammar.Class
@@ -84,7 +85,7 @@ import Distribution.Fields.Field
import Distribution.Fields.ParseResult
import Distribution.Parsec
import Distribution.Parsec.FieldLineStream
-import Distribution.Parsec.Position (positionRow, positionCol)
+import Distribution.Parsec.Position (positionCol, positionRow)
-------------------------------------------------------------------------------
-- Auxiliary types
@@ -150,7 +151,7 @@ warnMultipleSingularFields fn (x : xs) = do
parseWarning pos PWTMultipleSingularField $
"The field " <> show fn <> " is specified more than once at positions " ++ intercalate ", " (map showPos (pos : poss))
-instance FieldGrammar ParsecFieldGrammar where
+instance FieldGrammar Parsec ParsecFieldGrammar where
blurFieldGrammar _ (ParsecFG s s' parser) = ParsecFG s s' parser
uniqueFieldAla fn _pack _extract = ParsecFG (Set.singleton fn) Set.empty parser
@@ -234,6 +235,22 @@ instance FieldGrammar ParsecFieldGrammar where
| v >= CabalSpecV3_0 = pure (fieldlinesToFreeText3 pos fls)
| otherwise = pure (fieldlinesToFreeText fls)
+ -- freeTextFieldDefST = defaultFreeTextFieldDefST
+ freeTextFieldDefST fn _ = ParsecFG (Set.singleton fn) Set.empty parser where
+ parser v fields = case Map.lookup fn fields of
+ Nothing -> pure mempty
+ Just [] -> pure mempty
+ Just [x] -> parseOne v x
+ Just xs@(_:y:ys) -> do
+ warnMultipleSingularFields fn xs
+ NE.last <$> traverse (parseOne v) (y:|ys)
+
+ parseOne v (MkNamelessField pos fls) = case fls of
+ [] -> pure mempty
+ [FieldLine _ bs] -> pure (ShortText.unsafeFromUTF8BS bs)
+ _ | v >= CabalSpecV3_0 -> pure (ShortText.toShortText $ fieldlinesToFreeText3 pos fls)
+ | otherwise -> pure (ShortText.toShortText $ fieldlinesToFreeText fls)
+
monoidalFieldAla fn _pack _extract = ParsecFG (Set.singleton fn) Set.empty parser
where
parser v fields = case Map.lookup fn fields of
diff --git a/cabal/Cabal/Distribution/FieldGrammar/Pretty.hs b/cabal/Cabal/Distribution/FieldGrammar/Pretty.hs
index 77980f3..7c104d5 100644
--- a/cabal/Cabal/Distribution/FieldGrammar/Pretty.hs
+++ b/cabal/Cabal/Distribution/FieldGrammar/Pretty.hs
@@ -1,4 +1,5 @@
-{-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
module Distribution.FieldGrammar.Pretty (
PrettyFieldGrammar,
prettyFieldGrammar,
@@ -33,7 +34,7 @@ instance Applicative (PrettyFieldGrammar s) where
prettyFieldGrammar :: CabalSpecVersion -> PrettyFieldGrammar s a -> s -> [PrettyField ()]
prettyFieldGrammar = flip fieldGrammarPretty
-instance FieldGrammar PrettyFieldGrammar where
+instance FieldGrammar Pretty PrettyFieldGrammar where
blurFieldGrammar f (PrettyFG pp) = PrettyFG (\v -> pp v . aview f)
uniqueFieldAla fn _pack l = PrettyFG $ \_v s ->
@@ -72,6 +73,8 @@ instance FieldGrammar PrettyFieldGrammar where
showFT | v >= CabalSpecV3_0 = showFreeTextV3
| otherwise = showFreeText
+ freeTextFieldDefST = defaultFreeTextFieldDefST
+
monoidalFieldAla fn _pack l = PrettyFG pp
where
pp v s = ppField fn (prettyVersioned v (pack' _pack (aview l s)))
diff --git a/cabal/Cabal/Distribution/Fields/ConfVar.hs b/cabal/Cabal/Distribution/Fields/ConfVar.hs
index 7344d50..cc9016e 100644
--- a/cabal/Cabal/Distribution/Fields/ConfVar.hs
+++ b/cabal/Cabal/Distribution/Fields/ConfVar.hs
@@ -2,14 +2,14 @@
{-# LANGUAGE NoMonoLocalBinds #-}
module Distribution.Fields.ConfVar (parseConditionConfVar) where
-import Distribution.Compat.CharParsing (char, integral)
+import Distribution.Compat.CharParsing (char, integral)
import Distribution.Compat.Prelude
-import Distribution.Parsec (Parsec (..), runParsecParser, Position (..))
-import Distribution.Parsec.FieldLineStream (fieldLineStreamFromBS)
-import Distribution.Fields.Field (SectionArg (..))
+import Distribution.Fields.Field (SectionArg (..))
import Distribution.Fields.ParseResult
+import Distribution.Parsec (Parsec (..), Position (..), runParsecParser)
+import Distribution.Parsec.FieldLineStream (fieldLineStreamFromBS)
import Distribution.Types.Condition
-import Distribution.Types.ConfVar (ConfVar (..))
+import Distribution.Types.ConfVar (ConfVar (..))
import Distribution.Version
(anyVersion, earlierVersion, intersectVersionRanges, laterVersion, majorBoundVersion,
mkVersion, noVersion, orEarlierVersion, orLaterVersion, thisVersion, unionVersionRanges,
@@ -53,7 +53,7 @@ parser = condOr
boolLiteral = Lit <$> boolLiteral'
osCond = Var . OS <$ string "os" <*> parens fromParsec
- flagCond = Var . Flag <$ string "flag" <*> parens fromParsec
+ flagCond = Var . PackageFlag <$ string "flag" <*> parens fromParsec
archCond = Var . Arch <$ string "arch" <*> parens fromParsec
implCond = Var <$ string "impl" <*> parens implCond'
diff --git a/cabal/Cabal/Distribution/Fields/Field.hs b/cabal/Cabal/Distribution/Fields/Field.hs
index c2b97ff..42108ee 100644
--- a/cabal/Cabal/Distribution/Fields/Field.hs
+++ b/cabal/Cabal/Distribution/Fields/Field.hs
@@ -73,7 +73,7 @@ fieldLineBS (FieldLine _ bs) = bs
-- | Section arguments, e.g. name of the library
data SectionArg ann
= SecArgName !ann !ByteString
- -- ^ identifier, or omething which loos like number. Also many dot numbers, i.e. "7.6.3"
+ -- ^ identifier, or something which looks like number. Also many dot numbers, i.e. "7.6.3"
| SecArgStr !ann !ByteString
-- ^ quoted string
| SecArgOther !ann !ByteString
diff --git a/cabal/Cabal/Distribution/Fields/ParseResult.hs b/cabal/Cabal/Distribution/Fields/ParseResult.hs
index 52965e2..a702113 100644
--- a/cabal/Cabal/Distribution/Fields/ParseResult.hs
+++ b/cabal/Cabal/Distribution/Fields/ParseResult.hs
@@ -15,7 +15,8 @@ module Distribution.Fields.ParseResult (
getCabalSpecVersion,
setCabalSpecVersion,
readAndParseFile,
- parseString
+ parseString,
+ withoutWarnings,
) where
import qualified Data.ByteString.Char8 as BS
@@ -42,11 +43,21 @@ newtype ParseResult a = PR
-> r
}
+-- Note: we have version here, as we could get any version.
data PRState = PRState ![PWarning] ![PError] !(Maybe Version)
emptyPRState :: PRState
emptyPRState = PRState [] [] Nothing
+-- | Forget 'ParseResult's warnings.
+--
+-- @since 3.4.0.0
+withoutWarnings :: ParseResult a -> ParseResult a
+withoutWarnings m = PR $ \s failure success ->
+ unPR m s failure $ \ !s1 -> success (s1 `withWarningsOf` s)
+ where
+ withWarningsOf (PRState _ e v) (PRState w _ _) = PRState w e v
+
-- | Destruct a 'ParseResult' into the emitted warnings and either
-- a successful value or
-- list of errors and possibly recovered a spec-version declaration.
diff --git a/cabal/Cabal/Distribution/Fields/Parser.hs b/cabal/Cabal/Distribution/Fields/Parser.hs
index d00d2c1..5c244ff 100644
--- a/cabal/Cabal/Distribution/Fields/Parser.hs
+++ b/cabal/Cabal/Distribution/Fields/Parser.hs
@@ -27,7 +27,6 @@ module Distribution.Fields.Parser (
#endif
) where
-import Control.Monad (guard)
import qualified Data.ByteString.Char8 as B8
import Data.Functor.Identity
import Distribution.Compat.Prelude
diff --git a/cabal/Cabal/Distribution/Fields/Pretty.hs b/cabal/Cabal/Distribution/Fields/Pretty.hs
index 4b03826..7af4728 100644
--- a/cabal/Cabal/Distribution/Fields/Pretty.hs
+++ b/cabal/Cabal/Distribution/Fields/Pretty.hs
@@ -45,11 +45,21 @@ data PrettyField ann
-- between comment lines.
--
showFields :: (ann -> [String]) -> [PrettyField ann] -> String
-showFields rann = showFields' rann 4
+showFields rann = showFields' rann (const id) 4
-- | 'showFields' with user specified indentation.
-showFields' :: (ann -> [String]) -> Int -> [PrettyField ann] -> String
-showFields' rann n = unlines . renderFields (Opts rann indent) where
+showFields'
+ :: (ann -> [String])
+ -- ^ Convert an annotation to lined to preceed the field or section.
+ -> (ann -> [String] -> [String])
+ -- ^ Post-process non-annotation produced lines.
+ -> Int
+ -- ^ Indentation level.
+ -> [PrettyField ann]
+ -- ^ Fields/sections to show.
+ -> String
+showFields' rann post n = unlines . renderFields (Opts rann indent post)
+ where
-- few hardcoded, "unrolled" variants.
indent | n == 4 = indent4
| n == 2 = indent2
@@ -63,7 +73,11 @@ showFields' rann n = unlines . renderFields (Opts rann indent) where
indent2 [] = []
indent2 xs = ' ' : ' ' : xs
-data Opts ann = Opts (ann -> [String]) (String -> String)
+data Opts ann = Opts
+ { _optAnnotation ::(ann -> [String])
+ , _optIndent ::(String -> String)
+ , _optPostprocess :: ann -> [String] -> [String]
+ }
renderFields :: Opts ann -> [PrettyField ann] -> [String]
renderFields opts fields = flattenBlocks $ map (renderField opts len) fields
@@ -97,8 +111,8 @@ flattenBlocks = go0 where
| otherwise = id
renderField :: Opts ann -> Int -> PrettyField ann -> Block
-renderField (Opts rann indent) fw (PrettyField ann name doc) =
- Block before after $ comments ++ lines'
+renderField (Opts rann indent post) fw (PrettyField ann name doc) =
+ Block before after $ comments ++ post ann lines'
where
comments = rann ann
before = if null comments then NoMargin else Margin
@@ -115,10 +129,10 @@ renderField (Opts rann indent) fw (PrettyField ann name doc) =
narrowStyle :: PP.Style
narrowStyle = PP.style { PP.lineLength = PP.lineLength PP.style - fw }
-renderField opts@(Opts rann indent) _ (PrettySection ann name args fields) = Block Margin Margin $
+renderField opts@(Opts rann indent post) _ (PrettySection ann name args fields) = Block Margin Margin $
rann ann
- ++
- [ PP.render $ PP.hsep $ PP.text (fromUTF8BS name) : args ]
+ ++
+ post ann [ PP.render $ PP.hsep $ PP.text (fromUTF8BS name) : args ]
++
(map indent $ renderFields opts fields)
diff --git a/cabal/Cabal/Distribution/InstalledPackageInfo.hs b/cabal/Cabal/Distribution/InstalledPackageInfo.hs
index 18126c5..3970022 100644
--- a/cabal/Cabal/Distribution/InstalledPackageInfo.hs
+++ b/cabal/Cabal/Distribution/InstalledPackageInfo.hs
@@ -52,6 +52,8 @@ import Distribution.Package hiding (installedUnitId)
import Distribution.Types.ComponentName
import Distribution.Utils.Generic (toUTF8BS)
+import Data.ByteString (ByteString)
+
import qualified Data.Map as Map
import qualified Distribution.Fields as P
import qualified Text.PrettyPrint as Disp
@@ -59,7 +61,8 @@ import qualified Text.PrettyPrint as Disp
import Distribution.Types.InstalledPackageInfo
import Distribution.Types.InstalledPackageInfo.FieldGrammar
-
+-- $setup
+-- >>> :set -XOverloadedStrings
installedComponentId :: InstalledPackageInfo -> ComponentId
installedComponentId ipi =
@@ -91,17 +94,19 @@ sourceComponentName = CLibName . sourceLibName
-- Parsing
-- | Return either errors, or IPI with list of warnings
---
--- /Note:/ errors array /may/ be empty, but the parse is still failed (it's a bug though)
parseInstalledPackageInfo
- :: String
+ :: ByteString
-> Either (NonEmpty String) ([String], InstalledPackageInfo)
-parseInstalledPackageInfo s = case P.readFields (toUTF8BS s) of
+parseInstalledPackageInfo s = case P.readFields s of
Left err -> Left (show err :| [])
Right fs -> case partitionFields fs of
(fs', _) -> case P.runParseResult $ parseFieldGrammar cabalSpecLatest fs' ipiFieldGrammar of
- (ws, Right x) -> Right (ws', x) where
- ws' = map (P.showPWarning "") ws
+ (ws, Right x) -> x `deepseq` Right (ws', x) where
+ ws' = [ P.showPWarning "" w
+ | w@(P.PWarning wt _ _) <- ws
+ -- filter out warnings about experimental features
+ , wt /= P.PWTExperimental
+ ]
(_, Left (_, errs)) -> Left errs' where
errs' = fmap (P.showPError "") errs
diff --git a/cabal/Cabal/Distribution/License.hs b/cabal/Cabal/Distribution/License.hs
index 5ec6715..db4f888 100644
--- a/cabal/Cabal/Distribution/License.hs
+++ b/cabal/Cabal/Distribution/License.hs
@@ -128,7 +128,7 @@ data License =
deriving (Generic, Read, Show, Eq, Typeable, Data)
instance Binary License
-
+instance Structured License
instance NFData License where rnf = genericRnf
-- | The list of all currently recognised licenses.
diff --git a/cabal/Cabal/Distribution/Make.hs b/cabal/Cabal/Distribution/Make.hs
index cde201e..b5651d3 100644
--- a/cabal/Cabal/Distribution/Make.hs
+++ b/cabal/Cabal/Distribution/Make.hs
@@ -67,7 +67,6 @@ import Prelude ()
import Distribution.Compat.Prelude
-- local
-import Distribution.Compat.Exception
import Distribution.Package
import Distribution.Simple.Program
import Distribution.Simple.Setup
@@ -80,7 +79,6 @@ import Distribution.Version
import Distribution.Pretty
import System.Environment (getArgs, getProgName)
-import System.Exit
defaultMain :: IO ()
defaultMain = getArgs >>= defaultMainArgs
diff --git a/cabal/Cabal/Distribution/ModuleName.hs b/cabal/Cabal/Distribution/ModuleName.hs
index 99f7416..f23050f 100644
--- a/cabal/Cabal/Distribution/ModuleName.hs
+++ b/cabal/Cabal/Distribution/ModuleName.hs
@@ -1,6 +1,7 @@
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE DeriveGeneric #-}
-
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE ScopedTypeVariables #-}
-----------------------------------------------------------------------------
-- |
-- Module : Distribution.ModuleName
@@ -13,7 +14,7 @@
-- Data type for Haskell module names.
module Distribution.ModuleName (
- ModuleName (..), -- TODO: move Parsec instance here, don't export constructor
+ ModuleName,
fromString,
fromComponents,
components,
@@ -23,47 +24,70 @@ module Distribution.ModuleName (
validModuleComponent,
) where
-import Prelude ()
import Distribution.Compat.Prelude
+import Prelude ()
-import Distribution.Utils.ShortText
-import System.FilePath ( pathSeparator )
-
-import Distribution.Pretty
import Distribution.Parsec
+import Distribution.Pretty
+import Distribution.Utils.ShortText (ShortText, fromShortText, toShortText)
+import System.FilePath (pathSeparator)
import qualified Distribution.Compat.CharParsing as P
-import qualified Text.PrettyPrint as Disp
+import qualified Distribution.Compat.DList as DList
+import qualified Text.PrettyPrint as Disp
-- | A valid Haskell module name.
--
-newtype ModuleName = ModuleName ShortTextLst
+newtype ModuleName = ModuleName ShortText
deriving (Eq, Generic, Ord, Read, Show, Typeable, Data)
+unModuleName :: ModuleName -> String
+unModuleName (ModuleName s) = fromShortText s
+
instance Binary ModuleName
+instance Structured ModuleName
instance NFData ModuleName where
rnf (ModuleName ms) = rnf ms
instance Pretty ModuleName where
- pretty (ModuleName ms) =
- Disp.hcat (intersperse (Disp.char '.') (map Disp.text $ stlToStrings ms))
+ pretty = Disp.text . unModuleName
instance Parsec ModuleName where
- parsec = fromComponents <$> toList <$> P.sepByNonEmpty component (P.char '.')
- where
- component = do
- c <- P.satisfy isUpper
- cs <- P.munch validModuleChar
- return (c:cs)
+ parsec = parsecModuleName
+
+parsecModuleName :: forall m. CabalParsing m => m ModuleName
+parsecModuleName = state0 DList.empty where
+ upper :: m Char
+ !upper = P.satisfy isUpper
+
+ ch :: m Char
+ !ch = P.satisfy (\c -> validModuleChar c || c == '.')
+
+ alt :: m ModuleName -> m ModuleName -> m ModuleName
+ !alt = (<|>)
+
+ state0 :: DList.DList Char -> m ModuleName
+ state0 acc = do
+ c <- upper
+ state1 (DList.snoc acc c)
+
+ state1 :: DList.DList Char -> m ModuleName
+ state1 acc = state1' acc `alt` return (fromString (DList.toList acc))
+
+ state1' :: DList.DList Char -> m ModuleName
+ state1' acc = do
+ c <- ch
+ case c of
+ '.' -> state0 (DList.snoc acc c)
+ _ -> state1 (DList.snoc acc c)
validModuleChar :: Char -> Bool
validModuleChar c = isAlphaNum c || c == '_' || c == '\''
validModuleComponent :: String -> Bool
validModuleComponent [] = False
-validModuleComponent (c:cs) = isUpper c
- && all validModuleChar cs
+validModuleComponent (c:cs) = isUpper c && all validModuleChar cs
-- | Construct a 'ModuleName' from a valid module name 'String'.
--
@@ -72,34 +96,29 @@ validModuleComponent (c:cs) = isUpper c
-- are parsing user input then use 'Distribution.Text.simpleParse' instead.
--
instance IsString ModuleName where
- fromString string = fromComponents (split string)
- where
- split cs = case break (=='.') cs of
- (chunk,[]) -> chunk : []
- (chunk,_:rest) -> chunk : split rest
+ fromString = ModuleName . toShortText
-- | Construct a 'ModuleName' from valid module components, i.e. parts
-- separated by dots.
fromComponents :: [String] -> ModuleName
-fromComponents components'
- | null components' = error zeroComponents
- | all validModuleComponent components' = ModuleName (stlFromStrings components')
- | otherwise = error badName
- where
- zeroComponents = "ModuleName.fromComponents: zero components"
- badName = "ModuleName.fromComponents: invalid components " ++ show components'
+fromComponents comps = fromString (intercalate "." comps)
+{-# DEPRECATED fromComponents "Exists for cabal-install only" #-}
-- | The module name @Main@.
--
main :: ModuleName
-main = ModuleName (stlFromStrings ["Main"])
+main = ModuleName (fromString "Main")
-- | The individual components of a hierarchical module name. For example
--
-- > components (fromString "A.B.C") = ["A", "B", "C"]
--
components :: ModuleName -> [String]
-components (ModuleName ms) = stlToStrings ms
+components mn = split (unModuleName mn)
+ where
+ split cs = case break (=='.') cs of
+ (chunk,[]) -> chunk : []
+ (chunk,_:rest) -> chunk : split rest
-- | Convert a module name to a file path, but without any file extension.
-- For example:
@@ -107,40 +126,6 @@ components (ModuleName ms) = stlToStrings ms
-- > toFilePath (fromString "A.B.C") = "A/B/C"
--
toFilePath :: ModuleName -> FilePath
-toFilePath = intercalate [pathSeparator] . components
-
-----------------------------------------------------------------------------
--- internal helper
-
--- | Strict/unpacked representation of @[ShortText]@
-data ShortTextLst = STLNil
- | STLCons !ShortText !ShortTextLst
- deriving (Eq, Generic, Ord, Typeable, Data)
-
-instance NFData ShortTextLst where
- rnf = flip seq ()
-
-instance Show ShortTextLst where
- showsPrec p = showsPrec p . stlToList
-
-
-instance Read ShortTextLst where
- readsPrec p = map (first stlFromList) . readsPrec p
-
-instance Binary ShortTextLst where
- put = put . stlToList
- get = stlFromList <$> get
-
-stlToList :: ShortTextLst -> [ShortText]
-stlToList STLNil = []
-stlToList (STLCons st next) = st : stlToList next
-
-stlToStrings :: ShortTextLst -> [String]
-stlToStrings = map fromShortText . stlToList
-
-stlFromList :: [ShortText] -> ShortTextLst
-stlFromList [] = STLNil
-stlFromList (x:xs) = STLCons x (stlFromList xs)
-
-stlFromStrings :: [String] -> ShortTextLst
-stlFromStrings = stlFromList . map toShortText
+toFilePath = map f . unModuleName where
+ f '.' = pathSeparator
+ f c = c
diff --git a/cabal/Cabal/Distribution/PackageDescription.hs b/cabal/Cabal/Distribution/PackageDescription.hs
index 1eb3ef4..e9e5f9a 100644
--- a/cabal/Cabal/Distribution/PackageDescription.hs
+++ b/cabal/Cabal/Distribution/PackageDescription.hs
@@ -10,135 +10,91 @@
-- Maintainer : cabal-devel@haskell.org
-- Portability : portable
--
--- Backwards compatibility reexport of everything you need to know
+-- Backwards compatibility reexport of most things you need to know
-- about @.cabal@ files.
module Distribution.PackageDescription (
- -- * Package descriptions
- PackageDescription(..),
- emptyPackageDescription,
- specVersion,
- buildType,
- license,
- BuildType(..),
- knownBuildTypes,
- allLibraries,
-
- -- ** Renaming (syntactic)
- ModuleRenaming(..),
- defaultRenaming,
-
- -- ** Libraries
- Library(..),
- ModuleReexport(..),
- emptyLibrary,
- withLib,
- hasPublicLib,
- hasLibs,
- explicitLibModules,
- libModulesAutogen,
-
- -- ** Executables
- Executable(..),
- emptyExecutable,
- withExe,
- hasExes,
- exeModules,
- exeModulesAutogen,
-
- -- * Tests
- TestSuite(..),
- TestSuiteInterface(..),
- TestType(..),
- testType,
- knownTestTypes,
- emptyTestSuite,
- hasTests,
- withTest,
- testModules,
- testModulesAutogen,
-
- -- * Benchmarks
- Benchmark(..),
- BenchmarkInterface(..),
- BenchmarkType(..),
- benchmarkType,
- knownBenchmarkTypes,
- emptyBenchmark,
- hasBenchmarks,
- withBenchmark,
- benchmarkModules,
- benchmarkModulesAutogen,
-
- -- * Build information
- BuildInfo(..),
- emptyBuildInfo,
- allBuildInfo,
- allLanguages,
- allExtensions,
- usedExtensions,
- usesTemplateHaskellOrQQ,
- hcOptions,
- hcProfOptions,
- hcSharedOptions,
- hcStaticOptions,
-
- -- ** Supplementary build information
- allBuildDepends,
- enabledBuildDepends,
- ComponentName(..),
- LibraryName(..),
- defaultLibName,
- HookedBuildInfo,
- emptyHookedBuildInfo,
- updatePackageDescription,
-
- -- * package configuration
- GenericPackageDescription(..),
- Flag(..), emptyFlag,
- FlagName, mkFlagName, unFlagName,
- FlagAssignment, mkFlagAssignment, unFlagAssignment,
- nullFlagAssignment, showFlagValue,
- diffFlagAssignment, lookupFlagAssignment, insertFlagAssignment,
- dispFlagAssignment, parsecFlagAssignment,
- findDuplicateFlagAssignments,
- CondTree(..), ConfVar(..), Condition(..),
- cNot, cAnd, cOr,
-
- -- * Source repositories
- SourceRepo(..),
- RepoKind(..),
- RepoType(..),
- knownRepoTypes,
- emptySourceRepo,
-
- -- * Custom setup build information
- SetupBuildInfo(..),
+ -- * PD and GPD
+ module Distribution.Types.PackageDescription,
+ module Distribution.Types.GenericPackageDescription,
+ -- * Components
+ module Distribution.Types.ComponentName,
+ -- ** Library
+ module Distribution.Types.Library,
+ module Distribution.Types.LibraryName,
+ module Distribution.Types.LibraryVisibility,
+ -- ** Executable
+ module Distribution.Types.Executable,
+ module Distribution.Types.ExecutableScope,
+ -- ** TestSuite
+ module Distribution.Types.TestSuite,
+ module Distribution.Types.TestType,
+ module Distribution.Types.TestSuiteInterface,
+ -- ** Benchmark
+ module Distribution.Types.Benchmark,
+ module Distribution.Types.BenchmarkType,
+ module Distribution.Types.BenchmarkInterface,
+ -- ** Foreign library
+ module Distribution.Types.ForeignLib,
+ module Distribution.Types.ForeignLibType,
+ module Distribution.Types.ForeignLibOption,
+ -- * BuildInfo
+ module Distribution.Types.BuildType,
+ module Distribution.Types.BuildInfo,
+ module Distribution.Types.HookedBuildInfo,
+ module Distribution.Types.SetupBuildInfo,
+ -- * Flags
+ module Distribution.Types.Flag,
+ -- * Identifiers
+ module Distribution.Types.PackageId,
+ module Distribution.Types.PackageName,
+ module Distribution.Types.UnqualComponentName,
+ -- * Dependencies
+ module Distribution.Types.Dependency,
+ module Distribution.Types.ExeDependency,
+ module Distribution.Types.LegacyExeDependency,
+ module Distribution.Types.PkgconfigDependency,
+ -- * Condition trees
+ module Distribution.Types.CondTree,
+ module Distribution.Types.Condition,
+ module Distribution.Types.ConfVar,
+ -- * Source repository
+ module Distribution.Types.SourceRepo,
) where
import Prelude ()
--import Distribution.Compat.Prelude
-import Distribution.Types.Library
-import Distribution.Types.TestSuite
-import Distribution.Types.Executable
import Distribution.Types.Benchmark
-import Distribution.Types.TestType
-import Distribution.Types.TestSuiteInterface
-import Distribution.Types.BenchmarkType
import Distribution.Types.BenchmarkInterface
-import Distribution.Types.ModuleRenaming
-import Distribution.Types.ModuleReexport
+import Distribution.Types.BenchmarkType
import Distribution.Types.BuildInfo
-import Distribution.Types.SetupBuildInfo
import Distribution.Types.BuildType
-import Distribution.Types.GenericPackageDescription
-import Distribution.Types.CondTree
-import Distribution.Types.Condition
-import Distribution.Types.PackageDescription
import Distribution.Types.ComponentName
-import Distribution.Types.LibraryName
+import Distribution.Types.Condition
+import Distribution.Types.CondTree
+import Distribution.Types.ConfVar
+import Distribution.Types.Dependency
+import Distribution.Types.Executable
+import Distribution.Types.ExecutableScope
+import Distribution.Types.ExeDependency
+import Distribution.Types.Flag
+import Distribution.Types.ForeignLib
+import Distribution.Types.ForeignLibOption
+import Distribution.Types.ForeignLibType
+import Distribution.Types.GenericPackageDescription
import Distribution.Types.HookedBuildInfo
+import Distribution.Types.LegacyExeDependency
+import Distribution.Types.Library
+import Distribution.Types.LibraryName
+import Distribution.Types.LibraryVisibility
+import Distribution.Types.PackageDescription
+import Distribution.Types.PackageId
+import Distribution.Types.PackageName
+import Distribution.Types.PkgconfigDependency
+import Distribution.Types.SetupBuildInfo
import Distribution.Types.SourceRepo
-import Distribution.Types.Flag
-import Distribution.Types.ConfVar
+import Distribution.Types.TestSuite
+import Distribution.Types.TestSuiteInterface
+import Distribution.Types.TestType
+import Distribution.Types.UnqualComponentName
diff --git a/cabal/Cabal/Distribution/PackageDescription/Check.hs b/cabal/Cabal/Distribution/PackageDescription/Check.hs
index 2b5f6c5..01e94f6 100644
--- a/cabal/Cabal/Distribution/PackageDescription/Check.hs
+++ b/cabal/Cabal/Distribution/PackageDescription/Check.hs
@@ -15,7 +15,7 @@
-- like to encourage. There is a 'PackageCheck' type that distinguishes the
-- different kinds of check so we can see which ones are appropriate to report
-- in different situations. This code gets uses when configuring a package when
--- we consider only basic problems. The higher standard is uses when when
+-- we consider only basic problems. The higher standard is uses when
-- preparing a source tarball and by Hackage when uploading new packages. The
-- reason for this is that we want to hold packages that are expected to be
-- distributed to a higher standard than packages that are only ever expected
@@ -37,8 +37,8 @@ module Distribution.PackageDescription.Check (
import Distribution.Compat.Prelude
import Prelude ()
-import Control.Monad (mapM)
import Data.List (group)
+import Distribution.CabalSpecVersion
import Distribution.Compat.Lens
import Distribution.Compiler
import Distribution.License
@@ -53,11 +53,8 @@ import Distribution.Simple.Glob
import Distribution.Simple.Utils hiding (findPackageDesc, notice)
import Distribution.System
import Distribution.Types.ComponentRequestedSpec
-import Distribution.Types.CondTree
-import Distribution.Types.ExeDependency
-import Distribution.Types.LibraryName
-import Distribution.Types.UnqualComponentName
-import Distribution.Utils.Generic (isAscii, safeInit)
+import Distribution.Types.ModuleReexport
+import Distribution.Utils.Generic (isAscii)
import Distribution.Verbosity
import Distribution.Version
import Language.Haskell.Extension
@@ -74,6 +71,7 @@ import qualified System.Directory (getDirectoryContents)
import qualified System.FilePath.Windows as FilePath.Windows (isValid)
import qualified Data.Set as Set
+import qualified Distribution.Utils.ShortText as ShortText
import qualified Distribution.Types.BuildInfo.Lens as L
import qualified Distribution.Types.GenericPackageDescription.Lens as L
@@ -122,11 +120,11 @@ check :: Bool -> PackageCheck -> Maybe PackageCheck
check False _ = Nothing
check True pc = Just pc
-checkSpecVersion :: PackageDescription -> [Int] -> Bool -> PackageCheck
+checkSpecVersion :: PackageDescription -> CabalSpecVersion -> Bool -> PackageCheck
-> Maybe PackageCheck
checkSpecVersion pkg specver cond pc
- | specVersion pkg >= mkVersion specver = Nothing
- | otherwise = check cond pc
+ | specVersion pkg >= specver = Nothing
+ | otherwise = check cond pc
-- ------------------------------------------------------------
-- * Standard checks
@@ -226,14 +224,6 @@ checkSanity pkg =
++ concatMap (checkTestSuite pkg) (testSuites pkg)
++ concatMap (checkBenchmark pkg) (benchmarks pkg)
- ++ catMaybes [
-
- check (specVersion pkg > cabalVersion) $
- PackageBuildImpossible $
- "This package description follows version "
- ++ prettyShow (specVersion pkg) ++ " of the Cabal specification. This "
- ++ "tool only supports up to version " ++ prettyShow cabalVersion ++ "."
- ]
where
-- The public 'library' gets special dispensation, because it
-- is common practice to export a library and name the executable
@@ -259,7 +249,7 @@ checkLibrary pkg lib =
showLibraryName (libName lib) ++ " does not expose any modules"
-- check use of signatures sections
- , checkVersion [1,25] (not (null (signatures lib))) $
+ , checkVersion CabalSpecV2_0 (not (null (signatures lib))) $
PackageDistInexcusable $
"To use the 'signatures' field the package needs to specify "
++ "at least 'cabal-version: 2.0'."
@@ -280,10 +270,10 @@ checkLibrary pkg lib =
]
where
- checkVersion :: [Int] -> Bool -> PackageCheck -> Maybe PackageCheck
+ checkVersion :: CabalSpecVersion -> Bool -> PackageCheck -> Maybe PackageCheck
checkVersion ver cond pc
- | specVersion pkg >= mkVersion ver = Nothing
- | otherwise = check cond pc
+ | specVersion pkg >= ver = Nothing
+ | otherwise = check cond pc
-- TODO: not sure if this check is always right in Backpack
moduleDuplicates = dups (explicitLibModules lib ++
@@ -307,7 +297,7 @@ checkExecutable pkg exe =
++ "(even if it is generated by a preprocessor), "
++ "or it may specify a C/C++/obj-C source file."
- , checkSpecVersion pkg [1,17]
+ , checkSpecVersion pkg CabalSpecV1_18
(fileExtensionSupportedLanguage (modulePath exe)
&& takeExtension (modulePath exe) `notElem` [".hs", ".lhs"]) $
PackageDistInexcusable $
@@ -363,7 +353,7 @@ checkTestSuite pkg test =
++ "(even if it is generated by a preprocessor), "
++ "or it may specify a C/C++/obj-C source file."
- , checkSpecVersion pkg [1,17] (mainIsNotHsExt && not mainIsWrongExt) $
+ , checkSpecVersion pkg CabalSpecV1_18 (mainIsNotHsExt && not mainIsWrongExt) $
PackageDistInexcusable $
"The package uses a C/C++/obj-C source file for the 'main-is' field. "
++ "To use this feature you must specify 'cabal-version: >= 1.18'."
@@ -458,7 +448,7 @@ checkFields pkg =
"Package names with the prefix 'z-' are reserved by Cabal and "
++ "cannot be used."
- , check (isNothing (buildTypeRaw pkg) && specVersion pkg < mkVersion [2,1]) $
+ , check (isNothing (buildTypeRaw pkg) && specVersion pkg < CabalSpecV2_2) $
PackageBuildWarning $
"No 'build-type' specified. If you do not need a custom Setup.hs or "
++ "./configure script then use 'build-type: Simple'."
@@ -498,32 +488,32 @@ checkFields pkg =
++ "' use '" ++ prettyShow replacement ++ "'."
| (ext, Just replacement) <- ourDeprecatedExtensions ]
- , check (null (category pkg)) $
+ , check (ShortText.null (category pkg)) $
PackageDistSuspicious "No 'category' field."
- , check (null (maintainer pkg)) $
+ , check (ShortText.null (maintainer pkg)) $
PackageDistSuspicious "No 'maintainer' field."
- , check (null (synopsis pkg) && null (description pkg)) $
+ , check (ShortText.null (synopsis pkg) && ShortText.null (description pkg)) $
PackageDistInexcusable "No 'synopsis' or 'description' field."
- , check (null (description pkg) && not (null (synopsis pkg))) $
+ , check (ShortText.null (description pkg) && not (ShortText.null (synopsis pkg))) $
PackageDistSuspicious "No 'description' field."
- , check (null (synopsis pkg) && not (null (description pkg))) $
+ , check (ShortText.null (synopsis pkg) && not (ShortText.null (description pkg))) $
PackageDistSuspicious "No 'synopsis' field."
--TODO: recommend the bug reports URL, author and homepage fields
--TODO: recommend not using the stability field
--TODO: recommend specifying a source repo
- , check (length (synopsis pkg) >= 80) $
+ , check (ShortText.length (synopsis pkg) >= 80) $
PackageDistSuspicious
"The 'synopsis' field is rather long (max 80 chars is recommended)."
-- See also https://github.com/haskell/cabal/pull/3479
- , check (not (null (description pkg))
- && length (description pkg) <= length (synopsis pkg)) $
+ , check (not (ShortText.null (description pkg))
+ && ShortText.length (description pkg) <= ShortText.length (synopsis pkg)) $
PackageDistSuspicious $
"The 'description' field should be longer than the 'synopsis' "
++ "field. "
@@ -601,7 +591,7 @@ checkFields pkg =
, name `elem` map prettyShow knownLanguages ]
testedWithImpossibleRanges =
- [ Dependency (mkPackageName (prettyShow compiler)) vr Set.empty
+ [ Dependency (mkPackageName (prettyShow compiler)) vr mainLibSet
| (compiler, vr) <- testedWith pkg
, isNoVersion vr ]
@@ -680,7 +670,7 @@ checkOldLicense pkg lic = catMaybes
PackageDistSuspicious
"The 'license' is AllRightsReserved. Is that really what you want?"
- , checkVersion [1,4] (lic `notElem` compatLicenses) $
+ , checkVersion CabalSpecV1_4 (lic `notElem` compatLicenses) $
PackageDistInexcusable $
"Unfortunately the license " ++ quote (prettyShow (license pkg))
++ " messes up the parser in earlier Cabal versions so you need to "
@@ -733,10 +723,10 @@ checkOldLicense pkg lic = catMaybes
where knownVersions = [ v' | Apache (Just v') <- knownLicenses ]
unknownLicenseVersion _ = Nothing
- checkVersion :: [Int] -> Bool -> PackageCheck -> Maybe PackageCheck
+ checkVersion :: CabalSpecVersion -> Bool -> PackageCheck -> Maybe PackageCheck
checkVersion ver cond pc
- | specVersion pkg >= mkVersion ver = Nothing
- | otherwise = check cond pc
+ | specVersion pkg >= ver = Nothing
+ | otherwise = check cond pc
compatLicenses = [ GPL Nothing, LGPL Nothing, AGPL Nothing, BSD3, BSD4
, PublicDomain, AllRightsReserved
@@ -760,7 +750,7 @@ checkSourceRepos pkg =
PackageDistInexcusable
"The source-repository 'location' is a required field."
- , check (repoType repo == Just CVS && isNothing (repoModule repo)) $
+ , check (repoType repo == Just (KnownRepoType CVS) && isNothing (repoModule repo)) $
PackageDistInexcusable
"For a CVS source-repository, the 'module' is a required field."
@@ -807,7 +797,7 @@ checkGhcOptions fieldName getOptions pkg =
, checkFlags ["-fhpc"] $
PackageDistInexcusable $
- "'" ++ fieldName ++ ": -fhpc' is not not necessary. Use the configure flag "
+ "'" ++ fieldName ++ ": -fhpc' is not necessary. Use the configure flag "
++ " --enable-coverage instead."
, checkFlags ["-prof"] $
@@ -1146,41 +1136,8 @@ checkCabalVersion :: PackageDescription -> [PackageCheck]
checkCabalVersion pkg =
catMaybes [
- -- check syntax of cabal-version field
- check (specVersion pkg >= mkVersion [1,10]
- && not simpleSpecVersionRangeSyntax) $
- PackageBuildWarning $
- "Packages relying on Cabal 1.10 or later must only specify a "
- ++ "version range of the form 'cabal-version: >= x.y'. Use "
- ++ "'cabal-version: >= " ++ prettyShow (specVersion pkg) ++ "'."
-
- -- check syntax of cabal-version field
- , check (specVersion pkg < mkVersion [1,9]
- && not simpleSpecVersionRangeSyntax) $
- PackageDistSuspicious $
- "It is recommended that the 'cabal-version' field only specify a "
- ++ "version range of the form '>= x.y'. Use "
- ++ "'cabal-version: >= " ++ prettyShow (specVersion pkg) ++ "'. "
- ++ "Tools based on Cabal 1.10 and later will ignore upper bounds."
-
- -- check syntax of cabal-version field
- , checkVersion [1,12] simpleSpecVersionSyntax $
- PackageBuildWarning $
- "With Cabal 1.10 or earlier, the 'cabal-version' field must use "
- ++ "range syntax rather than a simple version number. Use "
- ++ "'cabal-version: >= " ++ prettyShow (specVersion pkg) ++ "'."
-
- -- check syntax of cabal-version field
- , check (specVersion pkg >= mkVersion [1,12]
- && not simpleSpecVersionSyntax) $
- (if specVersion pkg >= mkVersion [2,0] then PackageDistSuspicious else PackageDistSuspiciousWarn) $
- "Packages relying on Cabal 1.12 or later should specify a "
- ++ "specific version of the Cabal spec of the form "
- ++ "'cabal-version: x.y'. "
- ++ "Use 'cabal-version: " ++ prettyShow (specVersion pkg) ++ "'."
-
-- check use of test suite sections
- , checkVersion [1,8] (not (null $ testSuites pkg)) $
+ checkVersion CabalSpecV1_8 (not (null $ testSuites pkg)) $
PackageDistInexcusable $
"The 'test-suite' section is new in Cabal 1.10. "
++ "Unfortunately it messes up the parser in older Cabal versions "
@@ -1190,47 +1147,47 @@ checkCabalVersion pkg =
-- check use of default-language field
-- note that we do not need to do an equivalent check for the
-- other-language field since that one does not change behaviour
- , checkVersion [1,10] (any isJust (buildInfoField defaultLanguage)) $
+ , checkVersion CabalSpecV1_10 (any isJust (buildInfoField defaultLanguage)) $
PackageBuildWarning $
"To use the 'default-language' field the package needs to specify "
++ "at least 'cabal-version: >= 1.10'."
- , check (specVersion pkg >= mkVersion [1,10]
+ , check (specVersion pkg >= CabalSpecV1_10 && specVersion pkg < CabalSpecV3_4
&& (any isNothing (buildInfoField defaultLanguage))) $
PackageBuildWarning $
- "Packages using 'cabal-version: >= 1.10' must specify the "
+ "Packages using 'cabal-version: >= 1.10' and before 'cabal-version: 3.4' must specify the "
++ "'default-language' field for each component (e.g. Haskell98 or "
++ "Haskell2010). If a component uses different languages in "
++ "different modules then list the other ones in the "
++ "'other-languages' field."
- , checkVersion [1,18]
+ , checkVersion CabalSpecV1_18
(not . null $ extraDocFiles pkg) $
PackageDistInexcusable $
"To use the 'extra-doc-files' field the package needs to specify "
++ "at least 'cabal-version: >= 1.18'."
- , checkVersion [2,0]
+ , checkVersion CabalSpecV2_0
(not (null (subLibraries pkg))) $
PackageDistInexcusable $
"To use multiple 'library' sections or a named library section "
++ "the package needs to specify at least 'cabal-version: 2.0'."
-- check use of reexported-modules sections
- , checkVersion [1,21]
+ , checkVersion CabalSpecV1_22
(any (not.null.reexportedModules) (allLibraries pkg)) $
PackageDistInexcusable $
"To use the 'reexported-module' field the package needs to specify "
++ "at least 'cabal-version: >= 1.22'."
-- check use of thinning and renaming
- , checkVersion [1,25] usesBackpackIncludes $
+ , checkVersion CabalSpecV2_0 usesBackpackIncludes $
PackageDistInexcusable $
"To use the 'mixins' field the package needs to specify "
++ "at least 'cabal-version: 2.0'."
-- check use of 'extra-framework-dirs' field
- , checkVersion [1,23] (any (not . null) (buildInfoField extraFrameworkDirs)) $
+ , checkVersion CabalSpecV1_24 (any (not . null) (buildInfoField extraFrameworkDirs)) $
-- Just a warning, because this won't break on old Cabal versions.
PackageDistSuspiciousWarn $
"To use the 'extra-framework-dirs' field the package needs to specify"
@@ -1238,13 +1195,13 @@ checkCabalVersion pkg =
-- check use of default-extensions field
-- don't need to do the equivalent check for other-extensions
- , checkVersion [1,10] (any (not . null) (buildInfoField defaultExtensions)) $
+ , checkVersion CabalSpecV1_10 (any (not . null) (buildInfoField defaultExtensions)) $
PackageBuildWarning $
"To use the 'default-extensions' field the package needs to specify "
++ "at least 'cabal-version: >= 1.10'."
-- check use of extensions field
- , check (specVersion pkg >= mkVersion [1,10]
+ , check (specVersion pkg >= CabalSpecV1_10
&& (any (not . null) (buildInfoField oldExtensions))) $
PackageBuildWarning $
"For packages using 'cabal-version: >= 1.10' the 'extensions' "
@@ -1253,41 +1210,7 @@ checkCabalVersion pkg =
++ "the 'other-extensions' field lists extensions that are used in "
++ "some modules, e.g. via the {-# LANGUAGE #-} pragma."
- -- check use of "foo (>= 1.0 && < 1.4) || >=1.8 " version-range syntax
- , checkVersion [1,8] (not (null versionRangeExpressions)) $
- PackageDistInexcusable $
- "The package uses full version-range expressions "
- ++ "in a 'build-depends' field: "
- ++ commaSep (map displayRawDependency versionRangeExpressions)
- ++ ". To use this new syntax the package needs to specify at least "
- ++ "'cabal-version: >= 1.8'. Alternatively, if broader compatibility "
- ++ "is important, then convert to conjunctive normal form, and use "
- ++ "multiple 'build-depends:' lines, one conjunct per line."
-
- -- check use of "build-depends: foo == 1.*" syntax
- , checkVersion [1,6] (not (null depsUsingWildcardSyntax)) $
- PackageDistInexcusable $
- "The package uses wildcard syntax in the 'build-depends' field: "
- ++ commaSep (map prettyShow depsUsingWildcardSyntax)
- ++ ". To use this new syntax the package need to specify at least "
- ++ "'cabal-version: >= 1.6'. Alternatively, if broader compatibility "
- ++ "is important then use: " ++ commaSep
- [ prettyShow (Dependency name (eliminateWildcardSyntax versionRange) Set.empty)
- | Dependency name versionRange _ <- depsUsingWildcardSyntax ]
-
- -- check use of "build-depends: foo ^>= 1.2.3" syntax
- , checkVersion [2,0] (not (null depsUsingMajorBoundSyntax)) $
- PackageDistInexcusable $
- "The package uses major bounded version syntax in the "
- ++ "'build-depends' field: "
- ++ commaSep (map prettyShow depsUsingMajorBoundSyntax)
- ++ ". To use this new syntax the package need to specify at least "
- ++ "'cabal-version: 2.0'. Alternatively, if broader compatibility "
- ++ "is important then use: " ++ commaSep
- [ prettyShow (Dependency name (eliminateMajorBoundSyntax versionRange) Set.empty)
- | Dependency name versionRange _ <- depsUsingMajorBoundSyntax ]
-
- , checkVersion [2,1] (any (not . null)
+ , checkVersion CabalSpecV3_0 (any (not . null)
(concatMap buildInfoField
[ asmSources
, cmmSources
@@ -1296,60 +1219,40 @@ checkCabalVersion pkg =
PackageDistInexcusable $
"The use of 'asm-sources', 'cmm-sources', 'extra-bundled-libraries' "
++ " and 'extra-library-flavours' requires the package "
- ++ " to specify at least 'cabal-version: >= 2.1'."
+ ++ " to specify at least 'cabal-version: 3.0'."
- , checkVersion [2,5] (any (not . null) $ buildInfoField extraDynLibFlavours) $
+ , checkVersion CabalSpecV3_0 (any (not . null) $ buildInfoField extraDynLibFlavours) $
PackageDistInexcusable $
"The use of 'extra-dynamic-library-flavours' requires the package "
- ++ " to specify at least 'cabal-version: >= 2.5'. The flavours are: "
+ ++ " to specify at least 'cabal-version: 3.0'. The flavours are: "
++ commaSep [ flav
| flavs <- buildInfoField extraDynLibFlavours
, flav <- flavs ]
- , checkVersion [2,1] (any (not . null)
+ , checkVersion CabalSpecV2_2 (any (not . null)
(buildInfoField virtualModules)) $
PackageDistInexcusable $
"The use of 'virtual-modules' requires the package "
- ++ " to specify at least 'cabal-version: >= 2.1'."
-
- -- check use of "tested-with: GHC (>= 1.0 && < 1.4) || >=1.8 " syntax
- , checkVersion [1,8] (not (null testedWithVersionRangeExpressions)) $
- PackageDistInexcusable $
- "The package uses full version-range expressions "
- ++ "in a 'tested-with' field: "
- ++ commaSep (map displayRawDependency testedWithVersionRangeExpressions)
- ++ ". To use this new syntax the package needs to specify at least "
- ++ "'cabal-version: >= 1.8'."
-
- -- check use of "tested-with: GHC == 6.12.*" syntax
- , checkVersion [1,6] (not (null testedWithUsingWildcardSyntax)) $
- PackageDistInexcusable $
- "The package uses wildcard syntax in the 'tested-with' field: "
- ++ commaSep (map prettyShow testedWithUsingWildcardSyntax)
- ++ ". To use this new syntax the package need to specify at least "
- ++ "'cabal-version: >= 1.6'. Alternatively, if broader compatibility "
- ++ "is important then use: " ++ commaSep
- [ prettyShow (Dependency name (eliminateWildcardSyntax versionRange) Set.empty)
- | Dependency name versionRange _ <- testedWithUsingWildcardSyntax ]
+ ++ " to specify at least 'cabal-version: 2.2'."
-- check use of "source-repository" section
- , checkVersion [1,6] (not (null (sourceRepos pkg))) $
+ , checkVersion CabalSpecV1_6 (not (null (sourceRepos pkg))) $
PackageDistInexcusable $
"The 'source-repository' section is new in Cabal 1.6. "
++ "Unfortunately it messes up the parser in earlier Cabal versions "
++ "so you need to specify 'cabal-version: >= 1.6'."
-- check for new language extensions
- , checkVersion [1,2,3] (not (null mentionedExtensionsThatNeedCabal12)) $
+ , checkVersion CabalSpecV1_4 (not (null mentionedExtensionsThatNeedCabal12)) $
PackageDistInexcusable $
"Unfortunately the language extensions "
++ commaSep (map (quote . prettyShow) mentionedExtensionsThatNeedCabal12)
++ " break the parser in earlier Cabal versions so you need to "
- ++ "specify 'cabal-version: >= 1.2.3'. Alternatively if you require "
+ ++ "specify 'cabal-version: >= 1.4'. Alternatively if you require "
++ "compatibility with earlier Cabal versions then you may be able to "
++ "use an equivalent compiler-specific flag."
- , checkVersion [1,4] (not (null mentionedExtensionsThatNeedCabal14)) $
+ , checkVersion CabalSpecV1_4 (not (null mentionedExtensionsThatNeedCabal14)) $
PackageDistInexcusable $
"Unfortunately the language extensions "
++ commaSep (map (quote . prettyShow) mentionedExtensionsThatNeedCabal14)
@@ -1358,7 +1261,7 @@ checkCabalVersion pkg =
++ "compatibility with earlier Cabal versions then you may be able to "
++ "use an equivalent compiler-specific flag."
- , check (specVersion pkg >= mkVersion [1,23]
+ , check (specVersion pkg >= CabalSpecV1_24
&& isNothing (setupBuildInfo pkg)
&& buildType pkg == Custom) $
PackageBuildWarning $
@@ -1368,7 +1271,7 @@ checkCabalVersion pkg =
++ "The 'setup-depends' field uses the same syntax as 'build-depends', "
++ "so a simple example would be 'setup-depends: base, Cabal'."
- , check (specVersion pkg < mkVersion [1,23]
+ , check (specVersion pkg < CabalSpecV1_24
&& isNothing (setupBuildInfo pkg)
&& buildType pkg == Custom) $
PackageDistSuspiciousWarn $
@@ -1379,7 +1282,7 @@ checkCabalVersion pkg =
++ "The 'setup-depends' field uses the same syntax as 'build-depends', "
++ "so a simple example would be 'setup-depends: base, Cabal'."
- , check (specVersion pkg >= mkVersion [1,25]
+ , check (specVersion pkg >= CabalSpecV2_0
&& elem (autogenPathsModuleName pkg) allModuleNames
&& not (elem (autogenPathsModuleName pkg) allModuleNamesAutogen) ) $
PackageDistInexcusable $
@@ -1396,89 +1299,15 @@ checkCabalVersion pkg =
-- the version given. This is for cases where a new Cabal version adds
-- a new feature and we want to check that it is not used prior to that
-- version.
- checkVersion :: [Int] -> Bool -> PackageCheck -> Maybe PackageCheck
+ checkVersion :: CabalSpecVersion -> Bool -> PackageCheck -> Maybe PackageCheck
checkVersion ver cond pc
- | specVersion pkg >= mkVersion ver = Nothing
- | otherwise = check cond pc
+ | specVersion pkg >= ver = Nothing
+ | otherwise = check cond pc
buildInfoField field = map field (allBuildInfo pkg)
- versionRangeExpressions =
- [ dep | dep@(Dependency _ vr _) <- allBuildDepends pkg
- , usesNewVersionRangeSyntax vr ]
-
- testedWithVersionRangeExpressions =
- [ Dependency (mkPackageName (prettyShow compiler)) vr Set.empty
- | (compiler, vr) <- testedWith pkg
- , usesNewVersionRangeSyntax vr ]
-
- simpleSpecVersionRangeSyntax =
- either (const True) (cataVersionRange alg) (specVersionRaw pkg)
- where
- alg (OrLaterVersionF _) = True
- alg _ = False
-
- -- is the cabal-version field a simple version number, rather than a range
- simpleSpecVersionSyntax =
- either (const True) (const False) (specVersionRaw pkg)
-
- usesNewVersionRangeSyntax :: VersionRange -> Bool
- usesNewVersionRangeSyntax
- = (> 2) -- uses the new syntax if depth is more than 2
- . cataVersionRange alg
- where
- alg (UnionVersionRangesF a b) = a + b
- alg (IntersectVersionRangesF a b) = a + b
- alg (VersionRangeParensF _) = 3
- alg _ = 1 :: Int
-
- depsUsingWildcardSyntax = [ dep | dep@(Dependency _ vr _) <- allBuildDepends pkg
- , usesWildcardSyntax vr ]
-
- depsUsingMajorBoundSyntax = [ dep | dep@(Dependency _ vr _) <- allBuildDepends pkg
- , usesMajorBoundSyntax vr ]
-
usesBackpackIncludes = any (not . null . mixins) (allBuildInfo pkg)
- testedWithUsingWildcardSyntax =
- [ Dependency (mkPackageName (prettyShow compiler)) vr Set.empty
- | (compiler, vr) <- testedWith pkg
- , usesWildcardSyntax vr ]
-
- usesWildcardSyntax :: VersionRange -> Bool
- usesWildcardSyntax = cataVersionRange alg
- where
- alg (WildcardVersionF _) = True
- alg (UnionVersionRangesF a b) = a || b
- alg (IntersectVersionRangesF a b) = a || b
- alg (VersionRangeParensF a) = a
- alg _ = False
-
- -- NB: this eliminates both, WildcardVersion and MajorBoundVersion
- -- because when WildcardVersion is not support, neither is MajorBoundVersion
- eliminateWildcardSyntax = hyloVersionRange embed projectVersionRange
- where
- embed (WildcardVersionF v) = intersectVersionRanges
- (orLaterVersion v) (earlierVersion (wildcardUpperBound v))
- embed (MajorBoundVersionF v) = intersectVersionRanges
- (orLaterVersion v) (earlierVersion (majorUpperBound v))
- embed vr = embedVersionRange vr
-
- usesMajorBoundSyntax :: VersionRange -> Bool
- usesMajorBoundSyntax = cataVersionRange alg
- where
- alg (MajorBoundVersionF _) = True
- alg (UnionVersionRangesF a b) = a || b
- alg (IntersectVersionRangesF a b) = a || b
- alg (VersionRangeParensF a) = a
- alg _ = False
-
- eliminateMajorBoundSyntax = hyloVersionRange embed projectVersionRange
- where
- embed (MajorBoundVersionF v) = intersectVersionRanges
- (orLaterVersion v) (earlierVersion (majorUpperBound v))
- embed vr = embedVersionRange vr
-
mentionedExtensions = [ ext | bi <- allBuildInfo pkg
, ext <- allExtensions bi ]
mentionedExtensionsThatNeedCabal12 =
@@ -1529,16 +1358,11 @@ checkCabalVersion pkg =
allModuleNamesAutogen = concatMap autogenModules (allBuildInfo pkg)
-displayRawDependency :: Dependency -> String
-displayRawDependency (Dependency pkg vr _sublibs) =
- prettyShow pkg ++ " " ++ prettyShow vr
-
-
-- ------------------------------------------------------------
-- * Checks on the GenericPackageDescription
-- ------------------------------------------------------------
--- | Check the build-depends fields for any weirdness or bad practise.
+-- | Check the build-depends fields for any weirdness or bad practice.
--
checkPackageVersions :: GenericPackageDescription -> [PackageCheck]
checkPackageVersions pkg =
@@ -1553,7 +1377,7 @@ checkPackageVersions pkg =
"The dependency 'build-depends: base' does not specify an upper "
++ "bound on the version number. Each major release of the 'base' "
++ "package changes the API in various ways and most packages will "
- ++ "need some changes to compile with it. The recommended practise "
+ ++ "need some changes to compile with it. The recommended practice "
++ "is to specify an upper bound on the version of the 'base' "
++ "package. This ensures your package will continue to build when a "
++ "new major version of the 'base' package is released. If you are "
@@ -1673,12 +1497,12 @@ checkUnusedFlags gpd
used :: Set.Set FlagName
used = mconcat
- [ toSetOf (L.condLibrary . traverse . traverseCondTreeV . L._Flag) gpd
- , toSetOf (L.condSubLibraries . traverse . _2 . traverseCondTreeV . L._Flag) gpd
- , toSetOf (L.condForeignLibs . traverse . _2 . traverseCondTreeV . L._Flag) gpd
- , toSetOf (L.condExecutables . traverse . _2 . traverseCondTreeV . L._Flag) gpd
- , toSetOf (L.condTestSuites . traverse . _2 . traverseCondTreeV . L._Flag) gpd
- , toSetOf (L.condBenchmarks . traverse . _2 . traverseCondTreeV . L._Flag) gpd
+ [ toSetOf (L.condLibrary . traverse . traverseCondTreeV . L._PackageFlag) gpd
+ , toSetOf (L.condSubLibraries . traverse . _2 . traverseCondTreeV . L._PackageFlag) gpd
+ , toSetOf (L.condForeignLibs . traverse . _2 . traverseCondTreeV . L._PackageFlag) gpd
+ , toSetOf (L.condExecutables . traverse . _2 . traverseCondTreeV . L._PackageFlag) gpd
+ , toSetOf (L.condTestSuites . traverse . _2 . traverseCondTreeV . L._PackageFlag) gpd
+ , toSetOf (L.condBenchmarks . traverse . _2 . traverseCondTreeV . L._PackageFlag) gpd
]
checkUnicodeXFields :: GenericPackageDescription -> [PackageCheck]
@@ -1702,7 +1526,7 @@ checkUnicodeXFields gpd
-- | cabal-version <2.2 + Paths_module + default-extensions: doesn't build.
checkPathsModuleExtensions :: PackageDescription -> [PackageCheck]
checkPathsModuleExtensions pd
- | specVersion pd >= mkVersion [2,1] = []
+ | specVersion pd >= CabalSpecV2_2 = []
| any checkBI (allBuildInfo pd) || any checkLib (allLibraries pd)
= return $ PackageBuildImpossible $ unwords
[ "The package uses RebindableSyntax with OverloadedStrings or OverloadedLists"
@@ -1823,14 +1647,14 @@ checkDevelopmentOnlyFlags pkg =
-- We've basically got three-values logic here: True, False or unknown
-- hence this pattern to propagate the unknown cases properly.
- definitelyFalse (Var (Flag n)) = maybe False not (Map.lookup n manualFlags)
+ definitelyFalse (Var (PackageFlag n)) = maybe False not (Map.lookup n manualFlags)
definitelyFalse (Var _) = False
definitelyFalse (Lit b) = not b
definitelyFalse (CNot c) = definitelyTrue c
definitelyFalse (COr c1 c2) = definitelyFalse c1 && definitelyFalse c2
definitelyFalse (CAnd c1 c2) = definitelyFalse c1 || definitelyFalse c2
- definitelyTrue (Var (Flag n)) = fromMaybe False (Map.lookup n manualFlags)
+ definitelyTrue (Var (PackageFlag n)) = fromMaybe False (Map.lookup n manualFlags)
definitelyTrue (Var _) = False
definitelyTrue (Lit b) = b
definitelyTrue (CNot c) = definitelyFalse c
@@ -1886,7 +1710,7 @@ checkDevelopmentOnlyFlags pkg =
-- | Sanity check things that requires IO. It looks at the files in the
-- package and expects to find the package unpacked in at the given file path.
--
-checkPackageFiles :: Verbosity -> PackageDescription -> FilePath -> NoCallStackIO [PackageCheck]
+checkPackageFiles :: Verbosity -> PackageDescription -> FilePath -> IO [PackageCheck]
checkPackageFiles verbosity pkg root = do
contentChecks <- checkPackageContent checkFilesIO pkg
preDistributionChecks <- checkPackageFilesPreDistribution verbosity pkg root
@@ -1920,7 +1744,8 @@ data CheckPackageContentOps m = CheckPackageContentOps {
-- The point of this extra generality is to allow doing checks in some virtual
-- file system, for example a tarball in memory.
--
-checkPackageContent :: Monad m => CheckPackageContentOps m
+checkPackageContent :: (Monad m, Applicative m)
+ => CheckPackageContentOps m
-> PackageDescription
-> m [PackageCheck]
checkPackageContent ops pkg = do
@@ -2011,11 +1836,12 @@ findPackageDesc ops
++ "Please use only one of: "
++ intercalate ", " l
-checkLicensesExist :: Monad m => CheckPackageContentOps m
+checkLicensesExist :: (Monad m, Applicative m)
+ => CheckPackageContentOps m
-> PackageDescription
-> m [PackageCheck]
checkLicensesExist ops pkg = do
- exists <- mapM (doesFileExist ops) (licenseFiles pkg)
+ exists <- traverse (doesFileExist ops) (licenseFiles pkg)
return
[ PackageBuildWarning $
"The '" ++ fieldname ++ "' field refers to the file "
@@ -2068,17 +1894,18 @@ checkLocalPathsExist ops pkg = do
}
| (dir, kind) <- missing ]
-checkMissingVcsInfo :: Monad m => CheckPackageContentOps m
+checkMissingVcsInfo :: (Monad m, Applicative m)
+ => CheckPackageContentOps m
-> PackageDescription
-> m [PackageCheck]
checkMissingVcsInfo ops pkg | null (sourceRepos pkg) = do
- vcsInUse <- liftM or $ mapM (doesDirectoryExist ops) repoDirnames
+ vcsInUse <- liftM or $ traverse (doesDirectoryExist ops) repoDirnames
if vcsInUse
then return [ PackageDistSuspicious message ]
else return []
where
repoDirnames = [ dirname | repo <- knownRepoTypes
- , dirname <- repoTypeDirname repo ]
+ , dirname <- repoTypeDirname repo]
message = "When distributing packages it is encouraged to specify source "
++ "control information in the .cabal file using one or more "
++ "'source-repository' sections. See the Cabal user guide for "
@@ -2086,17 +1913,16 @@ checkMissingVcsInfo ops pkg | null (sourceRepos pkg) = do
checkMissingVcsInfo _ _ = return []
-repoTypeDirname :: RepoType -> [FilePath]
-repoTypeDirname Darcs = ["_darcs"]
-repoTypeDirname Git = [".git"]
-repoTypeDirname SVN = [".svn"]
-repoTypeDirname CVS = ["CVS"]
-repoTypeDirname Mercurial = [".hg"]
-repoTypeDirname GnuArch = [".arch-params"]
-repoTypeDirname Bazaar = [".bzr"]
-repoTypeDirname Monotone = ["_MTN"]
-repoTypeDirname _ = []
-
+repoTypeDirname :: KnownRepoType -> [FilePath]
+repoTypeDirname Darcs = ["_darcs"]
+repoTypeDirname Git = [".git"]
+repoTypeDirname SVN = [".svn"]
+repoTypeDirname CVS = ["CVS"]
+repoTypeDirname Mercurial = [".hg"]
+repoTypeDirname GnuArch = [".arch-params"]
+repoTypeDirname Bazaar = [".bzr"]
+repoTypeDirname Monotone = ["_MTN"]
+repoTypeDirname Pijul = [".pijul"]
-- ------------------------------------------------------------
-- * Checks involving files in the package
@@ -2202,7 +2028,7 @@ checkTarPath path
-- check these on the server; these checks only make sense in the development
-- and package-creation environment. Hence we can use IO, rather than needing
-- to pass a 'CheckPackageContentOps' dictionary around.
-checkPackageFilesPreDistribution :: Verbosity -> PackageDescription -> FilePath -> NoCallStackIO [PackageCheck]
+checkPackageFilesPreDistribution :: Verbosity -> PackageDescription -> FilePath -> IO [PackageCheck]
-- Note: this really shouldn't return any 'Inexcusable' warnings,
-- because that will make us say that Hackage would reject the package.
-- But, because Hackage doesn't run these tests, that will be a lie!
@@ -2212,7 +2038,7 @@ checkPackageFilesPreDistribution = checkGlobFiles
checkGlobFiles :: Verbosity
-> PackageDescription
-> FilePath
- -> NoCallStackIO [PackageCheck]
+ -> IO [PackageCheck]
checkGlobFiles verbosity pkg root =
fmap concat $ for allGlobs $ \(field, dir, glob) ->
-- Note: we just skip over parse errors here; they're reported elsewhere.
diff --git a/cabal/Cabal/Distribution/PackageDescription/Configuration.hs b/cabal/Cabal/Distribution/PackageDescription/Configuration.hs
index ee53b77..34adecc 100644
--- a/cabal/Cabal/Distribution/PackageDescription/Configuration.hs
+++ b/cabal/Cabal/Distribution/PackageDescription/Configuration.hs
@@ -32,42 +32,36 @@ module Distribution.PackageDescription.Configuration (
mapTreeConstrs,
transformAllBuildInfos,
transformAllBuildDepends,
+ transformAllBuildDependsN,
) where
-import Prelude ()
import Distribution.Compat.Prelude
+import Prelude ()
-- lens
-import qualified Distribution.Types.BuildInfo.Lens as L
+import qualified Distribution.Types.BuildInfo.Lens as L
import qualified Distribution.Types.GenericPackageDescription.Lens as L
-import qualified Distribution.Types.PackageDescription.Lens as L
-import qualified Distribution.Types.SetupBuildInfo.Lens as L
-
-import Distribution.PackageDescription
-import Distribution.PackageDescription.Utils
-import Distribution.Version
-import Distribution.Compiler
-import Distribution.System
-import Distribution.Parsec
-import Distribution.Pretty
-import Distribution.Compat.CharParsing hiding (char)
-import qualified Distribution.Compat.CharParsing as P
-import Distribution.Simple.Utils
-import Distribution.Compat.Lens
-import Distribution.Types.ComponentRequestedSpec
-import Distribution.Types.ForeignLib
-import Distribution.Types.Component
-import Distribution.Types.Dependency
-import Distribution.Types.PackageName
-import Distribution.Types.UnqualComponentName
-import Distribution.Types.CondTree
-import Distribution.Types.Condition
-import Distribution.Types.DependencyMap
-
-import qualified Data.Map.Strict as Map.Strict
-import qualified Data.Map.Lazy as Map
-import qualified Data.Set as Set
-import Data.Tree ( Tree(Node) )
+import qualified Distribution.Types.PackageDescription.Lens as L
+import qualified Distribution.Types.SetupBuildInfo.Lens as L
+
+import Distribution.Compat.CharParsing hiding (char)
+import qualified Distribution.Compat.CharParsing as P
+import Distribution.Compat.Lens
+import Distribution.Compiler
+import Distribution.PackageDescription
+import Distribution.PackageDescription.Utils
+import Distribution.Parsec
+import Distribution.Pretty
+import Distribution.Simple.Utils
+import Distribution.System
+import Distribution.Types.Component
+import Distribution.Types.ComponentRequestedSpec
+import Distribution.Types.DependencyMap
+import Distribution.Types.PackageVersionConstraint
+import Distribution.Version
+
+import qualified Data.Map.Lazy as Map
+import Data.Tree (Tree (Node))
------------------------------------------------------------------------------
@@ -89,7 +83,7 @@ simplifyWithSysParams os arch cinfo cond = (cond', flags)
Just compat -> Right (any matchImpl compat)
where
matchImpl (CompilerId c v) = comp == c && v `withinRange` vr
- interp (Flag f) = Left f
+ interp (PackageFlag f) = Left f
-- TODO: Add instances and check
--
@@ -126,10 +120,10 @@ parseCondition = condOr
boolLiteral = fmap Lit parsec
archIdent = fmap Arch parsec
osIdent = fmap OS parsec
- flagIdent = fmap (Flag . mkFlagName . lowercase) (munch1 isIdentChar)
+ flagIdent = fmap (PackageFlag . mkFlagName . lowercase) (munch1 isIdentChar)
isIdentChar c = isAlphaNum c || c == '_' || c == '-'
oper s = sp >> string s >> sp
- sp = spaces
+ sp = spaces
implIdent = do i <- parsec
vr <- sp >> option anyVersion parsec
return $ Impl i vr
@@ -178,7 +172,7 @@ resolveWithFlags ::
-> OS -- ^ OS as returned by Distribution.System.buildOS
-> Arch -- ^ Arch as returned by Distribution.System.buildArch
-> CompilerInfo -- ^ Compiler information
- -> [Dependency] -- ^ Additional constraints
+ -> [PackageVersionConstraint] -- ^ Additional constraints
-> [CondTree ConfVar [Dependency] P