summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsolpeth <>2020-01-20 04:45:00 (GMT)
committerhdiff <hdiff@hdiff.luite.com>2020-01-20 04:45:00 (GMT)
commit863ffa9d23dd152a9489f5b958c47fc5dcbf6f10 (patch)
tree421cb865d9a9998fe99887f5723f11b7c6391565
parentc119b2bdf7ac30795c293a34b4aa4c8b90f6af0e (diff)
version 0.6.30.6.3
-rw-r--r--Cabal2Ebuild.hs2
-rw-r--r--Main.hs4
-rw-r--r--Merge.hs53
-rw-r--r--Merge/Dependencies.hs42
-rw-r--r--Portage/Cabal.hs5
-rw-r--r--Portage/GHCCore.hs84
-rw-r--r--cabal/.ghci2
-rw-r--r--cabal/.ghcid1
-rw-r--r--cabal/.mailmap34
-rw-r--r--cabal/.projectile (renamed from cabal/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/setup-with-hpc.out)0
-rw-r--r--cabal/.travis.yml57
-rw-r--r--cabal/AUTHORS37
-rw-r--r--cabal/Cabal/Cabal.cabal285
-rw-r--r--cabal/Cabal/ChangeLog.md888
-rw-r--r--cabal/Cabal/Distribution/Backpack.hs111
-rw-r--r--cabal/Cabal/Distribution/Backpack/ConfiguredComponent.hs27
-rw-r--r--cabal/Cabal/Distribution/CabalSpecVersion.hs80
-rw-r--r--cabal/Cabal/Distribution/Compat/Binary.hs4
-rw-r--r--cabal/Cabal/Distribution/Compat/CharParsing.hs356
-rw-r--r--cabal/Cabal/Distribution/Compat/CopyFile.hs75
-rw-r--r--cabal/Cabal/Distribution/Compat/DList.hs4
-rw-r--r--cabal/Cabal/Distribution/Compat/Directory.hs44
-rw-r--r--cabal/Cabal/Distribution/Compat/Environment.hs20
-rw-r--r--cabal/Cabal/Distribution/Compat/Graph.hs17
-rw-r--r--cabal/Cabal/Distribution/Compat/Internal/TempFile.hs1
-rw-r--r--cabal/Cabal/Distribution/Compat/Lens.hs32
-rw-r--r--cabal/Cabal/Distribution/Compat/Map/Strict.hs31
-rw-r--r--cabal/Cabal/Distribution/Compat/Parsec.hs78
-rw-r--r--cabal/Cabal/Distribution/Compat/Parsing.hs403
-rw-r--r--cabal/Cabal/Distribution/Compat/Prelude.hs2
-rw-r--r--cabal/Cabal/Distribution/Compat/ReadP.hs31
-rw-r--r--cabal/Cabal/Distribution/Compat/Time.hs17
-rw-r--r--cabal/Cabal/Distribution/Compiler.hs13
-rw-r--r--cabal/Cabal/Distribution/FieldGrammar.hs3
-rw-r--r--cabal/Cabal/Distribution/FieldGrammar/Class.hs26
-rw-r--r--cabal/Cabal/Distribution/FieldGrammar/FieldDescrs.hs87
-rw-r--r--cabal/Cabal/Distribution/FieldGrammar/Parsec.hs173
-rw-r--r--cabal/Cabal/Distribution/FieldGrammar/Pretty.hs12
-rw-r--r--cabal/Cabal/Distribution/InstalledPackageInfo.hs461
-rw-r--r--cabal/Cabal/Distribution/License.hs90
-rw-r--r--cabal/Cabal/Distribution/Make.hs2
-rw-r--r--cabal/Cabal/Distribution/ModuleName.hs6
-rw-r--r--cabal/Cabal/Distribution/Package.hs2
-rw-r--r--cabal/Cabal/Distribution/PackageDescription.hs6
-rw-r--r--cabal/Cabal/Distribution/PackageDescription/Check.hs446
-rw-r--r--cabal/Cabal/Distribution/PackageDescription/Configuration.hs161
-rw-r--r--cabal/Cabal/Distribution/PackageDescription/FieldGrammar.hs44
-rw-r--r--cabal/Cabal/Distribution/PackageDescription/Parse.hs1336
-rw-r--r--cabal/Cabal/Distribution/PackageDescription/Parsec.hs560
-rw-r--r--cabal/Cabal/Distribution/PackageDescription/PrettyPrint.hs3
-rw-r--r--cabal/Cabal/Distribution/Parsec/Class.hs339
-rw-r--r--cabal/Cabal/Distribution/Parsec/Common.hs43
-rw-r--r--cabal/Cabal/Distribution/Parsec/ConfVar.hs47
-rw-r--r--cabal/Cabal/Distribution/Parsec/FieldLineStream.hs96
-rw-r--r--cabal/Cabal/Distribution/Parsec/Lexer.hs108
-rw-r--r--cabal/Cabal/Distribution/Parsec/LexerMonad.hs33
-rw-r--r--cabal/Cabal/Distribution/Parsec/Newtypes.hs96
-rw-r--r--cabal/Cabal/Distribution/Parsec/ParseResult.hs104
-rw-r--r--cabal/Cabal/Distribution/Parsec/Parser.hs2
-rw-r--r--cabal/Cabal/Distribution/PrettyUtils.hs2
-rw-r--r--cabal/Cabal/Distribution/ReadE.hs11
-rw-r--r--cabal/Cabal/Distribution/SPDX.hs40
-rw-r--r--cabal/Cabal/Distribution/SPDX/License.hs64
-rw-r--r--cabal/Cabal/Distribution/SPDX/LicenseExceptionId.hs213
-rw-r--r--cabal/Cabal/Distribution/SPDX/LicenseExpression.hs161
-rw-r--r--cabal/Cabal/Distribution/SPDX/LicenseId.hs1885
-rw-r--r--cabal/Cabal/Distribution/SPDX/LicenseListVersion.hs16
-rw-r--r--cabal/Cabal/Distribution/SPDX/LicenseReference.hs79
-rw-r--r--cabal/Cabal/Distribution/Simple.hs158
-rw-r--r--cabal/Cabal/Distribution/Simple/Bench.hs2
-rw-r--r--cabal/Cabal/Distribution/Simple/Build.hs82
-rw-r--r--cabal/Cabal/Distribution/Simple/Build/PathsModule.hs63
-rw-r--r--cabal/Cabal/Distribution/Simple/BuildPaths.hs30
-rw-r--r--cabal/Cabal/Distribution/Simple/BuildTarget.hs2
-rw-r--r--cabal/Cabal/Distribution/Simple/Compiler.hs25
-rw-r--r--cabal/Cabal/Distribution/Simple/Configure.hs172
-rw-r--r--cabal/Cabal/Distribution/Simple/Doctest.hs3
-rw-r--r--cabal/Cabal/Distribution/Simple/Flag.hs124
-rw-r--r--cabal/Cabal/Distribution/Simple/GHC.hs493
-rw-r--r--cabal/Cabal/Distribution/Simple/GHC/EnvironmentParser.hs51
-rw-r--r--cabal/Cabal/Distribution/Simple/GHC/IPI642.hs114
-rw-r--r--cabal/Cabal/Distribution/Simple/GHC/IPIConvert.hs54
-rw-r--r--cabal/Cabal/Distribution/Simple/GHC/ImplInfo.hs10
-rw-r--r--cabal/Cabal/Distribution/Simple/GHC/Internal.hs59
-rw-r--r--cabal/Cabal/Distribution/Simple/GHCJS.hs150
-rw-r--r--cabal/Cabal/Distribution/Simple/Glob.hs295
-rw-r--r--cabal/Cabal/Distribution/Simple/Haddock.hs250
-rw-r--r--cabal/Cabal/Distribution/Simple/HaskellSuite.hs4
-rw-r--r--cabal/Cabal/Distribution/Simple/Install.hs36
-rw-r--r--cabal/Cabal/Distribution/Simple/InstallDirs.hs30
-rw-r--r--cabal/Cabal/Distribution/Simple/JHC.hs195
-rw-r--r--cabal/Cabal/Distribution/Simple/LHC.hs778
-rw-r--r--cabal/Cabal/Distribution/Simple/PackageIndex.hs6
-rw-r--r--cabal/Cabal/Distribution/Simple/PreProcess.hs67
-rw-r--r--cabal/Cabal/Distribution/Simple/Program.hs21
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/Builtin.hs28
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/GHC.hs317
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/HcPkg.hs10
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/Types.hs12
-rw-r--r--cabal/Cabal/Distribution/Simple/Register.hs33
-rw-r--r--cabal/Cabal/Distribution/Simple/Setup.hs293
-rw-r--r--cabal/Cabal/Distribution/Simple/SrcDist.hs25
-rw-r--r--cabal/Cabal/Distribution/Simple/Test/ExeV10.hs2
-rw-r--r--cabal/Cabal/Distribution/Simple/Test/LibV09.hs2
-rw-r--r--cabal/Cabal/Distribution/Simple/UHC.hs8
-rw-r--r--cabal/Cabal/Distribution/Simple/UserHooks.hs5
-rw-r--r--cabal/Cabal/Distribution/Simple/Utils.hs65
-rw-r--r--cabal/Cabal/Distribution/System.hs45
-rw-r--r--cabal/Cabal/Distribution/Text.hs4
-rw-r--r--cabal/Cabal/Distribution/Types/AbiDependency.hs52
-rw-r--r--cabal/Cabal/Distribution/Types/AbiHash.hs15
-rw-r--r--cabal/Cabal/Distribution/Types/AnnotatedId.hs9
-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.hs2
-rw-r--r--cabal/Cabal/Distribution/Types/BuildInfo.hs8
-rw-r--r--cabal/Cabal/Distribution/Types/BuildInfo/Lens.hs4
-rw-r--r--cabal/Cabal/Distribution/Types/BuildType.hs45
-rw-r--r--cabal/Cabal/Distribution/Types/ComponentId.hs2
-rw-r--r--cabal/Cabal/Distribution/Types/CondTree.hs29
-rw-r--r--cabal/Cabal/Distribution/Types/Condition.hs2
-rw-r--r--cabal/Cabal/Distribution/Types/DependencyMap.hs23
-rw-r--r--cabal/Cabal/Distribution/Types/ExeDependency.hs2
-rw-r--r--cabal/Cabal/Distribution/Types/Executable.hs2
-rw-r--r--cabal/Cabal/Distribution/Types/Executable/Lens.hs9
-rw-r--r--cabal/Cabal/Distribution/Types/ExecutableScope.hs31
-rw-r--r--cabal/Cabal/Distribution/Types/ExposedModule.hs57
-rw-r--r--cabal/Cabal/Distribution/Types/ForeignLib.hs6
-rw-r--r--cabal/Cabal/Distribution/Types/ForeignLibOption.hs4
-rw-r--r--cabal/Cabal/Distribution/Types/ForeignLibType.hs4
-rw-r--r--cabal/Cabal/Distribution/Types/GenericPackageDescription.hs160
-rw-r--r--cabal/Cabal/Distribution/Types/GenericPackageDescription/Lens.hs37
-rw-r--r--cabal/Cabal/Distribution/Types/IncludeRenaming.hs4
-rw-r--r--cabal/Cabal/Distribution/Types/InstalledPackageInfo.hs170
-rw-r--r--cabal/Cabal/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs263
-rw-r--r--cabal/Cabal/Distribution/Types/InstalledPackageInfo/Lens.hs183
-rw-r--r--cabal/Cabal/Distribution/Types/LegacyExeDependency.hs2
-rw-r--r--cabal/Cabal/Distribution/Types/Library.hs4
-rw-r--r--cabal/Cabal/Distribution/Types/LocalBuildInfo.hs6
-rw-r--r--cabal/Cabal/Distribution/Types/Mixin.hs4
-rw-r--r--cabal/Cabal/Distribution/Types/Module.hs2
-rw-r--r--cabal/Cabal/Distribution/Types/ModuleReexport.hs6
-rw-r--r--cabal/Cabal/Distribution/Types/ModuleRenaming.hs6
-rw-r--r--cabal/Cabal/Distribution/Types/MungedPackageName.hs21
-rw-r--r--cabal/Cabal/Distribution/Types/PackageDescription.hs171
-rw-r--r--cabal/Cabal/Distribution/Types/PackageDescription/Lens.hs133
-rw-r--r--cabal/Cabal/Distribution/Types/PackageId.hs7
-rw-r--r--cabal/Cabal/Distribution/Types/PkgconfigDependency.hs2
-rw-r--r--cabal/Cabal/Distribution/Types/PkgconfigName.hs2
-rw-r--r--cabal/Cabal/Distribution/Types/SetupBuildInfo.hs2
-rw-r--r--cabal/Cabal/Distribution/Types/SourceRepo.hs10
-rw-r--r--cabal/Cabal/Distribution/Types/TestSuite.hs2
-rw-r--r--cabal/Cabal/Distribution/Types/TestSuiteInterface.hs1
-rw-r--r--cabal/Cabal/Distribution/Types/TestType.hs2
-rw-r--r--cabal/Cabal/Distribution/Types/UnitId.hs4
-rw-r--r--cabal/Cabal/Distribution/Types/Version.hs42
-rw-r--r--cabal/Cabal/Distribution/Types/VersionRange.hs130
-rw-r--r--cabal/Cabal/Distribution/Utils/Generic.hs45
-rw-r--r--cabal/Cabal/Distribution/Utils/IOData.hs6
-rw-r--r--cabal/Cabal/Distribution/Utils/String.hs2
-rw-r--r--cabal/Cabal/Distribution/Version.hs3
-rw-r--r--cabal/Cabal/Language/Haskell/Extension.hs24
-rw-r--r--cabal/Cabal/Makefile6
-rw-r--r--cabal/Cabal/README.md17
-rw-r--r--cabal/Cabal/changelog702
-rw-r--r--cabal/Cabal/doc/cabaldomain.py12
-rw-r--r--cabal/Cabal/doc/conf.py6
-rw-r--r--cabal/Cabal/doc/developing-packages.rst473
-rw-r--r--cabal/Cabal/doc/file-format-changelog.rst144
-rw-r--r--cabal/Cabal/doc/index.rst1
-rw-r--r--cabal/Cabal/doc/installing-packages.rst7
-rw-r--r--cabal/Cabal/doc/nix-local-build-overview.rst13
-rw-r--r--cabal/Cabal/doc/nix-local-build.rst278
-rw-r--r--cabal/Cabal/doc/references.inc2
-rwxr-xr-xcabal/Cabal/misc/travis-diff-files.sh2
-rw-r--r--cabal/Makefile50
-rw-r--r--cabal/README.md6
-rw-r--r--cabal/appveyor.yml76
-rw-r--r--cabal/boot/Lexer.x22
-rw-r--r--cabal/boot/SPDX.LicenseExceptionId.template.hs91
-rw-r--r--cabal/boot/SPDX.LicenseId.template.hs149
-rw-r--r--cabal/cabal-dev-scripts/cabal-dev-scripts.cabal41
-rw-r--r--cabal/cabal-dev-scripts/src/GenExtraSourceFiles.hs106
-rw-r--r--cabal/cabal-dev-scripts/src/GenSPDX.hs124
-rw-r--r--cabal/cabal-dev-scripts/src/GenSPDXExc.hs125
-rw-r--r--cabal/cabal-dev-scripts/src/GenUtils.hs104
-rw-r--r--cabal/cabal-dev-scripts/src/Preprocessor.hs222
-rw-r--r--cabal/cabal-install/Distribution/Client/Check.hs60
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdBench.hs32
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdBuild.hs69
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdClean.hs115
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdConfigure.hs6
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdErrorMessages.hs124
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdExec.hs7
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdFreeze.hs17
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdHaddock.hs38
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdInstall.hs706
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdLegacy.hs173
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdRepl.hs418
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdRun.hs336
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdSdist.hs362
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdTest.hs37
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdUpdate.hs79
-rw-r--r--cabal/cabal-install/Distribution/Client/Compat/Directory.hs13
-rw-r--r--cabal/cabal-install/Distribution/Client/Compat/ExecutablePath.hs19
-rw-r--r--cabal/cabal-install/Distribution/Client/Compat/Prelude.hs13
-rw-r--r--cabal/cabal-install/Distribution/Client/Compat/Process.hs6
-rw-r--r--cabal/cabal-install/Distribution/Client/Config.hs89
-rw-r--r--cabal/cabal-install/Distribution/Client/Configure.hs5
-rw-r--r--cabal/cabal-install/Distribution/Client/Dependency.hs56
-rw-r--r--cabal/cabal-install/Distribution/Client/DistDirLayout.hs32
-rw-r--r--cabal/cabal-install/Distribution/Client/Fetch.hs24
-rw-r--r--cabal/cabal-install/Distribution/Client/FetchUtils.hs24
-rw-r--r--cabal/cabal-install/Distribution/Client/FileMonitor.hs6
-rw-r--r--cabal/cabal-install/Distribution/Client/GenBounds.hs4
-rw-r--r--cabal/cabal-install/Distribution/Client/Get.hs338
-rw-r--r--cabal/cabal-install/Distribution/Client/GlobalFlags.hs22
-rw-r--r--cabal/cabal-install/Distribution/Client/Haddock.hs2
-rw-r--r--cabal/cabal-install/Distribution/Client/HttpUtils.hs121
-rw-r--r--cabal/cabal-install/Distribution/Client/IndexUtils.hs63
-rw-r--r--cabal/cabal-install/Distribution/Client/Init.hs120
-rw-r--r--cabal/cabal-install/Distribution/Client/Init/Types.hs4
-rw-r--r--cabal/cabal-install/Distribution/Client/Install.hs41
-rw-r--r--cabal/cabal-install/Distribution/Client/InstallPlan.hs10
-rw-r--r--cabal/cabal-install/Distribution/Client/InstallSymlink.hs36
-rw-r--r--cabal/cabal-install/Distribution/Client/List.hs13
-rw-r--r--cabal/cabal-install/Distribution/Client/Outdated.hs31
-rw-r--r--cabal/cabal-install/Distribution/Client/PackageHash.hs58
-rw-r--r--cabal/cabal-install/Distribution/Client/PackageUtils.hs8
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectBuilding.hs173
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectBuilding/Types.hs1
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectConfig.hs545
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectConfig/Legacy.hs181
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectConfig/Types.hs24
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectOrchestration.hs360
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectPlanOutput.hs64
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectPlanning.hs543
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectPlanning/Types.hs131
-rw-r--r--cabal/cabal-install/Distribution/Client/RebuildMonad.hs76
-rw-r--r--cabal/cabal-install/Distribution/Client/Run.hs2
-rw-r--r--cabal/cabal-install/Distribution/Client/Sandbox/Index.hs4
-rw-r--r--cabal/cabal-install/Distribution/Client/Setup.hs492
-rw-r--r--cabal/cabal-install/Distribution/Client/SetupWrapper.hs102
-rw-r--r--cabal/cabal-install/Distribution/Client/SourceRepoParse.hs22
-rw-r--r--cabal/cabal-install/Distribution/Client/SrcDist.hs4
-rw-r--r--cabal/cabal-install/Distribution/Client/TargetSelector.hs982
-rw-r--r--cabal/cabal-install/Distribution/Client/Targets.hs8
-rw-r--r--cabal/cabal-install/Distribution/Client/Types.hs29
-rw-r--r--cabal/cabal-install/Distribution/Client/Update.hs11
-rw-r--r--cabal/cabal-install/Distribution/Client/Upload.hs2
-rw-r--r--cabal/cabal-install/Distribution/Client/Utils.hs63
-rw-r--r--cabal/cabal-install/Distribution/Client/VCS.hs518
-rw-r--r--cabal/cabal-install/Distribution/Client/Win32SelfUpgrade.hs2
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular.hs137
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Builder.hs17
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/ConflictSet.hs2
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Dependency.hs46
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Explore.hs136
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Index.hs15
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/IndexConversion.hs334
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Linking.hs2
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Log.hs120
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Message.hs128
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Preference.hs12
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Solver.hs60
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Tree.hs10
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Validate.hs251
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Version.hs4
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/WeightedPSQ.hs11
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/ConstraintSource.hs6
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/SolverPackage.hs4
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/Variable.hs3
-rwxr-xr-xcabal/cabal-install/bootstrap.sh146
-rw-r--r--cabal/cabal-install/cabal-install.cabal598
-rw-r--r--cabal/cabal-install/cabal-install.cabal.pp642
-rw-r--r--cabal/cabal-install/changelog159
-rw-r--r--cabal/cabal-install/main/Main.hs164
-rw-r--r--cabal/cabal-install/solver-dsl/UnitTests/Distribution/Solver/Modular/DSL.hs (renamed from cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL.hs)77
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2.hs163
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/build/local-tarball/cabal.project2
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/build/local-tarball/p-0.1.tar.gzbin0 -> 319 bytes
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/build/local-tarball/q/Q.hs5
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/build/local-tarball/q/q.cabal8
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/targets/lib-only/p.cabal8
-rw-r--r--cabal/cabal-install/tests/UnitTests.hs6
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/ArbitraryInstances.hs4
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/Get.hs234
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs89
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/Targets.hs10
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/UserConfig.hs10
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/VCS.hs694
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL/TestCaseUtils.hs19
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/MemoryUsage.hs106
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck.hs69
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck/Utils.hs33
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs251
-rw-r--r--cabal/cabal-install/tests/UnitTests/Options.hs13
-rw-r--r--cabal/cabal-install/tests/UnitTests/TempTestDir.hs104
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutoconfBadPaths/Setup.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutoconfBadPaths/cabal.out82
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutoconfBadPaths/cabal.test.hs53
-rwxr-xr-xcabal/cabal-testsuite/PackageTests/AutoconfBadPaths/configure2406
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutoconfBadPaths/configure.ac3
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutoconfBadPaths/test.cabal8
-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.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/Package/setup.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/AutogenModules.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/setup.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes1/setup.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.cabal.out8
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes3/Includes3.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes5/setup.test.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/TargetSpecificDeps1/setup.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/TargetSpecificDeps3/setup.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildTargets/UseLocalPackage/use-local-version-of-package.out9
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildTargets/UseLocalPackageForSetup/use-local-package-as-setup-dep.out12
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildTargets/UseLocalPackageForSetup/use-local-package-as-setup-dep.test.hs27
-rw-r--r--cabal/cabal-testsuite/PackageTests/COnlyMain/my.cabal4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/InvalidGlob/cabal.out5
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/InvalidGlob/cabal.test.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/InvalidGlob/pkg.cabal13
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MissingGlobDirectory/Foo.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MissingGlobDirectory/cabal.out6
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MissingGlobDirectory/cabal.test.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MissingGlobDirectory/data/hello.dat1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MissingGlobDirectory/file-not-a-directory1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MissingGlobDirectory/pkg.cabal21
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MissingGlobDirectory/present/present/hello1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MissingGlobDirectory2/Foo.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MissingGlobDirectory2/cabal.out5
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MissingGlobDirectory2/cabal.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MissingGlobDirectory2/dir/foo.en.html1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MissingGlobDirectory2/pkg.cabal16
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MultiDotGlob2.2/check.out5
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MultiDotGlob2.2/check.test.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MultiDotGlob2.2/data/foo.bar.dat1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MultiDotGlob2.2/data/index.dat1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MultiDotGlob2.2/doc/.foo.html1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MultiDotGlob2.2/doc/bar.html1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MultiDotGlob2.2/doc/foo.en.html1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MultiDotGlob2.2/doc/foo.fr.html1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MultiDotGlob2.2/doc/index.html1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MultiDotGlob2.2/src/foo.cobol1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MultiDotGlob2.2/src/index.js1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/MultiDotGlob2.2/test.cabal19
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/NoGlobMatches/cabal.out3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/NoGlobMatches/cabal.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Check/NoGlobMatches/pkg.cabal14
-rw-r--r--cabal/cabal-testsuite/PackageTests/Configure/setup.test.hs8
-rw-r--r--cabal/cabal-testsuite/PackageTests/ConfigureComponent/Exe/setup.cabal.out6
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomDep/cabal.test.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomDep/custom/custom.cabal3
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomDep/sandbox.out6
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomDep/sandbox.test.hs8
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomPlain/cabal.test.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomPlain/plain.cabal1
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomPlain/setup.cabal.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomPlain/setup.out1
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomWithoutCabalDefaultMain/cabal.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/T4049/sandbox.out8
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/T4049/sandbox.test.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/legacy-autoconfigure.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/legacy-autoconfigure.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/legacy-no-args.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/legacy-no-args.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/legacy.out4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/legacy.test.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/sandbox-ghc-pkg.out10
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/sandbox-ghc-pkg.test.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/sandbox-hc-pkg.out10
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/sandbox-hc-pkg.test.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/sandbox-path.out10
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/sandbox-path.test.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/sandbox.out10
-rw-r--r--cabal/cabal-testsuite/PackageTests/Exec/sandbox.test.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/ForeignLibs/my-foreign-lib.cabal11
-rw-r--r--cabal/cabal-testsuite/PackageTests/ForeignLibs/src/MyForeignLib/Export.hs8
-rw-r--r--cabal/cabal-testsuite/PackageTests/Freeze/disable-benchmarks.out4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Freeze/disable-benchmarks.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Freeze/disable-tests.out4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Freeze/disable-tests.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Freeze/dry-run.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Freeze/dry-run.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Freeze/enable-benchmarks.out4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Freeze/enable-benchmarks.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Freeze/enable-tests.out4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Freeze/enable-tests.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Freeze/freeze.out4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Freeze/freeze.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/Executable/setup-static.test.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/sandbox-shadow.out10
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/sandbox-shadow.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/sandbox.out8
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/sandbox.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalVersions/BuildDependsBad/setup.cabal.out5
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/setup.cabal.out13
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/setup.out13
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalVersions/BuildDependsExtra/setup.test.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/OnlyConfigure/Bar.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/OnlyConfigure/Baz.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/OnlyConfigure/Foo.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/OnlyConfigure/Lib.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/OnlyConfigure/OnlyConfigure.cabal26
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/OnlyConfigure/cabal.out30
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/OnlyConfigure/cabal.project (renamed from cabal/cabal-testsuite/PackageTests/NewFreeze/cabal.project)0
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/OnlyConfigure/cabal.test.hs24
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/CmdExec/GhcInvocation/cabal.test.hs16
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/ExeAndLib/cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/MultipleExes/cabal.out4
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/MultiplePackages/cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/CustomSetup/LocalPackageWithCustomSetup/build-local-package-with-custom-setup.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/CustomSetup/LocalPackageWithCustomSetup/build-local-package-with-custom-setup.test.hs15
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/CustomSetup/RemotePackageWithCustomSetup/build-package-from-repo-with-custom-setup.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/CustomSetup/RemotePackageWithCustomSetup/build-package-from-repo-with-custom-setup.test.hs27
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/T3827/cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/T3978/cabal.out10
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/T4288/CustomIssue.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/T4288/Setup.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/T4288/T4288.cabal16
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/T4288/cabal.project1
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/T4288/cabal.test.hs17
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/T4288/setup-helper/SetupHelper.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/T4288/setup-helper/setup-helper.cabal9
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/T4375/cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/T4375/cabal.test.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/T5164/cabal.project2
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/T5164/cabal.test.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/T5164/setup-lib/SetupLib.hs9
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/T5164/setup-lib/example.txt1
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/T5164/setup-lib/setup-lib.cabal11
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/T5164/uses-custom-setup/Setup.hs7
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/T5164/uses-custom-setup/UsesCustomSetup.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewBuild/T5164/uses-custom-setup/uses-custom-setup.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/BuildTools/cabal.project1
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/BuildTools/my-local-package.cabal (renamed from cabal/cabal-testsuite/PackageTests/NewFreeze/my-local-package.cabal)0
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/BuildTools/new_freeze.out (renamed from cabal/cabal-testsuite/PackageTests/NewFreeze/new_freeze.out)10
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/BuildTools/new_freeze.test.hs (renamed from cabal/cabal-testsuite/PackageTests/NewFreeze/new_freeze.test.hs)5
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/BuildTools/repo/my-build-tool-dep-1.0/my-build-tool-dep.cabal (renamed from cabal/cabal-testsuite/PackageTests/NewFreeze/repo/my-build-tool-dep-1.0/my-build-tool-dep.cabal)0
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/BuildTools/repo/my-build-tool-dep-2.0/my-build-tool-dep.cabal (renamed from cabal/cabal-testsuite/PackageTests/NewFreeze/repo/my-build-tool-dep-2.0/my-build-tool-dep.cabal)0
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/BuildTools/repo/my-build-tool-dep-3.0/my-build-tool-dep.cabal (renamed from cabal/cabal-testsuite/PackageTests/NewFreeze/repo/my-build-tool-dep-3.0/my-build-tool-dep.cabal)0
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/BuildTools/repo/my-library-dep-1.0/my-library-dep.cabal (renamed from cabal/cabal-testsuite/PackageTests/NewFreeze/repo/my-library-dep-1.0/my-library-dep.cabal)0
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/Flags/cabal.project1
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/Flags/my-local-package.cabal7
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/Flags/new_freeze.out19
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/Flags/new_freeze.test.hs35
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/Flags/repo/false-dep-1.0/false-dep.cabal6
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/Flags/repo/my-library-dep-1.0/my-library-dep.cabal15
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/Flags/repo/true-dep-1.0/true-dep.cabal6
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/FreezeFile/Main.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/FreezeFile/cabal.project1
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/FreezeFile/my-local-package.cabal10
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/FreezeFile/new_freeze.out34
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/FreezeFile/new_freeze.test.hs53
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/FreezeFile/repo/my-library-dep-1.0/MyLibModule.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/FreezeFile/repo/my-library-dep-1.0/my-library-dep.cabal10
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/FreezeFile/repo/my-library-dep-2.0/MyLibModule.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewFreeze/FreezeFile/repo/my-library-dep-2.0/my-library-dep.cabal10
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/DeterministicTrivial/Main.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/DeterministicTrivial/cabal.project1
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/DeterministicTrivial/deterministic-0.tar.gzbin0 -> 303 bytes
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/DeterministicTrivial/deterministic.cabal7
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/DeterministicTrivial/deterministic.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/DeterministicTrivial/deterministic.test.hs18
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/Globbing/a/Main.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/Globbing/a/a.cabal9
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/Globbing/a/doc/index.html1
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/Globbing/cabal.out4
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/Globbing/cabal.project2
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/Globbing/cabal.test.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/ManyDataFiles/Main.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/ManyDataFiles/cabal.project1
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/ManyDataFiles/many-data-files.cabal9
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/ManyDataFiles/many-data-files.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/ManyDataFiles/many-data-files.test.hs17
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/a/Main.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/a/Test.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/a/a.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/all-output-dir.out3
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/all-output-dir.test.hs10
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/all-test-sute.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/all-test-sute.test.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/all.out3
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/all.test.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/b/Main.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/b/b.cabal7
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/cabal.project3
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/list-sources-output-dir.out3
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/list-sources-output-dir.test.hs9
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/multi-archive-to-stdout.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/multi-archive-to-stdout.test.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/multi-list-sources.out6
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/multi-list-sources.test.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/multi-target.out3
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/multi-target.test.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/target-remote-package.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/target-remote-package.test.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/valid-and-test-suite.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/MultiTarget/valid-and-test-suite.test.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/NullTerminated/Main.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/NullTerminated/cabal.outbin0 -> 42 bytes
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/NullTerminated/cabal.project2
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/NullTerminated/cabal.test.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/NewSdist/NullTerminated/test.cabal7
-rw-r--r--cabal/cabal-testsuite/PackageTests/Outdated/outdated-project-file.out10
-rw-r--r--cabal/cabal-testsuite/PackageTests/Outdated/outdated-project-file.test.hs13
-rw-r--r--cabal/cabal-testsuite/PackageTests/Outdated/outdated.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Outdated/outdated_freeze.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Outdated/variant.project1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Outdated/variant.project.freeze1
-rw-r--r--cabal/cabal-testsuite/PackageTests/PathsModule/Library/my.cabal23
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/HadrianT634/pkg/Main.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/HadrianT634/pkg/a.cabal9
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/HadrianT634/pkg/doc/hello.html1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/HadrianT634/setup.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/HadrianT634/setup.test.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3199/sandbox.out6
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3199/sandbox.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3436/cabal.test.hs8
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3436/sandbox.out14
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3436/sandbox.test.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3932/cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3932/cabal.test.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4154/install-time-with-constraint.out3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4154/install-time-with-constraint.test.hs17
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4154/repo/Cabal-99999/Cabal.cabal7
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4154/time.cabal2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4270/T4270.cabal1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4449/A.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4449/Setup.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4449/setup.out6
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4449/setup.test.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4449/test-t4449.cabal13
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4720/bug/Main.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4720/bug/bug.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4720/bug/cbits/bug.c2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4720/bug/extra-inc/bug-extra-inc.h0
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4720/cabal.out8
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4720/cabal.project4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4720/cabal.test.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4986/cabal.out6
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4986/cabal.project1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4986/cabal.test.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4986/client/Hello.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4986/client/client.cabal14
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4986/happy/Main.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4986/happy/happy.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5309/T5309.cabal149
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5309/app/Main.hs9
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5309/cabal.out54
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5309/cabal.project2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5309/cabal.test.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5309/lib/Bio/Character/Exportable/Class.hs56
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5309/lib/Data/TCM/Memoized.hs45
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5309/lib/Data/TCM/Memoized/FFI.hsc280
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5309/memoized-tcm/costMatrix.cpp93
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5309/memoized-tcm/costMatrix.h201
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5309/memoized-tcm/costMatrixWrapper.c28
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5309/memoized-tcm/costMatrixWrapper.h24
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5309/memoized-tcm/dynamicCharacterOperations.c35
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5309/memoized-tcm/dynamicCharacterOperations.h36
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5318/Main.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5318/empty-data-dir.cabal10
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5318/foo.dat1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5318/install.out8
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5318/install.test.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5318/sdist-list-sources.out3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5318/sdist-list-sources.test.hs7
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5386/Foo.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5386/Main.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5386/Setup.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5386/cabal.project2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5386/cabal.test.hs5
-rwxr-xr-xcabal/cabal-testsuite/PackageTests/Regression/T5386/configure2837
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5386/configure.ac5
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5386/test.buildinfo.in1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5386/test.cabal14
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5409/Main.hs11
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5409/cabal.project1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5409/pkg.cabal10
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5409/repo/build-tool-pkg-1/build-tool-pkg.cabal15
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5409/repo/build-tool-pkg-1/main/Main.hs11
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5409/repo/build-tool-pkg-1/src/BuildToolLibrary.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5409/repo/build-tool-pkg-2/build-tool-pkg.cabal15
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5409/repo/build-tool-pkg-2/main/Main.hs11
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5409/repo/build-tool-pkg-2/src/BuildToolLibrary.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5409/use-different-versions-of-dependency-for-library-and-build-tool.out5
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5409/use-different-versions-of-dependency-for-library-and-build-tool.test.hs28
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5677/cabal.out28
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5677/cabal.project4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5677/cabal.test.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5677/impl/Sig.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5677/impl/impl.cabal10
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5677/prog/prog.cabal19
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5677/prog/prog.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5677/prog/src/Prog.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5677/sig/Sig.hsig3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T5677/sig/sig.cabal10
-rw-r--r--cabal/cabal-testsuite/PackageTests/SDist/ListSources/Main.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/SDist/ListSources/data/blah/a.dat1
-rw-r--r--cabal/cabal-testsuite/PackageTests/SDist/ListSources/extra-doc/blah/a.tex1
-rw-r--r--cabal/cabal-testsuite/PackageTests/SDist/ListSources/extra-src/blah/a.html1
-rw-r--r--cabal/cabal-testsuite/PackageTests/SDist/ListSources/list-sources.cabal11
-rw-r--r--cabal/cabal-testsuite/PackageTests/SDist/ListSources/list-sources.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/SDist/ListSources/list-sources.test.hs10
-rw-r--r--cabal/cabal-testsuite/PackageTests/SDist/T5195/Main.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/SDist/T5195/actually-a-directory/some-file1
-rw-r--r--cabal/cabal-testsuite/PackageTests/SDist/T5195/cabal.out2
-rw-r--r--cabal/cabal-testsuite/PackageTests/SDist/T5195/cabal.test.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/SDist/T5195/t5195.cabal10
-rw-r--r--cabal/cabal-testsuite/PackageTests/SPDX/M.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/SPDX/Setup.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/SPDX/cabal-old-build.cabal.out10
-rw-r--r--cabal/cabal-testsuite/PackageTests/SPDX/cabal-old-build.out9
-rw-r--r--cabal/cabal-testsuite/PackageTests/SPDX/cabal-old-build.test.hs10
-rw-r--r--cabal/cabal-testsuite/PackageTests/SPDX/cabal.project1
-rw-r--r--cabal/cabal-testsuite/PackageTests/SPDX/cabal.test.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/SPDX/my.cabal10
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/MultipleSources/cabal.out10
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/MultipleSources/cabal.test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/Reinstall/p/Main.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/Reinstall/sandbox.out14
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/Reinstall/sandbox.test.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/Sandbox/Sources/sandbox.out10
-rw-r--r--cabal/cabal-testsuite/PackageTests/SimpleDefault/M.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/SimpleDefault/Setup.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/SimpleDefault/cabal.project1
-rw-r--r--cabal/cabal-testsuite/PackageTests/SimpleDefault/cabal.test.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/SimpleDefault/my.cabal10
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/cabal-with-hpc.multitest.hs55
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/setup-with-hpc.multitest.hs98
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/setup.out18
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/setup.test.hs7
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestSuiteTests/LibV09/LibV09.cabal1
-rw-r--r--cabal/cabal-testsuite/Test/Cabal/CheckArMetadata.hs1
-rw-r--r--cabal/cabal-testsuite/Test/Cabal/Monad.hs40
-rw-r--r--cabal/cabal-testsuite/Test/Cabal/Prelude.hs134
-rw-r--r--cabal/cabal-testsuite/cabal-testsuite.cabal18
-rw-r--r--cabal/cabal-testsuite/main/cabal-tests.hs6
-rw-r--r--cabal/cabal.project5
-rw-r--r--cabal/cabal.project.local.travis (renamed from cabal/cabal.project.travis)6
-rw-r--r--cabal/cabal.project.meta1
-rw-r--r--cabal/cabal.project.travis.libonly25
-rw-r--r--cabal/cabal.project.validate8
-rw-r--r--cabal/license-list-data/exceptions-3.0.json306
-rw-r--r--cabal/license-list-data/exceptions-3.2.json363
-rw-r--r--cabal/license-list-data/licenses-3.0.json4653
-rw-r--r--cabal/license-list-data/licenses-3.2.json4729
-rw-r--r--cabal/pretty-show-1.6.16/CHANGELOG41
-rw-r--r--cabal/pretty-show-1.6.16/LICENSE19
-rw-r--r--cabal/pretty-show-1.6.16/Setup.lhs8
-rw-r--r--cabal/pretty-show-1.6.16/Text/Show/Html.hs211
-rw-r--r--cabal/pretty-show-1.6.16/Text/Show/Parser.y130
-rw-r--r--cabal/pretty-show-1.6.16/Text/Show/Pretty.hs186
-rw-r--r--cabal/pretty-show-1.6.16/Text/Show/PrettyVal.hs130
-rw-r--r--cabal/pretty-show-1.6.16/Text/Show/Value.hs41
-rw-r--r--cabal/pretty-show-1.6.16/bin/ppsh.hs44
-rw-r--r--cabal/pretty-show-1.6.16/pretty-show.cabal73
-rw-r--r--cabal/pretty-show-1.6.16/style/jquery-src.js10337
-rw-r--r--cabal/pretty-show-1.6.16/style/jquery.js4
-rw-r--r--cabal/pretty-show-1.6.16/style/pretty-show.css32
-rw-r--r--cabal/pretty-show-1.6.16/style/pretty-show.js23
-rw-r--r--cabal/solver-benchmarks/solver-benchmarks.cabal4
-rw-r--r--cabal/solver-benchmarks/tests/HackageBenchmarkTest.hs37
-rw-r--r--cabal/stack.yaml3
-rw-r--r--cabal/travis-common.sh18
-rwxr-xr-xcabal/travis-deploy.sh2
-rwxr-xr-xcabal/travis-install.sh9
-rwxr-xr-xcabal/travis-meta.sh6
-rwxr-xr-xcabal/travis-script.sh39
-rwxr-xr-xcabal/travis-solver-debug-flags.sh15
-rwxr-xr-xcabal/travis-stack.sh12
-rw-r--r--cabal/travis/README.md12
-rw-r--r--cabal/travis/binaries/.travis.yml2
-rw-r--r--cabal/travis/binaries/travis-cleanup.sh2
-rwxr-xr-xcabal/travis/binaries/travis-test.sh12
-rw-r--r--cabal/travis/id_rsa27
-rw-r--r--cabal/travis/id_rsa.pub2
-rw-r--r--cabal/travis/id_rsa.rot1327
-rwxr-xr-xcabal/travis/upload.sh31
-rwxr-xr-xcabal/update-cabal-files.sh3
-rwxr-xr-xcabal/validate.sh199
-rw-r--r--hackport.cabal3
684 files changed, 51685 insertions, 10072 deletions
diff --git a/Cabal2Ebuild.hs b/Cabal2Ebuild.hs
index 539e4a1..15cffa1 100644
--- a/Cabal2Ebuild.hs
+++ b/Cabal2Ebuild.hs
@@ -22,7 +22,7 @@ module Cabal2Ebuild
,convertDependency) where
import qualified Distribution.PackageDescription as Cabal
- (PackageDescription(..))
+ (PackageDescription(..), license)
import qualified Distribution.Package as Cabal (PackageIdentifier(..)
, Dependency(..))
import qualified Distribution.Version as Cabal (VersionRange, foldVersionRange')
diff --git a/Main.hs b/Main.hs
index 6ad49d8..1fcb6f8 100644
--- a/Main.hs
+++ b/Main.hs
@@ -19,7 +19,7 @@ import Distribution.Simple.Setup
import Distribution.Simple.Command -- commandsRun
import Distribution.Simple.Utils ( die, cabalVersion, warn )
-import qualified Distribution.PackageDescription.Parse as Cabal
+import qualified Distribution.PackageDescription.Parsec as Cabal
import qualified Distribution.Package as Cabal
import Distribution.Verbosity (Verbosity, normal)
import Distribution.Text (display, simpleParse)
@@ -173,7 +173,7 @@ makeEbuildAction flags args globalFlags = do
let verbosity = fromFlag (makeEbuildVerbosity flags)
overlayPath <- getOverlayPath verbosity (fromFlag $ H.globalPathToOverlay globalFlags)
forM_ cabals $ \cabalFileName -> do
- pkg <- Cabal.readPackageDescription normal cabalFileName
+ pkg <- Cabal.readGenericPackageDescription normal cabalFileName
mergeGenericPackageDescription verbosity overlayPath cat pkg False (fromFlag $ makeEbuildCabalFlags flags)
makeEbuildCommand :: CommandUI MakeEbuildFlags
diff --git a/Merge.hs b/Merge.hs
index 0944c64..6458173 100644
--- a/Merge.hs
+++ b/Merge.hs
@@ -195,17 +195,20 @@ first_just_of = msum
-- USE_EXPAND values. If it's not a user-specified rename mangle
-- it into a hyphen ('-').
mangle_iuse :: String -> String
-mangle_iuse = map f
+mangle_iuse = drop_prefix . map f
where f '_' = '-'
f c = c
--- | Remove "with_" or "with-" from beginning of flag names.
-drop_with :: String -> String
-drop_with = \x ->
+-- | Remove "with" or "use" prefixes from flag names.
+drop_prefix :: String -> String
+drop_prefix = \x ->
case splitAt 5 x of
("with_", b) -> b
("with-", b) -> b
- _ -> x
+ _ -> case splitAt 4 x of
+ ("use_", b) -> b
+ ("use-", b) -> b
+ _ -> x
-- used to be FlagAssignment in Cabal but now it's an opaque type
type CabalFlags = [(Cabal.FlagName, Bool)]
@@ -260,8 +263,10 @@ mergeGenericPackageDescription verbosity overlayPath cat pkgGenericDesc fetch us
, " $ hackport make-ebuild " ++ cn ++ " " ++ pn ++ ".cabal"
]
- let (accepted_deps, skipped_deps) = Portage.partition_depends ghc_packages merged_cabal_pkg_name (Cabal.buildDepends pkgDesc0)
- pkgDesc = pkgDesc0 { Cabal.buildDepends = accepted_deps }
+ let (accepted_deps, skipped_deps) = Portage.partition_depends ghc_packages merged_cabal_pkg_name
+ (Merge.exeAndLibDeps pkgDesc0)
+
+ 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]
@@ -286,26 +291,26 @@ 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 . drop_with $ cfn
+ Nothing -> mangle_iuse cfn
Just ein -> ein
-
-- key idea is to generate all possible list of flags
deps1 :: [(CabalFlags, Merge.EDep)]
deps1 = [ ( f `updateFa` Cabal.unFlagAssignment fr
, cabal_to_emerge_dep pkgDesc_filtered_bdeps)
| f <- all_possible_flag_assignments
- -- TODO: move from 'finalizePackageDescription' to 'finalizePD'
- , Right (pkgDesc1,fr) <- [GHCCore.finalizePackageDescription (Cabal.mkFlagAssignment f)
- (GHCCore.dependencySatisfiable pix)
- GHCCore.platform
- compiler_info
- []
- pkgGenericDesc]
+ , Right (pkgDesc1,fr) <- [GHCCore.finalizePD (Cabal.mkFlagAssignment f)
+ GHCCore.defaultComponentRequestedSpec
+ (GHCCore.dependencySatisfiable pix)
+ GHCCore.platform
+ compiler_info
+ []
+ pkgGenericDesc]
-- drop circular deps and shipped deps
- , let (ad, _sd) = Portage.partition_depends ghc_packages merged_cabal_pkg_name (Cabal.buildDepends pkgDesc1)
+ , let (ad, _sd) = Portage.partition_depends ghc_packages merged_cabal_pkg_name
+ (Merge.exeAndLibDeps pkgDesc1)
-- TODO: drop ghc libraries from tests depends as well
-- (see deepseq in hackport-0.3.5 as an example)
- , let pkgDesc_filtered_bdeps = pkgDesc1 { Cabal.buildDepends = ad }
+ , let pkgDesc_filtered_bdeps = Merge.RetroPackageDescription pkgDesc1 ad
]
where
updateFa :: CabalFlags -> CabalFlags -> CabalFlags
@@ -375,12 +380,12 @@ mergeGenericPackageDescription verbosity overlayPath cat pkgGenericDesc fetch us
id fs
in k e
- cabal_to_emerge_dep :: Cabal.PackageDescription -> Merge.EDep
+ cabal_to_emerge_dep :: Merge.RetroPackageDescription -> Merge.EDep
cabal_to_emerge_dep cabal_pkg = Merge.resolveDependencies overlay cabal_pkg compiler_info ghc_packages merged_cabal_pkg_name
debug verbosity $ "buildDepends pkgDesc0 raw: " ++ Cabal.showPackageDescription pkgDesc0
- debug verbosity $ "buildDepends pkgDesc0: " ++ show (map display (Cabal.buildDepends pkgDesc0))
- debug verbosity $ "buildDepends pkgDesc: " ++ show (map display (Cabal.buildDepends pkgDesc))
+ debug verbosity $ "buildDepends pkgDesc0: " ++ show (map display (Merge.exeAndLibDeps pkgDesc0))
+ debug verbosity $ "buildDepends pkgDesc: " ++ show (map display (Merge.buildDepends pkgDesc))
notice verbosity $ "Accepted depends: " ++ show (map display accepted_deps)
notice verbosity $ "Skipped depends: " ++ show (map display skipped_deps)
@@ -431,11 +436,11 @@ mergeGenericPackageDescription verbosity overlayPath cat pkgGenericDesc fetch us
. ( case requested_cabal_flags of
Nothing -> id
Just ucf -> (\e -> e { E.used_options = E.used_options e ++ [("flags", ucf)] }))
- $ C2E.cabal2ebuild cat pkgDesc
+ $ C2E.cabal2ebuild cat (Merge.packageDescription pkgDesc)
mergeEbuild verbosity existing_meta pkgdir ebuild active_flag_descs
when fetch $ do
- let cabal_pkgId = Cabal.packageId pkgDesc
+ let cabal_pkgId = Cabal.packageId (Merge.packageDescription pkgDesc)
norm_pkgName = Cabal.packageName (Portage.normalizeCabalPackageId cabal_pkgId)
fetchDigestAndCheck verbosity (overlayPath </> display cat </> display norm_pkgName)
@@ -471,7 +476,7 @@ to_unstable kw =
-- | Generate a list of tuples containing Cabal flag names and descriptions
metaFlags :: [Cabal.Flag] -> [(String, String)]
-metaFlags flags = zip (mangle_iuse . drop_with . Cabal.unFlagName . Cabal.flagName <$> flags) (Cabal.flagDescription <$> flags)
+metaFlags flags = zip (mangle_iuse . Cabal.unFlagName . Cabal.flagName <$> flags) (Cabal.flagDescription <$> flags)
mergeEbuild :: Verbosity -> EM.EMeta -> FilePath -> E.EBuild -> [Cabal.Flag] -> IO ()
mergeEbuild verbosity existing_meta pkgdir ebuild flags = do
diff --git a/Merge/Dependencies.hs b/Merge/Dependencies.hs
index d7f7a5e..340ada7 100644
--- a/Merge/Dependencies.hs
+++ b/Merge/Dependencies.hs
@@ -4,6 +4,9 @@
-}
module Merge.Dependencies
( EDep(..)
+ , RetroPackageDescription(..)
+ , exeAndLibDeps
+ , mkRetroPD
, resolveDependencies
) where
@@ -49,6 +52,26 @@ data EDep = EDep
}
deriving (Show, Eq, Ord)
+-- | Cabal-1 style 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.
+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.
+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))
+
#if MIN_VERSION_base(4,9,0)
instance Semigroup EDep where
(EDep rdepA rdep_eA depA dep_eA) <> (EDep rdepB rdep_eB depB dep_eB) = EDep
@@ -76,41 +99,42 @@ instance Monoid EDep where
}
#endif
-resolveDependencies :: Portage.Overlay -> Cabal.PackageDescription -> Cabal.CompilerInfo
+resolveDependencies :: Portage.Overlay -> RetroPackageDescription -> Cabal.CompilerInfo
-> [Cabal.PackageName] -> Cabal.PackageName
-> EDep
resolveDependencies overlay pkg compiler_info ghc_package_names merged_cabal_pkg_name = edeps
where
-- hasBuildableExes p = any (buildable . buildInfo) . executables $ p
treatAsLibrary :: Bool
- treatAsLibrary = isJust (Cabal.library pkg)
+ treatAsLibrary = isJust (Cabal.library (packageDescription pkg))
-- without slot business
raw_haskell_deps :: Portage.Dependency
- raw_haskell_deps = PN.normalize_depend $ Portage.DependAllOf $ haskellDependencies overlay (Cabal.buildDepends pkg)
+ raw_haskell_deps = PN.normalize_depend $ Portage.DependAllOf $ haskellDependencies overlay (buildDepends pkg)
test_deps :: Portage.Dependency
test_deps = Portage.mkUseDependency (True, Portage.Use "test") $
Portage.DependAllOf $
remove_raw_common $
- testDependencies overlay pkg ghc_package_names merged_cabal_pkg_name
+ testDependencies overlay (packageDescription pkg) ghc_package_names merged_cabal_pkg_name
cabal_dep :: Portage.Dependency
- cabal_dep = cabalDependency overlay pkg compiler_info
+ cabal_dep = cabalDependency overlay (packageDescription pkg) compiler_info
ghc_dep :: Portage.Dependency
ghc_dep = compilerInfoToDependency compiler_info
extra_libs :: Portage.Dependency
- extra_libs = Portage.DependAllOf $ findCLibs pkg
+ extra_libs = Portage.DependAllOf $ findCLibs (packageDescription pkg)
pkg_config_libs :: [Portage.Dependency]
- pkg_config_libs = pkgConfigDependencies overlay pkg
+ pkg_config_libs = pkgConfigDependencies overlay (packageDescription pkg)
pkg_config_tools :: Portage.Dependency
pkg_config_tools = Portage.DependAllOf $ if L.null pkg_config_libs
then []
else [any_c_p "virtual" "pkgconfig"]
build_tools :: Portage.Dependency
- build_tools = Portage.DependAllOf $ pkg_config_tools : legacyBuildToolsDependencies pkg ++ hackageBuildToolsDependencies overlay pkg
+ build_tools = Portage.DependAllOf $ pkg_config_tools : legacyBuildToolsDependencies (packageDescription pkg)
+ ++ hackageBuildToolsDependencies overlay (packageDescription pkg)
setup_deps :: Portage.Dependency
setup_deps = PN.normalize_depend $ Portage.DependAllOf $
remove_raw_common $
- setupDependencies overlay pkg ghc_package_names merged_cabal_pkg_name
+ setupDependencies overlay (packageDescription pkg) ghc_package_names merged_cabal_pkg_name
edeps :: EDep
edeps
diff --git a/Portage/Cabal.hs b/Portage/Cabal.hs
index 7f17d27..25b4ff7 100644
--- a/Portage/Cabal.hs
+++ b/Portage/Cabal.hs
@@ -6,13 +6,14 @@ 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.Text as Cabal
-- map the cabal license type to the gentoo license string format
-convertLicense :: Cabal.License -> Either String String
+convertLicense :: SPDX.License -> Either String String
convertLicense l =
- case l of
+ case Cabal.licenseFromSPDX l of
-- good ones
Cabal.AGPL mv -> Right $ "AGPL-" ++ (maybe "3" Cabal.display mv) -- almost certainly version 3
Cabal.GPL mv -> Right $ "GPL-" ++ (maybe "2" Cabal.display mv) -- almost certainly version 2
diff --git a/Portage/GHCCore.hs b/Portage/GHCCore.hs
index b922e29..e8e0f2c 100644
--- a/Portage/GHCCore.hs
+++ b/Portage/GHCCore.hs
@@ -3,7 +3,8 @@
module Portage.GHCCore
( minimumGHCVersionToBuildPackage
, cabalFromGHC
- , finalizePackageDescription
+ , defaultComponentRequestedSpec
+ , finalizePD
, platform
, dependencySatisfiable
) where
@@ -19,6 +20,7 @@ import Distribution.PackageDescription
import Distribution.PackageDescription.Configuration
import Distribution.Compiler (CompilerId(..), CompilerFlavor(GHC))
import Distribution.System
+import Distribution.Types.ComponentRequestedSpec (defaultComponentRequestedSpec)
import Distribution.Text
@@ -31,13 +33,12 @@ import Debug.Trace
-- It means that first ghc in this list is a minmum default.
ghcs :: [(DC.CompilerInfo, InstalledPackageIndex)]
ghcs = modern_ghcs
- where modern_ghcs = [ghc741, ghc742, ghc761, ghc762, ghc782, ghc7101, ghc7102, ghc801, ghc802, ghc821, ghc843, ghc861, ghc863, ghc881]
+ where modern_ghcs = [ghc741, ghc742, ghc762, ghc782, ghc7101, ghc7102, ghc801, ghc802, ghc821, ghc843, ghc863, ghc865, ghc881]
cabalFromGHC :: [Int] -> Maybe Cabal.Version
cabalFromGHC ver = lookup ver table
where
table = [ ([7,4,2], Cabal.mkVersion [1,14,0])
- , ([7,6,1], Cabal.mkVersion [1,16,0])
, ([7,6,2], Cabal.mkVersion [1,16,0])
, ([7,8,2], Cabal.mkVersion [1,18,1,3])
, ([7,10,1], Cabal.mkVersion [1,22,2,0])
@@ -46,7 +47,8 @@ cabalFromGHC ver = lookup ver table
, ([8,0,2], Cabal.mkVersion [1,24,2,0])
, ([8,2,1], Cabal.mkVersion [2,0,0,2])
, ([8,4,3], Cabal.mkVersion [2,2,0,1])
- , ([8,6,1], Cabal.mkVersion [2,4,0,1])
+ , ([8,6,3], Cabal.mkVersion [2,4,0,1])
+ , ([8,6,5], Cabal.mkVersion [2,4,0,1])
, ([8,8,1], Cabal.mkVersion [3,0,0,0])
]
@@ -76,7 +78,7 @@ packageBuildableWithGHCVersion
-> (DC.CompilerInfo, InstalledPackageIndex)
-> Either [Cabal.Dependency] (PackageDescription, FlagAssignment)
packageBuildableWithGHCVersion pkg user_specified_fas (compiler_info, pkgIndex) = trace_failure $
- finalizePackageDescription user_specified_fas (dependencySatisfiable pkgIndex) platform compiler_info [] pkg
+ finalizePD user_specified_fas defaultComponentRequestedSpec (dependencySatisfiable pkgIndex) platform compiler_info [] pkg
where trace_failure v = case v of
(Left deps) -> trace (unwords ["rejecting dep:" , show_compiler compiler_info
, "as", show_deps deps
@@ -120,12 +122,12 @@ ghc nrs = DC.unknownCompilerInfo c_id DC.NoAbiTag
ghc881 :: (DC.CompilerInfo, InstalledPackageIndex)
ghc881 = (ghc [8,8,1], mkIndex ghc881_pkgs)
+ghc865 :: (DC.CompilerInfo, InstalledPackageIndex)
+ghc865 = (ghc [8,6,5], mkIndex ghc865_pkgs)
+
ghc863 :: (DC.CompilerInfo, InstalledPackageIndex)
ghc863 = (ghc [8,6,3], mkIndex ghc863_pkgs)
-ghc861 :: (DC.CompilerInfo, InstalledPackageIndex)
-ghc861 = (ghc [8,6,1], mkIndex ghc861_pkgs)
-
ghc843 :: (DC.CompilerInfo, InstalledPackageIndex)
ghc843 = (ghc [8,4,3], mkIndex ghc843_pkgs)
@@ -150,9 +152,6 @@ ghc782 = (ghc [7,8,2], mkIndex ghc782_pkgs)
ghc762 :: (DC.CompilerInfo, InstalledPackageIndex)
ghc762 = (ghc [7,6,2], mkIndex ghc762_pkgs)
-ghc761 :: (DC.CompilerInfo, InstalledPackageIndex)
-ghc761 = (ghc [7,6,1], mkIndex ghc761_pkgs)
-
ghc742 :: (DC.CompilerInfo, InstalledPackageIndex)
ghc742 = (ghc [7,4,2], mkIndex ghc742_pkgs)
@@ -160,8 +159,11 @@ ghc741 :: (DC.CompilerInfo, InstalledPackageIndex)
ghc741 = (ghc [7,4,1], mkIndex ghc741_pkgs)
-- | Non-upgradeable core packages
--- Source: http://haskell.org/haskellwiki/Libraries_released_with_GHC
--- and our binary tarballs (package.conf.d.initial subdir)
+-- Sources:
+-- * release notes
+-- example: https://downloads.haskell.org/~ghc/8.6.5/docs/html/users_guide/8.6.5-notes.html
+-- * our binary tarballs (package.conf.d.initial subdir)
+-- * ancient: http://haskell.org/haskellwiki/Libraries_released_with_GHC
ghc881_pkgs :: [Cabal.PackageIdentifier]
ghc881_pkgs =
@@ -174,8 +176,8 @@ ghc881_pkgs =
, p "deepseq" [1,4,4,0] -- used by time
, p "directory" [1,3,3,2]
, p "filepath" [1,4,2,1]
- , p "ghc-boot" [8,8,1]
- , p "ghc-boot-th" [8,8,1]
+ , p "ghc-boot" [8,8,1]
+ , p "ghc-boot-th" [8,8,1]
, p "ghc-compact" [0,1,0,0]
, p "ghc-prim" [0,5,3,0]
, p "ghci" [8,8,1]
@@ -196,8 +198,8 @@ ghc881_pkgs =
-- , p "xhtml" [3000,2,2,1]
]
-ghc863_pkgs :: [Cabal.PackageIdentifier]
-ghc863_pkgs =
+ghc865_pkgs :: [Cabal.PackageIdentifier]
+ghc865_pkgs =
[ p "array" [0,5,3,0]
, p "base" [4,12,0,0]
, p "binary" [0,8,6,0] -- used by libghc
@@ -207,31 +209,31 @@ ghc863_pkgs =
, p "deepseq" [1,4,4,0] -- used by time
, p "directory" [1,3,3,0]
, p "filepath" [1,4,2,1]
- , p "ghc-boot" [8,6,3]
- , p "ghc-boot-th" [8,6,3]
+ , p "ghc-boot" [8,6,5]
+ , p "ghc-boot-th" [8,6,5]
, p "ghc-compact" [0,1,0,0]
, p "ghc-prim" [0,5,3,0]
- , p "ghci" [8,6,3]
+ , p "ghci" [8,6,5]
-- , p "haskeline" [0,7,4,3] 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,13,0] package is upgradeable(?)
, p "pretty" [1,1,3,6]
- , p "process" [1,6,3,0]
+ , p "process" [1,6,5,0]
-- , p "stm" [2,5,0,0] package is upgradeable(?)
, p "template-haskell" [2,14,0,0] -- used by libghc
-- , p "terminfo" [0,4,1,2]
-- , p "text" [1,2,3,1] dependency of Cabal library
, p "time" [1,8,0,2] -- used by unix, directory, hpc, ghc. unsafe to upgrade
- , p "transformers" [0,5,5,0] -- used by libghc
+ , p "transformers" [0,5,6,2] -- used by libghc
, p "unix" [2,7,2,2]
-- , p "xhtml" [3000,2,2,1]
]
-ghc861_pkgs :: [Cabal.PackageIdentifier]
-ghc861_pkgs =
- [ p "array" [0,5,2,0]
+ghc863_pkgs :: [Cabal.PackageIdentifier]
+ghc863_pkgs =
+ [ p "array" [0,5,3,0]
, p "base" [4,12,0,0]
, p "binary" [0,8,6,0] -- used by libghc
, p "bytestring" [0,10,8,2]
@@ -240,11 +242,11 @@ ghc861_pkgs =
, p "deepseq" [1,4,4,0] -- used by time
, p "directory" [1,3,3,0]
, p "filepath" [1,4,2,1]
- , p "ghc-boot" [8,6,1]
- , p "ghc-boot-th" [8,6,1]
+ , p "ghc-boot" [8,6,3]
+ , p "ghc-boot-th" [8,6,3]
, p "ghc-compact" [0,1,0,0]
, p "ghc-prim" [0,5,3,0]
- , p "ghci" [8,6,1]
+ , p "ghci" [8,6,3]
-- , p "haskeline" [0,7,4,3] package is upgradeable
, p "hpc" [0,6,0,3] -- used by libghc
, p "integer-gmp" [1,0,2,0]
@@ -488,32 +490,6 @@ ghc762_pkgs =
, p "unix" [2,6,0,1]
]
-ghc761_pkgs :: [Cabal.PackageIdentifier]
-ghc761_pkgs =
- [ p "array" [0,4,0,1]
- , p "base" [4,6,0,0]
- , p "binary" [0,5,1,1] -- used by libghc
- , p "bytestring" [0,10,0,0]
--- , p "Cabal" [1,16,0] package is upgradeable
- , p "containers" [0,5,0,0]
- , p "deepseq" [1,3,0,1] -- used by time, haskell98
- , p "directory" [1,2,0,0]
- , p "filepath" [1,3,0,1]
- , p "ghc-prim" [0,3,0,0]
- , p "haskell2010" [1,1,1,0]
- , p "haskell98" [2,0,0,2]
- , p "hoopl" [3,9,0,0] -- used by libghc
- , p "hpc" [0,6,0,0] -- used by libghc
- , p "integer-gmp" [0,5,0,0]
- -- , p "old-locale" [1,0,0,5] -- stopped shipping in 7.10, deprecated
- -- , p "old-time" [1,1,0,1] -- stopped shipping in 7.10, deprecated
- , p "pretty" [1,1,1,0]
- , p "process" [1,1,0,2]
- , p "template-haskell" [2,8,0,0] -- used by libghc
- , p "time" [1,4,0,1] -- used by haskell98, unix, directory, hpc, ghc. unsafe to upgrade
- , p "unix" [2,6,0,0]
- ]
-
ghc742_pkgs :: [Cabal.PackageIdentifier]
ghc742_pkgs =
[ p "array" [0,4,0,0]
diff --git a/cabal/.ghci b/cabal/.ghci
new file mode 100644
index 0000000..1e251d3
--- /dev/null
+++ b/cabal/.ghci
@@ -0,0 +1,2 @@
+:set -icabal-install -icabal-install/main
+:load Main
diff --git a/cabal/.ghcid b/cabal/.ghcid
new file mode 100644
index 0000000..510c5ef
--- /dev/null
+++ b/cabal/.ghcid
@@ -0,0 +1 @@
+--command "ghci -j4 +RTS -A128m"
diff --git a/cabal/.mailmap b/cabal/.mailmap
index f4f867c..ef0cbb9 100644
--- a/cabal/.mailmap
+++ b/cabal/.mailmap
@@ -5,6 +5,11 @@
# Should be empty list: 'git shortlog -se | cut -f2 | cut -d'<' -f1 | uniq -d'.
Adam Langley <agl@imperialviolet.org>
+Alex Biehl <alexbiehl@gmail.com>
+Alex Biehl <alexbiehl@gmail.com> Alexander Biehl <abiehl@novomind.com>
+Alex Biehl <alexbiehl@gmail.com> alexbiehl <alex.biehl@gmail.com>
+Alex Washburn <github@recursion.ninja>
+Alex Washburn <github@recursion.ninja> recursion-ninja <github@recursion.ninja>
Alistair Bailey <alistair@abayley.org> alistair <alistair@abayley.org>
Alson Kemp <alson@alsonkemp.com> alson <alson@alsonkemp.com>
Andres Löh <andres.loeh@gmail.com>
@@ -30,11 +35,14 @@ Bram Schuur <bramschuur@gmail.com>
Brendan Hay <brendan.g.hay@gmail.com> <brendanhay@users.noreply.github.com>
Brent Yorgey <byorgey@gmail.com> <byorgey@cis.upenn.edu>
Brian Smith <brianlsmith@gmail.com> brianlsmith <brianlsmith@gmail.com>
+Daniel Díaz Carrete <daniel@bogusemailserver.com>
+Daniel Gröber <dxld@darkboxed.org> <daniel@dps.uibk.ac.at>
Daniel Wagner <daniel@wagner-home.com> <dmwit@galois.com>
David Himmelstrup <lemmih@gmail.com>
David Luposchainsky <dluposchainsky@gmail.com> <quchen@users.noreply.github.com>
David Waern <davve@dtek.chalmers.se> David Waern <unknown>
Dennis Gosnell <cdep.illabout@gmail.com>
+Dmitry Kovanikov <kovanikov@gmail.com> ChShersh <dmitrii@holmusk.com>
Don Stewart <dons00@gmail.com> <dons@galois.com>
Duncan Coutts <duncan@community.haskell.org>
Duncan Coutts <duncan@community.haskell.org> <Duncan Coutts duncan@community.haskell.org>
@@ -43,9 +51,11 @@ Duncan Coutts <duncan@community.haskell.org> <duncan@commu
Duncan Coutts <duncan@community.haskell.org> <duncan@haskell.org>
Duncan Coutts <duncan@community.haskell.org> <duncan@well-typed.com>
Duncan Coutts <duncan@community.haskell.org> unknown <unknown> # 04e9fcc80bc68b72126e33b20f08050df28e727d
+Edward Z. Yang <ezyang@cs.stanford.edu> <ezyang@fb.com>
Edward Z. Yang <ezyang@cs.stanford.edu> <ezyang@mit.edu>
Einar Karttunen <ekarttun@cs.helsinki.fi>
Federico Mastellone <fmaste@users.noreply.github.com>
+Felix Yan <felixonmars@archlinux.org> Felix Yan <felixonmars@gmail.com>
Francesco Gazzetta <francygazz@gmail.com> <fgaz@users.noreply.github.com>
Ganesh Sittampalam <ganesh.sittampalam@credit-suisse.com> <ganesh@earth.li>
Geoff Nixon <geoff-codes@users.noreply.github.com> <geoff.nixon@aol.com>
@@ -55,6 +65,8 @@ Gershom Bazerman <gershomb@gmail.com> U-CIQDEV\gbaz
Gershom Bazerman <gershomb@gmail.com> gbaz <gershomb@gmail.com>
Gleb Alexeev <gleb.alexeev@gmail.com>
Gleb Alexeev <gleb.alexeev@gmail.com> gleb.alexeev <gleb.alexeev@gmail.com>
+Gleb Popov <6yearold@gmail.com>
+Gleb Popov <6yearold@gmail.com> arrowd <6yearold@gmail.com>
Gwern Branwen <gwern0@gmail.com> gwern0 <gwern0@gmail.com>
Heather <heather@live.ru> <Heather@cynede.net>
Heather <heather@live.ru> <Heather@users.noreply.github.com>
@@ -73,15 +85,17 @@ Jens Petersen <juhpetersen@gmail.com> <petersen@red
Jeremy Shaw <jeremy.shaw@linspireinc.com>
Jeremy Shaw <jeremy.shaw@linspireinc.com> <jeremy@n-heptane.com>
Jim Burton <jim@sdf-eu.org>
+Joe Quinn <headprogrammingczar@gmail.com>
Joel Bitrauser <jo.da@posteo.de> <bitrauser@users.noreply.github.com>
Joel Bitrauser <jo.da@posteo.de> Bitrauser <jo.da@posteo.de>
-Joe Quinn <headprogrammingczar@gmail.com>
Joel Stanley <intractable@gmail.com>
Joeri van Eekelen <tchakkazulu@gmail.com>
John D. Ramsdell <ramsdell@mitre.org>
John Dias <dias@eecs.harvard.edu> dias <dias@eecs.harvard.edu>
-John Ericson <Ericson2314@yahoo.com> <Ericson2314@Yahoo.con>
+John Ericson <Ericson2314@yahoo.com>
+John Ericson <Ericson2314@yahoo.com> <John.Ericson@Obsidian.Systems>
John Ericson <Ericson2314@yahoo.com> <jericson@galois.com>
+John Ericson <Ericson2314@yahoo.com> John Ericson <Ericson2314@Yahoo.com>
Josh Hoyt <josh.hoyt@galois.com>
Judah Jacobson <judah.jacobson@gmail.com>
Jürgen Nicklisch-Franken <jnf@arcor.de>
@@ -93,13 +107,16 @@ Krasimir Angelov <kr.angelov@gmail.com> ka2_mail <ka2
Lennart Kolmodin <kolmodin@gmail.com> <kolmodin@dtek.chalmers.se>
Lennart Kolmodin <kolmodin@gmail.com> <kolmodin@gentoo.org>
Lennart Kolmodin <kolmodin@gmail.com> <kolmodin@google.com>
-Lennart Spitzner <lsp@informatik.uni-kiel.de>
+Lennart Spitzner <hexagoxel@hexagoxel.de>
+Lennart Spitzner <hexagoxel@hexagoxel.de> <lsp@informatik.uni-kiel.de>
+Li-yao Xia <lysxia@gmail.com>
Malcolm Wallace <Malcolm.Wallace@me.com> Malcolm.Wallace <Malcolm.Wallace@cs.york.ac.uk>
Mark Weber <marco-oweber@gmx.de> marco-oweber <marco-oweber@gmx.de>
Martin Sjögren <msjogren@gmail.com> md9ms <md9ms@mdstud.chalmers.se>
Mikhail Glushenkov <mikhail.glushenkov@gmail.com> <c05mgv@cs.umu.se>
Mikhail Glushenkov <mikhail.glushenkov@gmail.com> <mikhail@scrive.com>
Mikhail Glushenkov <mikhail.glushenkov@gmail.com> <the.dead.shall.rise@gmail.com>
+Nathan Conroy <nathanconroydev@gmail.com>
Neil Mitchell <ndmitchell@gmail.com> Neil Mitchell <unknown>
Niklas Broberg <niklas.broberg@gmail.com> <d00nibro@chalmers.se>
Niklas Broberg <niklas.broberg@gmail.com> <git@nand.wakku.to>
@@ -122,7 +139,18 @@ Simon Peyton Jones <simonpj@microsoft.com> simonpj <simo
Stephen Blackheath <stephen.blackheath@ipwnstudios.com> <grossly.sensitive.stephen@blacksapphire.com>
Stephen Blackheath <stephen.blackheath@ipwnstudios.com> <oversensitive.pastors.stephen@blacksapphire.com>
Stephen Blackheath <stephen.blackheath@ipwnstudios.com> rubbernecking.trumpet.stephen <rubbernecking.trumpet.stephen@blacksapphire.com>
+Suzumiya <suzumiyasmith@gmail.com> # Goes by that name online
Sven Panne <sven.panne@aedion.de>
+Tamar Christina <tamar@zhox.com>
+Tamar Christina <tamar@zhox.com> <Mistuke@users.noreply.github.com>
Thomas M. DuBuisson <thomas.dubuisson@gmail.com>
Thomas M. DuBuisson <thomas.dubuisson@gmail.com> Thomas M. DuBuisson <tommd@galois.com>
Thomas Schilling <nominolo@gmail.com> <nominolo@googlemail.com>
+Thomas Tuegel <ttuegel@gmail.com>
+Thomas Tuegel <ttuegel@gmail.com> <ttuegel@mailbox.org>
+Thomas Tuegel <ttuegel@gmail.com> <ttuegel@secure.mailbox.org>
+Veronika Romashkina <vrom911@gmail.com>
+capsjac <capsjac@gmail.com> # Goes by that name online
+ghthrowaway7 <41365123+ghthrowaway7@users.noreply.github.com> # Goes by that name online
+quasicomputational <quasicomputational@gmail.com> # Goes by that name online
+vedksah <31156362+vedksah@users.noreply.github.com> # Goes by that name online
diff --git a/cabal/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/setup-with-hpc.out b/cabal/.projectile
index e69de29..e69de29 100644
--- a/cabal/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/setup-with-hpc.out
+++ b/cabal/.projectile
diff --git a/cabal/.travis.yml b/cabal/.travis.yml
index d5a5831..051641d 100644
--- a/cabal/.travis.yml
+++ b/cabal/.travis.yml
@@ -4,13 +4,17 @@ language: c
dist: trusty
-sudo: false
+# 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
-# Remember to add release branches
-# we whitelist branches, as we don't really need to build dev-branches.
+# We whitelist branches, as we don't really need to build dev-branches.
+# Remember to add release branches, both here and to appveyor.yml.
branches:
only:
- master
+ - "2.4"
+ - "2.2"
- "2.0"
- "1.24"
- "1.22"
@@ -26,18 +30,16 @@ branches:
# TAGSUFFIX to help travis/upload.sh disambiguate the matrix entry.
matrix:
include:
- - env: GHCVER=8.2.1 SCRIPT=meta BUILDER=none
+ - 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
- - env: GHCVER=7.4.2 SCRIPT=script CABAL_LIB_ONLY=YES TEST_OTHER_VERSIONS=YES
+ # 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.6.3 SCRIPT=script
- os: linux
- sudo: required
- - env: GHCVER=7.8.4 SCRIPT=script USE_GOLD=YES
+ - 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
@@ -47,30 +49,36 @@ matrix:
- env: GHCVER=7.10.3 SCRIPT=script USE_GOLD=YES
os: linux
sudo: required
- - env: GHCVER=8.0.2 SCRIPT=script DEPLOY_DOCS=YES USE_GOLD=YES TEST_SOLVER_BENCHMARKS=YES
+ - 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.2 SCRIPT=script USE_GOLD=YES
os: linux
+ sudo: required
- - env: GHCVER=8.0.2 SCRIPT=solver-debug-flags USE_GOLD=YES
+ - env: GHCVER=8.4.4 SCRIPT=solver-debug-flags USE_GOLD=YES
sudo: required
os: linux
- - env: GHCVER=8.0.2 SCRIPT=script DEBUG_EXPENSIVE_ASSERTIONS=YES TAGSUFFIX="-fdebug-expensive-assertions" USE_GOLD=YES
+ - 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.2.2 SCRIPT=bootstrap USE_GOLD=YES
+ - env: GHCVER=8.4.4 SCRIPT=bootstrap USE_GOLD=YES
sudo: required
os: linux
- - env: GHCVER=8.2.1 SCRIPT=script
- os: linux
- sudo: required
# 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
+ - 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
@@ -84,15 +92,13 @@ matrix:
- env: GHCVER=8.0.2 SCRIPT=bootstrap
os: osx
- - env: GHCVER=via-stack SCRIPT=stack STACKAGE_RESOLVER=lts
+ - env: GHCVER=via-stack SCRIPT=stack STACK_CONFIG=stack.yaml
os: linux
- addons:
- apt:
- packages:
- - libgmp-dev
+ # See https://github.com/haskell/cabal/pull/4667#issuecomment-321036564
+ # for why failures are allowed.
allow_failures:
- - env: GHCVER=via-stack SCRIPT=stack STACKAGE_RESOLVER=lts
+ - env: GHCVER=via-stack SCRIPT=stack STACK_CONFIG=stack.yaml
# TODO add PARSEC_BUNDLED=YES when it's so
# It seems pointless to run head if we're going to ignore the results.
@@ -105,8 +111,7 @@ before_install:
- export PATH=$HOME/bin:$PATH
- export PATH=$HOME/.cabal/bin:$PATH
- export PATH=$HOME/.local/bin:$PATH
- - export PATH=/opt/cabal/2.0/bin:$PATH
- - export PATH=/opt/happy/1.19.5/bin:$PATH
+ - export PATH=/opt/cabal/2.4/bin:$PATH
- export PATH=/opt/alex/3.1.7/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
@@ -145,6 +150,8 @@ before_cache:
- 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:
diff --git a/cabal/AUTHORS b/cabal/AUTHORS
index d98324e..a887424 100644
--- a/cabal/AUTHORS
+++ b/cabal/AUTHORS
@@ -6,10 +6,15 @@ Adam Langley <agl@imperialviolet.org>
Adam Sandberg Eriksson <adam@sandbergericsson.se>
Alan Zimmerman <alan.zimm@gmail.com>
Albert Krewinkel <tarleb@moltkeplatz.de>
+Alec Theriault <alec.theriault@gmail.com>
Alex Biehl <alexbiehl@gmail.com>
+Alex Hirsch <w4rh4wk@bluephoenix.at>
+Alex Lang <me@alang.ca>
+Alex Washburn <github@recursion.ninja>
Alexander Kjeldaas <alexander.kjeldaas@gmail.com>
Alexander Vershilov <alexander.vershilov@gmail.com>
Alexei Pastuchov <alexei.pastuchov@telecolumbus.de>
+Alexis Williams <alexis@typedr.at>
Alistair Bailey <alistair@abayley.org>
Alson Kemp <alson@alsonkemp.com>
Amir Mohammad Saied <amirsaied@gmail.com>
@@ -50,6 +55,7 @@ Brian Smith <brianlsmith@gmail.com>
Bryan O'Sullivan <bos@serpentine.com>
Bryan Richter <bryan.richter@gmail.com>
Carter Tazio Schonwald <carter.schonwald@gmail.com>
+Chang Yang Jiao <jiaochangyang@gmail.com>
Chris Allen <cma@bitemyapp.com>
Chris Wong <lambda.fairy@gmail.com>
Christiaan Baaij <christiaan.baaij@gmail.com>
@@ -60,11 +66,13 @@ Conal Elliott <conal@conal.net>
Curtis Gagliardi <curtis@curtis.io>
Dan Burton <danburton.email@gmail.com>
Daniel Buckmaster <dan.buckmaster@gmail.com>
+Daniel Díaz Carrete <daniel@bogusemailserver.com>
Daniel Gröber <dxld@darkboxed.org>
Daniel Trstenjak <daniel.trstenjak@gmail.com>
Daniel Velkov <norcobg@gmail.com>
Daniel Wagner <daniel@wagner-home.com>
Danny Navarro <j@dannynavarro.net>
+Dave Laing <dave.laing.80@gmail.com>
David Feuer <David.Feuer@gmail.com>
David Fox <dsf@seereason.com>
David Himmelstrup <lemmih@gmail.com>
@@ -76,6 +84,7 @@ David Waern <davve@dtek.chalmers.se>
Dennis Gosnell <cdep.illabout@gmail.com>
Dino Morelli <dino@ui3.info>
Dmitry Astapov <dastapov@gmail.com>
+Dmitry Kovanikov <kovanikov@gmail.com>
Dominic Steinitz <dominic@steinitz.org>
Don Stewart <dons00@gmail.com>
Doug Beardsley <mightybyte@gmail.com>
@@ -95,7 +104,9 @@ Eugene Sukhodolin <eugene@sukhodolin.com>
Eyal Lotem <eyal.lotem@gmail.com>
Fabián Orccón <fabian.orccon@pucp.pe>
Federico Mastellone <fmaste@users.noreply.github.com>
+Felix Yan <felixonmars@archlinux.org>
Florian Hartwig <florian.j.hartwig@gmail.com>
+Francesco Ariis <fa-ml@ariis.it>
Francesco Gazzetta <francygazz@gmail.com>
Franz Thoma <franz.thoma@tngtech.com>
Fujimura Daisuke <me@fujimuradaisuke.com>
@@ -103,9 +114,11 @@ Gabor Greif <ggreif@gmail.com>
Gabor Pali <pali.gabor@gmail.com>
Ganesh Sittampalam <ganesh.sittampalam@credit-suisse.com>
Geoff Nixon <geoff-codes@users.noreply.github.com>
+George Wilson <george@wils.online>
Gershom Bazerman <gershomb@gmail.com>
Getty Ritter <gdritter@galois.com>
Gleb Alexeev <gleb.alexeev@gmail.com>
+Gleb Popov <6yearold@gmail.com>
Gregory Collins <greg@gregorycollins.net>
Gwern Branwen <gwern0@gmail.com>
Haisheng.Wu <freizl@gmail.com>
@@ -143,7 +156,6 @@ Johan Tibell <johan.tibell@gmail.com>
John Chee <cheecheeo@gmail.com>
John D. Ramsdell <ramsdell@mitre.org>
John Dias <dias@eecs.harvard.edu>
-John Ericson <Ericson2314@Yahoo.com>
John Ericson <Ericson2314@yahoo.com>
John Lato <jwlato@tsurucapital.com>
John Wiegley <johnw@fpcomplete.com>
@@ -156,17 +168,21 @@ Jürgen Nicklisch-Franken <jnf@arcor.de>
Karel Gardas <karel.gardas@centrum.cz>
Keegan McAllister <mcallister.keegan@gmail.com>
Ken Bateman <novadenizen@gmail.com>
+Ken Micklas <kmicklas@gmail.com>
Keshav Kini <kkini@galois.com>
Kido Takahiro <shelarcy@gmail.com>
Krasimir Angelov <kr.angelov@gmail.com>
Kristen Kozak <grayjay@wordroute.com>
Lennart Kolmodin <kolmodin@gmail.com>
-Lennart Spitzner <lsp@informatik.uni-kiel.de>
+Lennart Spitzner <hexagoxel@hexagoxel.de>
+Leon Isenberg <ljli@users.noreply.github.com>
Leonid Onokhov <sopvop@gmail.com>
+Li-yao Xia <lysxia@gmail.com>
Liyang HU <git@liyang.hu>
Luite Stegeman <stegeman@gmail.com>
Luke Iannini <lukexi@me.com>
M Farkas-Dyck <strake888@gmail.com>
+Maciej Bielecki <maciej.bielecki@skubacz.pl>
Maciek Makowski <maciek.makowski@gmail.com>
Magnus Jonsson <magnus@smartelectronix.com>
Malcolm Wallace <Malcolm.Wallace@me.com>
@@ -196,7 +212,9 @@ Misty De Meo <mistydemeo@gmail.com>
Miëtek Bak <mietek@bak.io>
Mohit Agarwal <mohit@sdf.org>
Moritz Angermann <moritz.angermann@gmail.com>
+Moritz Drexl <mdrexl@fastmail.fm>
Moritz Kiefer <moritz.kiefer@purelyfunctional.org>
+Nathan Conroy <nathanconroydev@gmail.com>
Nathan Howell <nhowell@alphaheavy.com>
Neil Mitchell <ndmitchell@gmail.com>
Neil Vice <sardonicpresence@gmail.com>
@@ -221,6 +239,8 @@ Peter Higley <phigley@gmail.com>
Peter Robinson <thaldyron@gmail.com>
Peter Selinger <selinger@mathstat.dal.ca>
Peter Simons <simons@cryp.to>
+Peter Siska <siska.pe@gmail.com>
+Peter Trommler <ptrommler@acm.org>
Peter Trško <peter.trsko@gmail.com>
Phil Ruffwind <rf@rufflewind.com>
Philipp Schumann <philipp.schumann@gmail.com>
@@ -237,6 +257,7 @@ Roberto Zunino <zunrob@users.sf.net>
Robin Green <greenrd@greenrd.org>
Robin KAY <komadori@gekkou.co.uk>
Roman Cheplyaka <roma@ro-che.info>
+Roman Kashitcyn <rkashitsyn@rkashitsyn.zrh.corp.google.com>
Ross Paterson <ross@soi.city.ac.uk>
Rudy Matela <rudy@matela.com.br>
Ryan Desfosses <ryan@desfo.org>
@@ -258,10 +279,14 @@ Simon Peyton Jones <simonpj@microsoft.com>
Spencer Janssen <sjanssen@cse.unl.edu>
Stephen Blackheath <stephen.blackheath@ipwnstudios.com>
Stuart Popejoy <spopejoy@panix.com>
+Suzumiya <suzumiyasmith@gmail.com>
Sven Panne <sven.panne@aedion.de>
Sönke Hahn <shahn@joyridelabs.de>
+Takano Akio <tak@anoak.io>
+Takenobu Tani <takenobu.hs@gmail.com>
Tamar Christina <tamar@zhox.com>
Taru Karttunen <taruti@taruti.net>
+Taylor Fausak <taylor.fausak@verizonwireless.com>
Thomas Dziedzic <gostrc@gmail.com>
Thomas M. DuBuisson <thomas.dubuisson@gmail.com>
Thomas Miedema <thomasmiedema@gmail.com>
@@ -270,14 +295,22 @@ Thomas Tuegel <ttuegel@gmail.com>
Tillmann Rendel <rendel@informatik.uni-marburg.de>
Tim Chevalier <chevalier@alum.wellesley.edu>
Tim Humphries <tim.humphries@ambiata.com>
+Tim McGilchrist <timmcgil@gmail.com>
Tomas Vestelind <tomas.vestelind@gmail.com>
Toshio Ito <debug.ito@gmail.com>
Travis Cardwell <travis.cardwell@extellisys.com>
Tuncer Ayaz <tuncer.ayaz@gmail.com>
+Vaibhav Sagar <vaibhavsagar@gmail.com>
+Veronika Romashkina <vrom911@gmail.com>
Vincent Hanquez <vincent@snarc.org>
+Vladislav Zavialov <vlad.z.4096@gmail.com>
Vo Minh Thu <noteed@gmail.com>
Wojciech Danilo <wojtek.danilo@gmail.com>
Yitzchak Gale <gale@sefer.org>
Yuras Shumovich <shumovichy@gmail.com>
+Yuriy Syrovetskiy <cblp@cblp.su>
capsjac <capsjac@gmail.com>
+ghthrowaway7 <41365123+ghthrowaway7@users.noreply.github.com>
+quasicomputational <quasicomputational@gmail.com>
+vedksah <31156362+vedksah@users.noreply.github.com>
Łukasz Dąbek <sznurek@gmail.com>
diff --git a/cabal/Cabal/Cabal.cabal b/cabal/Cabal/Cabal.cabal
index 17b2b74..b97d346 100644
--- a/cabal/Cabal/Cabal.cabal
+++ b/cabal/Cabal/Cabal.cabal
@@ -1,6 +1,6 @@
name: Cabal
-version: 2.1.0.0
-copyright: 2003-2017, Cabal Development Team (see AUTHORS file)
+version: 2.4.1.0
+copyright: 2003-2018, Cabal Development Team (see AUTHORS file)
license: BSD3
license-file: LICENSE
author: Cabal Development Team <cabal-devel@haskell.org>
@@ -22,34 +22,145 @@ build-type: Simple
-- we can bootstrap.
extra-source-files:
- README.md tests/README.md changelog
+ README.md tests/README.md ChangeLog.md
doc/bugs-and-stability.rst doc/concepts-and-development.rst
doc/conf.py doc/config-and-install.rst doc/developing-packages.rst
doc/images/Cabal-dark.png doc/index.rst doc/installing-packages.rst
doc/intro.rst doc/misc.rst doc/nix-local-build-overview.rst
- doc/nix-local-build.rst doc/README.md doc/references.inc
+ doc/nix-local-build.rst doc/file-format-changelog.rst doc/README.md
+ doc/references.inc
- -- Generated with 'misc/gen-extra-source-files.sh'
+ -- Generated with 'make gen-extra-source-files'
-- Do NOT edit this section manually; instead, run the script.
-- BEGIN gen-extra-source-files
+ tests/ParserTests/errors/common1.cabal
+ tests/ParserTests/errors/common1.errors
+ tests/ParserTests/errors/common2.cabal
+ tests/ParserTests/errors/common2.errors
+ tests/ParserTests/errors/common3.cabal
+ tests/ParserTests/errors/common3.errors
+ tests/ParserTests/errors/forward-compat.cabal
+ tests/ParserTests/errors/forward-compat.errors
+ tests/ParserTests/errors/forward-compat2.cabal
+ tests/ParserTests/errors/forward-compat2.errors
+ tests/ParserTests/errors/forward-compat3.cabal
+ tests/ParserTests/errors/forward-compat3.errors
+ tests/ParserTests/errors/issue-5055-2.cabal
+ tests/ParserTests/errors/issue-5055-2.errors
+ tests/ParserTests/errors/issue-5055.cabal
+ tests/ParserTests/errors/issue-5055.errors
+ tests/ParserTests/errors/leading-comma.cabal
+ tests/ParserTests/errors/leading-comma.errors
+ tests/ParserTests/errors/noVersion.cabal
+ tests/ParserTests/errors/noVersion.errors
+ tests/ParserTests/errors/noVersion2.cabal
+ tests/ParserTests/errors/noVersion2.errors
+ tests/ParserTests/errors/range-ge-wild.cabal
+ tests/ParserTests/errors/range-ge-wild.errors
+ tests/ParserTests/errors/spdx-1.cabal
+ tests/ParserTests/errors/spdx-1.errors
+ tests/ParserTests/errors/spdx-2.cabal
+ tests/ParserTests/errors/spdx-2.errors
+ tests/ParserTests/errors/spdx-3.cabal
+ tests/ParserTests/errors/spdx-3.errors
+ tests/ParserTests/ipi/Includes2.cabal
+ tests/ParserTests/ipi/Includes2.expr
+ tests/ParserTests/ipi/Includes2.format
+ tests/ParserTests/ipi/internal-preprocessor-test.cabal
+ tests/ParserTests/ipi/internal-preprocessor-test.expr
+ tests/ParserTests/ipi/internal-preprocessor-test.format
+ tests/ParserTests/ipi/issue-2276-ghc-9885.cabal
+ tests/ParserTests/ipi/issue-2276-ghc-9885.expr
+ tests/ParserTests/ipi/issue-2276-ghc-9885.format
+ tests/ParserTests/ipi/transformers.cabal
+ tests/ParserTests/ipi/transformers.expr
+ tests/ParserTests/ipi/transformers.format
+ tests/ParserTests/regressions/MiniAgda.cabal
+ tests/ParserTests/regressions/MiniAgda.check
tests/ParserTests/regressions/Octree-0.5.cabal
+ tests/ParserTests/regressions/Octree-0.5.expr
+ tests/ParserTests/regressions/Octree-0.5.format
+ tests/ParserTests/regressions/bad-glob-syntax.cabal
+ tests/ParserTests/regressions/bad-glob-syntax.check
+ tests/ParserTests/regressions/cc-options-with-optimization.cabal
+ tests/ParserTests/regressions/cc-options-with-optimization.check
+ tests/ParserTests/regressions/common.cabal
+ tests/ParserTests/regressions/common.expr
+ tests/ParserTests/regressions/common.format
+ tests/ParserTests/regressions/common2.cabal
+ tests/ParserTests/regressions/common2.expr
+ tests/ParserTests/regressions/common2.format
+ tests/ParserTests/regressions/cxx-options-with-optimization.cabal
+ tests/ParserTests/regressions/cxx-options-with-optimization.check
tests/ParserTests/regressions/elif.cabal
+ tests/ParserTests/regressions/elif.expr
+ tests/ParserTests/regressions/elif.format
tests/ParserTests/regressions/elif2.cabal
+ tests/ParserTests/regressions/elif2.expr
+ tests/ParserTests/regressions/elif2.format
tests/ParserTests/regressions/encoding-0.8.cabal
+ tests/ParserTests/regressions/encoding-0.8.expr
+ tests/ParserTests/regressions/encoding-0.8.format
+ tests/ParserTests/regressions/extensions-paths-5054.cabal
+ tests/ParserTests/regressions/extensions-paths-5054.check
tests/ParserTests/regressions/generics-sop.cabal
+ tests/ParserTests/regressions/generics-sop.expr
+ tests/ParserTests/regressions/generics-sop.format
+ tests/ParserTests/regressions/ghc-option-j.cabal
+ 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/issue-5055.cabal
+ tests/ParserTests/regressions/issue-5055.expr
+ tests/ParserTests/regressions/issue-5055.format
tests/ParserTests/regressions/issue-774.cabal
+ tests/ParserTests/regressions/issue-774.check
+ tests/ParserTests/regressions/issue-774.expr
+ tests/ParserTests/regressions/issue-774.format
+ tests/ParserTests/regressions/leading-comma.cabal
+ tests/ParserTests/regressions/leading-comma.expr
+ tests/ParserTests/regressions/leading-comma.format
+ tests/ParserTests/regressions/noVersion.cabal
+ tests/ParserTests/regressions/noVersion.expr
+ tests/ParserTests/regressions/noVersion.format
tests/ParserTests/regressions/nothing-unicode.cabal
+ tests/ParserTests/regressions/nothing-unicode.check
+ tests/ParserTests/regressions/nothing-unicode.expr
+ tests/ParserTests/regressions/nothing-unicode.format
+ tests/ParserTests/regressions/pre-1.6-glob.cabal
+ 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/shake.cabal
+ tests/ParserTests/regressions/shake.expr
+ tests/ParserTests/regressions/shake.format
+ tests/ParserTests/regressions/spdx-1.cabal
+ tests/ParserTests/regressions/spdx-1.expr
+ tests/ParserTests/regressions/spdx-1.format
+ tests/ParserTests/regressions/spdx-2.cabal
+ tests/ParserTests/regressions/spdx-2.expr
+ tests/ParserTests/regressions/spdx-2.format
+ tests/ParserTests/regressions/spdx-3.cabal
+ tests/ParserTests/regressions/spdx-3.expr
+ tests/ParserTests/regressions/spdx-3.format
+ tests/ParserTests/regressions/th-lift-instances.cabal
+ tests/ParserTests/regressions/th-lift-instances.expr
+ tests/ParserTests/regressions/th-lift-instances.format
+ tests/ParserTests/regressions/wl-pprint-indef.cabal
+ tests/ParserTests/regressions/wl-pprint-indef.expr
+ tests/ParserTests/regressions/wl-pprint-indef.format
tests/ParserTests/warnings/bom.cabal
tests/ParserTests/warnings/bool.cabal
tests/ParserTests/warnings/deprecatedfield.cabal
+ tests/ParserTests/warnings/doubledash.cabal
tests/ParserTests/warnings/extratestmodule.cabal
tests/ParserTests/warnings/gluedop.cabal
+ tests/ParserTests/warnings/multiplesingular.cabal
tests/ParserTests/warnings/nbsp.cabal
tests/ParserTests/warnings/newsyntax.cabal
tests/ParserTests/warnings/oldsyntax.cabal
tests/ParserTests/warnings/subsection.cabal
+ tests/ParserTests/warnings/tab.cabal
tests/ParserTests/warnings/trailingfield.cabal
tests/ParserTests/warnings/unknownfield.cabal
tests/ParserTests/warnings/unknownsection.cabal
@@ -69,50 +180,28 @@ source-repository head
flag bundled-binary-generic
default: False
-flag old-directory
- description: Use directory < 1.2 and old-time
- default: False
-
-flag parsec-struct-diff
- description: Use StructDiff in parsec tests. Affects only parsec tests.
- default: False
- manual: True
-
library
build-depends:
- array >= 0.1 && < 0.6,
- base >= 4.5 && < 5,
- bytestring >= 0.9 && < 1,
- containers >= 0.4 && < 0.6,
- deepseq >= 1.3 && < 1.5,
- filepath >= 1.3 && < 1.5,
- pretty >= 1.1 && < 1.2,
- process >= 1.1.0.1 && < 1.7,
- time >= 1.4 && < 1.9
-
- if flag(old-directory)
- build-depends: directory >= 1.1 && < 1.2, old-time >= 1 && < 1.2,
- process >= 1.0.1.1 && < 1.1.0.2
- else
- build-depends: directory >= 1.2 && < 1.4,
- process >= 1.1.0.2 && < 1.7
+ array >= 0.4.0.1 && < 0.6,
+ base >= 4.6 && < 5,
+ bytestring >= 0.10.0.0 && < 0.11,
+ containers >= 0.5.0.0 && < 0.7,
+ deepseq >= 1.3.0.1 && < 1.5,
+ directory >= 1.2 && < 1.4,
+ 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
if flag(bundled-binary-generic)
- build-depends: binary >= 0.5 && < 0.7
+ build-depends: binary >= 0.5.1.1 && < 0.7
else
build-depends: binary >= 0.7 && < 0.9
- -- Needed for GHC.Generics before GHC 7.6
- if impl(ghc < 7.6)
- build-depends: ghc-prim >= 0.2 && < 0.3
-
- if !os(windows)
- build-depends:
- unix >= 2.5 && < 2.8
-
if os(windows)
- build-depends:
- Win32 >= 2.2 && < 2.7
+ build-depends: Win32 >= 2.3.0.0 && < 2.9
+ else
+ build-depends: unix >= 2.6.0.0 && < 2.8
ghc-options: -Wall -fno-ignore-asserts -fwarn-tabs
if impl(ghc >= 8.0)
@@ -130,15 +219,16 @@ library
Distribution.Backpack.ModSubst
Distribution.Backpack.ModuleShape
Distribution.Backpack.PreModuleShape
+ Distribution.CabalSpecVersion
Distribution.Utils.IOData
Distribution.Utils.LogProgress
Distribution.Utils.MapAccum
Distribution.Compat.CreatePipe
+ Distribution.Compat.Directory
Distribution.Compat.Environment
Distribution.Compat.Exception
Distribution.Compat.Graph
Distribution.Compat.Internal.TempFile
- Distribution.Compat.Map.Strict
Distribution.Compat.Newtype
Distribution.Compat.Prelude.Internal
Distribution.Compat.ReadP
@@ -148,6 +238,10 @@ library
Distribution.Compat.DList
Distribution.Compiler
Distribution.InstalledPackageInfo
+ Distribution.Types.AbiDependency
+ Distribution.Types.ExposedModule
+ Distribution.Types.InstalledPackageInfo
+ Distribution.Types.InstalledPackageInfo.FieldGrammar
Distribution.License
Distribution.Make
Distribution.ModuleName
@@ -155,7 +249,6 @@ library
Distribution.PackageDescription
Distribution.PackageDescription.Check
Distribution.PackageDescription.Configuration
- Distribution.PackageDescription.Parse
Distribution.PackageDescription.PrettyPrint
Distribution.PackageDescription.Utils
Distribution.ParseUtils
@@ -173,16 +266,16 @@ library
Distribution.Simple.Command
Distribution.Simple.Compiler
Distribution.Simple.Configure
+ Distribution.Simple.Flag
Distribution.Simple.GHC
Distribution.Simple.GHCJS
Distribution.Simple.Haddock
Distribution.Simple.Doctest
+ Distribution.Simple.Glob
Distribution.Simple.HaskellSuite
Distribution.Simple.Hpc
Distribution.Simple.Install
Distribution.Simple.InstallDirs
- Distribution.Simple.JHC
- Distribution.Simple.LHC
Distribution.Simple.LocalBuildInfo
Distribution.Simple.PackageIndex
Distribution.Simple.PreProcess
@@ -212,6 +305,13 @@ library
Distribution.Simple.UHC
Distribution.Simple.UserHooks
Distribution.Simple.Utils
+ Distribution.SPDX
+ Distribution.SPDX.License
+ Distribution.SPDX.LicenseId
+ Distribution.SPDX.LicenseExceptionId
+ Distribution.SPDX.LicenseExpression
+ Distribution.SPDX.LicenseListVersion
+ Distribution.SPDX.LicenseReference
Distribution.System
Distribution.TestSuite
Distribution.Text
@@ -276,15 +376,20 @@ library
Language.Haskell.Extension
Distribution.Compat.Binary
- -- Parsec parser relatedmodules
+ -- Parsec parser-related modules
build-depends:
- transformers,
- mtl >= 2.1 && <2.3,
- parsec >= 3.1.9 && <3.2
+ -- transformers-0.4.0.0 doesn't have record syntax e.g. for Identity
+ -- See also https://github.com/ekmett/transformers-compat/issues/35
+ transformers (>= 0.3 && < 0.4) || (>=0.4.1.0 && <0.6),
+ mtl >= 2.1 && < 2.3,
+ text >= 1.2.3.0 && < 1.3,
+ parsec >= 3.1.13.0 && < 3.2
exposed-modules:
- Distribution.Compat.Parsec
+ Distribution.Compat.Parsing
+ Distribution.Compat.CharParsing
Distribution.FieldGrammar
Distribution.FieldGrammar.Class
+ Distribution.FieldGrammar.FieldDescrs
Distribution.FieldGrammar.Parsec
Distribution.FieldGrammar.Pretty
Distribution.PackageDescription.FieldGrammar
@@ -294,6 +399,7 @@ library
Distribution.Parsec.Common
Distribution.Parsec.ConfVar
Distribution.Parsec.Field
+ Distribution.Parsec.FieldLineStream
Distribution.Parsec.Lexer
Distribution.Parsec.LexerMonad
Distribution.Parsec.Newtypes
@@ -309,6 +415,7 @@ library
Distribution.Types.Executable.Lens
Distribution.Types.ForeignLib.Lens
Distribution.Types.GenericPackageDescription.Lens
+ Distribution.Types.InstalledPackageInfo.Lens
Distribution.Types.Library.Lens
Distribution.Types.PackageDescription.Lens
Distribution.Types.PackageId.Lens
@@ -333,9 +440,8 @@ library
Distribution.GetOpt
Distribution.Lex
Distribution.Utils.String
+ Distribution.Simple.GHC.EnvironmentParser
Distribution.Simple.GHC.Internal
- Distribution.Simple.GHC.IPI642
- Distribution.Simple.GHC.IPIConvert
Distribution.Simple.GHC.ImplInfo
Paths_Cabal
@@ -386,9 +492,12 @@ test-suite unit-tests
UnitTests.Distribution.Compat.ReadP
UnitTests.Distribution.Compat.Time
UnitTests.Distribution.Compat.Graph
+ UnitTests.Distribution.Simple.Glob
UnitTests.Distribution.Simple.Program.Internal
UnitTests.Distribution.Simple.Utils
+ UnitTests.Distribution.SPDX
UnitTests.Distribution.System
+ UnitTests.Distribution.Types.GenericPackageDescription
UnitTests.Distribution.Utils.Generic
UnitTests.Distribution.Utils.NubList
UnitTests.Distribution.Utils.ShortText
@@ -402,13 +511,14 @@ test-suite unit-tests
directory,
filepath,
integer-logarithms >= 1.0.2 && <1.1,
- tasty,
+ tasty >= 1.1.0.3 && < 1.2,
tasty-hunit,
tasty-quickcheck,
tagged,
+ temporary,
text,
pretty,
- QuickCheck >= 2.7 && < 2.11,
+ QuickCheck >= 2.11.3 && < 2.12,
Cabal
ghc-options: -Wall
default-language: Haskell2010
@@ -417,12 +527,12 @@ test-suite parser-tests
type: exitcode-stdio-1.0
hs-source-dirs: tests
main-is: ParserTests.hs
- build-depends: containers
build-depends:
base,
+ base-compat >=0.10.4 && <0.11,
bytestring,
filepath,
- tasty,
+ tasty >= 1.1.0.3 && < 1.2,
tasty-hunit,
tasty-quickcheck,
tasty-golden >=2.3.1.1 && <2.4,
@@ -431,6 +541,15 @@ test-suite parser-tests
ghc-options: -Wall
default-language: Haskell2010
+ if impl(ghc >= 7.8)
+ build-depends:
+ tree-diff >= 0.0.1 && <0.1
+ other-modules:
+ Instances.TreeDiff
+ Instances.TreeDiff.Language
+ Instances.TreeDiff.SPDX
+ Instances.TreeDiff.Version
+
test-suite check-tests
type: exitcode-stdio-1.0
hs-source-dirs: tests
@@ -439,44 +558,62 @@ test-suite check-tests
base,
bytestring,
filepath,
- tasty,
+ tasty >= 1.1.0.3 && < 1.2,
tasty-golden >=2.3.1.1 && <2.4,
Diff >=0.3.4 && <0.4,
Cabal
ghc-options: -Wall
default-language: Haskell2010
-test-suite parser-hackage-tests
+test-suite custom-setup-tests
type: exitcode-stdio-1.0
- main-is: ParserHackageTests.hs
+ hs-source-dirs: tests/custom-setup
+ main-is: CustomSetupTests.hs
+ other-modules:
+ CabalDoctestSetup
+ IdrisSetup
+ build-depends:
+ Cabal,
+ base,
+ directory,
+ filepath,
+ process
+ default-language: Haskell2010
+
+test-suite hackage-tests
+ type: exitcode-stdio-1.0
+ main-is: HackageTests.hs
-- TODO: need to get 01-index.tar on appveyor
if os(windows)
buildable: False
hs-source-dirs: tests
+
build-depends:
base,
- base-orphans == 0.6.*,
- base-compat >=0.9.3 && <0.10,
- containers,
- tar >=0.5 && <0.6,
+ Cabal,
bytestring,
+ deepseq,
+ containers,
directory,
- filepath,
- Cabal
+ filepath
+
+ build-depends:
+ base-compat >=0.10.4 && <0.11,
+ base-orphans >=0.6 && <0.9,
+ optparse-applicative >=0.13.2.0 && <0.15,
+ tar >=0.5.0.3 && <0.6
- if flag(parsec-struct-diff)
+ if impl(ghc >= 7.8)
build-depends:
- generics-sop >= 0.3.1.0 && <0.4,
- these >=0.7.1 && <0.8,
- singleton-bool >=0.1.1.0 && <0.2,
- keys
+ tree-diff >= 0.0.1 && <0.1
other-modules:
- DiffInstances
- StructDiff
- cpp-options: -DHAS_STRUCT_DIFF
+ Instances.TreeDiff
+ Instances.TreeDiff.Language
+ Instances.TreeDiff.SPDX
+ Instances.TreeDiff.Version
- ghc-options: -Wall -rtsopts
+ ghc-options: -Wall -rtsopts -threaded
default-extensions: CPP
default-language: Haskell2010
diff --git a/cabal/Cabal/ChangeLog.md b/cabal/Cabal/ChangeLog.md
new file mode 100644
index 0000000..99105ee
--- /dev/null
+++ b/cabal/Cabal/ChangeLog.md
@@ -0,0 +1,888 @@
+### 2.4.1.0 [Mikhail Glushenkov](mailto:mikhail.glushenkov@gmail.com) November 2018
+
+ * Warnings in autogenerated files are now silenced
+ ([#5678](https://github.com/haskell/cabal/pulls/5678)).
+ * Improved recompilation avoidance, especially when using GHC 8.6
+ ([#5589](https://github.com/haskell/cabal/pulls/5589)).
+ * Do not error on empty packagedbs in `getInstalledPackages`
+ ([#5516](https://github.com/haskell/cabal/issues/5516)).
+
+
+### 2.4.0.1 [Mikhail Glushenkov](mailto:mikhail.glushenkov@gmail.com) September 2018
+
+ * Allow arguments to be passed to `Setup.hs haddock` for `build-type:configure`
+ ([#5503](https://github.com/haskell/cabal/issues/5503)).
+
+# 2.4.0.0 [Mikhail Glushenkov](mailto:mikhail.glushenkov@gmail.com) September 2018
+
+ * Due to [#5119](https://github.com/haskell/cabal/issues/5119), the
+ `cabal check` warning for bounds on internal libraries has been
+ disabled.
+ * `Distribution.Simple.Haddock` now checks to ensure that it
+ does not erroneously call Haddock with no target modules.
+ ([#5232](https://github.com/haskell/cabal/issues/5232),
+ [#5459](https://github.com/haskell/cabal/issues/5459)).
+ * Add `getting` (less general than `to`) Lens combinator,
+ `non`) and an optics to access the modules in a component
+ of a `PackageDescription` by the `ComponentName`:
+ `componentBuildInfo` and `componentModules`
+ * Add `readGhcEnvironmentFile` to parse GHC environment files.
+ * Drop support for GHC 7.4, since it is out of our support window
+ (and has been for over a year!)
+ * Deprecate `preSDist`, `sDistHook`, and `postSDist` in service of
+ `new-sdist`, since they violate key invariants of the new-build
+ ecosystem. Use `autogen-modules` and `build-tool-depends` instead.
+ ([#5389](https://github.com/haskell/cabal/pull/5389)).
+ * Added `--repl-options` flag to `Setup repl` used to pass flags to the
+ underlying repl without affecting the `LocalBuildInfo`
+ ([#4247](https://github.com/haskell/cabal/issues/4247),
+ [#5287](https://github.com/haskell/cabal/pull/5287))
+ * `KnownExtension`: added new extensions `BlockArguments`
+ ([#5101](https://github.com/haskell/cabal/issues/5101)),
+ `NumericUnderscores`
+ ([#5130]((https://github.com/haskell/cabal/issues/5130)),
+ `QuantifiedConstraints`, and `StarIsType`.
+ * `buildDepends` is removed from `PackageDescription`. It had long been
+ uselessly hanging about as top-level build-depends already got put
+ into per-component condition trees anyway. Now it's finally been put
+ out of its misery
+ ([#4383](https://github.com/haskell/cabal/issues/4283)).
+ * Added `Eta` to `CompilerFlavor` and to known compilers.
+ * `cabal haddock` now generates per-component documentation
+ ([#5226](https://github.com/haskell/cabal/issues/5226)).
+ * Wildcard improvements:
+ * Allow `**` wildcards in `data-files`, `extra-source-files` and
+ `extra-doc-files`. These allow a limited form of recursive
+ matching, and require `cabal-version: 2.4`.
+ ([#5284](https://github.com/haskell/cabal/issues/5284),
+ [#3178](https://github.com/haskell/cabal/issues/3178), et al.)
+ * With `cabal-version: 2.4`, when matching a wildcard, the
+ requirement for the full extension to match exactly has been
+ loosened. Instead, if the wildcard's extension is a suffix of the
+ file's extension, the file will be selected. For example,
+ previously `foo.en.html` would not match `*.html`, and
+ `foo.solaris.tar.gz` would not match `*.tar.gz`, but now both
+ do. This may lead to files unexpectedly being included by `sdist`;
+ please audit your package descriptions if you rely on this
+ behaviour to keep sensitive data out of distributed packages
+ ([#5372](https://github.com/haskell/cabal/pull/5372),
+ [#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
+ anything are now all detected by `cabal check`.
+ * Wildcard ('globbing') functions have been moved from
+ `Distribution.Simple.Utils` to `Distribution.Simple.Glob` and
+ have been refactored.
+ * Fixed `cxx-options` and `cxx-sources` buildinfo fields for
+ separate compilation of C++ source files to correctly build and link
+ non-library components ([#5309](https://github.com/haskell/cabal/issues/5309)).
+ * Reduced warnings generated by hsc2hs and c2hs when `cxx-options` field
+ is present in a component.
+ * `cabal check` now warns if `-j` is used in `ghc-options` in a Cabal
+ file. ([#5277](https://github.com/haskell/cabal/issues/5277))
+ * `install-includes` now works as expected with foreign libraries
+ ([#5302](https://github.com/haskell/cabal/issues/5299)).
+ * Removed support for JHC.
+ * Options listed in `ghc-options`, `cc-options`, `ld-options`,
+ `cxx-options`, `cpp-options` are not deduplicated anymore
+ ([#4449](https://github.com/haskell/cabal/issues/4449)).
+ * Deprecated `cabal hscolour` in favour of `cabal haddock --hyperlink-source` ([#5236](https://github.com/haskell/cabal/pull/5236/)).
+ * Recognize `powerpc64le` as architecture PPC64.
+ * Cabal now deduplicates more `-I` and `-L` and flags to avoid `E2BIG`
+ ([#5356](https://github.com/haskell/cabal/issues/5356)).
+ * With `build-type: configure`, avoid using backslashes to delimit
+ path components on Windows and warn about other unsafe characters
+ in the path to the source directory on all platforms
+ ([#5386](https://github.com/haskell/cabal/issues/5386)).
+ * `Distribution.PackageDescription.Check.checkPackageFiles` now
+ accepts a `Verbosity` argument.
+ * Added a parameter to
+ `Distribution.Backpack.ConfiguredComponent.toConfiguredComponent` in order to fix
+ [#5409](https://github.com/haskell/cabal/issues/5409).
+ * Partially silence `abi-depends` warnings
+ ([#5465](https://github.com/haskell/cabal/issues/5465)).
+ * Foreign libraries are now linked against the threaded RTS when the
+ 'ghc-options: -threaded' flag is used
+ ([#5431](https://github.com/haskell/cabal/pull/5431)).
+ * Pass command line arguments to `hsc2hs` using response files when possible
+ ([#3122](https://github.com/haskell/cabal/issues/3122)).
+
+----
+
+## 2.2.0.1 [Mikhail Glushenkov](mailto:mikhail.glushenkov@gmail.com) March 2018
+
+ * Fix `checkPackageFiles` for relative directories ([#5206](https://github.com/haskell/cabal/issues/5206))
+
+
+# 2.2.0.0 [Mikhail Glushenkov](mailto:mikhail.glushenkov@gmail.com) March 2018
+
+ * The 2.2 migration guide gives advice on adapting Custom setup
+ scripts to backwards-incompatible changes in this release:
+ https://github.com/haskell/cabal/wiki/2.2-migration-guide.
+ * New Parsec-based parser for `.cabal` files is now the
+ default. This brings memory consumption and speed improvements, as
+ well as making new syntax extensions easier to implement.
+ * Support for common stanzas (#4751).
+ * Added elif-conditionals to `.cabal` syntax (#4750).
+ * The package license information can now be specified using the
+ SPDX syntax. This requires setting `cabal-version` to 2.2+ (#2547,
+ #5050).
+ * Support for GHC's numeric -g debug levels (#4673).
+ * Compilation with section splitting is now supported via the
+ `--enable-split-sections` flag (#4819)
+ * Fields with mandatory commas (e.g. build-depends) may now have a
+ leading or a trailing comma (either one, not both) (#4953)
+ * Added `virtual-modules` field, to allow modules that are not built
+ but registered (#4875).
+ * Use better defaulting for `build-type`; rename `PackageDescription`'s
+ `buildType` field to `buildTypeRaw` and introduce new `buildType`
+ function (#4958)
+ * `D.T.PackageDescription.allBuildInfo` now returns all build infos, not
+ only for buildable components (#5087).
+ * Removed `UnknownBuildType` constructor from `BuildType` (#5003).
+ * Added `HexFloatLiterals` to `KnownExtension`.
+ * Cabal will no longer try to build an empty set of `inputModules`
+ (#4890).
+ * `copyComponent` and `installIncludeFiles` will now look for
+ include headers in the build directory (`dist/build/...` by
+ default) as well (#4866).
+ * Added `cxx-options` and `cxx-sources` buildinfo fields for
+ separate compilation of C++ source files (#3700).
+ * Removed unused `--allow-newer`/`--allow-older` support from
+ `Setup configure` (#4527).
+ * Changed `FlagAssignment` to be an opaque `newtype` (#4849).
+ * Changed `rawSystemStdInOut` to use proper type to represent
+ binary and textual data; new `Distribution.Utils.IOData` module;
+ removed obsolete `startsWithBOM`, `fileHasBOM`, `fromUTF8`,
+ and `toUTF8` functions; add new `toUTF8BS`/`toUTF8LBS`
+ encoding functions. (#4666)
+ * Added a `cabal check` warning when the `.cabal` file name does
+ not match package name (#4592).
+ * The `ar` program now receives its arguments via a response file
+ (`@file`). Old behaviour can be restored with
+ `--disable-response-files` argument to `configure` or
+ `install` (#4596).
+ * Added `.Lens` modules, with optics for package description data
+ types (#4701).
+ * Support for building with Win32 version 2.6 (#4835).
+ * Change `compilerExtensions` and `ghcOptExtensionMap` to contain
+ `Maybe Flag`s, since a supported extention can lack a flag (#4443).
+ * Pretty-printing of `.cabal` files is slightly different due to
+ parser changes. For an example, see
+ https://mail.haskell.org/pipermail/cabal-devel/2017-December/010414.html.
+ * `--hyperlink-source` now uses Haddock's hyperlinker backend when
+ Haddock is new enough, falling back to HsColour otherwise.
+ * `D.S.defaultHookedPackageDesc` has been deprecated in favour of
+ `D.S.findHookedPackageDesc` (#4874).
+ * `D.S.getHookedBuildInfo` now takes an additional parameter
+ specifying the build directory path (#4874).
+ * Emit warning when encountering unknown GHC versions (#415).
+
+### 2.0.1.1 [Mikhail Glushenkov](mailto:mikhail.glushenkov@gmail.com) December 2017
+
+ * Don't pass `other-modules` to stub executable for detailed-0.9
+ (#4918).
+ * Hpc: Use relative .mix search paths (#4917).
+
+## 2.0.1.0 [Mikhail Glushenkov](mailto:mikhail.glushenkov@gmail.com) November 2017
+
+ * Support for GHC's numeric -g debug levels (#4673).
+ * Added a new `Distribution.Verbosity.modifyVerbosity` combinator
+ (#4724).
+ * Added a new `cabal check` warning about unused, undeclared or
+ non-Unicode flags. Also, it warns about leading dash, which is
+ unusable but accepted if it's unused in conditionals. (#4687)
+ * Modify `allBuildInfo` to include foreign library info (#4763).
+ * Documentation fixes.
+
+### 2.0.0.2 [Mikhail Glushenkov](mailto:mikhail.glushenkov@gmail.com) July 2017
+
+ * See http://coldwa.st/e/blog/2017-09-09-Cabal-2-0.html
+ for more detailed release notes.
+ * The 2.0 migration guide gives advice on adapting Custom setup
+ scripts to backwards-incompatible changes in this release:
+ https://github.com/haskell/cabal/wiki/2.0-migration-guide
+ * Add CURRENT_PACKAGE_VERSION to cabal_macros.h (#4319)
+ * Dropped support for versions of GHC earlier than 6.12 (#3111).
+ * GHC compatibility window for the Cabal library has been extended
+ to five years (#3838).
+ * Convenience/internal libraries are now supported (#269).
+ An internal library is declared using the stanza `library
+ 'libname'`. Packages which use internal libraries can
+ result in multiple registrations; thus `--gen-pkg-config`
+ can now output a directory of registration scripts rather than
+ a single file.
+ * Backwards incompatible change to preprocessor interface:
+ the function in `PPSuffixHandler` now takes an additional
+ `ComponentLocalBuildInfo` specifying the build information
+ of the component being preprocessed.
+ * Backwards incompatible change to `cabal_macros.h` (#1893): we now
+ generate a macro file for each component which contains only
+ information about the direct dependencies of that component.
+ Consequently, `dist/build/autogen/cabal_macros.h` contains
+ only the macros for the library, and is not generated if a
+ package has no library; to find the macros for an executable
+ named `foobar`, look in `dist/build/foobar/autogen/cabal_macros.h`.
+ Similarly, if you used `autogenModulesDir` you should now
+ use `autogenComponentModulesDir`, which now requires a
+ `ComponentLocalBuildInfo` argument as well in order to
+ disambiguate which component the autogenerated files are for.
+ * Backwards incompatible change to `Component`: `TestSuite` and
+ `Benchmark` no longer have `testEnabled` and
+ `benchmarkEnabled`. If you used
+ `enabledTests` or `enabledBenchmarks`, please instead use
+ `enabledTestLBIs` and `enabledBenchLBIs`
+ (you will need a `LocalBuildInfo` for these functions.)
+ Additionally, the semantics of `withTest` and `withBench`
+ have changed: they now iterate over all buildable
+ such components, regardless of whether or not they have
+ been enabled; if you only want enabled components,
+ use `withTestLBI` and `withBenchLBI`.
+ `finalizePackageDescription` is deprecated:
+ its replacement `finalizePD` now takes an extra argument
+ `ComponentRequestedSpec` which specifies what components
+ are to be enabled: use this instead of modifying the
+ `Component` in a `GenericPackageDescription`. (As
+ it's not possible now, `finalizePackageDescription`
+ will assume tests/benchmarks are disabled.)
+ If you only need to test if a component is buildable
+ (i.e., it is marked buildable in the Cabal file)
+ use the new function `componentBuildable`.
+ * Backwards incompatible change to `PackageName` (#3896):
+ `PackageName` is now opaque; conversion to/from `String` now works
+ via (old) `unPackageName` and (new) `mkPackageName` functions.
+ * Backwards incompatible change to `ComponentId` (#3917):
+ `ComponentId` is now opaque; conversion to/from `String` now works
+ via `unComponentId` and `mkComponentId` functions.
+ * Backwards incompatible change to `AbiHash` (#3921):
+ `AbiHash` is now opaque; conversion to/from `String` now works
+ via `unAbiHash` and `mkAbiHash` functions.
+ * Backwards incompatible change to `FlagName` (#4062):
+ `FlagName` is now opaque; conversion to/from `String` now works
+ via `unFlagName` and `mkFlagName` functions.
+ * Backwards incompatible change to `Version` (#3905):
+ Version is now opaque; conversion to/from `[Int]` now works
+ via `versionNumbers` and `mkVersion` functions.
+ * Add support for `--allow-older` (dual to `--allow-newer`) (#3466)
+ * Improved an error message for process output decoding errors
+ (#3408).
+ * `getComponentLocalBuildInfo`, `withComponentsInBuildOrder`
+ and `componentsInBuildOrder` are deprecated in favor of a
+ new interface in `Distribution.Types.LocalBuildInfo`.
+ * New `autogen-modules` field. Modules that are built automatically at
+ setup, like Paths_PACKAGENAME or others created with a build-type
+ custom, appear on `other-modules` for the Library, Executable,
+ Test-Suite or Benchmark stanzas or also on `exposed-modules` for
+ libraries but are not really on the package when distributed. This
+ makes commands like sdist fail because the file is not found, so with
+ this new field modules that appear there are treated the same way as
+ Paths_PACKAGENAME was and there is no need to create complex build
+ hooks. Just add the module names on `other-modules` and
+ `exposed-modules` as always and on the new `autogen-modules` besides.
+ (#3656).
+ * New `./Setup configure` flag `--cabal-file`, allowing multiple
+ `.cabal` files in a single directory (#3553). Primarily intended for
+ internal use.
+ * Macros in `cabal_macros.h` are now ifndef'd, so that they
+ don't cause an error if the macro is already defined. (#3041)
+ * `./Setup configure` now accepts a single argument specifying
+ the component to be configured. The semantics of this mode
+ of operation are described in
+ <https://github.com/ghc-proposals/ghc-proposals/pull/4>
+ * Internal `build-tools` dependencies are now added to PATH
+ upon invocation of GHC, so that they can be conveniently
+ used via `-pgmF`. (#1541)
+ * Add support for new caret-style version range operator `^>=` (#3705)
+ * Verbosity `-v` now takes an extended format which allows
+ specifying exactly what you want to be logged. The format is
+ `[silent|normal|verbose|debug] flags`, where flags is a space
+ separated list of flags. At the moment, only the flags
+ +callsite and +callstack are supported; these report the
+ call site/stack of a logging output respectively (these
+ are only supported if Cabal is built with GHC 8.0/7.10.2
+ or greater, respectively).
+ * New `Distribution.Utils.ShortText.ShortText` type for representing
+ short text strings compactly (#3898)
+ * Cabal no longer supports using a version bound to disambiguate
+ between an internal and external package (#4020). This should
+ not affect many people, as this mode of use already did not
+ work with the dependency solver.
+ * Support for "foreign libraries" (#2540), which are Haskell
+ libraries intended to be used by foreign languages like C.
+ Foreign libraries only work with GHC 7.8 and later.
+ * Added a technical preview version of integrated doctest support (#4480).
+ * Added a new `scope` field to the executable stanza. Executables
+ with `scope: private` get installed into
+ $libexecdir/$libexecsubdir. Additionally $libexecdir now has a
+ subdir structure similar to $lib(sub)dir to allow installing
+ private executables of different packages and package versions
+ alongside one another. Private executables are those that are
+ expected to be run by other programs rather than users. (#3461)
+
+## 1.24.2.0 [Mikhail Glushenkov](mailto:mikhail.glushenkov@gmail.com) December 2016
+ * Fixed a bug in the handling of non-buildable components (#4094).
+ * Reverted a PVP-noncompliant API change in 1.24.1.0 (#4123).
+ * Bumped the directory upper bound to < 1.4 (#4158).
+
+## 1.24.1.0 [Ryan Thomas](mailto:ryan@ryant.org) October 2016
+ * API addition: `differenceVersionRanges` (#3519).
+ * Fixed reexported-modules display mangling (#3928).
+ * Check that the correct cabal-version is specified when the
+ extra-doc-files field is present (#3825).
+ * Fixed an incorrect invocation of GetShortPathName that was
+ causing build failures on Windows (#3649).
+ * Linker flags are now set correctly on GHC >= 7.8 (#3443).
+
+# 1.24.0.0 [Ryan Thomas](mailto:ryan@ryant.org) March 2016
+ * Support GHC 8.
+ * Deal with extra C sources from preprocessors (#238).
+ * Include cabal_macros.h when running c2hs (#2600).
+ * Don't recompile C sources unless needed (#2601).
+ * Read `builddir` option from `CABAL_BUILDDIR` environment variable.
+ * Add `--profiling-detail=$level` flag with a default for libraries
+ and executables of `exported-functions` and `toplevel-functions`
+ respectively (GHC's `-fprof-auto-{exported,top}` flags) (#193).
+ * New `custom-setup` stanza to specify setup deps. Setup is also built
+ with the cabal_macros.h style macros, for conditional compilation.
+ * Support Haddock response files (#2746).
+ * Fixed a bug in the Text instance for Platform (#2862).
+ * New `setup haddock` option: `--for-hackage` (#2852).
+ * New `--show-detail=direct`; like streaming, but allows the test
+ program to detect that is connected to a terminal, and works
+ reliable with a non-threaded runtime (#2911, and serves as a
+ work-around for #2398)
+ * Library support for multi-instance package DBs (#2948).
+ * Improved the `./Setup configure` solver (#3082, #3076).
+ * The `--allow-newer` option can be now used with `./Setup
+ configure` (#3163).
+ * Added a way to specify extra locations to find OS X frameworks
+ in (`extra-framework-dirs`). Can be used both in `.cabal` files and
+ as an argument to `./Setup configure` (#3158).
+ * Macros `VERSION_$pkgname` and `MIN_VERSION_$pkgname` are now
+ also generated for the current package. (#3235).
+ * Backpack is supported! Two new fields supported in Cabal
+ files: signatures and mixins; and a new flag
+ to setup scripts, `--instantiate-with`. See
+ https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst
+ for more details.
+
+----
+
+## 1.22.8.0 [Ryan Thomas](mailto:ryan@ryant.org) March 2016
+ * Distribution.Simple.Setup: remove job cap. Fixes #3191.
+ * Check all object file suffixes for recompilation. Fixes #3128.
+ * Move source files under `src/`. Fixes #3003.
+
+## 1.22.7.0 [Ryan Thomas](mailto:ryan@ryant.org) January 2016
+ * Backport #3012 to the 1.22 branch
+ * Cabal.cabal: change build-type to Simple
+ * Add foldl' import
+ * The Cabal part for fully gcc-like response files
+
+## 1.22.6.0 [Ryan Thomas](mailto:ryan@ryant.org) December 2015
+ * Relax upper bound to allow upcoming binary-0.8
+
+## 1.22.5.0 [Ryan Thomas](mailto:ryan@ryant.org) November 2015
+ * Don't recompile C sources unless needed (#2601). (Luke Iannini)
+ * Support Haddock response files.
+ * Add frameworks when linking a dynamic library.
+
+## 1.22.4.0 [Ryan Thomas](mailto:ryan@ryant.org) June 2015
+ * Add libname install-dirs variable, use it by default. Fixes #2437. (Edward Z. Yang)
+ * Reduce temporary directory name length, fixes #2502. (Edward Z. Yang)
+ * Workaround for #2527. (Mikhail Glushenkov)
+
+## 1.22.3.0 [Ryan Thomas](mailto:ryan@ryant.org) April 2015
+ * Fix for the ghcjs-pkg version number handling (Luite Stegeman)
+ * filterConfigureFlags: filter more flags (Mikhail Glushenkov)
+ * Cabal check will fail on -fprof-auto passed as a ghc-option - Fixes #2479 (John Chee)
+
+## 1.22.2.0 [Ryan Thomas](mailto:ryan@ryant.org) March 2015
+ * Don't pass `--{en,dis}able-profiling` to old setup.
+ * Add -Wall police
+ * Fix dependencies on `old-time`
+ * Fix test interface detailed-0.9 with GHC 7.10
+ * Fix HPC tests with GHC 7.10
+ * Make sure to pass the package key to ghc
+ * Use `--package-{name|version}` when available for Haddock when available
+ * Put full package name and version in library names
+ * Fully specify package key format, so external tools can generate it.
+
+# 1.22.0.0 [Johan Tibell](mailto:johan.tibell@gmail.com) January 2015
+ * Support GHC 7.10.
+ * Experimental support for emitting DWARF debug info.
+ * Preliminary support for relocatable packages.
+ * Allow cabal to be used inside cabal exec enviroments.
+ * hpc: support mutliple "ways" (e.g. profiling and vanilla).
+ * Support GHCJS.
+ * Improved command line documentation.
+ * Add `-none` constraint syntax for version ranges (#2093).
+ * Make the default doc index file path compiler/arch/os-dependent
+ (#2136).
+ * Warn instead of dying when generating documentation and hscolour
+ isn't installed (455f51622fa38347db62197a04bb0fa5b928ff17).
+ * Support the new BinaryLiterals extension
+ (1f25ab3c5eff311ada73c6c987061b80e9bbebd9).
+ * Warn about `ghc-prof-options: -auto-all` in `cabal check` (#2162).
+ * Add preliminary support for multiple instances of the same package
+ version installed side-by-side (#2002).
+ * New binary build config format - faster build times (#2076).
+ * Support module thinning and renaming (#2038).
+ * Add a new license type: UnspecifiedLicense (#2141).
+ * Remove support for Hugs and nhc98 (#2168).
+ * Invoke `tar` with `--formar ustar` if possible in `sdist` (#1903).
+ * Replace `--enable-library-coverage` with `--enable-coverage`, which
+ enables program coverage for all components (#1945).
+ * Suggest that `ExitFailure 9` is probably due to memory
+ exhaustion (#1522).
+ * Drop support for Haddock < 2.0 (#1808, #1718).
+ * Make `cabal test`/`cabal bench` build only what's needed for
+ running tests/benchmarks (#1821).
+ * Build shared libraries by default when linking executables dynamically.
+ * Build profiled libraries by default when profiling executables.
+
+----
+
+### 1.20.0.4 [Ryan Thomas](mailto:ryan@ryant.org) January 2016
+ * Cabal.cabal: change build-type to Simple.
+
+### 1.20.0.1 [Johan Tibell](mailto:johan.tibell@gmail.com) May 2014
+ * Fix streaming test output.
+
+# 1.20.0.0 [Johan Tibell](mailto:johan.tibell@gmail.com) April 2014
+ * Rewrite user guide
+ * Fix repl Ctrl+C handling
+ * Add haskell-suite compiler support
+ * Add __HADDOCK_VERSION__ define
+ * Allow specifying exact dependency version using hash
+ * Rename extra-html-files to extra-doc-files
+ * Add parallel build support for GHC 7.8 and later
+ * Don't call ranlib on OS X
+ * Avoid re-linking executables, test suites, and benchmarks
+ unnecessarily, shortening build times
+ * Add `--allow-newer` which allows upper version bounds to be
+ ignored
+ * Add `--enable-library-stripping`
+ * Add command for freezing dependencies
+ * Allow repl to be used outside Cabal packages
+ * Add `--require-sandbox`
+ * Don't use `--strip-unneeded` on OS X or iOS
+ * Add new license-files field got additional licenses
+ * Fix if(solaris) on some Solaris versions
+ * Don't use -dylib-install-name on OS X with GHC > 7.8
+ * Add DragonFly as a known OS
+ * Improve pretty-printing of Cabal files
+ * Add test flag `--show-details=streaming` for real-time test output
+ * Add exec command
+
+----
+
+## 1.10.2.0 [Duncan Coutts](mailto:duncan@community.haskell.org) June 2011
+ * Include test suites in cabal sdist
+ * Fix for conditionals in test suite stanzas in `.cabal` files
+ * Fix permissions of directories created during install
+ * Fix for global builds when $HOME env var is not set
+
+## 1.10.1.0 [Duncan Coutts](mailto:duncan@community.haskell.org) February 2011
+ * Improved error messages when test suites are not enabled
+ * Template parameters allowed in test `--test-option(s)` flag
+ * Improved documentation of the test feature
+ * Relaxed QA check on cabal-version when using test-suite sections
+ * `haddock` command now allows both `--hoogle` and `--html` at the same time
+ * Find ghc-version-specific instances of the hsc2hs program
+ * Preserve file executable permissions in sdist tarballs
+ * Pass gcc location and flags to ./configure scripts
+ * Get default gcc flags from ghc
+
+# 1.10.0.0 [Duncan Coutts](mailto:duncan@haskell.org) November 2010
+ * New cabal test feature
+ * Initial support for UHC
+ * New default-language and other-languages fields (e.g. Haskell98/2010)
+ * New default-extensions and other-extensions fields
+ * Deprecated extensions field (for packages using cabal-version >=1.10)
+ * Cabal-version field must now only be of the form `>= x.y`
+ * Removed deprecated `--copy-prefix=` feature
+ * Auto-reconfigure when `.cabal` file changes
+ * Workaround for haddock overwriting .hi and .o files when using TH
+ * Extra cpp flags used with hsc2hs and c2hs (-D${os}_BUILD_OS etc)
+ * New cpp define VERSION_<package> gives string version of dependencies
+ * User guide source now in markdown format for easier editing
+ * Improved checks and error messages for C libraries and headers
+ * Removed BSD4 from the list of suggested licenses
+ * Updated list of known language extensions
+ * Fix for include paths to allow C code to import FFI stub.h files
+ * Fix for intra-package dependencies on OSX
+ * Stricter checks on various bits of `.cabal` file syntax
+ * Minor fixes for c2hs
+
+----
+
+### 1.8.0.6 [Duncan Coutts](mailto:duncan@haskell.org) June 2010
+ * Fix `register --global/--user`
+
+### 1.8.0.4 [Duncan Coutts](mailto:duncan@haskell.org) March 2010
+ * Set dylib-install-name for dynalic libs on OSX
+ * Stricter configure check that compiler supports a package's extensions
+ * More configure-time warnings
+ * Hugs can compile Cabal lib again
+ * Default datadir now follows prefix on Windows
+ * 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 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
+
+# 1.8.0.2 [Duncan Coutts](mailto:duncan@haskell.org) December 2009
+ * Support for GHC-6.12
+ * New unique installed package IDs which use a package hash
+ * Allow executables to depend on the lib within the same package
+ * Dependencies for each component apply only to that component
+ (previously applied to all the other components too)
+ * Added new known license MIT and versioned GPL and LGPL
+ * More liberal package version range syntax
+ * Package registration files are now UTF8
+ * Support for LHC and JHC-0.7.2
+ * Deprecated RecordPuns extension in favour of NamedFieldPuns
+ * Deprecated PatternSignatures extension in favor of ScopedTypeVariables
+ * New VersionRange semantic view as a sequence of intervals
+ * Improved package quality checks
+ * Minor simplification in a couple `Setup.hs` hooks
+ * Beginnings of a unit level testsuite using QuickCheck
+ * Various bug fixes
+ * Various internal cleanups
+
+----
+
+### 1.6.0.2 [Duncan Coutts](mailto:duncan@haskell.org) February 2009
+ * New configure-time check for C headers and libraries
+ * Added language extensions present in ghc-6.10
+ * Added support for NamedFieldPuns extension in ghc-6.8
+ * Fix in configure step for ghc-6.6 on Windows
+ * Fix warnings in `Path_pkgname.hs` module on Windows
+ * Fix for exotic flags in ld-options field
+ * Fix for using pkg-config in a package with a lib and an executable
+ * Fix for building haddock docs for exes that use the Paths module
+ * Fix for installing header files in subdirectories
+ * Fix for the case of building profiling libs but not ordinary libs
+ * Fix read-only attribute of installed files on Windows
+ * Ignore ghc -threaded flag when profiling in ghc-6.8 and older
+
+### 1.6.0.1 [Duncan Coutts](mailto:duncan@haskell.org) October 2008
+ * Export a compat function to help alex and happy
+
+# 1.6.0.0 [Duncan Coutts](mailto:duncan@haskell.org) October 2008
+ * Support for ghc-6.10
+ * Source control repositories can now be specified in `.cabal` files
+ * Bug report URLs can be now specified in `.cabal` files
+ * Wildcards now allowed in data-files and extra-source-files fields
+ * New syntactic sugar for dependencies `build-depends: foo ==1.2.*`
+ * New cabal_macros.h provides macros to test versions of dependencies
+ * Relocatable bindists now possible on unix via env vars
+ * New `exposed` field allows packages to be not exposed by default
+ * Install dir flags can now use $os and $arch variables
+ * New `--builddir` flag allows multiple builds from a single sources dir
+ * cc-options now only apply to .c files, not for -fvia-C
+ * cc-options are not longer propagated to dependent packages
+ * The cpp/cc/ld-options fields no longer use `,` as a separator
+ * hsc2hs is now called using gcc instead of using ghc as gcc
+ * New api for manipulating sets and graphs of packages
+ * Internal api improvements and code cleanups
+ * Minor improvements to the user guide
+ * Miscellaneous minor bug fixes
+
+----
+
+### 1.4.0.2 [Duncan Coutts](mailto:duncan@haskell.org) August 2008
+ * Fix executable stripping default
+ * Fix striping exes on OSX that export dynamic symbols (like ghc)
+ * Correct the order of arguments given by `--prog-options=`
+ * Fix corner case with overlapping user and global packages
+ * Fix for modules that use pre-processing and `.hs-boot` files
+ * Clarify some points in the user guide and readme text
+ * Fix verbosity flags passed to sub-command like haddock
+ * Fix `sdist --snapshot`
+ * Allow meta-packages that contain no modules or C code
+ * Make the generated Paths module -Wall clean on Windows
+
+### 1.4.0.1 [Duncan Coutts](mailto:duncan@haskell.org) June 2008
+ * Fix a bug which caused `.` to always be in the sources search path
+ * Haddock-2.2 and later do now support the `--hoogle` flag
+
+# 1.4.0.0 [Duncan Coutts](mailto:duncan@haskell.org) June 2008
+ * Rewritten command line handling support
+ * Command line completion with bash
+ * Better support for Haddock 2
+ * Improved support for nhc98
+ * Removed support for ghc-6.2
+ * Haddock markup in `.lhs` files now supported
+ * Default colour scheme for highlighted source code
+ * Default prefix for `--user` installs is now `$HOME/.cabal`
+ * All `.cabal` files are treaded as UTF-8 and must be valid
+ * Many checks added for common mistakes
+ * New `--package-db=` option for specific package databases
+ * Many internal changes to support cabal-install
+ * Stricter parsing for version strings, eg dissalows "1.05"
+ * Improved user guide introduction
+ * Programatica support removed
+ * New options `--program-prefix/suffix` allows eg versioned programs
+ * Support packages that use `.hs-boot` files
+ * Fix sdist for Main modules that require preprocessing
+ * New configure -O flag with optimisation level 0--2
+ * Provide access to "`x-`" extension fields through the Cabal api
+ * Added check for broken installed packages
+ * Added warning about using inconsistent versions of dependencies
+ * Strip binary executable files by default with an option to disable
+ * New options to add site-specific include and library search paths
+ * Lift the restriction that libraries must have exposed-modules
+ * Many bugs fixed.
+ * Many internal structural improvements and code cleanups
+
+----
+
+## 1.2.4.0 [Duncan Coutts](mailto:duncan@haskell.org) June 2008
+ * Released with GHC 6.8.3
+ * Backported several fixes and minor improvements from Cabal-1.4
+ * Use a default colour scheme for sources with hscolour >=1.9
+ * Support `--hyperlink-source` for Haddock >= 2.0
+ * Fix for running in a non-writable directory
+ * Add OSX -framework arguments when linking executables
+ * Updates to the user guide
+ * Allow build-tools names to include + and _
+ * Export autoconfUserHooks and simpleUserHooks
+ * Export ccLdOptionsBuildInfo for `Setup.hs` scripts
+ * Export unionBuildInfo and make BuildInfo an instance of Monoid
+ * Fix to allow the `main-is` module to use a pre-processor
+
+## 1.2.3.0 [Duncan Coutts](mailto:duncan@haskell.org) Nov 2007
+ * Released with GHC 6.8.2
+ * Includes full list of GHC language extensions
+ * Fix infamous `dist/conftest.c` bug
+ * Fix `configure --interfacedir=`
+ * Find ld.exe on Windows correctly
+ * Export PreProcessor constructor and mkSimplePreProcessor
+ * Fix minor bug in unlit code
+ * Fix some markup in the haddock docs
+
+## 1.2.2.0 [Duncan Coutts](mailto:duncan@haskell.org) Nov 2007
+ * Released with GHC 6.8.1
+ * Support haddock-2.0
+ * Support building DSOs with GHC
+ * Require reconfiguring if the `.cabal` file has changed
+ * Fix os(windows) configuration test
+ * Fix building documentation
+ * Fix building packages on Solaris
+ * Other minor bug fixes
+
+## 1.2.1 [Duncan Coutts](mailto:duncan@haskell.org) Oct 2007
+ * To be included in GHC 6.8.1
+ * New field `cpp-options` used when preprocessing Haskell modules
+ * Fixes for hsc2hs when using ghc
+ * C source code gets compiled with -O2 by default
+ * OS aliases, to allow os(windows) rather than requiring os(mingw32)
+ * Fix cleaning of `stub` files
+ * Fix cabal-setup, command line ui that replaces `runhaskell Setup.hs`
+ * Build docs even when dependent packages docs are missing
+ * Allow the `--html-dir` to be specified at configure time
+ * Fix building with ghc-6.2
+ * Other minor bug fixes and build fixes
+
+# 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)
+ * New flag to allow linking to haddock docs on the web
+ * Supports pkg-config
+ * New field `build-tools` for tool dependencies
+ * Improved c2hs support
+ * Preprocessor output no longer clutters source dirs
+ * Separate `includes` and `install-includes` fields
+ * Makefile command to generate makefiles for building libs with GHC
+ * New `--docdir` configure flag
+ * Generic `--with-prog` `--prog-args` configure flags
+ * Better default installation paths on Windows
+ * Install paths can be specified relative to each other
+ * License files now installed
+ * Initial support for NHC (incomplete)
+ * Consistent treatment of verbosity
+ * Reduced verbosity of configure step by default
+ * Improved helpfulness of output messages
+ * Help output now clearer and fits in 80 columns
+ * New setup register `--gen-pkg-config` flag for distros
+ * Major internal refactoring, hooks api has changed
+ * Dozens of bug fixes
+
+----
+
+### 1.1.6.2 [Duncan Coutts](mailto:duncan.coutts@worc.ox.ac.uk) May 2007
+
+ * Released with GHC 6.6.1
+ * Handle windows text file encoding for `.cabal` files
+ * Fix compiling a executable for profiling that uses Template Haskell
+ * Other minor bug fixes and user guide clarifications
+
+### 1.1.6.1 [Duncan Coutts](mailto:duncan.coutts@worc.ox.ac.uk) Oct 2006
+
+ * fix unlit code
+ * fix escaping in register.sh
+
+## 1.1.6 [Duncan Coutts](mailto:duncan.coutts@worc.ox.ac.uk) Oct 2006
+
+ * Released with GHC 6.6
+ * Added support for hoogle
+ * Allow profiling and normal builds of libs to be chosen indepentantly
+ * Default installation directories on Win32 changed
+ * Register haddock docs with ghc-pkg
+ * Get haddock to make hyperlinks to dependent package docs
+ * Added BangPatterns language extension
+ * Various bug fixes
+
+## 1.1.4 [Duncan Coutts](mailto:duncan.coutts@worc.ox.ac.uk) May 2006
+
+ * Released with GHC 6.4.2
+ * Better support for packages that need to install header files
+ * cabal-setup added, but not installed by default yet
+ * Implemented `setup register --inplace`
+ * Have packages exposed by default with ghc-6.2
+ * It is no longer necessary to run `configure` before `clean` or `sdist`
+ * Added support for ghc's `-split-objs`
+ * Initial support for JHC
+ * Ignore extension fields in `.cabal` files (fields begining with "`x-`")
+ * Some changes to command hooks API to improve consistency
+ * Hugs support improvements
+ * Added GeneralisedNewtypeDeriving language extension
+ * Added cabal-version field
+ * Support hidden modules with haddock
+ * Internal code refactoring
+ * More bug fixes
+
+## 1.1.3 [Isaac Jones](mailto:ijones@syntaxpolice.org) Sept 2005
+
+ * WARNING: Interfaces not documented in the user's guide may
+ change in future releases.
+ * Move building of GHCi .o libs to the build phase rather than
+ register phase. (from Duncan Coutts)
+ * Use .tar.gz for source package extension
+ * Uses GHC instead of cpphs if the latter is not available
+ * Added experimental "command hooks" which completely override the
+ default behavior of a command.
+ * Some bugfixes
+
+# 1.1.1 [Isaac Jones](mailto:ijones@syntaxpolice.org) July 2005
+
+ * WARNING: Interfaces not documented in the user's guide may
+ change in future releases.
+ * Handles recursive modules for GHC 6.2 and GHC 6.4.
+ * Added `setup test` command (Used with UserHook)
+ * implemented handling of _stub.{c,h,o} files
+ * Added support for profiling
+ * Changed install prefix of libraries (pref/pkgname-version
+ to prefix/pkgname-version/compname-version)
+ * Added pattern guards as a language extension
+ * Moved some functionality to Language.Haskell.Extension
+ * Register / unregister .bat files for windows
+ * Exposed more of the API
+ * Added support for the hide-all-packages flag in GHC > 6.4
+ * Several bug fixes
+
+----
+
+# 1.0 [Isaac Jones](mailto:ijones@syntaxpolice.org) March 11 2005
+
+ * Released with GHC 6.4, Hugs March 2005, and nhc98 1.18
+ * Some sanity checking
+
+----
+
+# 0.5 [Isaac Jones](mailto:ijones@syntaxpolice.org) Wed Feb 19 2005
+
+ * __WARNING__: this is a pre-release and the interfaces are
+ still likely to change until we reach a 1.0 release.
+ * Hooks interfaces changed
+ * Added preprocessors to user hooks
+ * No more executable-modules or hidden-modules. Use
+ `other-modules` instead.
+ * Certain fields moved into BuildInfo, much refactoring
+ * `extra-libs` -> `extra-libraries`
+ * Added `--gen-script` to configure and unconfigure.
+ * `modules-ghc` (etc) now `ghc-modules` (etc)
+ * added new fields including `synopsis`
+ * 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
+ * more features to `./setup haddock`
+
+----
+
+# 0.4 [Isaac Jones](mailto:ijones@syntaxpolice.org) Sun Jan 16 2005
+
+ * Much thanks to all the awesome fptools hackers who have been
+ working hard to build the Haskell Cabal!
+
+ * __Interface Changes__:
+
+ * __WARNING__: this is a pre-release and the interfaces are still
+ likely to change until we reach a 1.0 release.
+
+ * Instead of Package.description, you should name your
+ description files <something>.cabal. In particular, we suggest
+ that you name it <packagename>.cabal, but this is not enforced
+ (yet). Multiple `.cabal` files in the same directory is an error,
+ at least for now.
+
+ * `./setup install --install-prefix` is gone. Use `./setup copy`
+ `--copy-prefix` instead.
+
+ * The `Modules` field is gone. Use `hidden-modules`,
+ `exposed-modules`, and `executable-modules`.
+
+ * `Build-depends` is now a package-only field, and can't go into
+ executable stanzas. Build-depends is a package-to-package
+ relationship.
+
+ * Some new fields. Use the Source.
+
+ * __New Features__
+
+ * Cabal is now included as a package in the CVS version of
+ fptools. That means it'll be released as `-package Cabal` in
+ future versions of the compilers, and if you are a bleeding-edge
+ user, you can grab it from the CVS repository with the compilers.
+
+ * Hugs compatibility and NHC98 compatibility should both be
+ improved.
+
+ * Hooks Interface / Autoconf compatibility: Most of the hooks
+ interface is hidden for now, because it's not finalized. I have
+ exposed only `defaultMainWithHooks` and `defaultUserHooks`. This
+ allows you to use a ./configure script to preprocess
+ `foo.buildinfo`, which gets merged with `foo.cabal`. In future
+ releases, we'll expose UserHooks, but we're definitely going to
+ change the interface to those. The interface to the two functions
+ I've exposed should stay the same, though.
+
+ * ./setup haddock is a baby feature which pre-processes the
+ source code with hscpp and runs haddock on it. This is brand new
+ and hardly tested, so you get to knock it around and see what you
+ think.
+
+ * Some commands now actually implement verbosity.
+
+ * The preprocessors have been tested a bit more, and seem to work
+ OK. Please give feedback if you use these.
+
+----
+
+# 0.3 [Isaac Jones](mailto:ijones@syntaxpolice.org) Sun Jan 16 2005
+
+ * Unstable snapshot release
+ * From now on, stable releases are even.
+
+----
+
+# 0.2 [Isaac Jones](mailto:ijones@syntaxpolice.org)
+
+ * Adds more HUGS support and preprocessor support.
diff --git a/cabal/Cabal/Distribution/Backpack.hs b/cabal/Cabal/Distribution/Backpack.hs
index 8185174..604579d 100644
--- a/cabal/Cabal/Distribution/Backpack.hs
+++ b/cabal/Cabal/Distribution/Backpack.hs
@@ -1,9 +1,9 @@
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE RankNTypes #-}
-{-# LANGUAGE PatternGuards #-}
-{-# LANGUAGE DeriveGeneric #-}
-{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE PatternGuards #-}
+{-# LANGUAGE RankNTypes #-}
-- | This module defines the core data types for Backpack. For more
-- details, see:
@@ -31,6 +31,8 @@ module Distribution.Backpack (
dispOpenModuleSubstEntry,
parseOpenModuleSubst,
parseOpenModuleSubstEntry,
+ parsecOpenModuleSubst,
+ parsecOpenModuleSubstEntry,
openModuleSubstFreeHoles,
-- * Conversions to 'UnitId'
@@ -38,22 +40,26 @@ module Distribution.Backpack (
hashModuleSubst,
) where
-import Prelude ()
import Distribution.Compat.Prelude hiding (mod)
-import Distribution.Compat.ReadP
-import qualified Distribution.Compat.ReadP as Parse
-import qualified Text.PrettyPrint as Disp
-import Text.PrettyPrint (hcat)
+import Distribution.Compat.ReadP ((<++))
+import Distribution.Parsec.Class
+import Distribution.Pretty
+import Prelude ()
+import Text.PrettyPrint (hcat)
+
+import qualified Distribution.Compat.CharParsing as P
+import qualified Distribution.Compat.ReadP as Parse
+import qualified Text.PrettyPrint as Disp
import Distribution.ModuleName
import Distribution.Text
import Distribution.Types.ComponentId
-import Distribution.Types.UnitId
import Distribution.Types.Module
+import Distribution.Types.UnitId
import Distribution.Utils.Base62
import qualified Data.Map as Map
-import Data.Set (Set)
+import Data.Set (Set)
import qualified Data.Set as Set
-----------------------------------------------------------------------
@@ -103,13 +109,32 @@ instance NFData OpenUnitId where
rnf (IndefFullUnitId cid subst) = rnf cid `seq` rnf subst
rnf (DefiniteUnitId uid) = rnf uid
-instance Text OpenUnitId where
- disp (IndefFullUnitId cid insts)
+instance Pretty OpenUnitId where
+ pretty (IndefFullUnitId cid insts)
-- TODO: arguably a smart constructor to enforce invariant would be
-- better
- | Map.null insts = disp cid
- | otherwise = disp cid <<>> Disp.brackets (dispOpenModuleSubst insts)
- disp (DefiniteUnitId uid) = disp uid
+ | Map.null insts = pretty cid
+ | otherwise = pretty cid <<>> Disp.brackets (dispOpenModuleSubst insts)
+ pretty (DefiniteUnitId uid) = pretty uid
+
+-- |
+--
+-- >>> eitherParsec "foobar" :: Either String OpenUnitId
+--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"]))]))
+--
+instance Parsec OpenUnitId where
+ parsec = P.try parseOpenUnitId <|> fmap DefiniteUnitId parsec
+ where
+ parseOpenUnitId = do
+ cid <- parsec
+ insts <- P.between (P.char '[') (P.char ']')
+ parsecOpenModuleSubst
+ return (IndefFullUnitId cid insts)
+
+instance Text OpenUnitId where
parse = parseOpenUnitId <++ fmap DefiniteUnitId parse
where
parseOpenUnitId = do
@@ -160,11 +185,33 @@ instance NFData OpenModule where
rnf (OpenModule uid mod_name) = rnf uid `seq` rnf mod_name
rnf (OpenModuleVar mod_name) = rnf mod_name
+instance Pretty OpenModule where
+ pretty (OpenModule uid mod_name) =
+ hcat [pretty uid, Disp.text ":", pretty mod_name]
+ pretty (OpenModuleVar mod_name) =
+ hcat [Disp.char '<', pretty mod_name, Disp.char '>']
+
+-- |
+--
+-- >>> 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"]))
+--
+instance Parsec OpenModule where
+ parsec = parsecModuleVar <|> parsecOpenModule
+ where
+ parsecOpenModule = do
+ uid <- parsec
+ _ <- P.char ':'
+ mod_name <- parsec
+ return (OpenModule uid mod_name)
+
+ parsecModuleVar = do
+ _ <- P.char '<'
+ mod_name <- parsec
+ _ <- P.char '>'
+ return (OpenModuleVar mod_name)
+
instance Text OpenModule where
- disp (OpenModule uid mod_name) =
- hcat [disp uid, Disp.text ":", disp mod_name]
- disp (OpenModuleVar mod_name) =
- hcat [Disp.char '<', disp mod_name, Disp.char '>']
parse = parseModuleVar <++ parseOpenModule
where
parseOpenModule = do
@@ -205,19 +252,37 @@ dispOpenModuleSubstEntry :: (ModuleName, OpenModule) -> Disp.Doc
dispOpenModuleSubstEntry (k, v) = disp k <<>> Disp.char '=' <<>> disp v
-- | Inverse to 'dispModSubst'.
-parseOpenModuleSubst :: ReadP r OpenModuleSubst
+parseOpenModuleSubst :: Parse.ReadP r OpenModuleSubst
parseOpenModuleSubst = fmap Map.fromList
. flip Parse.sepBy (Parse.char ',')
$ parseOpenModuleSubstEntry
-- | Inverse to 'dispModSubstEntry'.
-parseOpenModuleSubstEntry :: ReadP r (ModuleName, OpenModule)
+parseOpenModuleSubstEntry :: Parse.ReadP r (ModuleName, OpenModule)
parseOpenModuleSubstEntry =
do k <- parse
_ <- Parse.char '='
v <- parse
return (k, v)
+-- | Inverse to 'dispModSubst'.
+--
+-- @since 2.2
+parsecOpenModuleSubst :: CabalParsing m => m OpenModuleSubst
+parsecOpenModuleSubst = fmap Map.fromList
+ . flip P.sepBy (P.char ',')
+ $ parsecOpenModuleSubstEntry
+
+-- | Inverse to 'dispModSubstEntry'.
+--
+-- @since 2.2
+parsecOpenModuleSubstEntry :: CabalParsing m => m (ModuleName, OpenModule)
+parsecOpenModuleSubstEntry =
+ do k <- parsec
+ _ <- P.char '='
+ v <- parsec
+ return (k, v)
+
-- | Get the set of holes ('ModuleVar') embedded in a 'OpenModuleSubst'.
-- This is NOT the domain of the substitution.
openModuleSubstFreeHoles :: OpenModuleSubst -> Set ModuleName
diff --git a/cabal/Cabal/Distribution/Backpack/ConfiguredComponent.hs b/cabal/Cabal/Distribution/Backpack/ConfiguredComponent.hs
index 1d92963..dab4066 100644
--- a/cabal/Cabal/Distribution/Backpack/ConfiguredComponent.hs
+++ b/cabal/Cabal/Distribution/Backpack/ConfiguredComponent.hs
@@ -40,6 +40,7 @@ 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
@@ -158,17 +159,18 @@ toConfiguredComponent
:: PackageDescription
-> ComponentId
-> ConfiguredComponentMap
+ -> ConfiguredComponentMap
-> Component
-> LogProgress ConfiguredComponent
-toConfiguredComponent pkg_descr this_cid dep_map component = do
+toConfiguredComponent pkg_descr this_cid lib_dep_map exe_dep_map component = do
lib_deps <-
if newPackageDepsBehaviour pkg_descr
then forM (targetBuildDepends bi) $ \(Dependency name _) -> do
let (pn, cn) = fixFakePkgName pkg_descr name
- value <- case Map.lookup cn =<< Map.lookup pn dep_map of
+ value <- case Map.lookup cn =<< Map.lookup pn lib_dep_map of
Nothing ->
dieProgress $
- text "Dependency on unbuildable" <+>
+ text "Dependency on unbuildable (i.e. 'buildable: False')" <+>
text (showComponentName cn) <+>
text "from" <+> disp pn
Just v -> return v
@@ -179,7 +181,7 @@ toConfiguredComponent pkg_descr this_cid dep_map component = do
lib_deps exe_deps component
where
bi = componentBuildInfo component
- -- dep_map contains a mix of internal and external deps.
+ -- lib_dep_map contains a mix of internal and external deps.
-- We want all the public libraries (dep_cn == CLibName)
-- of all external deps (dep /= pn). Note that this
-- excludes the public library of the current package:
@@ -187,11 +189,15 @@ toConfiguredComponent pkg_descr this_cid dep_map component = do
-- because it would imply a cyclic dependency for the
-- library itself.
old_style_lib_deps = [ e
- | (pn, comp_map) <- Map.toList dep_map
+ | (pn, comp_map) <- Map.toList lib_dep_map
, pn /= packageName pkg_descr
, (cn, e) <- Map.toList comp_map
, cn == CLibName ]
- exe_deps =
+ -- We have to nub here, because 'getAllToolDependencies' may return
+ -- duplicates (see #4986). (NB: This is not needed for lib_deps,
+ -- since those elaborate into includes, for which there explicitly
+ -- may be multiple instances of a package)
+ exe_deps = ordNub $
[ exe
| ExeDependency pn cn _ <- getAllToolDependencies pkg_descr bi
-- The error suppression here is important, because in general
@@ -199,7 +205,7 @@ toConfiguredComponent pkg_descr this_cid dep_map component = do
-- which the package is attempting to use (those deps are only
-- fed in when cabal-install uses this codepath.)
-- TODO: Let cabal-install request errors here
- , Just exe <- [Map.lookup (CExeName cn) =<< Map.lookup pn dep_map]
+ , Just exe <- [Map.lookup (CExeName cn) =<< Map.lookup pn exe_dep_map]
]
-- | Also computes the 'ComponentId', and sets cc_public if necessary.
@@ -219,7 +225,7 @@ toConfiguredComponent' use_external_internal_deps flags
dep_map component = do
cc <- toConfiguredComponent
pkg_descr this_cid
- dep_map component
+ dep_map dep_map component
return $ if use_external_internal_deps
then cc { cc_public = True }
else cc
@@ -243,6 +249,11 @@ extendConfiguredComponentMap cc =
-- list of internal components must be topologically sorted
-- based on internal package dependencies, so that any internal
-- dependency points to an entry earlier in the list.
+--
+-- TODO: This function currently restricts the input configured components to
+-- one version per package, by using the type ConfiguredComponentMap. It cannot
+-- be used to configure a component that depends on one version of a package for
+-- a library and another version for a build-tool.
toConfiguredComponents
:: Bool -- use_external_internal_deps
-> FlagAssignment
diff --git a/cabal/Cabal/Distribution/CabalSpecVersion.hs b/cabal/Cabal/Distribution/CabalSpecVersion.hs
new file mode 100644
index 0000000..afdebf8
--- /dev/null
+++ b/cabal/Cabal/Distribution/CabalSpecVersion.hs
@@ -0,0 +1,80 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric #-}
+module Distribution.CabalSpecVersion where
+
+import Prelude ()
+import Distribution.Compat.Prelude
+import qualified Data.Set as Set
+
+-- | Different Cabal-the-spec versions.
+--
+-- We branch based on this at least in the parser.
+--
+data CabalSpecVersion
+ = CabalSpecOld
+ | CabalSpecV1_22
+ | CabalSpecV1_24
+ | CabalSpecV2_0
+ | CabalSpecV2_2
+ | CabalSpecV2_4
+ deriving (Eq, Ord, Show, Read, Enum, Bounded, Typeable, Data, Generic)
+
+cabalSpecLatest :: CabalSpecVersion
+cabalSpecLatest = CabalSpecV2_4
+
+cabalSpecFeatures :: CabalSpecVersion -> Set.Set CabalFeature
+cabalSpecFeatures CabalSpecOld = Set.empty
+cabalSpecFeatures CabalSpecV1_22 = Set.empty
+cabalSpecFeatures CabalSpecV1_24 = Set.empty
+cabalSpecFeatures CabalSpecV2_0 = Set.empty
+cabalSpecFeatures CabalSpecV2_2 = Set.fromList
+ [ Elif
+ , CommonStanzas
+ ]
+cabalSpecFeatures CabalSpecV2_4 = Set.fromList
+ [ Elif
+ , CommonStanzas
+ , Globstar
+ ]
+
+cabalSpecSupports :: CabalSpecVersion -> [Int] -> Bool
+cabalSpecSupports CabalSpecOld v = v < [1,21]
+cabalSpecSupports CabalSpecV1_22 v = v < [1,23]
+cabalSpecSupports CabalSpecV1_24 v = v < [1,25]
+cabalSpecSupports CabalSpecV2_0 v = v < [2,1]
+cabalSpecSupports CabalSpecV2_2 v = v < [2,3]
+cabalSpecSupports CabalSpecV2_4 _ = True
+
+specHasCommonStanzas :: CabalSpecVersion -> HasCommonStanzas
+specHasCommonStanzas CabalSpecV2_2 = HasCommonStanzas
+specHasCommonStanzas CabalSpecV2_4 = HasCommonStanzas
+specHasCommonStanzas _ = NoCommonStanzas
+
+specHasElif :: CabalSpecVersion -> HasElif
+specHasElif CabalSpecV2_2 = HasElif
+specHasElif CabalSpecV2_4 = HasElif
+specHasElif _ = NoElif
+
+-------------------------------------------------------------------------------
+-- Features
+-------------------------------------------------------------------------------
+
+data CabalFeature
+ = Elif
+ | CommonStanzas
+ | Globstar
+ -- ^ Implemented in #5284. Not actually a change to the parser,
+ -- as filename patterns are opaque to it currently.
+ deriving (Eq, Ord, Show, Read, Enum, Bounded, Typeable, Data, Generic)
+
+-------------------------------------------------------------------------------
+-- Booleans
+-------------------------------------------------------------------------------
+
+data HasElif = HasElif | NoElif
+ deriving (Eq, Show)
+
+data HasCommonStanzas = HasCommonStanzas | NoCommonStanzas
+ deriving (Eq, Show)
+
+data HasGlobstar = HasGlobstar | NoGlobstar
diff --git a/cabal/Cabal/Distribution/Compat/Binary.hs b/cabal/Cabal/Distribution/Compat/Binary.hs
index 00abe08..5bd22db 100644
--- a/cabal/Cabal/Distribution/Compat/Binary.hs
+++ b/cabal/Cabal/Distribution/Compat/Binary.hs
@@ -18,10 +18,6 @@ module Distribution.Compat.Binary
#endif
) where
-#if __GLASGOW_HASKELL__ < 706
-import Prelude hiding (catch)
-#endif
-
import Control.Exception (catch, evaluate)
#if __GLASGOW_HASKELL__ >= 711
import Control.Exception (pattern ErrorCall)
diff --git a/cabal/Cabal/Distribution/Compat/CharParsing.hs b/cabal/Cabal/Distribution/Compat/CharParsing.hs
new file mode 100644
index 0000000..74126c5
--- /dev/null
+++ b/cabal/Cabal/Distribution/Compat/CharParsing.hs
@@ -0,0 +1,356 @@
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# OPTIONS_GHC -fspec-constr -fspec-constr-count=8 #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module : Distribution.Compat.CharParsing
+-- Copyright : (c) Edward Kmett 2011
+-- License : BSD3
+--
+-- Maintainer : ekmett@gmail.com
+-- Stability : experimental
+-- Portability : non-portable
+--
+-- Parsers for character streams
+--
+-- Originally in @parsers@ package.
+--
+-----------------------------------------------------------------------------
+module Distribution.Compat.CharParsing
+ (
+ -- * Combinators
+ oneOf -- :: CharParsing m => [Char] -> m Char
+ , noneOf -- :: CharParsing m => [Char] -> m Char
+ , spaces -- :: CharParsing m => m ()
+ , space -- :: CharParsing m => m Char
+ , newline -- :: CharParsing m => m Char
+ , tab -- :: CharParsing m => m Char
+ , upper -- :: CharParsing m => m Char
+ , lower -- :: CharParsing m => m Char
+ , alphaNum -- :: CharParsing m => m Char
+ , letter -- :: CharParsing m => m Char
+ , digit -- :: CharParsing m => m Char
+ , hexDigit -- :: CharParsing m => m Char
+ , octDigit -- :: CharParsing m => m Char
+ , satisfyRange -- :: CharParsing m => Char -> Char -> m Char
+ -- * Class
+ , CharParsing(..)
+ -- * Cabal additions
+ , integral
+ , munch1
+ , munch
+ , skipSpaces1
+ , module Distribution.Compat.Parsing
+ ) where
+
+import Prelude ()
+import Distribution.Compat.Prelude
+
+import Control.Monad.Trans.Class (lift)
+import Control.Monad.Trans.State.Lazy as Lazy
+import Control.Monad.Trans.State.Strict as Strict
+import Control.Monad.Trans.Writer.Lazy as Lazy
+import Control.Monad.Trans.Writer.Strict as Strict
+import Control.Monad.Trans.RWS.Lazy as Lazy
+import Control.Monad.Trans.RWS.Strict as Strict
+import Control.Monad.Trans.Reader (ReaderT (..))
+import Control.Monad.Trans.Identity (IdentityT (..))
+import Data.Char
+import Data.Text (Text, unpack)
+
+import qualified Text.Parsec as Parsec
+import qualified Distribution.Compat.ReadP as ReadP
+
+import Distribution.Compat.Parsing
+
+-- | @oneOf cs@ succeeds if the current character is in the supplied
+-- list of characters @cs@. Returns the parsed character. See also
+-- 'satisfy'.
+--
+-- > vowel = oneOf "aeiou"
+oneOf :: CharParsing m => [Char] -> m Char
+oneOf xs = satisfy (\c -> c `elem` xs)
+{-# INLINE oneOf #-}
+
+-- | As the dual of 'oneOf', @noneOf cs@ succeeds if the current
+-- character is /not/ in the supplied list of characters @cs@. Returns the
+-- parsed character.
+--
+-- > consonant = noneOf "aeiou"
+noneOf :: CharParsing m => [Char] -> m Char
+noneOf xs = satisfy (\c -> c `notElem` xs)
+{-# INLINE noneOf #-}
+
+-- | Skips /zero/ or more white space characters. See also 'skipMany'.
+spaces :: CharParsing m => m ()
+spaces = skipMany space <?> "white space"
+{-# INLINE spaces #-}
+
+-- | Parses a white space character (any character which satisfies 'isSpace')
+-- Returns the parsed character.
+space :: CharParsing m => m Char
+space = satisfy isSpace <?> "space"
+{-# INLINE space #-}
+
+-- | Parses a newline character (\'\\n\'). Returns a newline character.
+newline :: CharParsing m => m Char
+newline = char '\n' <?> "new-line"
+{-# INLINE newline #-}
+
+-- | Parses a tab character (\'\\t\'). Returns a tab character.
+tab :: CharParsing m => m Char
+tab = char '\t' <?> "tab"
+{-# INLINE tab #-}
+
+-- | Parses an upper case letter. Returns the parsed character.
+upper :: CharParsing m => m Char
+upper = satisfy isUpper <?> "uppercase letter"
+{-# INLINE upper #-}
+
+-- | Parses a lower case character. Returns the parsed character.
+lower :: CharParsing m => m Char
+lower = satisfy isLower <?> "lowercase letter"
+{-# INLINE lower #-}
+
+-- | Parses a letter or digit. Returns the parsed character.
+alphaNum :: CharParsing m => m Char
+alphaNum = satisfy isAlphaNum <?> "letter or digit"
+{-# INLINE alphaNum #-}
+
+-- | Parses a letter (an upper case or lower case character). Returns the
+-- parsed character.
+letter :: CharParsing m => m Char
+letter = satisfy isAlpha <?> "letter"
+{-# INLINE letter #-}
+
+-- | Parses a digit. Returns the parsed character.
+digit :: CharParsing m => m Char
+digit = satisfy isDigit <?> "digit"
+{-# INLINE digit #-}
+
+-- | Parses a hexadecimal digit (a digit or a letter between \'a\' and
+-- \'f\' or \'A\' and \'F\'). Returns the parsed character.
+hexDigit :: CharParsing m => m Char
+hexDigit = satisfy isHexDigit <?> "hexadecimal digit"
+{-# INLINE hexDigit #-}
+
+-- | Parses an octal digit (a character between \'0\' and \'7\'). Returns
+-- the parsed character.
+octDigit :: CharParsing m => m Char
+octDigit = satisfy isOctDigit <?> "octal digit"
+{-# INLINE octDigit #-}
+
+satisfyRange :: CharParsing m => Char -> Char -> m Char
+satisfyRange a z = satisfy (\c -> c >= a && c <= z)
+{-# INLINE satisfyRange #-}
+
+-- | Additional functionality needed to parse character streams.
+class Parsing m => CharParsing m where
+ -- | Parse a single character of the input, with UTF-8 decoding
+ satisfy :: (Char -> Bool) -> m Char
+
+ -- | @char c@ parses a single character @c@. Returns the parsed
+ -- character (i.e. @c@).
+ --
+ -- /e.g./
+ --
+ -- @semiColon = 'char' ';'@
+ char :: Char -> m Char
+ char c = satisfy (c ==) <?> show [c]
+ {-# INLINE char #-}
+
+ -- | @notChar c@ parses any single character other than @c@. Returns the parsed
+ -- character.
+ notChar :: Char -> m Char
+ notChar c = satisfy (c /=)
+ {-# INLINE notChar #-}
+
+ -- | This parser succeeds for any character. Returns the parsed character.
+ anyChar :: m Char
+ anyChar = satisfy (const True)
+ {-# INLINE anyChar #-}
+
+ -- | @string s@ parses a sequence of characters given by @s@. Returns
+ -- the parsed string (i.e. @s@).
+ --
+ -- > divOrMod = string "div"
+ -- > <|> string "mod"
+ string :: String -> m String
+ string s = s <$ try (traverse_ char s) <?> show s
+ {-# INLINE string #-}
+
+ -- | @text t@ parses a sequence of characters determined by the text @t@ Returns
+ -- the parsed text fragment (i.e. @t@).
+ --
+ -- Using @OverloadedStrings@:
+ --
+ -- > divOrMod = text "div"
+ -- > <|> text "mod"
+ text :: Text -> m Text
+ text t = t <$ string (unpack t)
+ {-# INLINE text #-}
+
+instance (CharParsing m, MonadPlus m) => CharParsing (Lazy.StateT s m) where
+ satisfy = lift . satisfy
+ {-# INLINE satisfy #-}
+ char = lift . char
+ {-# INLINE char #-}
+ notChar = lift . notChar
+ {-# INLINE notChar #-}
+ anyChar = lift anyChar
+ {-# INLINE anyChar #-}
+ string = lift . string
+ {-# INLINE string #-}
+ text = lift . text
+ {-# INLINE text #-}
+
+instance (CharParsing m, MonadPlus m) => CharParsing (Strict.StateT s m) where
+ satisfy = lift . satisfy
+ {-# INLINE satisfy #-}
+ char = lift . char
+ {-# INLINE char #-}
+ notChar = lift . notChar
+ {-# INLINE notChar #-}
+ anyChar = lift anyChar
+ {-# INLINE anyChar #-}
+ string = lift . string
+ {-# INLINE string #-}
+ text = lift . text
+ {-# INLINE text #-}
+
+instance (CharParsing m, MonadPlus m) => CharParsing (ReaderT e m) where
+ satisfy = lift . satisfy
+ {-# INLINE satisfy #-}
+ char = lift . char
+ {-# INLINE char #-}
+ notChar = lift . notChar
+ {-# INLINE notChar #-}
+ anyChar = lift anyChar
+ {-# INLINE anyChar #-}
+ string = lift . string
+ {-# INLINE string #-}
+ text = lift . text
+ {-# INLINE text #-}
+
+instance (CharParsing m, MonadPlus m, Monoid w) => CharParsing (Strict.WriterT w m) where
+ satisfy = lift . satisfy
+ {-# INLINE satisfy #-}
+ char = lift . char
+ {-# INLINE char #-}
+ notChar = lift . notChar
+ {-# INLINE notChar #-}
+ anyChar = lift anyChar
+ {-# INLINE anyChar #-}
+ string = lift . string
+ {-# INLINE string #-}
+ text = lift . text
+ {-# INLINE text #-}
+
+instance (CharParsing m, MonadPlus m, Monoid w) => CharParsing (Lazy.WriterT w m) where
+ satisfy = lift . satisfy
+ {-# INLINE satisfy #-}
+ char = lift . char
+ {-# INLINE char #-}
+ notChar = lift . notChar
+ {-# INLINE notChar #-}
+ anyChar = lift anyChar
+ {-# INLINE anyChar #-}
+ string = lift . string
+ {-# INLINE string #-}
+ text = lift . text
+ {-# INLINE text #-}
+
+instance (CharParsing m, MonadPlus m, Monoid w) => CharParsing (Lazy.RWST r w s m) where
+ satisfy = lift . satisfy
+ {-# INLINE satisfy #-}
+ char = lift . char
+ {-# INLINE char #-}
+ notChar = lift . notChar
+ {-# INLINE notChar #-}
+ anyChar = lift anyChar
+ {-# INLINE anyChar #-}
+ string = lift . string
+ {-# INLINE string #-}
+ text = lift . text
+ {-# INLINE text #-}
+
+instance (CharParsing m, MonadPlus m, Monoid w) => CharParsing (Strict.RWST r w s m) where
+ satisfy = lift . satisfy
+ {-# INLINE satisfy #-}
+ char = lift . char
+ {-# INLINE char #-}
+ notChar = lift . notChar
+ {-# INLINE notChar #-}
+ anyChar = lift anyChar
+ {-# INLINE anyChar #-}
+ string = lift . string
+ {-# INLINE string #-}
+ text = lift . text
+ {-# INLINE text #-}
+
+instance (CharParsing m, MonadPlus m) => CharParsing (IdentityT m) where
+ satisfy = lift . satisfy
+ {-# INLINE satisfy #-}
+ char = lift . char
+ {-# INLINE char #-}
+ notChar = lift . notChar
+ {-# INLINE notChar #-}
+ anyChar = lift anyChar
+ {-# INLINE anyChar #-}
+ string = lift . string
+ {-# INLINE string #-}
+ text = lift . text
+ {-# INLINE text #-}
+
+instance Parsec.Stream s m Char => CharParsing (Parsec.ParsecT s u m) where
+ satisfy = Parsec.satisfy
+ char = Parsec.char
+ notChar c = Parsec.satisfy (/= c)
+ anyChar = Parsec.anyChar
+ string = Parsec.string
+
+instance t ~ Char => CharParsing (ReadP.Parser r t) where
+ satisfy = ReadP.satisfy
+ char = ReadP.char
+ notChar c = ReadP.satisfy (/= c)
+ anyChar = ReadP.get
+ string = ReadP.string
+
+-------------------------------------------------------------------------------
+-- Our additions
+-------------------------------------------------------------------------------
+
+integral :: (CharParsing m, Integral a) => m a
+integral = toNumber <$> some d <?> "integral"
+ where
+ toNumber = foldl' (\a b -> a * 10 + b) 0
+ d = f <$> satisfyRange '0' '9'
+ f '0' = 0
+ f '1' = 1
+ f '2' = 2
+ f '3' = 3
+ f '4' = 4
+ f '5' = 5
+ f '6' = 6
+ f '7' = 7
+ f '8' = 8
+ f '9' = 9
+ f _ = error "panic! integral"
+{-# INLINE integral #-}
+
+-- | Greedily munch characters while predicate holds.
+-- Require at least one character.
+munch1 :: CharParsing m => (Char -> Bool) -> m String
+munch1 = some . satisfy
+{-# INLINE munch1 #-}
+
+-- | Greedely munch characters while predicate holds.
+-- Always succeeds.
+munch :: CharParsing m => (Char -> Bool) -> m String
+munch = many . satisfy
+{-# INLINE munch #-}
+
+skipSpaces1 :: CharParsing m => m ()
+skipSpaces1 = skipSome space
+{-# INLINE skipSpaces1 #-}
diff --git a/cabal/Cabal/Distribution/Compat/CopyFile.hs b/cabal/Cabal/Distribution/Compat/CopyFile.hs
index ac0577b..826be7f 100644
--- a/cabal/Cabal/Distribution/Compat/CopyFile.hs
+++ b/cabal/Cabal/Distribution/Compat/CopyFile.hs
@@ -15,6 +15,8 @@ import Prelude ()
import Distribution.Compat.Prelude
import Distribution.Compat.Exception
+
+#ifndef mingw32_HOST_OS
import Distribution.Compat.Internal.TempFile
import Control.Exception
@@ -32,13 +34,29 @@ import System.IO
import Foreign
( allocaBytes )
-#ifndef mingw32_HOST_OS
import System.Posix.Types
( FileMode )
import System.Posix.Internals
( c_chmod, withFilePath )
import Foreign.C
( throwErrnoPathIfMinus1_ )
+
+#else /* else mingw32_HOST_OS */
+
+import Control.Exception
+ ( throwIO )
+import qualified Data.ByteString.Lazy as BSL
+import System.IO.Error
+ ( ioeSetLocation )
+import System.Directory
+ ( doesFileExist )
+import System.FilePath
+ ( isRelative, normalise )
+import System.IO
+ ( IOMode(ReadMode), hFileSize
+ , withBinaryFile )
+
+import qualified System.Win32.File as Win32 ( copyFile )
#endif /* mingw32_HOST_OS */
copyOrdinaryFile, copyExecutableFile :: FilePath -> FilePath -> NoCallStackIO ()
@@ -67,22 +85,45 @@ copyFile :: FilePath -> FilePath -> NoCallStackIO ()
copyFile fromFPath toFPath =
copy
`catchIO` (\ioe -> throwIO (ioeSetLocation ioe "copyFile"))
- where copy = withBinaryFile fromFPath ReadMode $ \hFrom ->
- bracketOnError openTmp cleanTmp $ \(tmpFPath, hTmp) ->
- do allocaBytes bufferSize $ copyContents hFrom hTmp
- hClose hTmp
- renameFile tmpFPath toFPath
- openTmp = openBinaryTempFile (takeDirectory toFPath) ".copyFile.tmp"
- cleanTmp (tmpFPath, hTmp) = do
- hClose hTmp `catchIO` \_ -> return ()
- removeFile tmpFPath `catchIO` \_ -> return ()
- bufferSize = 4096
-
- copyContents hFrom hTo buffer = do
- count <- hGetBuf hFrom buffer bufferSize
- when (count > 0) $ do
- hPutBuf hTo buffer count
- copyContents hFrom hTo buffer
+ where
+#ifndef mingw32_HOST_OS
+ copy = withBinaryFile fromFPath ReadMode $ \hFrom ->
+ bracketOnError openTmp cleanTmp $ \(tmpFPath, hTmp) ->
+ do allocaBytes bufferSize $ copyContents hFrom hTmp
+ hClose hTmp
+ renameFile tmpFPath toFPath
+ openTmp = openBinaryTempFile (takeDirectory toFPath) ".copyFile.tmp"
+ cleanTmp (tmpFPath, hTmp) = do
+ hClose hTmp `catchIO` \_ -> return ()
+ removeFile tmpFPath `catchIO` \_ -> return ()
+ bufferSize = 4096
+
+ copyContents hFrom hTo buffer = do
+ count <- hGetBuf hFrom buffer bufferSize
+ when (count > 0) $ do
+ hPutBuf hTo buffer count
+ copyContents hFrom hTo buffer
+#else
+ copy = Win32.copyFile (toExtendedLengthPath fromFPath)
+ (toExtendedLengthPath toFPath)
+ False
+
+-- NOTE: Shamelessly lifted from System.Directory.Internal.Windows
+
+-- | Add the @"\\\\?\\"@ prefix if necessary or possible. The path remains
+-- unchanged if the prefix is not added. This function can sometimes be used
+-- to bypass the @MAX_PATH@ length restriction in Windows API calls.
+toExtendedLengthPath :: FilePath -> FilePath
+toExtendedLengthPath path
+ | isRelative path = path
+ | otherwise =
+ case normalise path of
+ '\\' : '?' : '?' : '\\' : _ -> path
+ '\\' : '\\' : '?' : '\\' : _ -> path
+ '\\' : '\\' : '.' : '\\' : _ -> path
+ '\\' : subpath@('\\' : _) -> "\\\\?\\UNC" <> subpath
+ normalisedPath -> "\\\\?\\" <> normalisedPath
+#endif /* mingw32_HOST_OS */
-- | Like `copyFile`, but does not touch the target if source and destination
-- are already byte-identical. This is recommended as it is useful for
diff --git a/cabal/Cabal/Distribution/Compat/DList.hs b/cabal/Cabal/Distribution/Compat/DList.hs
index 6f045fe..76e8303 100644
--- a/cabal/Cabal/Distribution/Compat/DList.hs
+++ b/cabal/Cabal/Distribution/Compat/DList.hs
@@ -14,6 +14,7 @@ module Distribution.Compat.DList (
runDList,
singleton,
fromList,
+ toList,
snoc,
) where
@@ -33,6 +34,9 @@ singleton a = DList (a:)
fromList :: [a] -> DList a
fromList as = DList (as ++)
+toList :: DList a -> [a]
+toList = runDList
+
snoc :: DList a -> a -> DList a
snoc xs x = xs <> singleton x
diff --git a/cabal/Cabal/Distribution/Compat/Directory.hs b/cabal/Cabal/Distribution/Compat/Directory.hs
new file mode 100644
index 0000000..6bc4b07
--- /dev/null
+++ b/cabal/Cabal/Distribution/Compat/Directory.hs
@@ -0,0 +1,44 @@
+{-# LANGUAGE CPP #-}
+
+module Distribution.Compat.Directory
+( listDirectory
+, makeAbsolute
+, doesPathExist
+) where
+
+#if MIN_VERSION_directory(1,2,7)
+import System.Directory as Dir hiding (doesPathExist)
+import System.Directory (doesPathExist)
+#else
+import System.Directory as Dir
+#endif
+#if !MIN_VERSION_directory(1,2,2)
+import System.FilePath as Path
+#endif
+
+#if !MIN_VERSION_directory(1,2,5)
+
+listDirectory :: FilePath -> IO [FilePath]
+listDirectory path =
+ filter f `fmap` Dir.getDirectoryContents path
+ where f filename = filename /= "." && filename /= ".."
+
+#endif
+
+#if !MIN_VERSION_directory(1,2,2)
+
+makeAbsolute :: FilePath -> IO FilePath
+makeAbsolute p | Path.isAbsolute p = return p
+ | otherwise = do
+ cwd <- Dir.getCurrentDirectory
+ return $ cwd </> p
+
+#endif
+
+#if !MIN_VERSION_directory(1,2,7)
+
+doesPathExist :: FilePath -> IO Bool
+doesPathExist path = (||) <$> doesDirectoryExist path <*> doesFileExist path
+
+#endif
+
diff --git a/cabal/Cabal/Distribution/Compat/Environment.hs b/cabal/Cabal/Distribution/Compat/Environment.hs
index 13900ba..8c64e68 100644
--- a/cabal/Cabal/Distribution/Compat/Environment.hs
+++ b/cabal/Cabal/Distribution/Compat/Environment.hs
@@ -19,19 +19,18 @@ import Foreign.C.Error (throwErrnoIf_)
#endif
import qualified System.Environment as System
-#if __GLASGOW_HASKELL__ >= 706
import System.Environment (lookupEnv)
#if __GLASGOW_HASKELL__ >= 708
import System.Environment (unsetEnv)
#endif
-#else
-import Distribution.Compat.Exception (catchIO)
-#endif
import Distribution.Compat.Stack
#ifdef mingw32_HOST_OS
import Foreign.C
+#if __GLASGOW_HASKELL__ < 708
+import Foreign.Ptr (nullPtr)
+#endif
import GHC.Windows
#else
import Foreign.C.Types
@@ -53,13 +52,6 @@ getEnvironment = fmap upcaseVars System.getEnvironment
getEnvironment = System.getEnvironment
#endif
-#if __GLASGOW_HASKELL__ < 706
--- | @lookupEnv var@ returns the value of the environment variable @var@, or
--- @Nothing@ if there is no such value.
-lookupEnv :: String -> IO (Maybe String)
-lookupEnv name = (Just `fmap` System.getEnv name) `catchIO` const (return Nothing)
-#endif /* __GLASGOW_HASKELL__ < 706 */
-
-- | @setEnv name value@ sets the specified environment variable to @value@.
--
-- Throws `Control.Exception.IOException` if either @name@ or @value@ is the
@@ -124,6 +116,12 @@ unsetEnv key = withCWString key $ \k -> do
err <- c_GetLastError
unless (err == eRROR_ENVVAR_NOT_FOUND) $ do
throwGetLastError "unsetEnv"
+
+eRROR_ENVVAR_NOT_FOUND :: DWORD
+eRROR_ENVVAR_NOT_FOUND = 203
+
+foreign import WINDOWS_CCONV unsafe "windows.h GetLastError"
+ c_GetLastError:: IO DWORD
#else
unsetEnv key = withFilePath key (throwErrnoIf_ (/= 0) "unsetEnv" . c_unsetenv)
#if __GLASGOW_HASKELL__ > 706
diff --git a/cabal/Cabal/Distribution/Compat/Graph.hs b/cabal/Cabal/Distribution/Compat/Graph.hs
index afbd3ae..e26eae8 100644
--- a/cabal/Cabal/Distribution/Compat/Graph.hs
+++ b/cabal/Cabal/Distribution/Compat/Graph.hs
@@ -83,13 +83,6 @@ module Distribution.Compat.Graph (
nodeValue,
) where
--- For bootstrapping GHC
-#ifdef MIN_VERSION_containers
-#if MIN_VERSION_containers(0,5,0)
-#define HAVE_containers_050
-#endif
-#endif
-
import Prelude ()
import qualified Distribution.Compat.Prelude as Prelude
import Distribution.Compat.Prelude hiding (lookup, null, empty)
@@ -97,11 +90,7 @@ import Distribution.Compat.Prelude hiding (lookup, null, empty)
import Data.Graph (SCC(..))
import qualified Data.Graph as G
-#ifdef HAVE_containers_050
import qualified Data.Map.Strict as Map
-#else
-import qualified Data.Map as Map
-#endif
import qualified Data.Set as Set
import qualified Data.Array as Array
import Data.Array ((!))
@@ -148,11 +137,9 @@ instance Foldable.Foldable Graph where
foldr f z = Foldable.foldr f z . graphMap
foldl f z = Foldable.foldl f z . graphMap
foldMap f = Foldable.foldMap f . graphMap
-#ifdef MIN_VERSION_base
-#if MIN_VERSION_base(4,6,0)
foldl' f z = Foldable.foldl' f z . graphMap
foldr' f z = Foldable.foldr' f z . graphMap
-#endif
+#ifdef MIN_VERSION_base
#if MIN_VERSION_base(4,8,0)
length = Foldable.length . graphMap
null = Foldable.null . graphMap
@@ -182,7 +169,7 @@ instance (NFData a, NFData (Key a)) => NFData (Graph a) where
-- type @'Key' a@; given a node we can determine its key ('nodeKey')
-- and the keys of its neighbors ('nodeNeighbors').
class Ord (Key a) => IsNode a where
- type Key a :: *
+ type Key a
nodeKey :: a -> Key a
nodeNeighbors :: a -> [Key a]
diff --git a/cabal/Cabal/Distribution/Compat/Internal/TempFile.hs b/cabal/Cabal/Distribution/Compat/Internal/TempFile.hs
index edb2b88..dee86eb 100644
--- a/cabal/Cabal/Distribution/Compat/Internal/TempFile.hs
+++ b/cabal/Cabal/Distribution/Compat/Internal/TempFile.hs
@@ -33,7 +33,6 @@ import qualified System.Posix
-- This is here for Haskell implementations that do not come with
-- System.IO.openTempFile. This includes nhc-1.20, hugs-2006.9.
--- TODO: Not sure about JHC
-- TODO: This file should probably be removed.
-- This is a copy/paste of the openBinaryTempFile definition, but
diff --git a/cabal/Cabal/Distribution/Compat/Lens.hs b/cabal/Cabal/Distribution/Compat/Lens.hs
index b4a0104..e353d9f 100644
--- a/cabal/Cabal/Distribution/Compat/Lens.hs
+++ b/cabal/Cabal/Distribution/Compat/Lens.hs
@@ -21,6 +21,7 @@ module Distribution.Compat.Lens (
-- * Getter
view,
use,
+ getting,
-- * Setter
set,
over,
@@ -33,8 +34,6 @@ module Distribution.Compat.Lens (
aview,
-- * Common lenses
_1, _2,
- non,
- fromNon,
-- * Operators
(&),
(^.),
@@ -91,6 +90,14 @@ use :: MonadState s m => Getting a s a -> m a
use l = gets (view l)
{-# INLINE use #-}
+-- | @since 2.4
+--
+-- >>> (3 :: Int) ^. getting (+2) . getting show
+-- "5"
+getting :: (s -> a) -> Getting r s a
+getting k f = Const . getConst . f . k
+{-# INLINE getting #-}
+
-------------------------------------------------------------------------------
-- Setter
-------------------------------------------------------------------------------
@@ -121,6 +128,7 @@ toSetOf l s = getConst (l (\x -> Const (Set.singleton x)) s)
aview :: ALens s t a b -> s -> a
aview l = pretextPos . l pretextSell
{-# INLINE aview #-}
+
{-
lens :: (s -> a) -> (s -> a -> s) -> Lens' s a
lens sa sbt afb s = sbt s <$> afb (sa s)
@@ -136,24 +144,6 @@ _1 f (a, c) = flip (,) c <$> f a
_2 :: Lens (c, a) (c, b) a b
_2 f (c, a) = (,) c <$> f a
--- | /Note:/ not an isomorphism here.
-non :: Eq a => a -> Lens' (Maybe a) a
-non def f s = wrap <$> f (unwrap s)
- where
- wrap x | x == def = Nothing
- wrap x = Just x
-
- unwrap = fromMaybe def
-
-
-fromNon :: Eq a => a -> Lens' a (Maybe a)
-fromNon def f s = unwrap <$> f (wrap s)
- where
- wrap x | x == def = Nothing
- wrap x = Just x
-
- unwrap = fromMaybe def
-
-------------------------------------------------------------------------------
-- Operators
-------------------------------------------------------------------------------
@@ -250,7 +240,7 @@ instance Functor (Pretext a b) where
--
-- First start a repl
--
--- > cabal new-repl Cabal:parser-hackage-tests -fparsec-struct-diff
+-- > cabal new-repl Cabal:hackage-tests
--
-- Because @--extra-package@ isn't yet implemented, we use a test-suite
-- with @generics-sop@ dependency.
diff --git a/cabal/Cabal/Distribution/Compat/Map/Strict.hs b/cabal/Cabal/Distribution/Compat/Map/Strict.hs
deleted file mode 100644
index 6823777..0000000
--- a/cabal/Cabal/Distribution/Compat/Map/Strict.hs
+++ /dev/null
@@ -1,31 +0,0 @@
-{-# LANGUAGE CPP #-}
-
--- For bootstrapping GHC
-#ifdef MIN_VERSION_containers
-#if MIN_VERSION_containers(0,5,0)
-#define HAVE_containers_050
-#endif
-#endif
-
-module Distribution.Compat.Map.Strict
- ( module X
-#ifdef HAVE_containers_050
-#else
- , insertWith
- , fromSet
-#endif
- ) where
-
-#ifdef HAVE_containers_050
-import Data.Map.Strict as X
-#else
-import Data.Map as X hiding (insertWith, insertWith')
-import qualified Data.Map
-import qualified Data.Set
-
-insertWith :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
-insertWith = Data.Map.insertWith'
-
-fromSet :: (k -> a) -> Data.Set.Set k -> Map k a
-fromSet f = Data.Map.fromDistinctAscList . Prelude.map (\k -> (k, f k)) . Data.Set.toList
-#endif
diff --git a/cabal/Cabal/Distribution/Compat/Parsec.hs b/cabal/Cabal/Distribution/Compat/Parsec.hs
deleted file mode 100644
index d9d368b..0000000
--- a/cabal/Cabal/Distribution/Compat/Parsec.hs
+++ /dev/null
@@ -1,78 +0,0 @@
-{-# LANGUAGE FlexibleContexts #-}
-module Distribution.Compat.Parsec (
- P.Parsec,
- P.ParsecT,
- P.Stream,
- (P.<?>),
-
- P.runParser,
-
- -- * Combinators
- P.between,
- P.option,
- P.optional,
- P.optionMaybe,
- P.try,
- P.sepBy,
- P.sepBy1,
- P.choice,
- P.eof,
-
- -- * Char
- integral,
- P.char,
- P.anyChar,
- P.satisfy,
- P.space,
- P.spaces,
- skipSpaces1,
- P.string,
- munch,
- munch1,
- P.oneOf,
- ) where
-
-import Distribution.Compat.Prelude
-import Prelude ()
-
-import qualified Text.Parsec as P
-import qualified Text.Parsec.Pos as P
-
-integral :: (P.Stream s m Char, Integral a) => P.ParsecT s u m a
-integral = toNumber <$> some d P.<?> "integral"
- where
- toNumber = foldl' (\a b -> a * 10 + b) 0
- d = P.tokenPrim
- (\c -> show [c])
- (\pos c _cs -> P.updatePosChar pos c)
- f
- f '0' = Just 0
- f '1' = Just 1
- f '2' = Just 2
- f '3' = Just 3
- f '4' = Just 4
- f '5' = Just 5
- f '6' = Just 6
- f '7' = Just 7
- f '8' = Just 8
- f '9' = Just 9
- f _ = Nothing
-
--- | Greedily munch characters while predicate holds.
--- Require at least one character.
-munch1
- :: P.Stream s m Char
- => (Char -> Bool)
- -> P.ParsecT s u m String
-munch1 = some . P.satisfy
-
--- | Greedely munch characters while predicate holds.
--- Always succeeds.
-munch
- :: P.Stream s m Char
- => (Char -> Bool)
- -> P.ParsecT s u m String
-munch = many . P.satisfy
-
-skipSpaces1 :: P.Stream s m Char => P.ParsecT s u m ()
-skipSpaces1 = P.skipMany1 P.space
diff --git a/cabal/Cabal/Distribution/Compat/Parsing.hs b/cabal/Cabal/Distribution/Compat/Parsing.hs
new file mode 100644
index 0000000..bd5c39e
--- /dev/null
+++ b/cabal/Cabal/Distribution/Compat/Parsing.hs
@@ -0,0 +1,403 @@
+{-# LANGUAGE GADTs, UndecidableInstances #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module : Distribution.Compat.Parsing
+-- Copyright : (c) Edward Kmett 2011-2012
+-- License : BSD3
+--
+-- Maintainer : ekmett@gmail.com
+-- Stability : experimental
+-- Portability : non-portable
+--
+-- Alternative parser combinators.
+--
+-- Originally in @parsers@ package.
+--
+-----------------------------------------------------------------------------
+module Distribution.Compat.Parsing
+ (
+ -- * Parsing Combinators
+ choice
+ , option
+ , optional -- from Control.Applicative, parsec optionMaybe
+ , skipOptional -- parsec optional
+ , between
+ , some -- from Control.Applicative, parsec many1
+ , many -- from Control.Applicative
+ , sepBy
+ , sepBy1
+ -- , sepByNonEmpty
+ , sepEndBy1
+ -- , sepEndByNonEmpty
+ , sepEndBy
+ , endBy1
+ -- , endByNonEmpty
+ , endBy
+ , count
+ , chainl
+ , chainr
+ , chainl1
+ , chainr1
+ , manyTill
+ -- * Parsing Class
+ , Parsing(..)
+ ) where
+
+import Prelude ()
+import Distribution.Compat.Prelude
+
+import Control.Applicative ((<**>), optional)
+import Control.Monad.Trans.Class (lift)
+import Control.Monad.Trans.State.Lazy as Lazy
+import Control.Monad.Trans.State.Strict as Strict
+import Control.Monad.Trans.Writer.Lazy as Lazy
+import Control.Monad.Trans.Writer.Strict as Strict
+import Control.Monad.Trans.RWS.Lazy as Lazy
+import Control.Monad.Trans.RWS.Strict as Strict
+import Control.Monad.Trans.Reader (ReaderT (..))
+import Control.Monad.Trans.Identity (IdentityT (..))
+import Data.Foldable (asum)
+
+import qualified Text.Parsec as Parsec
+import qualified Distribution.Compat.ReadP as ReadP
+
+-- | @choice ps@ tries to apply the parsers in the list @ps@ in order,
+-- until one of them succeeds. Returns the value of the succeeding
+-- parser.
+choice :: Alternative m => [m a] -> m a
+choice = asum
+{-# INLINE choice #-}
+
+-- | @option x p@ tries to apply parser @p@. If @p@ fails without
+-- consuming input, it returns the value @x@, otherwise the value
+-- returned by @p@.
+--
+-- > priority = option 0 (digitToInt <$> digit)
+option :: Alternative m => a -> m a -> m a
+option x p = p <|> pure x
+{-# INLINE option #-}
+
+-- | @skipOptional p@ tries to apply parser @p@. It will parse @p@ or nothing.
+-- It only fails if @p@ fails after consuming input. It discards the result
+-- of @p@. (Plays the role of parsec's optional, which conflicts with Applicative's optional)
+skipOptional :: Alternative m => m a -> m ()
+skipOptional p = (() <$ p) <|> pure ()
+{-# INLINE skipOptional #-}
+
+-- | @between open close p@ parses @open@, followed by @p@ and @close@.
+-- Returns the value returned by @p@.
+--
+-- > braces = between (symbol "{") (symbol "}")
+between :: Applicative m => m bra -> m ket -> m a -> m a
+between bra ket p = bra *> p <* ket
+{-# INLINE between #-}
+
+-- | @sepBy p sep@ parses /zero/ or more occurrences of @p@, separated
+-- by @sep@. Returns a list of values returned by @p@.
+--
+-- > commaSep p = p `sepBy` (symbol ",")
+sepBy :: Alternative m => m a -> m sep -> m [a]
+sepBy p sep = sepBy1 p sep <|> pure []
+{-# INLINE sepBy #-}
+
+-- | @sepBy1 p sep@ parses /one/ or more occurrences of @p@, separated
+-- by @sep@. Returns a list of values returned by @p@.
+sepBy1 :: Alternative m => m a -> m sep -> m [a]
+sepBy1 p sep = (:) <$> p <*> many (sep *> p)
+-- toList <$> sepByNonEmpty p sep
+{-# INLINE sepBy1 #-}
+
+{-
+-- | @sepByNonEmpty p sep@ parses /one/ or more occurrences of @p@, separated
+-- by @sep@. Returns a non-empty list of values returned by @p@.
+sepByNonEmpty :: Alternative m => m a -> m sep -> m (NonEmpty a)
+sepByNonEmpty p sep = (:|) <$> p <*> many (sep *> p)
+{-# INLINE sepByNonEmpty #-}
+-}
+
+-- | @sepEndBy1 p sep@ parses /one/ or more occurrences of @p@,
+-- separated and optionally ended by @sep@. Returns a list of values
+-- returned by @p@.
+sepEndBy1 :: Alternative m => m a -> m sep -> m [a]
+sepEndBy1 p sep = (:) <$> p <*> ((sep *> sepEndBy p sep) <|> pure [])
+-- toList <$> sepEndByNonEmpty p sep
+
+{-
+-- | @sepEndByNonEmpty p sep@ parses /one/ or more occurrences of @p@,
+-- separated and optionally ended by @sep@. Returns a non-empty list of values
+-- returned by @p@.
+sepEndByNonEmpty :: Alternative m => m a -> m sep -> m (NonEmpty a)
+sepEndByNonEmpty p sep = (:|) <$> p <*> ((sep *> sepEndBy p sep) <|> pure [])
+-}
+
+-- | @sepEndBy p sep@ parses /zero/ or more occurrences of @p@,
+-- separated and optionally ended by @sep@, ie. haskell style
+-- statements. Returns a list of values returned by @p@.
+--
+-- > haskellStatements = haskellStatement `sepEndBy` semi
+sepEndBy :: Alternative m => m a -> m sep -> m [a]
+sepEndBy p sep = sepEndBy1 p sep <|> pure []
+{-# INLINE sepEndBy #-}
+
+-- | @endBy1 p sep@ parses /one/ or more occurrences of @p@, separated
+-- and ended by @sep@. Returns a list of values returned by @p@.
+endBy1 :: Alternative m => m a -> m sep -> m [a]
+endBy1 p sep = some (p <* sep)
+{-# INLINE endBy1 #-}
+
+{-
+-- | @endByNonEmpty p sep@ parses /one/ or more occurrences of @p@, separated
+-- and ended by @sep@. Returns a non-empty list of values returned by @p@.
+endByNonEmpty :: Alternative m => m a -> m sep -> m (NonEmpty a)
+endByNonEmpty p sep = some1 (p <* sep)
+{-# INLINE endByNonEmpty #-}
+-}
+
+-- | @endBy p sep@ parses /zero/ or more occurrences of @p@, separated
+-- and ended by @sep@. Returns a list of values returned by @p@.
+--
+-- > cStatements = cStatement `endBy` semi
+endBy :: Alternative m => m a -> m sep -> m [a]
+endBy p sep = many (p <* sep)
+{-# INLINE endBy #-}
+
+-- | @count n p@ parses @n@ occurrences of @p@. If @n@ is smaller or
+-- equal to zero, the parser equals to @return []@. Returns a list of
+-- @n@ values returned by @p@.
+count :: Applicative m => Int -> m a -> m [a]
+count n p | n <= 0 = pure []
+ | otherwise = sequenceA (replicate n p)
+{-# INLINE count #-}
+
+-- | @chainr p op x@ parses /zero/ or more occurrences of @p@,
+-- separated by @op@ Returns a value obtained by a /right/ associative
+-- application of all functions returned by @op@ to the values returned
+-- by @p@. If there are no occurrences of @p@, the value @x@ is
+-- returned.
+chainr :: Alternative m => m a -> m (a -> a -> a) -> a -> m a
+chainr p op x = chainr1 p op <|> pure x
+{-# INLINE chainr #-}
+
+-- | @chainl p op x@ parses /zero/ or more occurrences of @p@,
+-- separated by @op@. Returns a value obtained by a /left/ associative
+-- application of all functions returned by @op@ to the values returned
+-- by @p@. If there are zero occurrences of @p@, the value @x@ is
+-- returned.
+chainl :: Alternative m => m a -> m (a -> a -> a) -> a -> m a
+chainl p op x = chainl1 p op <|> pure x
+{-# INLINE chainl #-}
+
+-- | @chainl1 p op x@ parses /one/ or more occurrences of @p@,
+-- separated by @op@ Returns a value obtained by a /left/ associative
+-- application of all functions returned by @op@ to the values returned
+-- by @p@. . This parser can for example be used to eliminate left
+-- recursion which typically occurs in expression grammars.
+--
+-- > expr = term `chainl1` addop
+-- > term = factor `chainl1` mulop
+-- > factor = parens expr <|> integer
+-- >
+-- > mulop = (*) <$ symbol "*"
+-- > <|> div <$ symbol "/"
+-- >
+-- > addop = (+) <$ symbol "+"
+-- > <|> (-) <$ symbol "-"
+chainl1 :: Alternative m => m a -> m (a -> a -> a) -> m a
+chainl1 p op = scan where
+ scan = p <**> rst
+ rst = (\f y g x -> g (f x y)) <$> op <*> p <*> rst <|> pure id
+{-# INLINE chainl1 #-}
+
+-- | @chainr1 p op x@ parses /one/ or more occurrences of @p@,
+-- separated by @op@ Returns a value obtained by a /right/ associative
+-- application of all functions returned by @op@ to the values returned
+-- by @p@.
+chainr1 :: Alternative m => m a -> m (a -> a -> a) -> m a
+chainr1 p op = scan where
+ scan = p <**> rst
+ rst = (flip <$> op <*> scan) <|> pure id
+{-# INLINE chainr1 #-}
+
+-- | @manyTill p end@ applies parser @p@ /zero/ or more times until
+-- parser @end@ succeeds. Returns the list of values returned by @p@.
+-- This parser can be used to scan comments:
+--
+-- > simpleComment = do{ string "<!--"
+-- > ; manyTill anyChar (try (string "-->"))
+-- > }
+--
+-- Note the overlapping parsers @anyChar@ and @string \"-->\"@, and
+-- therefore the use of the 'try' combinator.
+manyTill :: Alternative m => m a -> m end -> m [a]
+manyTill p end = go where go = ([] <$ end) <|> ((:) <$> p <*> go)
+{-# INLINE manyTill #-}
+
+infixr 0 <?>
+
+-- | Additional functionality needed to describe parsers independent of input type.
+class Alternative m => Parsing m where
+ -- | Take a parser that may consume input, and on failure, go back to
+ -- where we started and fail as if we didn't consume input.
+ try :: m a -> m a
+
+ -- | Give a parser a name
+ (<?>) :: m a -> String -> m a
+
+ -- | A version of many that discards its input. Specialized because it
+ -- can often be implemented more cheaply.
+ skipMany :: m a -> m ()
+ skipMany p = () <$ many p
+ {-# INLINE skipMany #-}
+
+ -- | @skipSome p@ applies the parser @p@ /one/ or more times, skipping
+ -- its result. (aka skipMany1 in parsec)
+ skipSome :: m a -> m ()
+ skipSome p = p *> skipMany p
+ {-# INLINE skipSome #-}
+
+ -- | Used to emit an error on an unexpected token
+ unexpected :: String -> m a
+
+ -- | This parser only succeeds at the end of the input. This is not a
+ -- primitive parser but it is defined using 'notFollowedBy'.
+ --
+ -- > eof = notFollowedBy anyChar <?> "end of input"
+ eof :: m ()
+
+ -- | @notFollowedBy p@ only succeeds when parser @p@ fails. This parser
+ -- does not consume any input. This parser can be used to implement the
+ -- \'longest match\' rule. For example, when recognizing keywords (for
+ -- example @let@), we want to make sure that a keyword is not followed
+ -- by a legal identifier character, in which case the keyword is
+ -- actually an identifier (for example @lets@). We can program this
+ -- behaviour as follows:
+ --
+ -- > keywordLet = try $ string "let" <* notFollowedBy alphaNum
+ notFollowedBy :: Show a => m a -> m ()
+
+instance (Parsing m, MonadPlus m) => Parsing (Lazy.StateT s m) where
+ try (Lazy.StateT m) = Lazy.StateT $ try . m
+ {-# INLINE try #-}
+ Lazy.StateT m <?> l = Lazy.StateT $ \s -> m s <?> l
+ {-# INLINE (<?>) #-}
+ unexpected = lift . unexpected
+ {-# INLINE unexpected #-}
+ eof = lift eof
+ {-# INLINE eof #-}
+ notFollowedBy (Lazy.StateT m) = Lazy.StateT
+ $ \s -> notFollowedBy (fst <$> m s) >> return ((),s)
+ {-# INLINE notFollowedBy #-}
+
+instance (Parsing m, MonadPlus m) => Parsing (Strict.StateT s m) where
+ try (Strict.StateT m) = Strict.StateT $ try . m
+ {-# INLINE try #-}
+ Strict.StateT m <?> l = Strict.StateT $ \s -> m s <?> l
+ {-# INLINE (<?>) #-}
+ unexpected = lift . unexpected
+ {-# INLINE unexpected #-}
+ eof = lift eof
+ {-# INLINE eof #-}
+ notFollowedBy (Strict.StateT m) = Strict.StateT
+ $ \s -> notFollowedBy (fst <$> m s) >> return ((),s)
+ {-# INLINE notFollowedBy #-}
+
+instance (Parsing m, MonadPlus m) => Parsing (ReaderT e m) where
+ try (ReaderT m) = ReaderT $ try . m
+ {-# INLINE try #-}
+ ReaderT m <?> l = ReaderT $ \e -> m e <?> l
+ {-# INLINE (<?>) #-}
+ skipMany (ReaderT m) = ReaderT $ skipMany . m
+ {-# INLINE skipMany #-}
+ unexpected = lift . unexpected
+ {-# INLINE unexpected #-}
+ eof = lift eof
+ {-# INLINE eof #-}
+ notFollowedBy (ReaderT m) = ReaderT $ notFollowedBy . m
+ {-# INLINE notFollowedBy #-}
+
+instance (Parsing m, MonadPlus m, Monoid w) => Parsing (Strict.WriterT w m) where
+ try (Strict.WriterT m) = Strict.WriterT $ try m
+ {-# INLINE try #-}
+ Strict.WriterT m <?> l = Strict.WriterT (m <?> l)
+ {-# INLINE (<?>) #-}
+ unexpected = lift . unexpected
+ {-# INLINE unexpected #-}
+ eof = lift eof
+ {-# INLINE eof #-}
+ notFollowedBy (Strict.WriterT m) = Strict.WriterT
+ $ notFollowedBy (fst <$> m) >>= \x -> return (x, mempty)
+ {-# INLINE notFollowedBy #-}
+
+instance (Parsing m, MonadPlus m, Monoid w) => Parsing (Lazy.WriterT w m) where
+ try (Lazy.WriterT m) = Lazy.WriterT $ try m
+ {-# INLINE try #-}
+ Lazy.WriterT m <?> l = Lazy.WriterT (m <?> l)
+ {-# INLINE (<?>) #-}
+ unexpected = lift . unexpected
+ {-# INLINE unexpected #-}
+ eof = lift eof
+ {-# INLINE eof #-}
+ notFollowedBy (Lazy.WriterT m) = Lazy.WriterT
+ $ notFollowedBy (fst <$> m) >>= \x -> return (x, mempty)
+ {-# INLINE notFollowedBy #-}
+
+instance (Parsing m, MonadPlus m, Monoid w) => Parsing (Lazy.RWST r w s m) where
+ try (Lazy.RWST m) = Lazy.RWST $ \r s -> try (m r s)
+ {-# INLINE try #-}
+ Lazy.RWST m <?> l = Lazy.RWST $ \r s -> m r s <?> l
+ {-# INLINE (<?>) #-}
+ unexpected = lift . unexpected
+ {-# INLINE unexpected #-}
+ eof = lift eof
+ {-# INLINE eof #-}
+ notFollowedBy (Lazy.RWST m) = Lazy.RWST
+ $ \r s -> notFollowedBy ((\(a,_,_) -> a) <$> m r s) >>= \x -> return (x, s, mempty)
+ {-# INLINE notFollowedBy #-}
+
+instance (Parsing m, MonadPlus m, Monoid w) => Parsing (Strict.RWST r w s m) where
+ try (Strict.RWST m) = Strict.RWST $ \r s -> try (m r s)
+ {-# INLINE try #-}
+ Strict.RWST m <?> l = Strict.RWST $ \r s -> m r s <?> l
+ {-# INLINE (<?>) #-}
+ unexpected = lift . unexpected
+ {-# INLINE unexpected #-}
+ eof = lift eof
+ {-# INLINE eof #-}
+ notFollowedBy (Strict.RWST m) = Strict.RWST
+ $ \r s -> notFollowedBy ((\(a,_,_) -> a) <$> m r s) >>= \x -> return (x, s, mempty)
+ {-# INLINE notFollowedBy #-}
+
+instance (Parsing m, Monad m) => Parsing (IdentityT m) where
+ try = IdentityT . try . runIdentityT
+ {-# INLINE try #-}
+ IdentityT m <?> l = IdentityT (m <?> l)
+ {-# INLINE (<?>) #-}
+ skipMany = IdentityT . skipMany . runIdentityT
+ {-# INLINE skipMany #-}
+ unexpected = lift . unexpected
+ {-# INLINE unexpected #-}
+ eof = lift eof
+ {-# INLINE eof #-}
+ notFollowedBy (IdentityT m) = IdentityT $ notFollowedBy m
+ {-# INLINE notFollowedBy #-}
+
+instance (Parsec.Stream s m t, Show t) => Parsing (Parsec.ParsecT s u m) where
+ try = Parsec.try
+ (<?>) = (Parsec.<?>)
+ skipMany = Parsec.skipMany
+ skipSome = Parsec.skipMany1
+ unexpected = Parsec.unexpected
+ eof = Parsec.eof
+ notFollowedBy = Parsec.notFollowedBy
+
+instance t ~ Char => Parsing (ReadP.Parser r t) where
+ try = id
+ (<?>) = const
+ skipMany = ReadP.skipMany
+ skipSome = ReadP.skipMany1
+ unexpected = const ReadP.pfail
+ eof = ReadP.eof
+
+ -- TODO: we would like to have <++ here
+ notFollowedBy p = ((Just <$> p) ReadP.+++ pure Nothing)
+ >>= maybe (pure ()) (unexpected . show)
diff --git a/cabal/Cabal/Distribution/Compat/Prelude.hs b/cabal/Cabal/Distribution/Compat/Prelude.hs
index 45dbd96..d032825 100644
--- a/cabal/Cabal/Distribution/Compat/Prelude.hs
+++ b/cabal/Cabal/Distribution/Compat/Prelude.hs
@@ -6,11 +6,9 @@
#ifdef MIN_VERSION_base
#define MINVER_base_48 MIN_VERSION_base(4,8,0)
#define MINVER_base_47 MIN_VERSION_base(4,7,0)
-#define MINVER_base_46 MIN_VERSION_base(4,6,0)
#else
#define MINVER_base_48 (__GLASGOW_HASKELL__ >= 710)
#define MINVER_base_47 (__GLASGOW_HASKELL__ >= 708)
-#define MINVER_base_46 (__GLASGOW_HASKELL__ >= 706)
#endif
-- | This module does two things:
diff --git a/cabal/Cabal/Distribution/Compat/ReadP.hs b/cabal/Cabal/Distribution/Compat/ReadP.hs
index a9c79c8..1f5a989 100644
--- a/cabal/Cabal/Distribution/Compat/ReadP.hs
+++ b/cabal/Cabal/Distribution/Compat/ReadP.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE GADTs #-}
-----------------------------------------------------------------------------
-- |
-- Module : Distribution.Compat.ReadP
@@ -69,21 +70,18 @@ module Distribution.Compat.ReadP
readP_to_S, -- :: ReadP a -> ReadS a
readS_to_P, -- :: ReadS a -> ReadP a
- -- ** Parsec
- parsecToReadP,
+ -- ** Internal
+ Parser,
)
where
import Prelude ()
import Distribution.Compat.Prelude hiding (many, get)
-import Control.Applicative (liftA2)
import qualified Distribution.Compat.MonadFail as Fail
import Control.Monad( replicateM, (>=>) )
-import qualified Text.Parsec as P
-
infixr 5 +++, <++
-- ---------------------------------------------------------------------------
@@ -168,6 +166,10 @@ instance Applicative (Parser r s) where
pure x = R (\k -> k x)
(<*>) = ap
+instance s ~ Char => Alternative (Parser r s) where
+ empty = pfail
+ (<|>) = (+++)
+
instance Monad (Parser r s) where
return = pure
fail = Fail.fail
@@ -176,9 +178,9 @@ instance Monad (Parser r s) where
instance Fail.MonadFail (Parser r s) where
fail _ = R (const Fail)
---instance MonadPlus (Parser r s) where
--- mzero = pfail
--- mplus = (+++)
+instance s ~ Char => MonadPlus (Parser r s) where
+ mzero = pfail
+ mplus = (+++)
-- ---------------------------------------------------------------------------
-- Operations over P
@@ -420,16 +422,3 @@ readS_to_P :: ReadS a -> ReadP r a
-- parser, and therefore a possible inefficiency.
readS_to_P r =
R (\k -> Look (\s -> final [bs'' | (a,s') <- r s, bs'' <- run (k a) s']))
-
--- ---------------------------------------------------------------------------
--- Converting from Parsec to ReadP
---
--- | Convert @Parsec@ parser to 'ReadP'.
-parsecToReadP
- :: P.Parsec [Char] u a
- -> u -- ^ initial user state
- -> ReadP r a
-parsecToReadP p u = R $ \k -> Look $ \s ->
- case P.runParser (liftA2 (,) p P.getInput) u "<parsecToReadP>" s of
- Right (x, s') -> final (run (k x) s')
- Left _ -> Fail
diff --git a/cabal/Cabal/Distribution/Compat/Time.hs b/cabal/Cabal/Distribution/Compat/Time.hs
index db359ac..6cd02f7 100644
--- a/cabal/Cabal/Distribution/Compat/Time.hs
+++ b/cabal/Cabal/Distribution/Compat/Time.hs
@@ -23,12 +23,8 @@ import System.FilePath
import Data.Time.Clock.POSIX ( POSIXTime, getPOSIXTime )
import Data.Time ( diffUTCTime, getCurrentTime )
-#if MIN_VERSION_directory(1,2,0)
import Data.Time.Clock.POSIX ( posixDayLength )
-#else
-import System.Time ( getClockTime, diffClockTimes
- , normalizeTimeDiff, tdDay, tdHour )
-#endif
+
#if defined mingw32_HOST_OS
@@ -135,12 +131,7 @@ getModTime path = do
return $! (extractFileTime st)
extractFileTime :: FileStatus -> ModTime
-#if MIN_VERSION_unix(2,6,0)
extractFileTime x = posixTimeToModTime (modificationTimeHiRes x)
-#else
-extractFileTime x = posixSecondsToModTime $ fromIntegral $ fromEnum $
- modificationTime x
-#endif
#endif
@@ -162,14 +153,8 @@ posixTimeToModTime p = ModTime $ (ceiling $ p * 1e7) -- 100 ns precision
getFileAge :: FilePath -> NoCallStackIO Double
getFileAge file = do
t0 <- getModificationTime file
-#if MIN_VERSION_directory(1,2,0)
t1 <- getCurrentTime
return $ realToFrac (t1 `diffUTCTime` t0) / realToFrac posixDayLength
-#else
- t1 <- getClockTime
- let dt = normalizeTimeDiff (t1 `diffClockTimes` t0)
- return $ fromIntegral ((24 * tdDay dt) + tdHour dt) / 24.0
-#endif
-- | Return the current time as 'ModTime'.
getCurTime :: NoCallStackIO ModTime
diff --git a/cabal/Cabal/Distribution/Compiler.hs b/cabal/Cabal/Distribution/Compiler.hs
index b6a2675..92018ea 100644
--- a/cabal/Cabal/Distribution/Compiler.hs
+++ b/cabal/Cabal/Distribution/Compiler.hs
@@ -16,7 +16,6 @@
--
-- > case compilerFlavor comp of
-- > GHC -> GHC.getInstalledPackages verbosity packageDb progdb
--- > JHC -> JHC.getInstalledPackages verbosity packageDb progdb
--
-- Obviously it would be better to use the proper 'Compiler' abstraction
-- because that would keep all the compiler-specific code together.
@@ -33,6 +32,7 @@ module Distribution.Compiler (
defaultCompilerFlavor,
parseCompilerFlavorCompat,
classifyCompilerFlavor,
+ knownCompilerFlavors,
-- * Compiler id
CompilerId(..),
@@ -55,19 +55,22 @@ import Distribution.Parsec.Class (Parsec (..))
import Distribution.Pretty (Pretty (..))
import Distribution.Text (Text(..), display)
import qualified Distribution.Compat.ReadP as Parse
-import qualified Distribution.Compat.Parsec as P
+import qualified Distribution.Compat.CharParsing as P
import qualified Text.PrettyPrint as Disp
data CompilerFlavor =
- GHC | GHCJS | NHC | YHC | Hugs | HBC | Helium | JHC | LHC | UHC
+ GHC | GHCJS | NHC | YHC | Hugs | HBC | Helium | JHC | LHC | UHC | Eta
| HaskellSuite String -- string is the id of the actual compiler
| OtherCompiler String
deriving (Generic, Show, Read, Eq, Ord, Typeable, Data)
instance Binary CompilerFlavor
+instance NFData CompilerFlavor where rnf = genericRnf
+
knownCompilerFlavors :: [CompilerFlavor]
-knownCompilerFlavors = [GHC, GHCJS, NHC, YHC, Hugs, HBC, Helium, JHC, LHC, UHC]
+knownCompilerFlavors =
+ [GHC, GHCJS, NHC, YHC, Hugs, HBC, Helium, JHC, LHC, UHC, Eta]
instance Pretty CompilerFlavor where
pretty (OtherCompiler name) = Disp.text name
@@ -149,6 +152,8 @@ data CompilerId = CompilerId CompilerFlavor Version
instance Binary CompilerId
+instance NFData CompilerId where rnf = genericRnf
+
instance Text CompilerId where
disp (CompilerId f v)
| v == nullVersion = disp f
diff --git a/cabal/Cabal/Distribution/FieldGrammar.hs b/cabal/Cabal/Distribution/FieldGrammar.hs
index 3d80d9f..71a02d8 100644
--- a/cabal/Cabal/Distribution/FieldGrammar.hs
+++ b/cabal/Cabal/Distribution/FieldGrammar.hs
@@ -8,7 +8,6 @@ module Distribution.FieldGrammar (
uniqueField,
optionalField,
optionalFieldDef,
- optionalFieldDefAla,
monoidalField,
deprecatedField',
-- * Concrete grammar implementations
@@ -32,7 +31,7 @@ module Distribution.FieldGrammar (
import Distribution.Compat.Prelude
import Prelude ()
-import qualified Distribution.Compat.Map.Strict as Map
+import qualified Data.Map.Strict as Map
import Distribution.FieldGrammar.Class
import Distribution.FieldGrammar.Parsec
diff --git a/cabal/Cabal/Distribution/FieldGrammar/Class.hs b/cabal/Cabal/Distribution/FieldGrammar/Class.hs
index 853fec2..6bd391d 100644
--- a/cabal/Cabal/Distribution/FieldGrammar/Class.hs
+++ b/cabal/Cabal/Distribution/FieldGrammar/Class.hs
@@ -3,7 +3,6 @@ module Distribution.FieldGrammar.Class (
uniqueField,
optionalField,
optionalFieldDef,
- optionalFieldDefAla,
monoidalField,
deprecatedField',
) where
@@ -55,6 +54,15 @@ class FieldGrammar g where
-> ALens' s (Maybe a) -- ^ lens into the field
-> g s (Maybe a)
+ -- | Optional field with default value.
+ optionalFieldDefAla
+ :: (Parsec b, Pretty b, Newtype b a, Eq a)
+ => FieldName -- ^ field name
+ -> (a -> b) -- ^ 'Newtype' pack
+ -> ALens' s a -- ^ @'Lens'' s a@: lens into the field
+ -> a -- ^ default value
+ -> g s a
+
-- | Monoidal field.
--
-- Values are combined with 'mappend'.
@@ -90,6 +98,7 @@ class FieldGrammar g where
-- | Annotate field with since spec-version.
availableSince
:: [Int] -- ^ spec version
+ -> a -- ^ default value
-> g s a
-> g s a
@@ -111,24 +120,13 @@ optionalField fn = optionalFieldAla fn Identity
-- | Optional field with default value.
optionalFieldDef
- :: (FieldGrammar g, Functor (g s), Parsec a, Pretty a, Eq a, Show a)
+ :: (FieldGrammar g, Functor (g s), Parsec a, Pretty a, Eq a)
=> FieldName -- ^ field name
- -> LensLike' (Pretext (Maybe a) (Maybe a)) s a -- ^ @'Lens'' s a@: lens into the field
+ -> ALens' s a -- ^ @'Lens'' s a@: lens into the field
-> a -- ^ default value
-> g s a
optionalFieldDef fn = optionalFieldDefAla fn Identity
--- | Optional field with default value.
-optionalFieldDefAla
- :: (FieldGrammar g, Functor (g s), Parsec b, Pretty b, Newtype b a, Eq a, Show a)
- => FieldName -- ^ field name
- -> (a -> b) -- ^ 'Newtype' pack
- -> LensLike' (Pretext (Maybe a) (Maybe a)) s a -- ^ @'Lens'' s a@: lens into the field
- -> a -- ^ default value
- -> g s a
-optionalFieldDefAla fn pack l def =
- fromMaybe def <$> optionalFieldAla fn pack (l . fromNon def)
-
-- | Field which can be define multiple times, and the results are @mappend@ed.
monoidalField
:: (FieldGrammar g, Parsec a, Pretty a, Monoid a)
diff --git a/cabal/Cabal/Distribution/FieldGrammar/FieldDescrs.hs b/cabal/Cabal/Distribution/FieldGrammar/FieldDescrs.hs
new file mode 100644
index 0000000..3bd820e
--- /dev/null
+++ b/cabal/Cabal/Distribution/FieldGrammar/FieldDescrs.hs
@@ -0,0 +1,87 @@
+{-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE NoMonoLocalBinds #-}
+module Distribution.FieldGrammar.FieldDescrs (
+ FieldDescrs,
+ fieldDescrPretty,
+ fieldDescrParse,
+ fieldDescrsToList,
+ ) where
+
+import Distribution.Compat.Prelude
+import Prelude ()
+
+import Distribution.Compat.Lens (aview, cloneLens)
+import Distribution.Compat.Newtype
+import Distribution.FieldGrammar
+import Distribution.Pretty (pretty)
+import Distribution.Utils.Generic (fromUTF8BS)
+
+import qualified Data.Map as Map
+import qualified Distribution.Parsec.Class as P
+import qualified Distribution.Parsec.Field as P
+import qualified Text.PrettyPrint as Disp
+
+-- strict pair
+data SP s = SP
+ { pPretty :: !(s -> Disp.Doc)
+ , pParse :: !(forall m. P.CabalParsing m => s -> m s)
+ }
+
+-- | A collection field parsers and pretty-printers.
+newtype FieldDescrs s a = F { runF :: Map String (SP s) }
+ deriving (Functor)
+
+instance Applicative (FieldDescrs s) where
+ pure _ = F mempty
+ f <*> x = F (mappend (runF f) (runF x))
+
+singletonF :: P.FieldName -> (s -> Disp.Doc) -> (forall m. P.CabalParsing m => s -> m s) -> FieldDescrs s a
+singletonF fn f g = F $ Map.singleton (fromUTF8BS fn) (SP f g)
+
+-- | Lookup a field value pretty-printer.
+fieldDescrPretty :: FieldDescrs s a -> String -> Maybe (s -> Disp.Doc)
+fieldDescrPretty (F m) fn = pPretty <$> Map.lookup fn m
+
+-- | Lookup a field value parser.
+fieldDescrParse :: P.CabalParsing m => FieldDescrs s a -> String -> Maybe (s -> m s)
+fieldDescrParse (F m) fn = pParse <$> Map.lookup fn m
+
+fieldDescrsToList
+ :: P.CabalParsing m
+ => FieldDescrs s a
+ -> [(String, s -> Disp.Doc, s -> m s)]
+fieldDescrsToList = map mk . Map.toList . runF where
+ mk (name, SP ppr parse) = (name, ppr, parse)
+
+-- | /Note:/ default values are printed.
+instance FieldGrammar FieldDescrs where
+ blurFieldGrammar l (F m) = F (fmap blur m) where
+ blur (SP f g) = SP (f . aview l) (cloneLens l g)
+
+ booleanFieldDef fn l _def = singletonF fn f g where
+ f s = Disp.text (show (aview l s))
+ g s = cloneLens l (const P.parsec) s
+ -- Note: eta expansion is needed for RankNTypes type-checking to work.
+
+ uniqueFieldAla fn _pack l = singletonF fn f g where
+ f s = pretty (pack' _pack (aview l s))
+ g s = cloneLens l (const (unpack' _pack <$> P.parsec)) s
+
+ optionalFieldAla fn _pack l = singletonF fn f g where
+ f s = maybe mempty (pretty . pack' _pack) (aview l s)
+ g s = cloneLens l (const (Just . unpack' _pack <$> P.parsec)) s
+
+ optionalFieldDefAla fn _pack l _def = singletonF fn f g where
+ f s = pretty (pack' _pack (aview l s))
+ g s = cloneLens l (const (unpack' _pack <$> P.parsec)) s
+
+ 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
+
+ prefixedFields _fnPfx _l = F mempty
+ knownField _ = pure ()
+ deprecatedSince _ _ x = x
+ availableSince _ _ = id
+ hiddenField _ = F mempty
diff --git a/cabal/Cabal/Distribution/FieldGrammar/Parsec.hs b/cabal/Cabal/Distribution/FieldGrammar/Parsec.hs
index bf72f8f..6567d68 100644
--- a/cabal/Cabal/Distribution/FieldGrammar/Parsec.hs
+++ b/cabal/Cabal/Distribution/FieldGrammar/Parsec.hs
@@ -1,5 +1,6 @@
-{-# LANGUAGE DeriveFunctor #-}
-{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ScopedTypeVariables #-}
-- | This module provides a 'FieldGrammarParser', one way to parse
-- @.cabal@ -like files.
--
@@ -56,28 +57,32 @@ module Distribution.FieldGrammar.Parsec (
-- * Auxiliary
Fields,
NamelessField (..),
+ namelessFieldAnn,
Section (..),
runFieldParser,
runFieldParser',
) where
-import qualified Data.ByteString as BS
-import Data.List (dropWhileEnd)
-import Data.Ord (comparing)
-import Data.Set (Set)
-import qualified Data.Set as Set
-import qualified Distribution.Compat.Map.Strict as Map
-import Distribution.Compat.Prelude
-import Distribution.Compat.Newtype
-import Distribution.Simple.Utils (fromUTF8BS)
-import Prelude ()
-import qualified Text.Parsec as P
-import qualified Text.Parsec.Error as P
-
+import Data.List (dropWhileEnd)
+import Data.Ord (comparing)
+import Data.Set (Set)
+import Distribution.Compat.Newtype
+import Distribution.Compat.Prelude
+import Distribution.Simple.Utils (fromUTF8BS)
+import Prelude ()
+
+import qualified Data.ByteString as BS
+import qualified Data.Set as Set
+import qualified Data.Map.Strict as Map
+import qualified Text.Parsec as P
+import qualified Text.Parsec.Error as P
+
+import Distribution.CabalSpecVersion
import Distribution.FieldGrammar.Class
import Distribution.Parsec.Class
import Distribution.Parsec.Common
import Distribution.Parsec.Field
+import Distribution.Parsec.FieldLineStream
import Distribution.Parsec.ParseResult
-------------------------------------------------------------------------------
@@ -90,6 +95,9 @@ type Fields ann = Map FieldName [NamelessField ann]
data NamelessField ann = MkNamelessField !ann [FieldLine ann]
deriving (Eq, Show, Functor)
+namelessFieldAnn :: NamelessField ann -> ann
+namelessFieldAnn (MkNamelessField ann _) = ann
+
-- | The 'Section' constructor of 'Field'.
data Section ann = MkSection !(Name ann) [SectionArg ann] [Field ann]
deriving (Eq, Show, Functor)
@@ -101,19 +109,19 @@ data Section ann = MkSection !(Name ann) [SectionArg ann] [Field ann]
data ParsecFieldGrammar s a = ParsecFG
{ fieldGrammarKnownFields :: !(Set FieldName)
, fieldGrammarKnownPrefixes :: !(Set FieldName)
- , fieldGrammarParser :: !(Fields Position -> ParseResult a)
+ , fieldGrammarParser :: !(CabalSpecVersion -> Fields Position -> ParseResult a)
}
deriving (Functor)
-parseFieldGrammar :: Fields Position -> ParsecFieldGrammar s a -> ParseResult a
-parseFieldGrammar fields grammar = do
+parseFieldGrammar :: CabalSpecVersion -> Fields Position -> ParsecFieldGrammar s a -> ParseResult a
+parseFieldGrammar v fields grammar = do
for_ (Map.toList (Map.filterWithKey isUnknownField fields)) $ \(name, nfields) ->
for_ nfields $ \(MkNamelessField pos _) ->
parseWarning pos PWTUnknownField $ "Unknown field: " ++ show name
-- TODO: fields allowed in this section
-- parse
- fieldGrammarParser grammar fields
+ fieldGrammarParser grammar v fields
where
isUnknownField k _ = not $
@@ -124,73 +132,94 @@ fieldGrammarKnownFieldList :: ParsecFieldGrammar s a -> [FieldName]
fieldGrammarKnownFieldList = Set.toList . fieldGrammarKnownFields
instance Applicative (ParsecFieldGrammar s) where
- pure x = ParsecFG mempty mempty (\_ -> pure x)
+ pure x = ParsecFG mempty mempty (\_ _ -> pure x)
{-# INLINE pure #-}
ParsecFG f f' f'' <*> ParsecFG x x' x'' = ParsecFG
(mappend f x)
(mappend f' x')
- (\fields -> f'' fields <*> x'' fields)
+ (\v fields -> f'' v fields <*> x'' v fields)
{-# INLINE (<*>) #-}
+warnMultipleSingularFields :: FieldName -> [NamelessField Position] -> ParseResult ()
+warnMultipleSingularFields _ [] = pure ()
+warnMultipleSingularFields fn (x : xs) = do
+ let pos = namelessFieldAnn x
+ poss = map namelessFieldAnn xs
+ parseWarning pos PWTMultipleSingularField $
+ "The field " <> show fn <> " is specified more than once at positions " ++ intercalate ", " (map showPos (pos : poss))
+
instance FieldGrammar ParsecFieldGrammar where
blurFieldGrammar _ (ParsecFG s s' parser) = ParsecFG s s' parser
uniqueFieldAla fn _pack _extract = ParsecFG (Set.singleton fn) Set.empty parser
where
- parser fields = case Map.lookup fn fields of
- Nothing -> parseFatalFailure zeroPos $ show fn ++ " field missing:"
- Just [] -> parseFatalFailure zeroPos $ show fn ++ " field foo"
- Just [x] -> parseOne x
- -- TODO: parse all
- -- TODO: warn about duplicate fields?
- Just xs-> parseOne (last xs)
+ parser v fields = case Map.lookup fn fields of
+ Nothing -> parseFatalFailure zeroPos $ show fn ++ " field missing"
+ Just [] -> parseFatalFailure zeroPos $ show fn ++ " field missing"
+ Just [x] -> parseOne v x
+ Just xs -> do
+ warnMultipleSingularFields fn xs
+ last <$> traverse (parseOne v) xs
- parseOne (MkNamelessField pos fls) =
- unpack' _pack <$> runFieldParser pos parsec fls
+ parseOne v (MkNamelessField pos fls) =
+ unpack' _pack <$> runFieldParser pos parsec v fls
booleanFieldDef fn _extract def = ParsecFG (Set.singleton fn) Set.empty parser
where
- parser :: Fields Position -> ParseResult Bool
- parser fields = case Map.lookup fn fields of
+ parser v fields = case Map.lookup fn fields of
Nothing -> pure def
Just [] -> pure def
- Just [x] -> parseOne x
- -- TODO: parse all
- -- TODO: warn about duplicate optional fields?
- Just xs -> parseOne (last xs)
+ Just [x] -> parseOne v x
+ Just xs -> do
+ warnMultipleSingularFields fn xs
+ last <$> traverse (parseOne v) xs
- parseOne (MkNamelessField pos fls) = runFieldParser pos parsec fls
+ parseOne v (MkNamelessField pos fls) = runFieldParser pos parsec v fls
optionalFieldAla fn _pack _extract = ParsecFG (Set.singleton fn) Set.empty parser
where
- parser fields = case Map.lookup fn fields of
+ parser v fields = case Map.lookup fn fields of
Nothing -> pure Nothing
Just [] -> pure Nothing
- Just [x] -> parseOne x
- -- TODO: parse all!
- Just xs -> parseOne (last xs) -- TODO: warn about duplicate optional fields?
+ Just [x] -> parseOne v x
+ Just xs -> do
+ warnMultipleSingularFields fn xs
+ last <$> traverse (parseOne v) xs
- parseOne (MkNamelessField pos fls)
+ parseOne v (MkNamelessField pos fls)
| null fls = pure Nothing
- | otherwise = Just . (unpack' _pack) <$> runFieldParser pos parsec fls
+ | otherwise = Just . unpack' _pack <$> runFieldParser pos parsec v fls
+
+ optionalFieldDefAla fn _pack _extract def = ParsecFG (Set.singleton fn) Set.empty parser
+ where
+ parser v fields = case Map.lookup fn fields of
+ Nothing -> pure def
+ Just [] -> pure def
+ Just [x] -> parseOne v x
+ Just xs -> do
+ warnMultipleSingularFields fn xs
+ last <$> traverse (parseOne v) xs
+
+ parseOne v (MkNamelessField pos fls)
+ | null fls = pure def
+ | otherwise = unpack' _pack <$> runFieldParser pos parsec v fls
monoidalFieldAla fn _pack _extract = ParsecFG (Set.singleton fn) Set.empty parser
where
- parser fields = case Map.lookup fn fields of
+ parser v fields = case Map.lookup fn fields of
Nothing -> pure mempty
- Just xs -> foldMap (unpack' _pack) <$> traverse parseOne xs
+ Just xs -> foldMap (unpack' _pack) <$> traverse (parseOne v) xs
- parseOne (MkNamelessField pos fls) = runFieldParser pos parsec fls
+ parseOne v (MkNamelessField pos fls) = runFieldParser pos parsec v fls
- prefixedFields fnPfx _extract = ParsecFG mempty (Set.singleton fnPfx) (pure . parser)
+ prefixedFields fnPfx _extract = ParsecFG mempty (Set.singleton fnPfx) (\_ fs -> pure (parser fs))
where
parser :: Fields Position -> [(String, String)]
parser values = reorder $ concatMap convert $ filter match $ Map.toList values
match (fn, _) = fnPfx `BS.isPrefixOf` fn
convert (fn, fields) =
- -- TODO: warn about invalid UTF8
[ (pos, (fromUTF8BS fn, trim $ fromUTF8BS $ fieldlinesToBS fls))
| MkNamelessField pos fls <- fields
]
@@ -199,21 +228,33 @@ instance FieldGrammar ParsecFieldGrammar where
trim :: String -> String
trim = dropWhile isSpace . dropWhileEnd isSpace
- availableSince _ = id
-
+ availableSince vs def (ParsecFG names prefixes parser) = ParsecFG names prefixes parser'
+ where
+ parser' v values
+ | cabalSpecSupports v vs = parser v values
+ | otherwise = do
+ let unknownFields = Map.intersection values $ Map.fromSet (const ()) names
+ for_ (Map.toList unknownFields) $ \(name, fields) ->
+ for_ fields $ \(MkNamelessField pos _) ->
+ parseWarning pos PWTUnknownField $
+ "The field " <> show name <> " is available since Cabal " ++ show vs
+
+ pure def
+
+ -- todo we know about this field
deprecatedSince (_ : _) _ grammar = grammar -- pass on non-empty version
deprecatedSince _ msg (ParsecFG names prefixes parser) = ParsecFG names prefixes parser'
where
- parser' values = do
+ parser' v values = do
let deprecatedFields = Map.intersection values $ Map.fromSet (const ()) names
for_ (Map.toList deprecatedFields) $ \(name, fields) ->
for_ fields $ \(MkNamelessField pos _) ->
parseWarning pos PWTDeprecatedField $
"The field " <> show name <> " is deprecated. " ++ msg
- parser values
+ parser v values
- knownField fn = ParsecFG (Set.singleton fn) Set.empty (\_ -> pure ())
+ knownField fn = ParsecFG (Set.singleton fn) Set.empty (\_ _ -> pure ())
hiddenField = id
@@ -221,8 +262,8 @@ instance FieldGrammar ParsecFieldGrammar where
-- Parsec
-------------------------------------------------------------------------------
-runFieldParser' :: Position -> FieldParser a -> String -> ParseResult a
-runFieldParser' (Position row col) p str = case P.runParser p' [] "<field>" str of
+runFieldParser' :: Position -> ParsecParser a -> CabalSpecVersion -> FieldLineStream -> ParseResult a
+runFieldParser' (Position row col) p v str = case P.runParser p' [] "<field>" str of
Right (pok, ws) -> do
-- TODO: map pos
traverse_ (\(PWarning t pos w) -> parseWarning pos t w) ws
@@ -234,13 +275,18 @@ runFieldParser' (Position row col) p str = case P.runParser p' [] "<field>" str
let msg = P.showErrorMessages
"or" "unknown parse error" "expecting" "unexpected" "end of input"
(P.errorMessages err)
+ let str' = unlines (filter (not . all isSpace) (fieldLineStreamToLines str))
- parseFatalFailure epos $ msg ++ ": " ++ show str
+ parseFatalFailure epos $ msg ++ "\n" ++ "\n" ++ str'
where
- p' = (,) <$ P.spaces <*> p <* P.spaces <* P.eof <*> P.getState
+ p' = (,) <$ P.spaces <*> unPP p v <* P.spaces <* P.eof <*> P.getState
+
+fieldLineStreamToLines :: FieldLineStream -> [String]
+fieldLineStreamToLines (FLSLast bs) = [ fromUTF8BS bs ]
+fieldLineStreamToLines (FLSCons bs s) = fromUTF8BS bs : fieldLineStreamToLines s
-runFieldParser :: Position -> FieldParser a -> [FieldLine Position] -> ParseResult a
-runFieldParser pp p ls = runFieldParser' pos p =<< fieldlinesToString pos ls
+runFieldParser :: Position -> ParsecParser a -> CabalSpecVersion -> [FieldLine Position] -> ParseResult a
+runFieldParser pp p v ls = runFieldParser' pos p v (fieldLinesToStream ls)
where
-- TODO: make per line lookup
pos = case ls of
@@ -249,12 +295,3 @@ runFieldParser pp p ls = runFieldParser' pos p =<< fieldlinesToString pos ls
fieldlinesToBS :: [FieldLine ann] -> BS.ByteString
fieldlinesToBS = BS.intercalate "\n" . map (\(FieldLine _ bs) -> bs)
-
--- TODO: Take position from FieldLine
--- TODO: Take field name
-fieldlinesToString :: Position -> [FieldLine ann] -> ParseResult String
-fieldlinesToString pos fls =
- let str = intercalate "\n" . map (\(FieldLine _ bs') -> fromUTF8BS bs') $ fls
- in if '\xfffd' `elem` str
- then str <$ parseWarning pos PWTUTF "Invalid UTF8 encoding"
- else pure str
diff --git a/cabal/Cabal/Distribution/FieldGrammar/Pretty.hs b/cabal/Cabal/Distribution/FieldGrammar/Pretty.hs
index 865ba10..d0f585c 100644
--- a/cabal/Cabal/Distribution/FieldGrammar/Pretty.hs
+++ b/cabal/Cabal/Distribution/FieldGrammar/Pretty.hs
@@ -26,6 +26,8 @@ instance Applicative (PrettyFieldGrammar s) where
PrettyFG f <*> PrettyFG x = PrettyFG (\s -> f s PP.$$ x s)
-- | We can use 'PrettyFieldGrammar' to pp print the @s@.
+--
+-- /Note:/ there is not trailing @($+$ text "")@.
prettyFieldGrammar :: PrettyFieldGrammar s a -> s -> Doc
prettyFieldGrammar = fieldGrammarPretty
@@ -49,6 +51,14 @@ instance FieldGrammar PrettyFieldGrammar where
Nothing -> mempty
Just a -> ppField (fromUTF8BS fn) (pretty (pack' _pack a))
+ optionalFieldDefAla fn _pack l def = PrettyFG pp
+ where
+ pp s
+ | x == def = mempty
+ | otherwise = ppField (fromUTF8BS fn) (pretty (pack' _pack x))
+ where
+ x = aview l s
+
monoidalFieldAla fn _pack l = PrettyFG pp
where
pp s = ppField (fromUTF8BS fn) (pretty (pack' _pack (aview l s)))
@@ -66,5 +76,5 @@ instance FieldGrammar PrettyFieldGrammar where
knownField _ = pure ()
deprecatedSince [] _ _ = PrettyFG (\_ -> mempty)
deprecatedSince _ _ x = x
- availableSince _ = id
+ availableSince _ _ = id
hiddenField _ = PrettyFG (\_ -> mempty)
diff --git a/cabal/Cabal/Distribution/InstalledPackageInfo.hs b/cabal/Cabal/Distribution/InstalledPackageInfo.hs
index 6bacbb4..a5c84b2 100644
--- a/cabal/Cabal/Distribution/InstalledPackageInfo.hs
+++ b/cabal/Cabal/Distribution/InstalledPackageInfo.hs
@@ -1,7 +1,3 @@
-{-# LANGUAGE DeriveGeneric #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE TypeFamilies #-}
-
-----------------------------------------------------------------------------
-- |
-- Module : Distribution.InstalledPackageInfo
@@ -41,93 +37,37 @@ module Distribution.InstalledPackageInfo (
emptyInstalledPackageInfo,
parseInstalledPackageInfo,
showInstalledPackageInfo,
+ showFullInstalledPackageInfo,
showInstalledPackageInfoField,
showSimpleInstalledPackageInfoField,
- fieldsInstalledPackageInfo,
) where
-import Prelude ()
import Distribution.Compat.Prelude
+import Prelude ()
-import Distribution.ParseUtils
-import Distribution.License
-import Distribution.Package hiding (installedUnitId, installedPackageId)
+import Data.Set (Set)
import Distribution.Backpack
-import qualified Distribution.Package as Package
+import Distribution.CabalSpecVersion (cabalSpecLatest)
+import Distribution.FieldGrammar
+import Distribution.FieldGrammar.FieldDescrs
import Distribution.ModuleName
-import Distribution.Version
-import Distribution.Text
-import qualified Distribution.Compat.ReadP as Parse
-import Distribution.Compat.Graph
-import Distribution.Types.MungedPackageId
+import Distribution.Package hiding (installedPackageId, installedUnitId)
+import Distribution.ParseUtils
import Distribution.Types.ComponentName
-import Distribution.Types.MungedPackageName
-import Distribution.Types.UnqualComponentName
+import Distribution.Utils.Generic (toUTF8BS)
-import Text.PrettyPrint as Disp
-import qualified Data.Char as Char
-import qualified Data.Map as Map
-import Data.Set (Set)
+import qualified Data.Map as Map
+import qualified Distribution.Parsec.Common as P
+import qualified Distribution.Parsec.Parser as P
+import qualified Distribution.Parsec.ParseResult as P
+import qualified Text.Parsec.Error as Parsec
+import qualified Text.Parsec.Pos as Parsec
+import qualified Text.PrettyPrint as Disp
+
+import Distribution.Types.InstalledPackageInfo
+import Distribution.Types.InstalledPackageInfo.FieldGrammar
--- -----------------------------------------------------------------------------
--- The InstalledPackageInfo type
--- For BC reasons, we continue to name this record an InstalledPackageInfo;
--- but it would more accurately be called an InstalledUnitInfo with Backpack
-data InstalledPackageInfo
- = InstalledPackageInfo {
- -- these parts are exactly the same as PackageDescription
- sourcePackageId :: PackageId,
- installedUnitId :: UnitId,
- installedComponentId_ :: ComponentId,
- -- INVARIANT: if this package is definite, OpenModule's
- -- OpenUnitId directly records UnitId. If it is
- -- indefinite, OpenModule is always an OpenModuleVar
- -- with the same ModuleName as the key.
- instantiatedWith :: [(ModuleName, OpenModule)],
- sourceLibName :: Maybe UnqualComponentName,
- compatPackageKey :: String,
- license :: License,
- copyright :: String,
- maintainer :: String,
- author :: String,
- stability :: String,
- homepage :: String,
- pkgUrl :: String,
- synopsis :: String,
- description :: String,
- category :: String,
- -- these parts are required by an installed package only:
- abiHash :: AbiHash,
- indefinite :: Bool,
- exposed :: Bool,
- -- INVARIANT: if the package is definite, OpenModule's
- -- OpenUnitId directly records UnitId.
- exposedModules :: [ExposedModule],
- hiddenModules :: [ModuleName],
- trusted :: Bool,
- importDirs :: [FilePath],
- libraryDirs :: [FilePath],
- libraryDynDirs :: [FilePath], -- ^ overrides 'libraryDirs'
- dataDir :: FilePath,
- hsLibraries :: [String],
- extraLibraries :: [String],
- extraGHCiLibraries:: [String], -- overrides extraLibraries for GHCi
- includeDirs :: [FilePath],
- includes :: [String],
- -- INVARIANT: if the package is definite, UnitId is NOT
- -- a ComponentId of an indefinite package
- depends :: [UnitId],
- abiDepends :: [AbiDependency],
- ccOptions :: [String],
- ldOptions :: [String],
- frameworkDirs :: [FilePath],
- frameworks :: [String],
- haddockInterfaces :: [FilePath],
- haddockHTMLs :: [FilePath],
- pkgRoot :: Maybe FilePath
- }
- deriving (Eq, Generic, Typeable, Read, Show)
installedComponentId :: InstalledPackageInfo -> ComponentId
installedComponentId ipi =
@@ -158,150 +98,6 @@ requiredSignatures ipi = openModuleSubstFreeHoles (Map.fromList (instantiatedWit
installedPackageId :: InstalledPackageInfo -> UnitId
installedPackageId = installedUnitId
-instance Binary InstalledPackageInfo
-
-instance Package.HasMungedPackageId InstalledPackageInfo where
- mungedId = mungedPackageId
-
-instance Package.Package InstalledPackageInfo where
- packageId = sourcePackageId
-
-instance Package.HasUnitId InstalledPackageInfo where
- installedUnitId = installedUnitId
-
-instance Package.PackageInstalled InstalledPackageInfo where
- installedDepends = depends
-
-instance IsNode InstalledPackageInfo where
- type Key InstalledPackageInfo = UnitId
- nodeKey = installedUnitId
- nodeNeighbors = depends
-
-emptyInstalledPackageInfo :: InstalledPackageInfo
-emptyInstalledPackageInfo
- = InstalledPackageInfo {
- sourcePackageId = PackageIdentifier (mkPackageName "") nullVersion,
- installedUnitId = mkUnitId "",
- installedComponentId_ = mkComponentId "",
- instantiatedWith = [],
- sourceLibName = Nothing,
- compatPackageKey = "",
- license = UnspecifiedLicense,
- copyright = "",
- maintainer = "",
- author = "",
- stability = "",
- homepage = "",
- pkgUrl = "",
- synopsis = "",
- description = "",
- category = "",
- abiHash = mkAbiHash "",
- indefinite = False,
- exposed = False,
- exposedModules = [],
- hiddenModules = [],
- trusted = False,
- importDirs = [],
- libraryDirs = [],
- libraryDynDirs = [],
- dataDir = "",
- hsLibraries = [],
- extraLibraries = [],
- extraGHCiLibraries= [],
- includeDirs = [],
- includes = [],
- depends = [],
- abiDepends = [],
- ccOptions = [],
- ldOptions = [],
- frameworkDirs = [],
- frameworks = [],
- haddockInterfaces = [],
- haddockHTMLs = [],
- pkgRoot = Nothing
- }
-
--- -----------------------------------------------------------------------------
--- Exposed modules
-
-data ExposedModule
- = ExposedModule {
- exposedName :: ModuleName,
- exposedReexport :: Maybe OpenModule
- }
- deriving (Eq, Generic, Read, Show)
-
-instance Text ExposedModule where
- disp (ExposedModule m reexport) =
- Disp.hsep [ disp m
- , case reexport of
- Just m' -> Disp.hsep [Disp.text "from", disp m']
- Nothing -> Disp.empty
- ]
- parse = do
- m <- parseModuleNameQ
- Parse.skipSpaces
- reexport <- Parse.option Nothing $ do
- _ <- Parse.string "from"
- Parse.skipSpaces
- fmap Just parse
- return (ExposedModule m reexport)
-
-instance Binary ExposedModule
-
--- To maintain backwards-compatibility, we accept both comma/non-comma
--- separated variants of this field. You SHOULD use the comma syntax if you
--- use any new functions, although actually it's unambiguous due to a quirk
--- of the fact that modules must start with capital letters.
-
-showExposedModules :: [ExposedModule] -> Disp.Doc
-showExposedModules xs
- | all isExposedModule xs = fsep (map disp xs)
- | otherwise = fsep (Disp.punctuate comma (map disp xs))
- where isExposedModule (ExposedModule _ Nothing) = True
- isExposedModule _ = False
-
-parseExposedModules :: Parse.ReadP r [ExposedModule]
-parseExposedModules = parseOptCommaList parse
-
-dispMaybe :: Text a => Maybe a -> Disp.Doc
-dispMaybe Nothing = Disp.empty
-dispMaybe (Just x) = disp x
-
-parseMaybe :: Text a => Parse.ReadP r (Maybe a)
-parseMaybe = fmap Just parse Parse.<++ return Nothing
-
--- -----------------------------------------------------------------------------
--- ABI dependency
-
--- | An ABI dependency is a dependency on a library which also
--- records the ABI hash ('abiHash') of the library it depends
--- on.
---
--- The primary utility of this is to enable an extra sanity when
--- GHC loads libraries: it can check if the dependency has a matching
--- ABI and if not, refuse to load this library. This information
--- is critical if we are shadowing libraries; differences in the
--- ABI hash let us know what packages get shadowed by the new version
--- of a package.
-data AbiDependency = AbiDependency {
- depUnitId :: UnitId,
- depAbiHash :: AbiHash
- }
- deriving (Eq, Generic, Read, Show)
-
-instance Text AbiDependency where
- disp (AbiDependency uid abi) =
- disp uid <<>> Disp.char '=' <<>> disp abi
- parse = do
- uid <- parse
- _ <- Parse.char '='
- abi <- parse
- return (AbiDependency uid abi)
-
-instance Binary AbiDependency
-
-- -----------------------------------------------------------------------------
-- Munging
@@ -311,207 +107,44 @@ sourceComponentName ipi =
Nothing -> CLibName
Just qn -> CSubLibName qn
--- | Returns @Just@ if the @name@ field of the IPI record would not contain
--- the package name verbatim. This helps us avoid writing @package-name@
--- when it's redundant.
-maybePackageName :: InstalledPackageInfo -> Maybe PackageName
-maybePackageName ipi =
- case sourceLibName ipi of
- Nothing -> Nothing
- Just _ -> Just (packageName ipi)
-
--- | Setter for the @package-name@ field. It should be acceptable for this
--- to be a no-op.
-setMaybePackageName :: Maybe PackageName -> InstalledPackageInfo -> InstalledPackageInfo
-setMaybePackageName Nothing ipi = ipi
-setMaybePackageName (Just pn) ipi = ipi {
- sourcePackageId=(sourcePackageId ipi){pkgName=pn}
- }
-
--- | Returns the munged package name, which we write into @name@ for
--- compatibility with old versions of GHC.
-mungedPackageName :: InstalledPackageInfo -> MungedPackageName
-mungedPackageName ipi =
- computeCompatPackageName
- (packageName ipi)
- (sourceLibName ipi)
-
-setMungedPackageName :: MungedPackageName -> InstalledPackageInfo -> InstalledPackageInfo
-setMungedPackageName mpn ipi =
- let (pn, mb_uqn) = decodeCompatPackageName mpn
- in ipi {
- sourcePackageId = (sourcePackageId ipi) {pkgName=pn},
- sourceLibName = mb_uqn
- }
-
-mungedPackageId :: InstalledPackageInfo -> MungedPackageId
-mungedPackageId ipi =
- MungedPackageId (mungedPackageName ipi) (packageVersion ipi)
-
-- -----------------------------------------------------------------------------
-- Parsing
parseInstalledPackageInfo :: String -> ParseResult InstalledPackageInfo
-parseInstalledPackageInfo =
- parseFieldsFlat (fieldsInstalledPackageInfo ++ deprecatedFieldDescrs)
- emptyInstalledPackageInfo
+parseInstalledPackageInfo s = case P.readFields (toUTF8BS s) of
+ Left err -> ParseFailed (NoParse (show err) $ Parsec.sourceLine $ Parsec.errorPos err)
+ Right fs -> case partitionFields fs of
+ (fs', _) -> case P.runParseResult $ parseFieldGrammar cabalSpecLatest fs' ipiFieldGrammar of
+ (ws, Right x) -> ParseOk ws' x where
+ ws' = map (PWarning . P.showPWarning "") ws
+ (_, Left (_, errs)) -> ParseFailed (NoParse errs' 0) where
+ errs' = intercalate "; " $ map (\(P.PError _ msg) -> msg) errs
-- -----------------------------------------------------------------------------
-- Pretty-printing
+-- | Pretty print 'InstalledPackageInfo'.
+--
+-- @pkgRoot@ isn't printed, as ghc-pkg prints it manually (as GHC-8.4).
showInstalledPackageInfo :: InstalledPackageInfo -> String
-showInstalledPackageInfo = showFields fieldsInstalledPackageInfo
+showInstalledPackageInfo ipi =
+ showFullInstalledPackageInfo ipi { pkgRoot = Nothing }
+
+-- | The variant of 'showInstalledPackageInfo' which outputs @pkgroot@ field too.
+showFullInstalledPackageInfo :: InstalledPackageInfo -> String
+showFullInstalledPackageInfo = Disp.render . (Disp.$+$ Disp.text "") . prettyFieldGrammar ipiFieldGrammar
+-- |
+--
+-- >>> let ipi = emptyInstalledPackageInfo { maintainer = "Tester" }
+-- >>> fmap ($ ipi) $ showInstalledPackageInfoField "maintainer"
+-- Just "maintainer: Tester"
showInstalledPackageInfoField :: String -> Maybe (InstalledPackageInfo -> String)
-showInstalledPackageInfoField = showSingleNamedField fieldsInstalledPackageInfo
+showInstalledPackageInfoField fn =
+ fmap (\g -> Disp.render . ppField fn . g) $ fieldDescrPretty ipiFieldGrammar fn
showSimpleInstalledPackageInfoField :: String -> Maybe (InstalledPackageInfo -> String)
-showSimpleInstalledPackageInfoField = showSimpleSingleNamedField fieldsInstalledPackageInfo
-
-dispCompatPackageKey :: String -> Doc
-dispCompatPackageKey = text
-
-parseCompatPackageKey :: Parse.ReadP r String
-parseCompatPackageKey = Parse.munch1 uid_char
- where uid_char c = Char.isAlphaNum c || c `elem` "-_.=[],:<>+"
-
--- -----------------------------------------------------------------------------
--- Description of the fields, for parsing/printing
-
-fieldsInstalledPackageInfo :: [FieldDescr InstalledPackageInfo]
-fieldsInstalledPackageInfo = basicFieldDescrs ++ installedFieldDescrs
-
-basicFieldDescrs :: [FieldDescr InstalledPackageInfo]
-basicFieldDescrs =
- [ simpleField "name"
- disp (parseMaybeQuoted parse)
- mungedPackageName setMungedPackageName
- , simpleField "version"
- disp parseOptVersion
- packageVersion (\ver pkg -> pkg{sourcePackageId=(sourcePackageId pkg){pkgVersion=ver}})
- , simpleField "id"
- disp parse
- installedUnitId (\pk pkg -> pkg{installedUnitId=pk})
- , simpleField "instantiated-with"
- (dispOpenModuleSubst . Map.fromList) (fmap Map.toList parseOpenModuleSubst)
- instantiatedWith (\iw pkg -> pkg{instantiatedWith=iw})
- , simpleField "package-name"
- dispMaybe parseMaybe
- maybePackageName setMaybePackageName
- , simpleField "lib-name"
- dispMaybe parseMaybe
- sourceLibName (\n pkg -> pkg{sourceLibName=n})
- , simpleField "key"
- dispCompatPackageKey parseCompatPackageKey
- compatPackageKey (\pk pkg -> pkg{compatPackageKey=pk})
- , simpleField "license"
- disp parseLicenseQ
- license (\l pkg -> pkg{license=l})
- , simpleField "copyright"
- showFreeText parseFreeText
- copyright (\val pkg -> pkg{copyright=val})
- , simpleField "maintainer"
- showFreeText parseFreeText
- maintainer (\val pkg -> pkg{maintainer=val})
- , simpleField "stability"
- showFreeText parseFreeText
- stability (\val pkg -> pkg{stability=val})
- , simpleField "homepage"
- showFreeText parseFreeText
- homepage (\val pkg -> pkg{homepage=val})
- , simpleField "package-url"
- showFreeText parseFreeText
- pkgUrl (\val pkg -> pkg{pkgUrl=val})
- , simpleField "synopsis"
- showFreeText parseFreeText
- synopsis (\val pkg -> pkg{synopsis=val})
- , simpleField "description"
- showFreeText parseFreeText
- description (\val pkg -> pkg{description=val})
- , simpleField "category"
- showFreeText parseFreeText
- category (\val pkg -> pkg{category=val})
- , simpleField "author"
- showFreeText parseFreeText
- author (\val pkg -> pkg{author=val})
- ]
-
-installedFieldDescrs :: [FieldDescr InstalledPackageInfo]
-installedFieldDescrs = [
- boolField "exposed"
- exposed (\val pkg -> pkg{exposed=val})
- , boolField "indefinite"
- indefinite (\val pkg -> pkg{indefinite=val})
- , simpleField "exposed-modules"
- showExposedModules parseExposedModules
- exposedModules (\xs pkg -> pkg{exposedModules=xs})
- , listField "hidden-modules"
- disp parseModuleNameQ
- hiddenModules (\xs pkg -> pkg{hiddenModules=xs})
- , simpleField "abi"
- disp parse
- abiHash (\abi pkg -> pkg{abiHash=abi})
- , boolField "trusted"
- trusted (\val pkg -> pkg{trusted=val})
- , listField "import-dirs"
- showFilePath parseFilePathQ
- importDirs (\xs pkg -> pkg{importDirs=xs})
- , listField "library-dirs"
- showFilePath parseFilePathQ
- libraryDirs (\xs pkg -> pkg{libraryDirs=xs})
- , listField "dynamic-library-dirs"
- showFilePath parseFilePathQ
- libraryDynDirs (\xs pkg -> pkg{libraryDynDirs=xs})
- , simpleField "data-dir"
- showFilePath (parseFilePathQ Parse.<++ return "")
- dataDir (\val pkg -> pkg{dataDir=val})
- , listField "hs-libraries"
- showFilePath parseTokenQ
- hsLibraries (\xs pkg -> pkg{hsLibraries=xs})
- , listField "extra-libraries"
- showToken parseTokenQ
- extraLibraries (\xs pkg -> pkg{extraLibraries=xs})
- , listField "extra-ghci-libraries"
- showToken parseTokenQ
- extraGHCiLibraries (\xs pkg -> pkg{extraGHCiLibraries=xs})
- , listField "include-dirs"
- showFilePath parseFilePathQ
- includeDirs (\xs pkg -> pkg{includeDirs=xs})
- , listField "includes"
- showFilePath parseFilePathQ
- includes (\xs pkg -> pkg{includes=xs})
- , listField "depends"
- disp parse
- depends (\xs pkg -> pkg{depends=xs})
- , listField "abi-depends"
- disp parse
- abiDepends (\xs pkg -> pkg{abiDepends=xs})
- , listField "cc-options"
- showToken parseTokenQ
- ccOptions (\path pkg -> pkg{ccOptions=path})
- , listField "ld-options"
- showToken parseTokenQ
- ldOptions (\path pkg -> pkg{ldOptions=path})
- , listField "framework-dirs"
- showFilePath parseFilePathQ
- frameworkDirs (\xs pkg -> pkg{frameworkDirs=xs})
- , listField "frameworks"
- showToken parseTokenQ
- frameworks (\xs pkg -> pkg{frameworks=xs})
- , listField "haddock-interfaces"
- showFilePath parseFilePathQ
- haddockInterfaces (\xs pkg -> pkg{haddockInterfaces=xs})
- , listField "haddock-html"
- showFilePath parseFilePathQ
- haddockHTMLs (\xs pkg -> pkg{haddockHTMLs=xs})
- , simpleField "pkgroot"
- (const Disp.empty) parseFilePathQ
- (fromMaybe "" . pkgRoot) (\xs pkg -> pkg{pkgRoot=Just xs})
- ]
-
-deprecatedFieldDescrs :: [FieldDescr InstalledPackageInfo]
-deprecatedFieldDescrs = [
- listField "hugs-options"
- showToken parseTokenQ
- (const []) (const id)
- ]
+showSimpleInstalledPackageInfoField fn =
+ fmap (Disp.renderStyle myStyle .) $ fieldDescrPretty ipiFieldGrammar fn
+ where
+ myStyle = Disp.style { Disp.mode = Disp.LeftMode }
diff --git a/cabal/Cabal/Distribution/License.hs b/cabal/Cabal/Distribution/License.hs
index c40c605..5ca540c 100644
--- a/cabal/Cabal/Distribution/License.hs
+++ b/cabal/Cabal/Distribution/License.hs
@@ -45,6 +45,8 @@
module Distribution.License (
License(..),
knownLicenses,
+ licenseToSPDX,
+ licenseFromSPDX,
) where
import Distribution.Compat.Prelude
@@ -55,9 +57,11 @@ import Distribution.Pretty
import Distribution.Text
import Distribution.Version
-import qualified Distribution.Compat.Parsec as P
-import qualified Distribution.Compat.ReadP as Parse
-import qualified Text.PrettyPrint as Disp
+import qualified Distribution.Compat.CharParsing as P
+import qualified Data.Map.Strict as Map
+import qualified Distribution.Compat.ReadP as Parse
+import qualified Distribution.SPDX as SPDX
+import qualified Text.PrettyPrint as Disp
-- | Indicates the license under which a package's source code is released.
-- Versions of the licenses not listed here will be rejected by Hackage and
@@ -127,6 +131,8 @@ data License =
instance Binary License
+instance NFData License where rnf = genericRnf
+
-- | The list of all currently recognised licenses.
knownLicenses :: [License]
knownLicenses = [ GPL unversioned, GPL (version [2]), GPL (version [3])
@@ -136,9 +142,79 @@ knownLicenses = [ GPL unversioned, GPL (version [2]), GPL (version [3])
, MPL (mkVersion [2, 0])
, Apache unversioned, Apache (version [2, 0])
, PublicDomain, AllRightsReserved, OtherLicense]
- where
- unversioned = Nothing
- version = Just . mkVersion
+ where
+ unversioned = Nothing
+ version = Just . mkVersion
+
+-- | Convert old 'License' to SPDX 'SPDX.License'.
+-- Non-SPDX licenses are converted to 'SPDX.LicenseRef'.
+--
+-- @since 2.2.0.0
+licenseToSPDX :: License -> SPDX.License
+licenseToSPDX l = case l of
+ GPL v | v == version [2] -> spdx SPDX.GPL_2_0_only
+ GPL v | v == version [3] -> spdx SPDX.GPL_3_0_only
+ LGPL v | v == version [2,1] -> spdx SPDX.LGPL_2_1_only
+ LGPL v | v == version [3] -> spdx SPDX.LGPL_3_0_only
+ AGPL v | v == version [3] -> spdx SPDX.AGPL_3_0_only
+ BSD2 -> spdx SPDX.BSD_2_Clause
+ BSD3 -> spdx SPDX.BSD_3_Clause
+ BSD4 -> spdx SPDX.BSD_4_Clause
+ MIT -> spdx SPDX.MIT
+ ISC -> spdx SPDX.ISC
+ MPL v | v == mkVersion [2,0] -> spdx SPDX.MPL_2_0
+ Apache v | v == version [2,0] -> spdx SPDX.Apache_2_0
+ AllRightsReserved -> SPDX.NONE
+ UnspecifiedLicense -> SPDX.NONE
+ OtherLicense -> ref (SPDX.mkLicenseRef' Nothing "OtherLicense")
+ PublicDomain -> ref (SPDX.mkLicenseRef' Nothing "PublicDomain")
+ UnknownLicense str -> ref (SPDX.mkLicenseRef' Nothing str)
+ _ -> ref (SPDX.mkLicenseRef' Nothing $ prettyShow l)
+ where
+ version = Just . mkVersion
+ spdx = SPDX.License . SPDX.simpleLicenseExpression
+ ref r = SPDX.License $ SPDX.ELicense (SPDX.ELicenseRef r) Nothing
+
+-- | Convert 'SPDX.License' to 'License',
+--
+-- This is lossy conversion. We try our best.
+--
+-- >>> licenseFromSPDX . licenseToSPDX $ BSD3
+-- BSD3
+--
+-- >>> licenseFromSPDX . licenseToSPDX $ GPL (Just (mkVersion [3]))
+-- GPL (Just (mkVersion [3]))
+--
+-- >>> licenseFromSPDX . licenseToSPDX $ PublicDomain
+-- UnknownLicense "LicenseRefPublicDomain"
+--
+-- >>> licenseFromSPDX $ SPDX.License $ SPDX.simpleLicenseExpression SPDX.EUPL_1_1
+-- UnknownLicense "EUPL-1.1"
+--
+-- >>> licenseFromSPDX . licenseToSPDX $ AllRightsReserved
+-- AllRightsReserved
+--
+-- >>> licenseFromSPDX <$> simpleParsec "BSD-3-Clause OR GPL-3.0-only"
+-- Just (UnknownLicense "BSD3ClauseORGPL30only")
+--
+-- @since 2.2.0.0
+licenseFromSPDX :: SPDX.License -> License
+licenseFromSPDX SPDX.NONE = AllRightsReserved
+licenseFromSPDX l =
+ fromMaybe (mungle $ prettyShow l) $ Map.lookup l m
+ where
+ m :: Map.Map SPDX.License License
+ m = Map.fromList $ filter (isSimple . fst ) $
+ map (\x -> (licenseToSPDX x, x)) knownLicenses
+
+ isSimple (SPDX.License (SPDX.ELicense (SPDX.ELicenseId _) Nothing)) = True
+ isSimple _ = False
+
+ mungle name = fromMaybe (UnknownLicense (mapMaybe mangle name)) (simpleParsec name)
+
+ mangle c
+ | isAlphaNum c = Just c
+ | otherwise = Nothing
instance Pretty License where
pretty (GPL version) = Disp.text "GPL" <<>> dispOptVersion version
@@ -152,7 +228,7 @@ instance Pretty License where
instance Parsec License where
parsec = do
name <- P.munch1 isAlphaNum
- version <- P.optionMaybe (P.char '-' *> parsec)
+ version <- P.optional (P.char '-' *> parsec)
return $! case (name, version :: Maybe Version) of
("GPL", _ ) -> GPL version
("LGPL", _ ) -> LGPL version
diff --git a/cabal/Cabal/Distribution/Make.hs b/cabal/Cabal/Distribution/Make.hs
index 63467c0..50491ca 100644
--- a/cabal/Cabal/Distribution/Make.hs
+++ b/cabal/Cabal/Distribution/Make.hs
@@ -146,6 +146,8 @@ copyAction flags args = do
let destArgs = case fromFlag $ copyDest flags of
NoCopyDest -> ["install"]
CopyTo path -> ["copy", "destdir=" ++ path]
+ CopyToDb _ -> error "CopyToDb not supported via Make"
+
rawSystemExit (fromFlag $ copyVerbosity flags) "make" destArgs
installAction :: InstallFlags -> [String] -> IO ()
diff --git a/cabal/Cabal/Distribution/ModuleName.hs b/cabal/Cabal/Distribution/ModuleName.hs
index 2e5ae5d..fd5d608 100644
--- a/cabal/Cabal/Distribution/ModuleName.hs
+++ b/cabal/Cabal/Distribution/ModuleName.hs
@@ -34,8 +34,8 @@ import Distribution.Pretty
import Distribution.Parsec.Class
import Distribution.Text
-import qualified Distribution.Compat.Parsec as P
-import qualified Distribution.Compat.ReadP as Parse
+import qualified Distribution.Compat.CharParsing as P
+import qualified Distribution.Compat.ReadP as Parse
import qualified Text.PrettyPrint as Disp
-- | A valid Haskell module name.
@@ -79,7 +79,7 @@ validModuleComponent [] = False
validModuleComponent (c:cs) = isUpper c
&& all validModuleChar cs
-{-# DEPRECATED simple "use ModuleName.fromString instead" #-}
+{-# DEPRECATED simple "use ModuleName.fromString instead. This symbol will be removed in Cabal-3.0 (est. Mar 2019)." #-}
simple :: String -> ModuleName
simple str = ModuleName (stlFromStrings [str])
diff --git a/cabal/Cabal/Distribution/Package.hs b/cabal/Cabal/Distribution/Package.hs
index 1ca340a..0b467d1 100644
--- a/cabal/Cabal/Distribution/Package.hs
+++ b/cabal/Cabal/Distribution/Package.hs
@@ -87,7 +87,7 @@ instance HasMungedPackageId MungedPackageId where
class Package pkg => HasUnitId pkg where
installedUnitId :: pkg -> UnitId
-{-# DEPRECATED installedPackageId "Use installedUnitId instead" #-}
+{-# DEPRECATED installedPackageId "Use installedUnitId instead. This symbol will be removed in Cabal-3.0 (est. Mar 2019)." #-}
-- | Compatibility wrapper for Cabal pre-1.24.
installedPackageId :: HasUnitId pkg => pkg -> UnitId
installedPackageId = installedUnitId
diff --git a/cabal/Cabal/Distribution/PackageDescription.hs b/cabal/Cabal/Distribution/PackageDescription.hs
index 53660f1..afa23f8 100644
--- a/cabal/Cabal/Distribution/PackageDescription.hs
+++ b/cabal/Cabal/Distribution/PackageDescription.hs
@@ -1,7 +1,6 @@
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE NoMonoLocalBinds #-}
-
-----------------------------------------------------------------------------
-- |
-- Module : Distribution.PackageDescription
@@ -19,6 +18,8 @@ module Distribution.PackageDescription (
PackageDescription(..),
emptyPackageDescription,
specVersion,
+ buildType,
+ license,
descCabalVersion,
BuildType(..),
knownBuildTypes,
@@ -85,6 +86,8 @@ module Distribution.PackageDescription (
hcStaticOptions,
-- ** Supplementary build information
+ allBuildDepends,
+ enabledBuildDepends,
ComponentName(..),
defaultLibName,
HookedBuildInfo,
@@ -99,6 +102,7 @@ module Distribution.PackageDescription (
nullFlagAssignment, showFlagValue,
diffFlagAssignment, lookupFlagAssignment, insertFlagAssignment,
dispFlagAssignment, parseFlagAssignment, parsecFlagAssignment,
+ findDuplicateFlagAssignments,
CondTree(..), ConfVar(..), Condition(..),
cNot, cAnd, cOr,
diff --git a/cabal/Cabal/Distribution/PackageDescription/Check.hs b/cabal/Cabal/Distribution/PackageDescription/Check.hs
index b8007f0..7814967 100644
--- a/cabal/Cabal/Distribution/PackageDescription/Check.hs
+++ b/cabal/Cabal/Distribution/PackageDescription/Check.hs
@@ -34,52 +34,50 @@ module Distribution.PackageDescription.Check (
checkPackageFileNames,
) where
-import Prelude ()
import Distribution.Compat.Prelude
+import Prelude ()
-import Distribution.PackageDescription
-import Distribution.PackageDescription.Configuration
-import qualified Distribution.Compat.DList as DList
+import Control.Monad (mapM)
+import Data.List (group)
+import Distribution.Compat.Lens
import Distribution.Compiler
-import Distribution.System
import Distribution.License
-import Distribution.Simple.BuildPaths (autogenPathsModuleName)
+import Distribution.Package
+import Distribution.PackageDescription
+import Distribution.PackageDescription.Configuration
+import Distribution.Pretty (prettyShow)
+import Distribution.Simple.BuildPaths (autogenPathsModuleName)
import Distribution.Simple.BuildToolDepends
import Distribution.Simple.CCompiler
+import Distribution.Simple.Glob
+import Distribution.Simple.Utils hiding (findPackageDesc, notice)
+import Distribution.System
+import Distribution.Text
import Distribution.Types.ComponentRequestedSpec
import Distribution.Types.CondTree
-import Distribution.Types.Dependency
import Distribution.Types.ExeDependency
-import Distribution.Types.PackageName
-import Distribution.Types.ExecutableScope
import Distribution.Types.UnqualComponentName
-import Distribution.Simple.Utils hiding (findPackageDesc, notice)
+import Distribution.Utils.Generic (isAscii)
+import Distribution.Verbosity
import Distribution.Version
-import Distribution.Package
-import Distribution.Text
-import Distribution.Utils.Generic (isAscii)
import Language.Haskell.Extension
+import System.FilePath
+ (splitDirectories, splitExtension, splitPath, takeExtension, takeFileName, (<.>), (</>))
-import Control.Monad (mapM)
-import qualified Data.ByteString.Lazy as BS
-import Data.List (group)
-import qualified System.Directory as System
- ( doesFileExist, doesDirectoryExist )
-import qualified Data.Map as Map
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import qualified Distribution.Compat.DList as DList
+import qualified Distribution.SPDX as SPDX
+import qualified System.Directory as System
-import qualified System.Directory (getDirectoryContents)
-import System.FilePath
- ( (</>), (<.>), takeExtension, takeFileName, splitDirectories
- , splitPath, splitExtension )
-import System.FilePath.Windows as FilePath.Windows
- ( isValid )
+import qualified System.Directory (getDirectoryContents)
+import qualified System.FilePath.Windows as FilePath.Windows (isValid)
import qualified Data.Set as Set
-import Distribution.Compat.Lens
-import qualified Distribution.Types.BuildInfo.Lens as L
-import qualified Distribution.Types.PackageDescription.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
-- | Results of some kind of failed package check.
--
@@ -115,7 +113,7 @@ data PackageCheck =
-- quite legitimately refuse to publicly distribute packages with these
-- problems.
| PackageDistInexcusable { explanation :: String }
- deriving (Eq)
+ deriving (Eq, Ord)
instance Show PackageCheck where
show notice = explanation notice
@@ -155,6 +153,7 @@ checkPackage gpkg mpkg =
++ checkFlagNames gpkg
++ checkUnusedFlags gpkg
++ checkUnicodeXFields gpkg
+ ++ checkPathsModuleExtensions pkg
where
pkg = fromMaybe (flattenPackageDescription gpkg) mpkg
@@ -168,6 +167,7 @@ checkConfiguredPackage pkg =
++ checkSourceRepos pkg
++ checkGhcOptions pkg
++ checkCCOptions pkg
+ ++ checkCxxOptions pkg
++ checkCPPOptions pkg
++ checkPaths pkg
++ checkCabalVersion pkg
@@ -265,7 +265,7 @@ checkLibrary pkg lib =
, checkVersion [1,25] (not (null (signatures lib))) $
PackageDistInexcusable $
"To use the 'signatures' field the package needs to specify "
- ++ "at least 'cabal-version: >= 1.25'."
+ ++ "at least 'cabal-version: 2.0'."
-- check that all autogen-modules appear on other-modules or exposed-modules
, check
@@ -319,12 +319,6 @@ checkExecutable pkg exe =
PackageBuildImpossible $
"On executable '" ++ display (exeName exe) ++ "' an 'autogen-module' is not "
++ "on 'other-modules'"
-
- , checkSpecVersion pkg [2,0] (exeScope exe /= ExecutableScopeUnknown) $
- PackageDistSuspiciousWarn $
- "To use the 'scope' field the package needs to specify "
- ++ "at least 'cabal-version: >= 2.0'."
-
]
where
moduleDuplicates = dups (exeModules exe)
@@ -449,20 +443,12 @@ checkFields pkg =
"Package names with the prefix 'z-' are reserved by Cabal and "
++ "cannot be used."
- , check (isNothing (buildType pkg)) $
+ , check (isNothing (buildTypeRaw pkg) && specVersion pkg < mkVersion [2,1]) $
PackageBuildWarning $
"No 'build-type' specified. If you do not need a custom Setup.hs or "
++ "./configure script then use 'build-type: Simple'."
- , case buildType pkg of
- Just (UnknownBuildType unknown) -> Just $
- PackageBuildWarning $
- quote unknown ++ " is not a known 'build-type'. "
- ++ "The known build types are: "
- ++ commaSep (map display knownBuildTypes)
- _ -> Nothing
-
- , check (isJust (setupBuildInfo pkg) && buildType pkg /= Just Custom) $
+ , check (isJust (setupBuildInfo pkg) && buildType pkg /= Custom) $
PackageBuildWarning $
"Ignoring the 'custom-setup' section because the 'build-type' is "
++ "not 'Custom'. Use 'build-type: Custom' if you need to use a "
@@ -546,7 +532,10 @@ checkFields pkg =
++ "for example 'tested-with: GHC==6.10.4, GHC==6.12.3' and not "
++ "'tested-with: GHC==6.10.4 && ==6.12.3'."
- , check (not (null depInternalLibraryWithExtraVersion)) $
+ -- Disabled due to #5119: we generate loads of spurious instances of
+ -- this warning. Re-enabling this check should be part of the fix to
+ -- #5119.
+ , check (False && not (null depInternalLibraryWithExtraVersion)) $
PackageBuildWarning $
"The package has an extraneous version range for a dependency on an "
++ "internal library: "
@@ -658,17 +647,35 @@ checkFields pkg =
checkLicense :: PackageDescription -> [PackageCheck]
-checkLicense pkg =
- catMaybes [
+checkLicense pkg = case licenseRaw pkg of
+ Right l -> checkOldLicense pkg l
+ Left l -> checkNewLicense pkg l
+
+checkNewLicense :: PackageDescription -> SPDX.License -> [PackageCheck]
+checkNewLicense _pkg lic = catMaybes
+ [ check (lic == SPDX.NONE) $
+ PackageDistInexcusable
+ "The 'license' field is missing or is NONE."
+ ]
- check (license pkg == UnspecifiedLicense) $
+checkOldLicense :: PackageDescription -> License -> [PackageCheck]
+checkOldLicense pkg lic = catMaybes
+ [ check (lic == UnspecifiedLicense) $
PackageDistInexcusable
"The 'license' field is missing."
- , check (license pkg == AllRightsReserved) $
+ , check (lic == AllRightsReserved) $
PackageDistSuspicious
"The 'license' is AllRightsReserved. Is that really what you want?"
- , case license pkg of
+
+ , checkVersion [1,4] (lic `notElem` compatLicenses) $
+ PackageDistInexcusable $
+ "Unfortunately the license " ++ quote (prettyShow (license pkg))
+ ++ " messes up the parser in earlier Cabal versions so you need to "
+ ++ "specify 'cabal-version: >= 1.4'. Alternatively if you require "
+ ++ "compatibility with earlier Cabal versions then use 'OtherLicense'."
+
+ , case lic of
UnknownLicense l -> Just $
PackageBuildWarning $
quote ("license: " ++ l) ++ " is not a recognised license. The "
@@ -676,23 +683,23 @@ checkLicense pkg =
++ commaSep (map display knownLicenses)
_ -> Nothing
- , check (license pkg == BSD4) $
+ , check (lic == BSD4) $
PackageDistSuspicious $
"Using 'license: BSD4' is almost always a misunderstanding. 'BSD4' "
++ "refers to the old 4-clause BSD license with the advertising "
++ "clause. 'BSD3' refers the new 3-clause BSD license."
- , case unknownLicenseVersion (license pkg) of
+ , case unknownLicenseVersion (lic) of
Just knownVersions -> Just $
PackageDistSuspicious $
- "'license: " ++ display (license pkg) ++ "' is not a known "
+ "'license: " ++ display (lic) ++ "' is not a known "
++ "version of that license. The known versions are "
++ commaSep (map display knownVersions)
++ ". If this is not a mistake and you think it should be a known "
++ "version then please file a ticket."
_ -> Nothing
- , check (license pkg `notElem` [ AllRightsReserved
+ , check (lic `notElem` [ AllRightsReserved
, UnspecifiedLicense, PublicDomain]
-- AllRightsReserved and PublicDomain are not strictly
-- licenses so don't need license files.
@@ -714,6 +721,15 @@ checkLicense pkg =
where knownVersions = [ v' | Apache (Just v') <- knownLicenses ]
unknownLicenseVersion _ = Nothing
+ checkVersion :: [Int] -> Bool -> PackageCheck -> Maybe PackageCheck
+ checkVersion ver cond pc
+ | specVersion pkg >= mkVersion ver = Nothing
+ | otherwise = check cond pc
+
+ compatLicenses = [ GPL Nothing, LGPL Nothing, AGPL Nothing, BSD3, BSD4
+ , PublicDomain, AllRightsReserved
+ , UnspecifiedLicense, OtherLicense ]
+
checkSourceRepos :: PackageDescription -> [PackageCheck]
checkSourceRepos pkg =
catMaybes $ concat [[
@@ -795,11 +811,16 @@ checkGhcOptions pkg =
PackageDistSuspicious $
"'ghc-options: -main-is' is not portable."
- , checkFlags ["-O0", "-Onot"] $
+ , checkNonTestAndBenchmarkFlags ["-O0", "-Onot"] $
PackageDistSuspicious $
"'ghc-options: -O0' is not needed. "
++ "Use the --disable-optimization configure flag."
+ , checkTestAndBenchmarkFlags ["-O0", "-Onot"] $
+ PackageDistSuspiciousWarn $
+ "'ghc-options: -O0' is not needed. "
+ ++ "Use the --disable-optimization configure flag."
+
, checkFlags [ "-O", "-O1"] $
PackageDistInexcusable $
"'ghc-options: -O' is not needed. "
@@ -886,9 +907,26 @@ checkGhcOptions pkg =
get_ghc_options bi = hcOptions GHC bi ++ hcProfOptions GHC bi
++ hcSharedOptions GHC bi
+ test_ghc_options = concatMap (get_ghc_options . testBuildInfo)
+ (testSuites pkg)
+ benchmark_ghc_options = concatMap (get_ghc_options . benchmarkBuildInfo)
+ (benchmarks pkg)
+ test_and_benchmark_ghc_options = test_ghc_options ++
+ benchmark_ghc_options
+ non_test_and_benchmark_ghc_options = concatMap get_ghc_options
+ (allBuildInfo (pkg { testSuites = []
+ , benchmarks = []
+ }))
+
checkFlags :: [String] -> PackageCheck -> Maybe PackageCheck
checkFlags flags = check (any (`elem` flags) all_ghc_options)
+ checkTestAndBenchmarkFlags :: [String] -> PackageCheck -> Maybe PackageCheck
+ checkTestAndBenchmarkFlags flags = check (any (`elem` flags) test_and_benchmark_ghc_options)
+
+ checkNonTestAndBenchmarkFlags :: [String] -> PackageCheck -> Maybe PackageCheck
+ checkNonTestAndBenchmarkFlags flags = check (any (`elem` flags) non_test_and_benchmark_ghc_options)
+
ghcExtension ('-':'f':name) = case name of
"allow-overlapping-instances" -> enable OverlappingInstances
"no-allow-overlapping-instances" -> disable OverlappingInstances
@@ -928,17 +966,23 @@ checkGhcOptions pkg =
disable e = Just (DisableExtension e)
checkCCOptions :: PackageDescription -> [PackageCheck]
-checkCCOptions pkg =
+checkCCOptions = checkCLikeOptions "C" "cc-options" ccOptions
+
+checkCxxOptions :: PackageDescription -> [PackageCheck]
+checkCxxOptions = checkCLikeOptions "C++" "cxx-options" cxxOptions
+
+checkCLikeOptions :: String -> String -> (BuildInfo -> [String]) -> PackageDescription -> [PackageCheck]
+checkCLikeOptions label prefix accessor pkg =
catMaybes [
- checkAlternatives "cc-options" "include-dirs"
- [ (flag, dir) | flag@('-':'I':dir) <- all_ccOptions ]
+ checkAlternatives prefix "include-dirs"
+ [ (flag, dir) | flag@('-':'I':dir) <- all_cLikeOptions ]
- , checkAlternatives "cc-options" "extra-libraries"
- [ (flag, lib) | flag@('-':'l':lib) <- all_ccOptions ]
+ , checkAlternatives prefix "extra-libraries"
+ [ (flag, lib) | flag@('-':'l':lib) <- all_cLikeOptions ]
- , checkAlternatives "cc-options" "extra-lib-dirs"
- [ (flag, dir) | flag@('-':'L':dir) <- all_ccOptions ]
+ , checkAlternatives prefix "extra-lib-dirs"
+ [ (flag, dir) | flag@('-':'L':dir) <- all_cLikeOptions ]
, checkAlternatives "ld-options" "extra-libraries"
[ (flag, lib) | flag@('-':'l':lib) <- all_ldOptions ]
@@ -948,19 +992,18 @@ checkCCOptions pkg =
, checkCCFlags [ "-O", "-Os", "-O0", "-O1", "-O2", "-O3" ] $
PackageDistSuspicious $
- "'cc-options: -O[n]' is generally not needed. When building with "
- ++ " optimisations Cabal automatically adds '-O2' for C code. "
- ++ "Setting it yourself interferes with the --disable-optimization "
- ++ "flag."
+ "'"++prefix++": -O[n]' is generally not needed. When building with "
+ ++ " optimisations Cabal automatically adds '-O2' for "++label++" code. "
+ ++ "Setting it yourself interferes with the --disable-optimization flag."
]
- where all_ccOptions = [ opts | bi <- allBuildInfo pkg
- , opts <- ccOptions bi ]
+ where all_cLikeOptions = [ opts | bi <- allBuildInfo pkg
+ , opts <- accessor bi ]
all_ldOptions = [ opts | bi <- allBuildInfo pkg
, opts <- ldOptions bi ]
checkCCFlags :: [String] -> PackageCheck -> Maybe PackageCheck
- checkCCFlags flags = check (any (`elem` flags) all_ccOptions)
+ checkCCFlags flags = check (any (`elem` flags) all_cLikeOptions)
checkCPPOptions :: PackageDescription -> [PackageCheck]
checkCPPOptions pkg =
@@ -1014,6 +1057,24 @@ checkPaths pkg =
, (GHC, flags) <- options bi
, path <- flags
, isInsideDist path ]
+ ++
+ [ PackageDistInexcusable $
+ "In the 'data-files' field: " ++ explainGlobSyntaxError pat err
+ | pat <- dataFiles pkg
+ , Left err <- [parseFileGlob (specVersion pkg) pat]
+ ]
+ ++
+ [ PackageDistInexcusable $
+ "In the 'extra-source-files' field: " ++ explainGlobSyntaxError pat err
+ | pat <- extraSrcFiles pkg
+ , Left err <- [parseFileGlob (specVersion pkg) pat]
+ ]
+ ++
+ [ PackageDistInexcusable $
+ "In the 'extra-doc-files' field: " ++ explainGlobSyntaxError pat err
+ | pat <- extraDocFiles pkg
+ , Left err <- [parseFileGlob (specVersion pkg) pat]
+ ]
where
isOutsideTree path = case splitDirectories path of
"..":_ -> True
@@ -1025,12 +1086,12 @@ checkPaths pkg =
_ -> False
-- paths that must be relative
relPaths =
- [ (path, "extra-src-files") | path <- extraSrcFiles pkg ]
- ++ [ (path, "extra-tmp-files") | path <- extraTmpFiles pkg ]
- ++ [ (path, "extra-doc-files") | path <- extraDocFiles pkg ]
- ++ [ (path, "data-files") | path <- dataFiles pkg ]
- ++ [ (path, "data-dir") | path <- [dataDir pkg]]
- ++ [ (path, "license-file") | path <- licenseFiles pkg ]
+ [ (path, "extra-source-files") | path <- extraSrcFiles pkg ]
+ ++ [ (path, "extra-tmp-files") | path <- extraTmpFiles pkg ]
+ ++ [ (path, "extra-doc-files") | path <- extraDocFiles pkg ]
+ ++ [ (path, "data-files") | path <- dataFiles pkg ]
+ ++ [ (path, "data-dir") | path <- [dataDir pkg]]
+ ++ [ (path, "license-file") | path <- licenseFiles pkg ]
++ concat
[ [ (path, "asm-sources") | path <- asmSources bi ]
++ [ (path, "cmm-sources") | path <- cmmSources bi ]
@@ -1084,6 +1145,15 @@ checkCabalVersion pkg =
++ "range syntax rather than a simple version number. Use "
++ "'cabal-version: >= " ++ display (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: " ++ display (specVersion pkg) ++ "'."
+
-- check use of test suite sections
, checkVersion [1,8] (not (null $ testSuites pkg)) $
PackageDistInexcusable $
@@ -1115,31 +1185,31 @@ checkCabalVersion pkg =
"To use the 'extra-doc-files' field the package needs to specify "
++ "at least 'cabal-version: >= 1.18'."
- , checkVersion [1,23]
+ , checkVersion [2,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 >= 1.23'."
+ ++ "the package needs to specify at least 'cabal-version: 2.0'."
-- check use of reexported-modules sections
, checkVersion [1,21]
(any (not.null.reexportedModules) (allLibraries pkg)) $
PackageDistInexcusable $
"To use the 'reexported-module' field the package needs to specify "
- ++ "at least 'cabal-version: >= 1.21'."
+ ++ "at least 'cabal-version: >= 1.22'."
-- check use of thinning and renaming
, checkVersion [1,25] usesBackpackIncludes $
PackageDistInexcusable $
"To use the 'mixins' field the package needs to specify "
- ++ "at least 'cabal-version: >= 1.25'."
+ ++ "at least 'cabal-version: 2.0'."
-- check use of 'extra-framework-dirs' field
, checkVersion [1,23] (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"
- ++ " at least 'cabal-version: >= 1.23'."
+ ++ " at least 'cabal-version: >= 1.24'."
-- check use of default-extensions field
-- don't need to do the equivalent check for other-extensions
@@ -1187,7 +1257,7 @@ checkCabalVersion pkg =
++ "'build-depends' field: "
++ commaSep (map display depsUsingMajorBoundSyntax)
++ ". To use this new syntax the package need to specify at least "
- ++ "'cabal-version: >= 2.0'. Alternatively, if broader compatibility "
+ ++ "'cabal-version: 2.0'. Alternatively, if broader compatibility "
++ "is important then use: " ++ commaSep
[ display (Dependency name (eliminateMajorBoundSyntax versionRange))
| Dependency name versionRange <- depsUsingMajorBoundSyntax ]
@@ -1208,7 +1278,7 @@ checkCabalVersion pkg =
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 $
@@ -1229,25 +1299,6 @@ checkCabalVersion pkg =
[ display (Dependency name (eliminateWildcardSyntax versionRange))
| Dependency name versionRange <- testedWithUsingWildcardSyntax ]
- -- check use of "data-files: data/*.txt" syntax
- , checkVersion [1,6] (not (null dataFilesUsingGlobSyntax)) $
- PackageDistInexcusable $
- "Using wildcards like "
- ++ commaSep (map quote $ take 3 dataFilesUsingGlobSyntax)
- ++ " in the 'data-files' field requires 'cabal-version: >= 1.6'. "
- ++ "Alternatively if you require compatibility with earlier Cabal "
- ++ "versions then list all the files explicitly."
-
- -- check use of "extra-source-files: mk/*.in" syntax
- , checkVersion [1,6] (not (null extraSrcFilesUsingGlobSyntax)) $
- PackageDistInexcusable $
- "Using wildcards like "
- ++ commaSep (map quote $ take 3 extraSrcFilesUsingGlobSyntax)
- ++ " in the 'extra-source-files' field requires "
- ++ "'cabal-version: >= 1.6'. Alternatively if you require "
- ++ "compatibility with earlier Cabal versions then list all the files "
- ++ "explicitly."
-
-- check use of "source-repository" section
, checkVersion [1,6] (not (null (sourceRepos pkg))) $
PackageDistInexcusable $
@@ -1255,14 +1306,6 @@ checkCabalVersion pkg =
++ "Unfortunately it messes up the parser in earlier Cabal versions "
++ "so you need to specify 'cabal-version: >= 1.6'."
- -- check for new licenses
- , checkVersion [1,4] (license pkg `notElem` compatLicenses) $
- PackageDistInexcusable $
- "Unfortunately the license " ++ quote (display (license pkg))
- ++ " messes up the parser in earlier Cabal versions so you need to "
- ++ "specify 'cabal-version: >= 1.4'. Alternatively if you require "
- ++ "compatibility with earlier Cabal versions then use 'OtherLicense'."
-
-- check for new language extensions
, checkVersion [1,2,3] (not (null mentionedExtensionsThatNeedCabal12)) $
PackageDistInexcusable $
@@ -1284,9 +1327,9 @@ checkCabalVersion pkg =
, check (specVersion pkg >= mkVersion [1,23]
&& isNothing (setupBuildInfo pkg)
- && buildType pkg == Just Custom) $
+ && buildType pkg == Custom) $
PackageBuildWarning $
- "Packages using 'cabal-version: >= 1.23' with 'build-type: Custom' "
+ "Packages using 'cabal-version: >= 1.24' with 'build-type: Custom' "
++ "must use a 'custom-setup' section with a 'setup-depends' field "
++ "that specifies the dependencies of the Setup.hs script itself. "
++ "The 'setup-depends' field uses the same syntax as 'build-depends', "
@@ -1294,10 +1337,10 @@ checkCabalVersion pkg =
, check (specVersion pkg < mkVersion [1,23]
&& isNothing (setupBuildInfo pkg)
- && buildType pkg == Just Custom) $
+ && buildType pkg == Custom) $
PackageDistSuspiciousWarn $
- "From version 1.23 cabal supports specifiying explicit dependencies "
- ++ "for Custom setup scripts. Consider using cabal-version >= 1.23 and "
+ "From version 1.24 cabal supports specifiying explicit dependencies "
+ ++ "for Custom setup scripts. Consider using cabal-version >= 1.24 and "
++ "adding a 'custom-setup' section with a 'setup-depends' field "
++ "that specifies the dependencies of the Setup.hs script itself. "
++ "The 'setup-depends' field uses the same syntax as 'build-depends', "
@@ -1307,7 +1350,7 @@ checkCabalVersion pkg =
&& elem (autogenPathsModuleName pkg) allModuleNames
&& not (elem (autogenPathsModuleName pkg) allModuleNamesAutogen) ) $
PackageDistInexcusable $
- "Packages using 'cabal-version: >= 1.25' and the autogenerated "
+ "Packages using 'cabal-version: 2.0' and the autogenerated "
++ "module Paths_* must include it also on the 'autogen-modules' field "
++ "besides 'exposed-modules' and 'other-modules'. This specifies that "
++ "the module does not come with the package and is generated on "
@@ -1326,14 +1369,9 @@ checkCabalVersion pkg =
| otherwise = check cond pc
buildInfoField field = map field (allBuildInfo pkg)
- dataFilesUsingGlobSyntax = filter usesGlobSyntax (dataFiles pkg)
- extraSrcFilesUsingGlobSyntax = filter usesGlobSyntax (extraSrcFiles pkg)
- usesGlobSyntax str = case parseFileGlob str of
- Just (FileGlob _ _) -> True
- _ -> False
versionRangeExpressions =
- [ dep | dep@(Dependency _ vr) <- buildDepends pkg
+ [ dep | dep@(Dependency _ vr) <- allBuildDepends pkg
, usesNewVersionRangeSyntax vr ]
testedWithVersionRangeExpressions =
@@ -1361,11 +1399,11 @@ checkCabalVersion pkg =
alg (VersionRangeParensF _) = 3
alg _ = 1 :: Int
- depsUsingWildcardSyntax = [ dep | dep@(Dependency _ vr) <- buildDepends pkg
+ depsUsingWildcardSyntax = [ dep | dep@(Dependency _ vr) <- allBuildDepends pkg
, usesWildcardSyntax vr ]
- depsUsingMajorBoundSyntax = [ dep | dep@(Dependency _ vr) <- buildDepends pkg
- , usesMajorBoundSyntax vr ]
+ depsUsingMajorBoundSyntax = [ dep | dep@(Dependency _ vr) <- allBuildDepends pkg
+ , usesMajorBoundSyntax vr ]
usesBackpackIncludes = any (not . null . mixins) (allBuildInfo pkg)
@@ -1408,10 +1446,6 @@ checkCabalVersion pkg =
(orLaterVersion v) (earlierVersion (majorUpperBound v))
embed vr = embedVersionRange vr
- compatLicenses = [ GPL Nothing, LGPL Nothing, AGPL Nothing, BSD3, BSD4
- , PublicDomain, AllRightsReserved
- , UnspecifiedLicense, OtherLicense ]
-
mentionedExtensions = [ ext | bi <- allBuildInfo pkg
, ext <- allExtensions bi ]
mentionedExtensionsThatNeedCabal12 =
@@ -1515,7 +1549,7 @@ checkPackageVersions pkg =
foldr intersectVersionRanges anyVersion baseDeps
where
baseDeps =
- [ vr | Dependency pname vr <- buildDepends pkg'
+ [ vr | Dependency pname vr <- allBuildDepends pkg'
, pname == mkPackageName "base" ]
-- Just in case finalizePD fails for any reason,
@@ -1629,9 +1663,39 @@ checkUnicodeXFields gpd
xfields :: [(String,String)]
xfields = DList.runDList $ mconcat
[ toDListOf (L.packageDescription . L.customFieldsPD . traverse) gpd
- , toDListOf (L.buildInfos . L.customFieldsBI . traverse) gpd
+ , toDListOf (L.traverseBuildInfos . L.customFieldsBI . traverse) gpd
]
+-- | cabal-version <2.2 + Paths_module + default-extensions: doesn't build.
+checkPathsModuleExtensions :: PackageDescription -> [PackageCheck]
+checkPathsModuleExtensions pd
+ | specVersion pd >= mkVersion [2,1] = []
+ | any checkBI (allBuildInfo pd) || any checkLib (allLibraries pd)
+ = return $ PackageBuildImpossible $ unwords
+ [ "The package uses RebindableSyntax with OverloadedStrings or OverloadedLists"
+ , "in default-extensions, and also Paths_ autogen module."
+ , "That configuration is known to cause compile failures with Cabal < 2.2."
+ , "To use these default-extensions with Paths_ autogen module"
+ , "specify at least 'cabal-version: 2.2'."
+ ]
+ | otherwise = []
+ where
+ mn = autogenPathsModuleName pd
+
+ checkLib :: Library -> Bool
+ checkLib l = mn `elem` exposedModules l && checkExts (l ^. L.defaultExtensions)
+
+ checkBI :: BuildInfo -> Bool
+ checkBI bi =
+ (mn `elem` otherModules bi || mn `elem` autogenModules bi) &&
+ checkExts (bi ^. L.defaultExtensions)
+
+ checkExts exts = rebind `elem` exts && (strings `elem` exts || lists `elem` exts)
+ where
+ rebind = EnableExtension RebindableSyntax
+ strings = EnableExtension OverloadedStrings
+ lists = EnableExtension OverloadedLists
+
checkDevelopmentOnlyFlagsBuildInfo :: BuildInfo -> [PackageCheck]
checkDevelopmentOnlyFlagsBuildInfo bi =
catMaybes [
@@ -1650,6 +1714,12 @@ checkDevelopmentOnlyFlagsBuildInfo bi =
++ "add new warnings. "
++ extraExplanation
+ , check (has_J) $
+ PackageDistInexcusable $
+ "'ghc-options: -j[N]' can make sense for specific user's setup,"
+ ++ " but it is not appropriate for a distributed package."
+ ++ extraExplanation
+
, checkFlags ["-fdefer-type-errors"] $
PackageDistInexcusable $
"'ghc-options: -fdefer-type-errors' is fine during development but "
@@ -1687,6 +1757,13 @@ checkDevelopmentOnlyFlagsBuildInfo bi =
has_Werror = "-Werror" `elem` ghc_options
has_Wall = "-Wall" `elem` ghc_options
has_W = "-W" `elem` ghc_options
+ has_J = any
+ (\o -> case o of
+ "-j" -> True
+ ('-' : 'j' : d : _) -> isDigit d
+ _ -> False
+ )
+ ghc_options
ghc_options = hcOptions GHC bi ++ hcProfOptions GHC bi
++ hcSharedOptions GHC bi
@@ -1767,14 +1844,20 @@ 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 :: PackageDescription -> FilePath -> NoCallStackIO [PackageCheck]
-checkPackageFiles pkg root = checkPackageContent checkFilesIO pkg
+checkPackageFiles :: Verbosity -> PackageDescription -> FilePath -> NoCallStackIO [PackageCheck]
+checkPackageFiles verbosity pkg root = do
+ contentChecks <- checkPackageContent checkFilesIO pkg
+ preDistributionChecks <- checkPackageFilesPreDistribution verbosity pkg root
+ -- Sort because different platforms will provide files from
+ -- `getDirectoryContents` in different orders, and we'd like to be
+ -- stable for test output.
+ return (sort contentChecks ++ sort preDistributionChecks)
where
checkFilesIO = CheckPackageContentOps {
doesFileExist = System.doesFileExist . relative,
doesDirectoryExist = System.doesDirectoryExist . relative,
getDirectoryContents = System.Directory.getDirectoryContents . relative,
- getFileContents = BS.readFile
+ getFileContents = BS.readFile . relative
}
relative path = root </> path
@@ -1904,7 +1987,7 @@ checkSetupExists :: Monad m => CheckPackageContentOps m
-> PackageDescription
-> m (Maybe PackageCheck)
checkSetupExists ops pkg = do
- let simpleBuild = buildType pkg == Just Simple
+ let simpleBuild = buildType pkg == Simple
hsexists <- doesFileExist ops "Setup.hs"
lhsexists <- doesFileExist ops "Setup.lhs"
return $ check (not simpleBuild && not hsexists && not lhsexists) $
@@ -1914,13 +1997,14 @@ checkSetupExists ops pkg = do
checkConfigureExists :: Monad m => CheckPackageContentOps m
-> PackageDescription
-> m (Maybe PackageCheck)
-checkConfigureExists ops PackageDescription { buildType = Just Configure } = do
- exists <- doesFileExist ops "configure"
- return $ check (not exists) $
- PackageBuildWarning $
- "The 'build-type' is 'Configure' but there is no 'configure' script. "
- ++ "You probably need to run 'autoreconf -i' to generate it."
-checkConfigureExists _ _ = return Nothing
+checkConfigureExists ops pd
+ | buildType pd == Configure = do
+ exists <- doesFileExist ops "configure"
+ return $ check (not exists) $
+ PackageBuildWarning $
+ "The 'build-type' is 'Configure' but there is no 'configure' script. "
+ ++ "You probably need to run 'autoreconf -i' to generate it."
+ | otherwise = return Nothing
checkLocalPathsExist :: Monad m => CheckPackageContentOps m
-> PackageDescription
@@ -2063,6 +2147,82 @@ checkTarPath path
++ "Files with an empty name cannot be stored in a tar archive or in "
++ "standard file systems."
+-- --------------------------------------------------------------
+-- * Checks for missing content and other pre-distribution checks
+-- --------------------------------------------------------------
+
+-- | Similar to 'checkPackageContent', 'checkPackageFilesPreDistribution'
+-- inspects the files included in the package, but is primarily looking for
+-- files in the working tree that may have been missed or other similar
+-- problems that can only be detected pre-distribution.
+--
+-- Because Hackage necessarily checks the uploaded tarball, it is too late to
+-- 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]
+-- 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!
+checkPackageFilesPreDistribution = checkGlobFiles
+
+-- | Discover problems with the package's wildcards.
+checkGlobFiles :: Verbosity
+ -> PackageDescription
+ -> FilePath
+ -> NoCallStackIO [PackageCheck]
+checkGlobFiles verbosity pkg root =
+ fmap concat $ for allGlobs $ \(field, dir, glob) ->
+ -- Note: we just skip over parse errors here; they're reported elsewhere.
+ case parseFileGlob (specVersion pkg) glob of
+ Left _ -> return []
+ Right parsedGlob -> do
+ results <- runDirFileGlob verbosity (root </> dir) parsedGlob
+ let individualWarnings = results >>= getWarning field glob
+ noMatchesWarning =
+ [ PackageDistSuspiciousWarn $
+ "In '" ++ field ++ "': the pattern '" ++ glob ++ "' does not"
+ ++ " match any files."
+ | all (not . suppressesNoMatchesWarning) results
+ ]
+ return (noMatchesWarning ++ individualWarnings)
+ where
+ adjustedDataDir = if null (dataDir pkg) then "." else dataDir pkg
+ allGlobs = concat
+ [ (,,) "extra-source-files" "." <$> extraSrcFiles pkg
+ , (,,) "extra-doc-files" "." <$> extraDocFiles pkg
+ , (,,) "data-files" adjustedDataDir <$> dataFiles pkg
+ ]
+
+ -- If there's a missing directory in play, since our globs don't
+ -- (currently) support disjunction, that will always mean there are no
+ -- matches. The no matches error in this case is strictly less informative
+ -- than the missing directory error, so sit on it.
+ suppressesNoMatchesWarning (GlobMatch _) = True
+ suppressesNoMatchesWarning (GlobWarnMultiDot _) = False
+ suppressesNoMatchesWarning (GlobMissingDirectory _) = True
+
+ getWarning :: String -> FilePath -> GlobResult FilePath -> [PackageCheck]
+ getWarning _ _ (GlobMatch _) =
+ []
+ -- Before Cabal 2.4, the extensions of globs had to match the file
+ -- exactly. This has been relaxed in 2.4 to allow matching only the
+ -- suffix. This warning detects when pre-2.4 package descriptions are
+ -- omitting files purely because of the stricter check.
+ getWarning field glob (GlobWarnMultiDot file) =
+ [ PackageDistSuspiciousWarn $
+ "In '" ++ field ++ "': the pattern '" ++ glob ++ "' does not"
+ ++ " match the file '" ++ file ++ "' because the extensions do not"
+ ++ " exactly match (e.g., foo.en.html does not exactly match *.html)."
+ ++ " To enable looser suffix-only matching, set 'cabal-version: 2.4' or higher."
+ ]
+ getWarning field glob (GlobMissingDirectory dir) =
+ [ PackageDistSuspiciousWarn $
+ "In '" ++ field ++ "': the pattern '" ++ glob ++ "' attempts to"
+ ++ " match files in the directory '" ++ dir ++ "', but there is no"
+ ++ " directory by that name."
+ ]
+
-- ------------------------------------------------------------
-- * Utils
-- ------------------------------------------------------------
diff --git a/cabal/Cabal/Distribution/PackageDescription/Configuration.hs b/cabal/Cabal/Distribution/PackageDescription/Configuration.hs
index 5efcfc7..5d9249e 100644
--- a/cabal/Cabal/Distribution/PackageDescription/Configuration.hs
+++ b/cabal/Cabal/Distribution/PackageDescription/Configuration.hs
@@ -37,6 +37,12 @@ module Distribution.PackageDescription.Configuration (
import Prelude ()
import Distribution.Compat.Prelude
+-- lens
+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
@@ -44,6 +50,7 @@ import Distribution.Compiler
import Distribution.System
import Distribution.Simple.Utils
import Distribution.Text
+import Distribution.Compat.Lens
import Distribution.Compat.ReadP as ReadP hiding ( char )
import qualified Distribution.Compat.ReadP as ReadP ( char )
import Distribution.Types.ComponentRequestedSpec
@@ -57,7 +64,7 @@ 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.Map.Lazy as Map
import Data.Tree ( Tree(Node) )
------------------------------------------------------------------------------
@@ -352,18 +359,18 @@ overallDependencies enabled (TargetSet targets) = mconcat depss
-- | Collect up the targets in a TargetSet of tagged targets, storing the
-- dependencies as we go.
flattenTaggedTargets :: TargetSet PDTagged -> (Maybe Library, [(UnqualComponentName, Component)])
-flattenTaggedTargets (TargetSet targets) = foldr untag (Nothing, []) targets
- where
- untag (_, Lib _) (Just _, _) = userBug "Only one library expected"
- untag (_, Lib l) (Nothing, comps) = (Just l, comps)
- untag (_, SubComp n c) (mb_lib, comps)
- | any ((== n) . fst) comps =
- userBug $ "There exist several components with the same name: '" ++ unUnqualComponentName n ++ "'"
-
- | otherwise = (mb_lib, (n, c) : comps)
-
- untag (_, PDNull) x = x -- actually this should not happen, but let's be liberal
-
+flattenTaggedTargets (TargetSet targets) = foldr untag (Nothing, []) targets where
+ untag (depMap, pdTagged) accum = case (pdTagged, accum) of
+ (Lib _, (Just _, _)) -> userBug "Only one library expected"
+ (Lib l, (Nothing, comps)) -> (Just $ redoBD l, comps)
+ (SubComp n c, (mb_lib, comps))
+ | any ((== n) . fst) comps ->
+ userBug $ "There exist several components with the same name: '" ++ display n ++ "'"
+ | otherwise -> (mb_lib, (n, redoBD c) : comps)
+ (PDNull, x) -> x -- actually this should not happen, but let's be liberal
+ where
+ redoBD :: L.HasBuildInfo a => a -> a
+ redoBD = set L.targetBuildDepends $ fromDepMap depMap
------------------------------------------------------------------------------
-- Convert GenericPackageDescription to PackageDescription
@@ -448,7 +455,6 @@ finalizePD userflags enabled satisfyDep
, executables = exes'
, testSuites = tests'
, benchmarks = bms'
- , buildDepends = fromDepMap (overallDependencies enabled targetSet)
}
, flagVals )
where
@@ -472,7 +478,7 @@ finalizePD userflags enabled satisfyDep
then DepOk
else MissingDeps missingDeps
-{-# DEPRECATED finalizePackageDescription "This function now always assumes tests and benchmarks are disabled; use finalizePD with ComponentRequestedSpec to specify something more specific." #-}
+{-# DEPRECATED finalizePackageDescription "This function now always assumes tests and benchmarks are disabled; use finalizePD with ComponentRequestedSpec to specify something more specific. This symbol will be removed in Cabal-3.0 (est. Mar 2019)." #-}
finalizePackageDescription ::
FlagAssignment -- ^ Explicitly specified flag assignments
-> (Dependency -> Bool) -- ^ Is a given dependency satisfiable from the set of
@@ -518,38 +524,25 @@ flattenPackageDescription
, executables = reverse exes
, testSuites = reverse tests
, benchmarks = reverse bms
- , buildDepends = ldeps
- ++ reverse sub_ldeps
- ++ reverse pldeps
- ++ reverse edeps
- ++ reverse tdeps
- ++ reverse bdeps
}
where
- (mlib, ldeps) = case mlib0 of
- Just lib -> let (l,ds) = ignoreConditions lib in
- (Just ((libFillInDefaults l) { libName = Nothing }), ds)
- Nothing -> (Nothing, [])
- (sub_libs, sub_ldeps) = foldr flattenLib ([],[]) sub_libs0
- (flibs, pldeps) = foldr flattenFLib ([],[]) flibs0
- (exes, edeps) = foldr flattenExe ([],[]) exes0
- (tests, tdeps) = foldr flattenTst ([],[]) tests0
- (bms, bdeps) = foldr flattenBm ([],[]) bms0
- flattenLib (n, t) (es, ds) =
- let (e, ds') = ignoreConditions t in
- ( (libFillInDefaults $ e { libName = Just n, libExposed = False }) : es, ds' ++ ds )
- flattenFLib (n, t) (es, ds) =
- let (e, ds') = ignoreConditions t in
- ( (flibFillInDefaults $ e { foreignLibName = n }) : es, ds' ++ ds )
- flattenExe (n, t) (es, ds) =
- let (e, ds') = ignoreConditions t in
- ( (exeFillInDefaults $ e { exeName = n }) : es, ds' ++ ds )
- flattenTst (n, t) (es, ds) =
- let (e, ds') = ignoreConditions t in
- ( (testFillInDefaults $ e { testName = n }) : es, ds' ++ ds )
- flattenBm (n, t) (es, ds) =
- let (e, ds') = ignoreConditions t in
- ( (benchFillInDefaults $ e { benchmarkName = n }) : es, ds' ++ ds )
+ mlib = f <$> mlib0
+ where f lib = (libFillInDefaults . fst . ignoreConditions $ lib) { libName = Nothing }
+ sub_libs = flattenLib <$> sub_libs0
+ flibs = flattenFLib <$> flibs0
+ exes = flattenExe <$> exes0
+ tests = flattenTst <$> tests0
+ bms = flattenBm <$> bms0
+ flattenLib (n, t) = libFillInDefaults $ (fst $ ignoreConditions t)
+ { libName = Just n, libExposed = False }
+ flattenFLib (n, t) = flibFillInDefaults $ (fst $ ignoreConditions t)
+ { foreignLibName = n }
+ flattenExe (n, t) = exeFillInDefaults $ (fst $ ignoreConditions t)
+ { exeName = n }
+ flattenTst (n, t) = testFillInDefaults $ (fst $ ignoreConditions t)
+ { testName = n }
+ flattenBm (n, t) = benchFillInDefaults $ (fst $ ignoreConditions t)
+ { benchmarkName = n }
-- This is in fact rather a hack. The original version just overrode the
-- default values, however, when adding conditions we had to switch to a
@@ -590,79 +583,17 @@ transformAllBuildInfos :: (BuildInfo -> BuildInfo)
-> (SetupBuildInfo -> SetupBuildInfo)
-> GenericPackageDescription
-> GenericPackageDescription
-transformAllBuildInfos onBuildInfo onSetupBuildInfo gpd = gpd'
- where
- onLibrary lib = lib { libBuildInfo = onBuildInfo $ libBuildInfo lib }
- onExecutable exe = exe { buildInfo = onBuildInfo $ buildInfo exe }
- onTestSuite tst = tst { testBuildInfo = onBuildInfo $ testBuildInfo tst }
- onBenchmark bmk = bmk { benchmarkBuildInfo =
- onBuildInfo $ benchmarkBuildInfo bmk }
-
- pd = packageDescription gpd
- pd' = pd {
- library = fmap onLibrary (library pd),
- subLibraries = map onLibrary (subLibraries pd),
- executables = map onExecutable (executables pd),
- testSuites = map onTestSuite (testSuites pd),
- benchmarks = map onBenchmark (benchmarks pd),
- setupBuildInfo = fmap onSetupBuildInfo (setupBuildInfo pd)
- }
-
- gpd' = transformAllCondTrees onLibrary onExecutable
- onTestSuite onBenchmark id
- $ gpd { packageDescription = pd' }
+transformAllBuildInfos onBuildInfo onSetupBuildInfo =
+ over L.traverseBuildInfos onBuildInfo
+ . over (L.packageDescription . L.setupBuildInfo . traverse) onSetupBuildInfo
-- | Walk a 'GenericPackageDescription' and apply @f@ to all nested
-- @build-depends@ fields.
transformAllBuildDepends :: (Dependency -> Dependency)
-> GenericPackageDescription
-> GenericPackageDescription
-transformAllBuildDepends f gpd = gpd'
- where
- onBI bi = bi { targetBuildDepends = map f $ targetBuildDepends bi }
- onSBI stp = stp { setupDepends = map f $ setupDepends stp }
- onPD pd = pd { buildDepends = map f $ buildDepends pd }
-
- pd' = onPD $ packageDescription gpd
- gpd' = transformAllCondTrees id id id id (map f)
- . transformAllBuildInfos onBI onSBI
- $ gpd { packageDescription = pd' }
-
--- | Walk all 'CondTree's inside a 'GenericPackageDescription' and apply
--- appropriate transformations to all nodes. Helper function used by
--- 'transformAllBuildDepends' and 'transformAllBuildInfos'.
-transformAllCondTrees :: (Library -> Library)
- -> (Executable -> Executable)
- -> (TestSuite -> TestSuite)
- -> (Benchmark -> Benchmark)
- -> ([Dependency] -> [Dependency])
- -> GenericPackageDescription -> GenericPackageDescription
-transformAllCondTrees onLibrary onExecutable
- onTestSuite onBenchmark onDepends gpd = gpd'
- where
- gpd' = gpd {
- condLibrary = condLib',
- condSubLibraries = condSubLibs',
- condExecutables = condExes',
- condTestSuites = condTests',
- condBenchmarks = condBenchs'
- }
-
- condLib = condLibrary gpd
- condSubLibs = condSubLibraries gpd
- condExes = condExecutables gpd
- condTests = condTestSuites gpd
- condBenchs = condBenchmarks gpd
-
- condLib' = fmap (onCondTree onLibrary) condLib
- condSubLibs' = map (mapSnd $ onCondTree onLibrary) condSubLibs
- condExes' = map (mapSnd $ onCondTree onExecutable) condExes
- condTests' = map (mapSnd $ onCondTree onTestSuite) condTests
- condBenchs' = map (mapSnd $ onCondTree onBenchmark) condBenchs
-
- mapSnd :: (a -> b) -> (c,a) -> (c,b)
- mapSnd = fmap
-
- onCondTree :: (a -> b) -> CondTree v [Dependency] a
- -> CondTree v [Dependency] b
- onCondTree g = mapCondTree g onDepends id
+transformAllBuildDepends f =
+ over (L.traverseBuildInfos . L.targetBuildDepends . traverse) f
+ . over (L.packageDescription . L.setupBuildInfo . traverse . L.setupDepends . traverse) f
+ -- cannot be point-free as normal because of higher rank
+ . over (\f' -> L.allCondTrees $ traverseCondTreeC f') (map f)
diff --git a/cabal/Cabal/Distribution/PackageDescription/FieldGrammar.hs b/cabal/Cabal/Distribution/PackageDescription/FieldGrammar.hs
index 5788838..0aedbc3 100644
--- a/cabal/Cabal/Distribution/PackageDescription/FieldGrammar.hs
+++ b/cabal/Cabal/Distribution/PackageDescription/FieldGrammar.hs
@@ -45,7 +45,6 @@ import Prelude ()
import Distribution.Compiler (CompilerFlavor (..))
import Distribution.FieldGrammar
-import Distribution.License (License (..))
import Distribution.ModuleName (ModuleName)
import Distribution.Package
import Distribution.PackageDescription
@@ -53,11 +52,14 @@ import Distribution.Parsec.Common
import Distribution.Parsec.Newtypes
import Distribution.Parsec.ParseResult
import Distribution.Text (display)
+import Distribution.Types.ExecutableScope
import Distribution.Types.ForeignLib
import Distribution.Types.ForeignLibType
import Distribution.Types.UnqualComponentName
import Distribution.Version (anyVersion)
+import qualified Distribution.SPDX as SPDX
+
import qualified Distribution.Types.Lens as L
-------------------------------------------------------------------------------
@@ -68,8 +70,9 @@ packageDescriptionFieldGrammar
:: (FieldGrammar g, Applicative (g PackageDescription), Applicative (g PackageIdentifier))
=> g PackageDescription PackageDescription
packageDescriptionFieldGrammar = PackageDescription
- <$> blurFieldGrammar L.package packageIdentifierGrammar
- <*> optionalFieldDef "license" L.license UnspecifiedLicense
+ <$> optionalFieldDefAla "cabal-version" SpecVersion L.specVersionRaw (Right anyVersion)
+ <*> blurFieldGrammar L.package packageIdentifierGrammar
+ <*> optionalFieldDefAla "license" SpecLicense L.licenseRaw (Left SPDX.NONE)
<*> licenseFilesGrammar
<*> optionalFieldDefAla "copyright" FreeText L.copyright ""
<*> optionalFieldDefAla "maintainer" FreeText L.maintainer ""
@@ -84,9 +87,7 @@ packageDescriptionFieldGrammar = PackageDescription
<*> optionalFieldDefAla "description" FreeText L.description ""
<*> optionalFieldDefAla "category" FreeText L.category ""
<*> prefixedFields "x-" L.customFieldsPD
- <*> pure [] -- build-depends
- <*> optionalFieldDefAla "cabal-version" SpecVersion L.specVersionRaw (Right anyVersion)
- <*> optionalField "build-type" L.buildType
+ <*> optionalField "build-type" L.buildTypeRaw
<*> pure Nothing -- custom-setup
-- components
<*> pure Nothing -- lib
@@ -125,6 +126,7 @@ libraryFieldGrammar n = Library n
<$> monoidalFieldAla "exposed-modules" (alaList' VCat MQuoted) L.exposedModules
<*> monoidalFieldAla "reexported-modules" (alaList CommaVCat) L.reexportedModules
<*> monoidalFieldAla "signatures" (alaList' VCat MQuoted) L.signatures
+ ^^^ availableSince [2,0] []
<*> booleanFieldDef "exposed" L.libExposed True
<*> blurFieldGrammar L.libBuildInfo buildInfoFieldGrammar
{-# SPECIALIZE libraryFieldGrammar :: Maybe UnqualComponentName -> ParsecFieldGrammar' Library #-}
@@ -157,7 +159,8 @@ executableFieldGrammar
executableFieldGrammar n = Executable n
-- main-is is optional as conditional blocks don't have it
<$> optionalFieldDefAla "main-is" FilePathNT L.modulePath ""
- <*> monoidalField "scope" L.exeScope
+ <*> optionalFieldDef "scope" L.exeScope ExecutablePublic
+ ^^^ availableSince [2,0] ExecutablePublic
<*> blurFieldGrammar L.buildInfo buildInfoFieldGrammar
{-# SPECIALIZE executableFieldGrammar :: UnqualComponentName -> ParsecFieldGrammar' Executable #-}
{-# SPECIALIZE executableFieldGrammar :: UnqualComponentName -> PrettyFieldGrammar' Executable #-}
@@ -175,6 +178,9 @@ data TestSuiteStanza = TestSuiteStanza
, _testStanzaBuildInfo :: BuildInfo
}
+instance L.HasBuildInfo TestSuiteStanza where
+ buildInfo = testStanzaBuildInfo
+
testStanzaTestType :: Lens' TestSuiteStanza (Maybe TestType)
testStanzaTestType f s = fmap (\x -> s { _testStanzaTestType = x }) (f (_testStanzaTestType s))
{-# INLINE testStanzaTestType #-}
@@ -274,6 +280,9 @@ data BenchmarkStanza = BenchmarkStanza
, _benchmarkStanzaBuildInfo :: BuildInfo
}
+instance L.HasBuildInfo BenchmarkStanza where
+ buildInfo = benchmarkStanzaBuildInfo
+
benchmarkStanzaBenchmarkType :: Lens' BenchmarkStanza (Maybe BenchmarkType)
benchmarkStanzaBenchmarkType f s = fmap (\x -> s { _benchmarkStanzaBenchmarkType = x }) (f (_benchmarkStanzaBenchmarkType s))
{-# INLINE benchmarkStanzaBenchmarkType #-}
@@ -358,12 +367,17 @@ buildInfoFieldGrammar = BuildInfo
<*> monoidalFieldAla "build-tools" (alaList CommaFSep) L.buildTools
^^^ deprecatedSince [2,0] "Please use 'build-tool-depends' field"
<*> monoidalFieldAla "build-tool-depends" (alaList CommaFSep) L.buildToolDepends
- ^^^ availableSince [2,0]
+ -- {- ^^^ availableSince [2,0] [] -}
+ -- here, we explicitly want to recognise build-tool-depends for all Cabal files
+ -- as otherwise cabal new-build cannot really work.
+ --
+ -- I.e. we don't want trigger unknown field warning
<*> monoidalFieldAla "cpp-options" (alaList' NoCommaFSep Token') L.cppOptions
<*> monoidalFieldAla "asm-options" (alaList' NoCommaFSep Token') L.asmOptions
<*> monoidalFieldAla "cmm-options" (alaList' NoCommaFSep Token') L.cmmOptions
<*> monoidalFieldAla "cc-options" (alaList' NoCommaFSep Token') L.ccOptions
<*> monoidalFieldAla "cxx-options" (alaList' NoCommaFSep Token') L.cxxOptions
+ ^^^ availableSince [2,1] [] -- TODO change to 2,2 when version is bumped
<*> monoidalFieldAla "ld-options" (alaList' NoCommaFSep Token') L.ldOptions
<*> monoidalFieldAla "pkgconfig-depends" (alaList CommaFSep) L.pkgconfigDepends
<*> monoidalFieldAla "frameworks" (alaList' FSep Token) L.frameworks
@@ -372,10 +386,12 @@ buildInfoFieldGrammar = BuildInfo
<*> monoidalFieldAla "cmm-sources" (alaList' VCat FilePathNT) L.cmmSources
<*> monoidalFieldAla "c-sources" (alaList' VCat FilePathNT) L.cSources
<*> monoidalFieldAla "cxx-sources" (alaList' VCat FilePathNT) L.cxxSources
+ ^^^ availableSince [2,1] [] -- TODO change to 2,2 when version is bumped
<*> monoidalFieldAla "js-sources" (alaList' VCat FilePathNT) L.jsSources
<*> hsSourceDirsGrammar
<*> monoidalFieldAla "other-modules" (alaList' VCat MQuoted) L.otherModules
<*> monoidalFieldAla "virtual-modules" (alaList' VCat MQuoted) L.virtualModules
+ ^^^ availableSince [2,1] [] -- TODO change to 2,2 when version is bumped
<*> monoidalFieldAla "autogen-modules" (alaList' VCat MQuoted) L.autogenModules
<*> optionalFieldAla "default-language" MQuoted L.defaultLanguage
<*> monoidalFieldAla "other-languages" (alaList' FSep MQuoted) L.otherLanguages
@@ -398,6 +414,7 @@ buildInfoFieldGrammar = BuildInfo
<*> prefixedFields "x-" L.customFieldsBI
<*> monoidalFieldAla "build-depends" (alaList CommaVCat) L.targetBuildDepends
<*> monoidalFieldAla "mixins" (alaList CommaVCat) L.mixins
+ ^^^ availableSince [2,0] []
{-# SPECIALIZE buildInfoFieldGrammar :: ParsecFieldGrammar' BuildInfo #-}
{-# SPECIALIZE buildInfoFieldGrammar :: PrettyFieldGrammar' BuildInfo #-}
@@ -415,17 +432,18 @@ optionsFieldGrammar
optionsFieldGrammar = combine
<$> monoidalFieldAla "ghc-options" (alaList' NoCommaFSep Token') (extract GHC)
<*> monoidalFieldAla "ghcjs-options" (alaList' NoCommaFSep Token') (extract GHCJS)
- <*> monoidalFieldAla "jhc-options" (alaList' NoCommaFSep Token') (extract JHC)
- -- NOTE: Hugs and NHC are not supported anymore, but these fields are kept
- -- around for backwards compatibility.
+ -- NOTE: Hugs, NHC and JHC are not supported anymore, but these
+ -- fields are kept around so that we can still parse legacy .cabal
+ -- files that have them.
+ <* knownField "jhc-options"
<* knownField "hugs-options"
<* knownField "nhc98-options"
where
extract :: CompilerFlavor -> ALens' BuildInfo [String]
extract flavor = L.options . lookupLens flavor
- combine ghc ghcjs jhs =
- f GHC ghc ++ f GHCJS ghcjs ++ f JHC jhs
+ combine ghc ghcjs =
+ f GHC ghc ++ f GHCJS ghcjs
where
f _flavor [] = []
f flavor opts = [(flavor, opts)]
diff --git a/cabal/Cabal/Distribution/PackageDescription/Parse.hs b/cabal/Cabal/Distribution/PackageDescription/Parse.hs
deleted file mode 100644
index 565fca9..0000000
--- a/cabal/Cabal/Distribution/PackageDescription/Parse.hs
+++ /dev/null
@@ -1,1336 +0,0 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE RankNTypes #-}
-{-# LANGUAGE ScopedTypeVariables #-}
------------------------------------------------------------------------------
--- |
--- Module : Distribution.PackageDescription.Parse
--- Copyright : Isaac Jones 2003-2005
--- License : BSD3
---
--- Maintainer : cabal-devel@haskell.org
--- Portability : portable
---
--- This defined parsers and partial pretty printers for the @.cabal@ format.
--- Some of the complexity in this module is due to the fact that we have to be
--- backwards compatible with old @.cabal@ files, so there's code to translate
--- into the newer structure.
-
-module Distribution.PackageDescription.Parse (
- -- * Package descriptions
- readGenericPackageDescription,
- parseGenericPackageDescription,
-
- -- ** Deprecated names
- readPackageDescription,
- parsePackageDescription,
-
- -- ** Parsing
- ParseResult(..),
- FieldDescr(..),
- LineNo,
-
- -- ** Private, but needed for pretty-printer
- TestSuiteStanza(..),
- BenchmarkStanza(..),
-
- -- ** Supplementary build information
- readHookedBuildInfo,
- parseHookedBuildInfo,
-
- pkgDescrFieldDescrs,
- libFieldDescrs,
- foreignLibFieldDescrs,
- executableFieldDescrs,
- binfoFieldDescrs,
- sourceRepoFieldDescrs,
- testSuiteFieldDescrs,
- benchmarkFieldDescrs,
- flagFieldDescrs
- ) where
-
-import Prelude ()
-import Distribution.Compat.Prelude
-
-import Distribution.Types.Dependency
-import Distribution.Types.ForeignLib
-import Distribution.Types.ForeignLibType
-import Distribution.Types.UnqualComponentName
-import Distribution.Types.CondTree
-import Distribution.Types.PackageId
-import Distribution.ParseUtils hiding (parseFields)
-import Distribution.PackageDescription
-import Distribution.PackageDescription.Utils
-import Distribution.Package
-import Distribution.ModuleName
-import Distribution.Version
-import Distribution.Verbosity
-import Distribution.Compiler
-import Distribution.PackageDescription.Configuration
-import Distribution.Simple.Utils
-import Distribution.Text
-import Distribution.Compat.ReadP hiding (get)
-
-import Data.List (partition, (\\))
-import System.Directory (doesFileExist)
-import Control.Monad (mapM)
-
-import Text.PrettyPrint
- (vcat, ($$), (<+>), text, render,
- comma, fsep, nest, ($+$), punctuate)
-
-
--- -----------------------------------------------------------------------------
--- The PackageDescription type
-
-pkgDescrFieldDescrs :: [FieldDescr PackageDescription]
-pkgDescrFieldDescrs =
- [ simpleField "name"
- disp parse
- packageName (\name pkg -> pkg{package=(package pkg){pkgName=name}})
- , simpleField "version"
- disp parse
- packageVersion (\ver pkg -> pkg{package=(package pkg){pkgVersion=ver}})
- , simpleField "cabal-version"
- (either disp disp) (liftM Left parse +++ liftM Right parse)
- specVersionRaw (\v pkg -> pkg{specVersionRaw=v})
- , simpleField "build-type"
- (maybe mempty disp) (fmap Just parse)
- buildType (\t pkg -> pkg{buildType=t})
- , simpleField "license"
- disp parseLicenseQ
- license (\l pkg -> pkg{license=l})
- -- We have both 'license-file' and 'license-files' fields.
- -- Rather than declaring license-file to be deprecated, we will continue
- -- to allow both. The 'license-file' will continue to only allow single
- -- tokens, while 'license-files' allows multiple. On pretty-printing, we
- -- will use 'license-file' if there's just one, and use 'license-files'
- -- otherwise.
- , simpleField "license-file"
- showFilePath parseFilePathQ
- (\pkg -> case licenseFiles pkg of
- [x] -> x
- _ -> "")
- (\l pkg -> pkg{licenseFiles=licenseFiles pkg ++ [l]})
- , listField "license-files"
- showFilePath parseFilePathQ
- (\pkg -> case licenseFiles pkg of
- [_] -> []
- xs -> xs)
- (\ls pkg -> pkg{licenseFiles=licenseFiles pkg ++ ls})
- , simpleField "copyright"
- showFreeText parseFreeText
- copyright (\val pkg -> pkg{copyright=val})
- , simpleField "maintainer"
- showFreeText parseFreeText
- maintainer (\val pkg -> pkg{maintainer=val})
- , simpleField "stability"
- showFreeText parseFreeText
- stability (\val pkg -> pkg{stability=val})
- , simpleField "homepage"
- showFreeText parseFreeText
- homepage (\val pkg -> pkg{homepage=val})
- , simpleField "package-url"
- showFreeText parseFreeText
- pkgUrl (\val pkg -> pkg{pkgUrl=val})
- , simpleField "bug-reports"
- showFreeText parseFreeText
- bugReports (\val pkg -> pkg{bugReports=val})
- , simpleField "synopsis"
- showFreeText parseFreeText
- synopsis (\val pkg -> pkg{synopsis=val})
- , simpleField "description"
- showFreeText parseFreeText
- description (\val pkg -> pkg{description=val})
- , simpleField "category"
- showFreeText parseFreeText
- category (\val pkg -> pkg{category=val})
- , simpleField "author"
- showFreeText parseFreeText
- author (\val pkg -> pkg{author=val})
- , listField "tested-with"
- showTestedWith parseTestedWithQ
- testedWith (\val pkg -> pkg{testedWith=val})
- , listFieldWithSep vcat "data-files"
- showFilePath parseFilePathQ
- dataFiles (\val pkg -> pkg{dataFiles=val})
- , simpleField "data-dir"
- showFilePath parseFilePathQ
- dataDir (\val pkg -> pkg{dataDir=val})
- , listFieldWithSep vcat "extra-source-files"
- showFilePath parseFilePathQ
- extraSrcFiles (\val pkg -> pkg{extraSrcFiles=val})
- , listFieldWithSep vcat "extra-tmp-files"
- showFilePath parseFilePathQ
- extraTmpFiles (\val pkg -> pkg{extraTmpFiles=val})
- , listFieldWithSep vcat "extra-doc-files"
- showFilePath parseFilePathQ
- extraDocFiles (\val pkg -> pkg{extraDocFiles=val})
- ]
-
--- | Store any fields beginning with "x-" in the customFields field of
--- a PackageDescription. All other fields will generate a warning.
-storeXFieldsPD :: UnrecFieldParser PackageDescription
-storeXFieldsPD (f@('x':'-':_),val) pkg =
- Just pkg{ customFieldsPD =
- customFieldsPD pkg ++ [(f,val)]}
-storeXFieldsPD _ _ = Nothing
-
--- ---------------------------------------------------------------------------
--- The Library type
-
-libFieldDescrs :: [FieldDescr Library]
-libFieldDescrs =
- [ listFieldWithSep vcat "exposed-modules" disp parseModuleNameQ
- exposedModules (\mods lib -> lib{exposedModules=mods})
-
- , commaListFieldWithSep vcat "reexported-modules" disp parse
- reexportedModules (\mods lib -> lib{reexportedModules=mods})
-
- , listFieldWithSep vcat "signatures" disp parseModuleNameQ
- signatures (\mods lib -> lib{signatures=mods})
-
- , boolField "exposed"
- libExposed (\val lib -> lib{libExposed=val})
- ] ++ map biToLib binfoFieldDescrs
- where biToLib = liftField libBuildInfo (\bi lib -> lib{libBuildInfo=bi})
-
-storeXFieldsLib :: UnrecFieldParser Library
-storeXFieldsLib (f@('x':'-':_), val) l@(Library { libBuildInfo = bi }) =
- Just $ l {libBuildInfo =
- bi{ customFieldsBI = customFieldsBI bi ++ [(f,val)]}}
-storeXFieldsLib _ _ = Nothing
-
--- ---------------------------------------------------------------------------
--- Foreign libraries
-
-foreignLibFieldDescrs :: [FieldDescr ForeignLib]
-foreignLibFieldDescrs =
- [ simpleField "type"
- disp parse
- foreignLibType (\x flib -> flib { foreignLibType = x })
- , listField "options"
- disp parse
- foreignLibOptions (\x flib -> flib { foreignLibOptions = x })
- , simpleField "lib-version-info"
- (maybe mempty disp) (fmap Just parse)
- foreignLibVersionInfo (\x flib -> flib { foreignLibVersionInfo = x })
- , simpleField "lib-version-linux"
- (maybe mempty disp) (fmap Just parse)
- foreignLibVersionLinux (\x flib -> flib { foreignLibVersionLinux = x })
- , listField "mod-def-file"
- showFilePath parseFilePathQ
- foreignLibModDefFile (\x flib -> flib { foreignLibModDefFile = x })
- ]
- ++ map biToFLib binfoFieldDescrs
- where biToFLib = liftField foreignLibBuildInfo $ \bi flib ->
- flib { foreignLibBuildInfo = bi }
-
-storeXFieldsForeignLib :: UnrecFieldParser ForeignLib
-storeXFieldsForeignLib (f@('x':'-':_), val)
- l@(ForeignLib { foreignLibBuildInfo = bi }) =
- Just $ l { foreignLibBuildInfo = bi {
- customFieldsBI = (f,val):customFieldsBI bi
- }
- }
-storeXFieldsForeignLib _ _ = Nothing
-
--- ---------------------------------------------------------------------------
--- The Executable type
-
-
-executableFieldDescrs :: [FieldDescr Executable]
-executableFieldDescrs =
- [ simpleField "main-is"
- showFilePath parseFilePathQ
- modulePath (\xs exe -> exe{modulePath=xs})
- , simpleField "scope"
- disp parse
- exeScope (\sc exe -> exe{exeScope=sc})
- ]
- ++ map biToExe binfoFieldDescrs
- where biToExe = liftField buildInfo (\bi exe -> exe{buildInfo=bi})
-
-storeXFieldsExe :: UnrecFieldParser Executable
-storeXFieldsExe (f@('x':'-':_), val) e@(Executable { buildInfo = bi }) =
- Just $ e {buildInfo = bi{ customFieldsBI = (f,val):customFieldsBI bi}}
-storeXFieldsExe _ _ = Nothing
-
--- ---------------------------------------------------------------------------
--- The TestSuite type
-
--- | An intermediate type just used for parsing the test-suite stanza.
--- After validation it is converted into the proper 'TestSuite' type.
-data TestSuiteStanza = TestSuiteStanza {
- testStanzaTestType :: Maybe TestType,
- testStanzaMainIs :: Maybe FilePath,
- testStanzaTestModule :: Maybe ModuleName,
- testStanzaBuildInfo :: BuildInfo
- }
-
-emptyTestStanza :: TestSuiteStanza
-emptyTestStanza = TestSuiteStanza Nothing Nothing Nothing mempty
-
-testSuiteFieldDescrs :: [FieldDescr TestSuiteStanza]
-testSuiteFieldDescrs =
- [ simpleField "type"
- (maybe mempty disp) (fmap Just parse)
- testStanzaTestType (\x suite -> suite { testStanzaTestType = x })
- , simpleField "main-is"
- (maybe mempty showFilePath) (fmap Just parseFilePathQ)
- testStanzaMainIs (\x suite -> suite { testStanzaMainIs = x })
- , simpleField "test-module"
- (maybe mempty disp) (fmap Just parseModuleNameQ)
- testStanzaTestModule (\x suite -> suite { testStanzaTestModule = x })
- ]
- ++ map biToTest binfoFieldDescrs
- where
- biToTest = liftField testStanzaBuildInfo
- (\bi suite -> suite { testStanzaBuildInfo = bi })
-
-storeXFieldsTest :: UnrecFieldParser TestSuiteStanza
-storeXFieldsTest (f@('x':'-':_), val) t@(TestSuiteStanza { testStanzaBuildInfo = bi }) =
- Just $ t {testStanzaBuildInfo = bi{ customFieldsBI = (f,val):customFieldsBI bi}}
-storeXFieldsTest _ _ = Nothing
-
-validateTestSuite :: LineNo -> TestSuiteStanza -> ParseResult TestSuite
-validateTestSuite line stanza =
- case testStanzaTestType stanza of
- Nothing -> return $
- emptyTestSuite { testBuildInfo = testStanzaBuildInfo stanza }
-
- Just tt@(TestTypeUnknown _ _) ->
- return emptyTestSuite {
- testInterface = TestSuiteUnsupported tt,
- testBuildInfo = testStanzaBuildInfo stanza
- }
-
- Just tt | tt `notElem` knownTestTypes ->
- return emptyTestSuite {
- testInterface = TestSuiteUnsupported tt,
- testBuildInfo = testStanzaBuildInfo stanza
- }
-
- Just tt@(TestTypeExe ver) ->
- case testStanzaMainIs stanza of
- Nothing -> syntaxError line (missingField "main-is" tt)
- Just file -> do
- when (isJust (testStanzaTestModule stanza)) $
- warning (extraField "test-module" tt)
- return emptyTestSuite {
- testInterface = TestSuiteExeV10 ver file,
- testBuildInfo = testStanzaBuildInfo stanza
- }
-
- Just tt@(TestTypeLib ver) ->
- case testStanzaTestModule stanza of
- Nothing -> syntaxError line (missingField "test-module" tt)
- Just module_ -> do
- when (isJust (testStanzaMainIs stanza)) $
- warning (extraField "main-is" tt)
- return emptyTestSuite {
- testInterface = TestSuiteLibV09 ver module_,
- testBuildInfo = testStanzaBuildInfo stanza
- }
-
- where
- missingField name tt = "The '" ++ name ++ "' field is required for the "
- ++ display tt ++ " test suite type."
-
- extraField name tt = "The '" ++ name ++ "' field is not used for the '"
- ++ display tt ++ "' test suite type."
-
-
--- ---------------------------------------------------------------------------
--- The Benchmark type
-
--- | An intermediate type just used for parsing the benchmark stanza.
--- After validation it is converted into the proper 'Benchmark' type.
-data BenchmarkStanza = BenchmarkStanza {
- benchmarkStanzaBenchmarkType :: Maybe BenchmarkType,
- benchmarkStanzaMainIs :: Maybe FilePath,
- benchmarkStanzaBenchmarkModule :: Maybe ModuleName,
- benchmarkStanzaBuildInfo :: BuildInfo
- }
-
-emptyBenchmarkStanza :: BenchmarkStanza
-emptyBenchmarkStanza = BenchmarkStanza Nothing Nothing Nothing mempty
-
-benchmarkFieldDescrs :: [FieldDescr BenchmarkStanza]
-benchmarkFieldDescrs =
- [ simpleField "type"
- (maybe mempty disp) (fmap Just parse)
- benchmarkStanzaBenchmarkType
- (\x suite -> suite { benchmarkStanzaBenchmarkType = x })
- , simpleField "main-is"
- (maybe mempty showFilePath) (fmap Just parseFilePathQ)
- benchmarkStanzaMainIs
- (\x suite -> suite { benchmarkStanzaMainIs = x })
- ]
- ++ map biToBenchmark binfoFieldDescrs
- where
- biToBenchmark = liftField benchmarkStanzaBuildInfo
- (\bi suite -> suite { benchmarkStanzaBuildInfo = bi })
-
-storeXFieldsBenchmark :: UnrecFieldParser BenchmarkStanza
-storeXFieldsBenchmark (f@('x':'-':_), val)
- t@(BenchmarkStanza { benchmarkStanzaBuildInfo = bi }) =
- Just $ t {benchmarkStanzaBuildInfo =
- bi{ customFieldsBI = (f,val):customFieldsBI bi}}
-storeXFieldsBenchmark _ _ = Nothing
-
-validateBenchmark :: LineNo -> BenchmarkStanza -> ParseResult Benchmark
-validateBenchmark line stanza =
- case benchmarkStanzaBenchmarkType stanza of
- Nothing -> return $
- emptyBenchmark { benchmarkBuildInfo = benchmarkStanzaBuildInfo stanza }
-
- Just tt@(BenchmarkTypeUnknown _ _) ->
- return emptyBenchmark {
- benchmarkInterface = BenchmarkUnsupported tt,
- benchmarkBuildInfo = benchmarkStanzaBuildInfo stanza
- }
-
- Just tt | tt `notElem` knownBenchmarkTypes ->
- return emptyBenchmark {
- benchmarkInterface = BenchmarkUnsupported tt,
- benchmarkBuildInfo = benchmarkStanzaBuildInfo stanza
- }
-
- Just tt@(BenchmarkTypeExe ver) ->
- case benchmarkStanzaMainIs stanza of
- Nothing -> syntaxError line (missingField "main-is" tt)
- Just file -> do
- when (isJust (benchmarkStanzaBenchmarkModule stanza)) $
- warning (extraField "benchmark-module" tt)
- return emptyBenchmark {
- benchmarkInterface = BenchmarkExeV10 ver file,
- benchmarkBuildInfo = benchmarkStanzaBuildInfo stanza
- }
-
- where
- missingField name tt = "The '" ++ name ++ "' field is required for the "
- ++ display tt ++ " benchmark type."
-
- extraField name tt = "The '" ++ name ++ "' field is not used for the '"
- ++ display tt ++ "' benchmark type."
-
--- ---------------------------------------------------------------------------
--- The BuildInfo type
-
-binfoFieldDescrs :: [FieldDescr BuildInfo]
-binfoFieldDescrs =
- [ boolField "buildable"
- buildable (\val binfo -> binfo{buildable=val})
- , commaListField "build-tools"
- disp parse
- buildTools (\xs binfo -> binfo{buildTools=xs})
- , commaListField "build-tool-depends"
- disp parse
- buildToolDepends (\xs binfo -> binfo{buildToolDepends=xs})
- , commaListFieldWithSep vcat "build-depends"
- disp parse
- targetBuildDepends (\xs binfo -> binfo{targetBuildDepends=xs})
- , commaListFieldWithSep vcat "mixins"
- disp parse
- mixins (\xs binfo -> binfo{mixins=xs})
- , spaceListField "cpp-options"
- showToken parseTokenQ'
- cppOptions (\val binfo -> binfo{cppOptions=val})
- , spaceListField "asm-options"
- showToken parseTokenQ'
- asmOptions (\val binfo -> binfo{asmOptions=val})
- , spaceListField "cmm-options"
- showToken parseTokenQ'
- cmmOptions (\val binfo -> binfo{cmmOptions=val})
- , spaceListField "cc-options"
- showToken parseTokenQ'
- ccOptions (\val binfo -> binfo{ccOptions=val})
- , spaceListField "cxx-options"
- showToken parseTokenQ'
- cxxOptions (\val binfo -> binfo{cxxOptions=val})
- , spaceListField "ld-options"
- showToken parseTokenQ'
- ldOptions (\val binfo -> binfo{ldOptions=val})
- , commaListField "pkgconfig-depends"
- disp parse
- pkgconfigDepends (\xs binfo -> binfo{pkgconfigDepends=xs})
- , listField "frameworks"
- showToken parseTokenQ
- frameworks (\val binfo -> binfo{frameworks=val})
- , listField "extra-framework-dirs"
- showToken parseFilePathQ
- extraFrameworkDirs (\val binfo -> binfo{extraFrameworkDirs=val})
- , listFieldWithSep vcat "asm-sources"
- showFilePath parseFilePathQ
- asmSources (\paths binfo -> binfo{asmSources=paths})
- , listFieldWithSep vcat "cmm-sources"
- showFilePath parseFilePathQ
- cmmSources (\paths binfo -> binfo{cmmSources=paths})
- , listFieldWithSep vcat "c-sources"
- showFilePath parseFilePathQ
- cSources (\paths binfo -> binfo{cSources=paths})
- , listFieldWithSep vcat "cxx-sources"
- showFilePath parseFilePathQ
- cxxSources (\paths binfo -> binfo{cxxSources=paths})
- , listFieldWithSep vcat "js-sources"
- showFilePath parseFilePathQ
- jsSources (\paths binfo -> binfo{jsSources=paths})
- , simpleField "default-language"
- (maybe mempty disp) (option Nothing (fmap Just parseLanguageQ))
- defaultLanguage (\lang binfo -> binfo{defaultLanguage=lang})
- , listField "other-languages"
- disp parseLanguageQ
- otherLanguages (\langs binfo -> binfo{otherLanguages=langs})
- , listField "default-extensions"
- disp parseExtensionQ
- defaultExtensions (\exts binfo -> binfo{defaultExtensions=exts})
- , listField "other-extensions"
- disp parseExtensionQ
- otherExtensions (\exts binfo -> binfo{otherExtensions=exts})
- , listField "extensions"
- disp parseExtensionQ
- oldExtensions (\exts binfo -> binfo{oldExtensions=exts})
-
- , listFieldWithSep vcat "extra-libraries"
- showToken parseTokenQ
- extraLibs (\xs binfo -> binfo{extraLibs=xs})
- , listFieldWithSep vcat "extra-ghci-libraries"
- showToken parseTokenQ
- extraGHCiLibs (\xs binfo -> binfo{extraGHCiLibs=xs})
- , listFieldWithSep vcat "extra-bundled-libraries"
- showToken parseTokenQ
- extraBundledLibs (\xs binfo -> binfo{extraBundledLibs=xs})
- , listFieldWithSep vcat "extra-library-flavours"
- showToken parseTokenQ
- extraLibFlavours (\xs binfo -> binfo{extraLibFlavours=xs})
- , listField "extra-lib-dirs"
- showFilePath parseFilePathQ
- extraLibDirs (\xs binfo -> binfo{extraLibDirs=xs})
- , listFieldWithSep vcat "includes"
- showFilePath parseFilePathQ
- includes (\paths binfo -> binfo{includes=paths})
- , listFieldWithSep vcat "install-includes"
- showFilePath parseFilePathQ
- installIncludes (\paths binfo -> binfo{installIncludes=paths})
- , listField "include-dirs"
- showFilePath parseFilePathQ
- includeDirs (\paths binfo -> binfo{includeDirs=paths})
- , listField "hs-source-dirs"
- showFilePath parseFilePathQ
- hsSourceDirs (\paths binfo -> binfo{hsSourceDirs=paths})
- , listFieldWithSep vcat "other-modules"
- disp parseModuleNameQ
- otherModules (\val binfo -> binfo{otherModules=val})
- , listFieldWithSep vcat "virtual-modules"
- disp parseModuleNameQ
- virtualModules (\val binfo -> binfo{virtualModules=val})
- , listFieldWithSep vcat "autogen-modules"
- disp parseModuleNameQ
- autogenModules (\val binfo -> binfo{autogenModules=val})
- , optsField "ghc-prof-options" GHC
- profOptions (\val binfo -> binfo{profOptions=val})
- , optsField "ghcjs-prof-options" GHCJS
- profOptions (\val binfo -> binfo{profOptions=val})
- , optsField "ghc-shared-options" GHC
- sharedOptions (\val binfo -> binfo{sharedOptions=val})
- , optsField "ghcjs-shared-options" GHCJS
- sharedOptions (\val binfo -> binfo{sharedOptions=val})
- , optsField "ghc-options" GHC
- options (\path binfo -> binfo{options=path})
- , optsField "ghcjs-options" GHCJS
- options (\path binfo -> binfo{options=path})
- , optsField "jhc-options" JHC
- options (\path binfo -> binfo{options=path})
-
- -- NOTE: Hugs and NHC are not supported anymore, but these fields are kept
- -- around for backwards compatibility.
- , optsField "hugs-options" Hugs
- options (const id)
- , optsField "nhc98-options" NHC
- options (const id)
- ]
-
-storeXFieldsBI :: UnrecFieldParser BuildInfo
-storeXFieldsBI (f@('x':'-':_),val) bi = Just bi{ customFieldsBI = (f,val):customFieldsBI bi }
-storeXFieldsBI _ _ = Nothing
-
-------------------------------------------------------------------------------
-
-flagFieldDescrs :: [FieldDescr Flag]
-flagFieldDescrs =
- [ simpleField "description"
- showFreeText parseFreeText
- flagDescription (\val fl -> fl{ flagDescription = val })
- , boolField "default"
- flagDefault (\val fl -> fl{ flagDefault = val })
- , boolField "manual"
- flagManual (\val fl -> fl{ flagManual = val })
- ]
-
-------------------------------------------------------------------------------
-
-sourceRepoFieldDescrs :: [FieldDescr SourceRepo]
-sourceRepoFieldDescrs =
- [ simpleField "type"
- (maybe mempty disp) (fmap Just parse)
- repoType (\val repo -> repo { repoType = val })
- , simpleField "location"
- (maybe mempty showFreeText) (fmap Just parseFreeText)
- repoLocation (\val repo -> repo { repoLocation = val })
- , simpleField "module"
- (maybe mempty showToken) (fmap Just parseTokenQ)
- repoModule (\val repo -> repo { repoModule = val })
- , simpleField "branch"
- (maybe mempty showToken) (fmap Just parseTokenQ)
- repoBranch (\val repo -> repo { repoBranch = val })
- , simpleField "tag"
- (maybe mempty showToken) (fmap Just parseTokenQ)
- repoTag (\val repo -> repo { repoTag = val })
- , simpleField "subdir"
- (maybe mempty showFilePath) (fmap Just parseFilePathQ)
- repoSubdir (\val repo -> repo { repoSubdir = val })
- ]
-
-------------------------------------------------------------------------------
-
-setupBInfoFieldDescrs :: [FieldDescr SetupBuildInfo]
-setupBInfoFieldDescrs =
- [ commaListFieldWithSep vcat "setup-depends"
- disp parse
- setupDepends (\xs binfo -> binfo{setupDepends=xs})
- ]
-
--- ---------------------------------------------------------------
--- Parsing
-
--- | Given a parser and a filename, return the parse of the file,
--- after checking if the file exists.
-readAndParseFile :: (FilePath -> (String -> IO a) -> IO a)
- -> (String -> ParseResult a)
- -> Verbosity
- -> FilePath -> IO a
-readAndParseFile withFileContents' parser verbosity fpath = do
- exists <- doesFileExist fpath
- unless exists $
- die' verbosity $
- "Error Parsing: file \"" ++ fpath ++ "\" doesn't exist. Cannot continue."
- withFileContents' fpath $ \str -> case parser str of
- ParseFailed e -> do
- let (line, message) = locatedErrorMsg e
- dieWithLocation' verbosity fpath line message
- ParseOk warnings x -> do
- traverse_ (warn verbosity . showPWarning fpath) $ reverse warnings
- return x
-
-readHookedBuildInfo :: Verbosity -> FilePath -> IO HookedBuildInfo
-readHookedBuildInfo =
- readAndParseFile withFileContents parseHookedBuildInfo
-
-readPackageDescription :: Verbosity -> FilePath -> IO GenericPackageDescription
-readPackageDescription = readGenericPackageDescription
-{-# DEPRECATED readPackageDescription "Use readGenericPackageDescription, old name is misleading." #-}
-
--- | Parse the given package file.
-readGenericPackageDescription :: Verbosity -> FilePath -> IO GenericPackageDescription
-readGenericPackageDescription =
- readAndParseFile withUTF8FileContents parseGenericPackageDescription
-
-stanzas :: [Field] -> [[Field]]
-stanzas [] = []
-stanzas (f:fields) = (f:this) : stanzas rest
- where
- (this, rest) = break isStanzaHeader fields
-
-isStanzaHeader :: Field -> Bool
-isStanzaHeader (F _ f _) = f == "executable"
-isStanzaHeader _ = False
-
-------------------------------------------------------------------------------
-
-
-mapSimpleFields :: (Field -> ParseResult Field) -> [Field]
- -> ParseResult [Field]
-mapSimpleFields f = traverse walk
- where
- walk fld@F{} = f fld
- walk (IfBlock l c fs1 fs2) = do
- fs1' <- traverse walk fs1
- fs2' <- traverse walk fs2
- return (IfBlock l c fs1' fs2')
- walk (Section ln n l fs1) = do
- fs1' <- traverse walk fs1
- return (Section ln n l fs1')
-
--- prop_isMapM fs = mapSimpleFields return fs == return fs
-
-
--- names of fields that represents dependencies
--- TODO: maybe build-tools should go here too?
-constraintFieldNames :: [String]
-constraintFieldNames = ["build-depends"]
-
--- Possible refactoring would be to have modifiers be explicit about what
--- they add and define an accessor that specifies what the dependencies
--- are. This way we would completely reuse the parsing knowledge from the
--- field descriptor.
-parseConstraint :: Field -> ParseResult [Dependency]
-parseConstraint (F l n v)
- | n `elem` constraintFieldNames = runP l n (parseCommaList parse) v
-parseConstraint f = userBug $ "Constraint was expected (got: " ++ show f ++ ")"
-
-{-
-headerFieldNames :: [String]
-headerFieldNames = filter (\n -> not (n `elem` constraintFieldNames))
- . map fieldName $ pkgDescrFieldDescrs
--}
-
-libFieldNames :: [String]
-libFieldNames = map fieldName libFieldDescrs
- ++ buildInfoNames ++ constraintFieldNames
-
--- exeFieldNames :: [String]
--- exeFieldNames = map fieldName executableFieldDescrs
--- ++ buildInfoNames
-
-buildInfoNames :: [String]
-buildInfoNames = map fieldName binfoFieldDescrs
- ++ map fst deprecatedFieldsBuildInfo
-
--- A minimal implementation of the StateT monad transformer to avoid depending
--- on the 'mtl' package.
-newtype StT s m a = StT { runStT :: s -> m (a,s) }
-
-instance Functor f => Functor (StT s f) where
- fmap g (StT f) = StT $ fmap (first g) . f
-
-#if __GLASGOW_HASKELL__ >= 710
-instance (Monad m) => Applicative (StT s m) where
-#else
-instance (Monad m, Functor m) => Applicative (StT s m) where
-#endif
- pure a = StT (\s -> return (a,s))
- (<*>) = ap
-
-
-instance Monad m => Monad (StT s m) where
-#if __GLASGOW_HASKELL__ < 710
- return a = StT (\s -> return (a,s))
-#endif
- StT f >>= g = StT $ \s -> do
- (a,s') <- f s
- runStT (g a) s'
-
-getSt :: Monad m => StT s m s
-getSt = StT $ \s -> return (s, s)
-
-modify :: Monad m => (s -> s) -> StT s m ()
-modify f = StT $ \s -> return ((),f s)
-
-lift :: Monad m => m a -> StT s m a
-lift m = StT $ \s -> m >>= \a -> return (a,s)
-
-evalStT :: Monad m => StT s m a -> s -> m a
-evalStT st s = liftM fst $ runStT st s
-
--- Our monad for parsing a list/tree of fields.
---
--- The state represents the remaining fields to be processed.
-type PM a = StT [Field] ParseResult a
-
-
-
--- return look-ahead field or nothing if we're at the end of the file
-peekField :: PM (Maybe Field)
-peekField = liftM listToMaybe getSt
-
--- Unconditionally discard the first field in our state. Will error when it
--- reaches end of file. (Yes, that's evil.)
-skipField :: PM ()
-skipField = modify tail
-
---FIXME: this should take a ByteString, not a String. We have to be able to
--- decode UTF8 and handle the BOM.
-
-parsePackageDescription :: String -> ParseResult GenericPackageDescription
-parsePackageDescription = parseGenericPackageDescription
-{-# DEPRECATED parsePackageDescription "Use parseGenericPackageDescription, old name is misleading" #-}
-
--- | Parses the given file into a 'GenericPackageDescription'.
---
--- In Cabal 1.2 the syntax for package descriptions was changed to a format
--- with sections and possibly indented property descriptions.
-parseGenericPackageDescription :: String -> ParseResult GenericPackageDescription
-parseGenericPackageDescription file = do
-
- -- This function is quite complex because it needs to be able to parse
- -- both pre-Cabal-1.2 and post-Cabal-1.2 files. Additionally, it contains
- -- a lot of parser-related noise since we do not want to depend on Parsec.
- --
- -- If we detect an pre-1.2 file we implicitly convert it to post-1.2
- -- style. See 'sectionizeFields' below for details about the conversion.
-
- fields0 <- readFields file `catchParseError` \err ->
- let tabs = findIndentTabs file in
- case err of
- -- In case of a TabsError report them all at once.
- TabsError tabLineNo -> reportTabsError
- -- but only report the ones including and following
- -- the one that caused the actual error
- [ t | t@(lineNo',_) <- tabs
- , lineNo' >= tabLineNo ]
- _ -> parseFail err
-
- let cabalVersionNeeded =
- head $ [ minVersionBound versionRange
- | Just versionRange <- [ simpleParse v
- | F _ "cabal-version" v <- fields0 ] ]
- ++ [mkVersion [0]]
- minVersionBound versionRange =
- case asVersionIntervals versionRange of
- [] -> mkVersion [0]
- ((LowerBound version _, _):_) -> version
-
- handleFutureVersionParseFailure cabalVersionNeeded $ do
-
- let sf = sectionizeFields fields0 -- ensure 1.2 format
-
- -- figure out and warn about deprecated stuff (warnings are collected
- -- inside our parsing monad)
- fields <- mapSimpleFields deprecField sf
-
- -- Our parsing monad takes the not-yet-parsed fields as its state.
- -- After each successful parse we remove the field from the state
- -- ('skipField') and move on to the next one.
- --
- -- Things are complicated a bit, because fields take a tree-like
- -- structure -- they can be sections or "if"/"else" conditionals.
-
- flip evalStT fields $ do
-
- -- The header consists of all simple fields up to the first section
- -- (flag, library, executable).
- header_fields <- getHeader []
-
- -- Parses just the header fields and stores them in a
- -- 'PackageDescription'. Note that our final result is a
- -- 'GenericPackageDescription'; for pragmatic reasons we just store
- -- the partially filled-out 'PackageDescription' inside the
- -- 'GenericPackageDescription'.
- pkg <- lift $ parseFields pkgDescrFieldDescrs
- storeXFieldsPD
- emptyPackageDescription
- header_fields
-
- -- 'getBody' assumes that the remaining fields only consist of
- -- flags, lib and exe sections.
- (repos, flags, mcsetup, mlib, sub_libs, flibs, exes, tests, bms) <- getBody pkg
- warnIfRest -- warn if getBody did not parse up to the last field.
- -- warn about using old/new syntax with wrong cabal-version:
- maybeWarnCabalVersion (not $ oldSyntax fields0) pkg
- checkForUndefinedFlags flags mlib sub_libs exes tests
- return $ GenericPackageDescription
- pkg { sourceRepos = repos, setupBuildInfo = mcsetup }
- flags mlib sub_libs flibs exes tests bms
-
- where
- oldSyntax = all isSimpleField
- reportTabsError tabs =
- syntaxError (fst (head tabs)) $
- "Do not use tabs for indentation (use spaces instead)\n"
- ++ " Tabs were used at (line,column): " ++ show tabs
-
- maybeWarnCabalVersion newsyntax pkg
- | newsyntax && specVersion pkg < mkVersion [1,2]
- = lift $ warning $
- "A package using section syntax must specify at least\n"
- ++ "'cabal-version: >= 1.2'."
-
- maybeWarnCabalVersion newsyntax pkg
- | not newsyntax && specVersion pkg >= mkVersion [1,2]
- = lift $ warning $
- "A package using 'cabal-version: "
- ++ displaySpecVersion (specVersionRaw pkg)
- ++ "' must use section syntax. See the Cabal user guide for details."
- where
- displaySpecVersion (Left version) = display version
- displaySpecVersion (Right versionRange) =
- case asVersionIntervals versionRange of
- [] {- impossible -} -> display versionRange
- ((LowerBound version _, _):_) -> display (orLaterVersion version)
-
- maybeWarnCabalVersion _ _ = return ()
-
-
- handleFutureVersionParseFailure cabalVersionNeeded parseBody =
- (unless versionOk (warning message) >> parseBody)
- `catchParseError` \parseError -> case parseError of
- TabsError _ -> parseFail parseError
- _ | versionOk -> parseFail parseError
- | otherwise -> fail message
- where versionOk = cabalVersionNeeded <= cabalVersion
- message = "This package requires at least Cabal version "
- ++ display cabalVersionNeeded
-
- -- "Sectionize" an old-style Cabal file. A sectionized file has:
- --
- -- * all global fields at the beginning, followed by
- --
- -- * all flag declarations, followed by
- --
- -- * an optional library section, and an arbitrary number of executable
- -- sections (in any order).
- --
- -- The current implementation just gathers all library-specific fields
- -- in a library section and wraps all executable stanzas in an executable
- -- section.
- sectionizeFields :: [Field] -> [Field]
- sectionizeFields fs
- | oldSyntax fs =
- let
- -- "build-depends" is a local field now. To be backwards
- -- compatible, we still allow it as a global field in old-style
- -- package description files and translate it to a local field by
- -- adding it to every non-empty section
- (hdr0, exes0) = break ((=="executable") . fName) fs
- (hdr, libfs0) = partition (not . (`elem` libFieldNames) . fName) hdr0
-
- (deps, libfs) = partition ((== "build-depends") . fName)
- libfs0
-
- exes = unfoldr toExe exes0
- toExe [] = Nothing
- toExe (F l e n : r)
- | e == "executable" =
- let (efs, r') = break ((=="executable") . fName) r
- in Just (Section l "executable" n (deps ++ efs), r')
- toExe _ = cabalBug "unexpected input to 'toExe'"
- in
- hdr ++
- (if null libfs then []
- else [Section (lineNo (head libfs)) "library" "" (deps ++ libfs)])
- ++ exes
- | otherwise = fs
-
- isSimpleField F{} = True
- isSimpleField _ = False
-
- -- warn if there's something at the end of the file
- warnIfRest :: PM ()
- warnIfRest = do
- s <- getSt
- case s of
- [] -> return ()
- _ -> lift $ warning "Ignoring trailing declarations." -- add line no.
-
- -- all simple fields at the beginning of the file are (considered) header
- -- fields
- getHeader :: [Field] -> PM [Field]
- getHeader acc = peekField >>= \mf -> case mf of
- Just f@F{} -> skipField >> getHeader (f:acc)
- _ -> return (reverse acc)
-
- --
- -- body ::= { repo | flag | library | sub library | foreign library
- -- | executable | test | bench }+
- --
- -- The body consists of an optional sequence of declarations of flags and
- -- an arbitrary number of components
- --
- -- TODO: This method is long due for a rewrite to use a accumulator
- -- data type, or perhaps some more general way of balling the
- -- components up.
- getBody :: PackageDescription
- -> PM ([SourceRepo], [Flag]
- ,Maybe SetupBuildInfo
- ,(Maybe (CondTree ConfVar [Dependency] Library))
- ,[(UnqualComponentName, CondTree ConfVar [Dependency] Library)]
- ,[(UnqualComponentName, CondTree ConfVar [Dependency] ForeignLib)]
- ,[(UnqualComponentName, CondTree ConfVar [Dependency] Executable)]
- ,[(UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)]
- ,[(UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)])
- getBody pkg = peekField >>= \mf -> case mf of
- Just (Section line_no sec_type sec_label sec_fields)
- | sec_type == "executable" -> do
- when (null sec_label) $ lift $ syntaxError line_no
- "'executable' needs one argument (the executable's name)"
- exename <- lift $ runP line_no "executable" parseTokenQ sec_label
- flds <- collectFields parseExeFields sec_fields
- skipField
- (repos, flags, csetup, mlib, sub_libs, flibs, exes, tests, bms) <- getBody pkg
- return (repos, flags, csetup, mlib, sub_libs, flibs, (mkUnqualComponentName exename, flds): exes, tests, bms)
-
- | sec_type == "foreign-library" -> do
- when (null sec_label) $ lift $ syntaxError line_no
- "'foreign-library' needs one argument (the library's name)"
- libname <- lift $ runP line_no "foreign-library" parseTokenQ sec_label
- flds <- collectFields parseForeignLibFields sec_fields
-
- -- Check that a valid foreign library type has been chosen. A type
- -- field may be given inside a conditional block, so we must check
- -- for that before complaining that a type field has not been given.
- -- The foreign library must always have a valid type, so we need to
- -- check both the 'then' and 'else' blocks, though the blocks need
- -- not have the same type.
- let hasType ts = foreignLibType ts /= foreignLibType mempty
- if onAllBranches hasType flds
- then do
- skipField
- (repos, flags, csetup, mlib, sub_libs, flibs, exes, tests, bms) <- getBody pkg
- return (repos, flags, csetup, mlib, sub_libs, (mkUnqualComponentName libname, flds):flibs, exes, tests, bms)
- else lift $ syntaxError line_no $
- "Foreign library \"" ++ libname
- ++ "\" is missing required field \"type\" or the field "
- ++ "is not present in all conditional branches. The "
- ++ "available test types are: "
- ++ intercalate ", " (map display knownForeignLibTypes)
-
- | sec_type == "test-suite" -> do
- when (null sec_label) $ lift $ syntaxError line_no
- "'test-suite' needs one argument (the test suite's name)"
- testname <- lift $ runP line_no "test" parseTokenQ sec_label
- flds <- collectFields (parseTestFields line_no) sec_fields
-
- -- Check that a valid test suite type has been chosen. A type field
- -- may be given inside a conditional block, so we must check for
- -- that before complaining that a type field has not been given. The
- -- test suite must always have a valid type, so we need to check
- -- both the 'then' and 'else' blocks, though the blocks need not
- -- have the same type.
- let hasType ts = testInterface ts /= testInterface mempty
- if onAllBranches hasType flds
- then do
- skipField
- (repos, flags, csetup, mlib, sub_libs, flibs, exes, tests, bms) <- getBody pkg
- return (repos, flags, csetup, mlib, sub_libs, flibs, exes,
- (mkUnqualComponentName testname, flds) : tests, bms)
- else lift $ syntaxError line_no $
- "Test suite \"" ++ testname
- ++ "\" is missing required field \"type\" or the field "
- ++ "is not present in all conditional branches. The "
- ++ "available test types are: "
- ++ intercalate ", " (map display knownTestTypes)
-
- | sec_type == "benchmark" -> do
- when (null sec_label) $ lift $ syntaxError line_no
- "'benchmark' needs one argument (the benchmark's name)"
- benchname <- lift $ runP line_no "benchmark" parseTokenQ sec_label
- flds <- collectFields (parseBenchmarkFields line_no) sec_fields
-
- -- Check that a valid benchmark type has been chosen. A type field
- -- may be given inside a conditional block, so we must check for
- -- that before complaining that a type field has not been given. The
- -- benchmark must always have a valid type, so we need to check both
- -- the 'then' and 'else' blocks, though the blocks need not have the
- -- same type.
- let hasType ts = benchmarkInterface ts /= benchmarkInterface mempty
- if onAllBranches hasType flds
- then do
- skipField
- (repos, flags, csetup, mlib, sub_libs, flibs, exes, tests, bms) <- getBody pkg
- return (repos, flags, csetup, mlib, sub_libs, flibs, exes,
- tests, (mkUnqualComponentName benchname, flds) : bms)
- else lift $ syntaxError line_no $
- "Benchmark \"" ++ benchname
- ++ "\" is missing required field \"type\" or the field "
- ++ "is not present in all conditional branches. The "
- ++ "available benchmark types are: "
- ++ intercalate ", " (map display knownBenchmarkTypes)
-
- | sec_type == "library" -> do
- mb_libname <- if null sec_label
- then return Nothing
- -- TODO: relax this parsing so that scoping is handled
- -- correctly
- else fmap Just . lift
- $ runP line_no "library" parseTokenQ sec_label
- flds <- collectFields parseLibFields sec_fields
- skipField
- (repos, flags, csetup, mlib, sub_libs, flibs, exes, tests, bms) <- getBody pkg
- case mb_libname of
- Just libname ->
- return (repos, flags, csetup, mlib, (mkUnqualComponentName libname, flds) : sub_libs, flibs, exes, tests, bms)
- Nothing -> do
- when (isJust mlib) $ lift $ syntaxError line_no
- "There can only be one (public) library section in a package description."
- return (repos, flags, csetup, Just flds, sub_libs, flibs, exes, tests, bms)
-
- | sec_type == "flag" -> do
- when (null sec_label) $ lift $
- syntaxError line_no "'flag' needs one argument (the flag's name)"
- flag <- lift $ parseFields
- flagFieldDescrs
- warnUnrec
- (emptyFlag (mkFlagName (lowercase sec_label)))
- sec_fields
- skipField
- (repos, flags, csetup, mlib, sub_libs, flibs, exes, tests, bms) <- getBody pkg
- return (repos, flag:flags, csetup, mlib, sub_libs, flibs, exes, tests, bms)
-
- | sec_type == "source-repository" -> do
- when (null sec_label) $ lift $ syntaxError line_no $
- "'source-repository' needs one argument, "
- ++ "the repo kind which is usually 'head' or 'this'"
- kind <- case simpleParse sec_label of
- Just kind -> return kind
- Nothing -> lift $ syntaxError line_no $
- "could not parse repo kind: " ++ sec_label
- repo <- lift $ parseFields
- sourceRepoFieldDescrs
- warnUnrec
- (emptySourceRepo kind)
- sec_fields
- skipField
- (repos, flags, csetup, mlib, sub_libs, flibs, exes, tests, bms) <- getBody pkg
- return (repo:repos, flags, csetup, mlib, sub_libs, flibs, exes, tests, bms)
-
- | sec_type == "custom-setup" -> do
- unless (null sec_label) $ lift $
- syntaxError line_no "'setup' expects no argument"
- flds <- lift $ parseFields
- setupBInfoFieldDescrs
- warnUnrec
- mempty
- sec_fields
- skipField
- (repos, flags, csetup0, mlib, sub_libs, flibs, exes, tests, bms) <- getBody pkg
- when (isJust csetup0) $ lift $ syntaxError line_no
- "There can only be one 'custom-setup' section in a package description."
- return (repos, flags, Just flds, mlib, sub_libs, flibs, exes, tests, bms)
-
- | otherwise -> do
- lift $ warning $ "Ignoring unknown section type: " ++ sec_type
- skipField
- getBody pkg
- Just f@(F {}) -> do
- _ <- lift $ syntaxError (lineNo f) $
- "Plain fields are not allowed in between stanzas: " ++ show f
- skipField
- getBody pkg
- Just f@(IfBlock {}) -> do
- _ <- lift $ syntaxError (lineNo f) $
- "If-blocks are not allowed in between stanzas: " ++ show f
- skipField
- getBody pkg
- Nothing -> return ([], [], Nothing, Nothing, [], [], [], [], [])
-
- -- Extracts all fields in a block and returns a 'CondTree'.
- --
- -- We have to recurse down into conditionals and we treat fields that
- -- describe dependencies specially.
- collectFields :: ([Field] -> PM a) -> [Field]
- -> PM (CondTree ConfVar [Dependency] a)
- collectFields parser allflds = do
-
- let simplFlds = [ F l n v | F l n v <- allflds ]
- condFlds = [ f | f@IfBlock{} <- allflds ]
- sections = [ s | s@Section{} <- allflds ]
-
- traverse_
- (\(Section l n _ _) -> lift . warning $
- "Unexpected section '" ++ n ++ "' on line " ++ show l)
- sections
-
- a <- parser simplFlds
-
- -- Dependencies must be treated specially: when we
- -- parse into a CondTree, not only do we parse them into
- -- the targetBuildDepends/etc field inside the
- -- PackageDescription, but we also have to put the
- -- combined dependencies into CondTree.
- --
- -- This information is, in principle, redundant, but
- -- putting it here makes it easier for the constraint
- -- solver to pick a flag assignment which supports
- -- all of the dependencies (because it only has
- -- to check the CondTree, rather than grovel everywhere
- -- inside the conditional bits).
- deps <- liftM concat
- . traverse (lift . parseConstraint)
- . filter isConstraint
- $ simplFlds
-
- ifs <- traverse processIfs condFlds
-
- return (CondNode a deps ifs)
- where
- isConstraint (F _ n _) = n `elem` constraintFieldNames
- isConstraint _ = False
-
- processIfs (IfBlock l c t e) = do
- cnd <- lift $ runP l "if" parseCondition c
- t' <- collectFields parser t
- e' <- case e of
- [] -> return Nothing
- es -> do fs <- collectFields parser es
- return (Just fs)
- return (CondBranch cnd t' e')
- processIfs _ = cabalBug "processIfs called with wrong field type"
-
- parseLibFields :: [Field] -> PM Library
- parseLibFields = lift . parseFields libFieldDescrs storeXFieldsLib emptyLibrary
-
- -- Note: we don't parse the "executable" field here, hence the tail hack.
- parseExeFields :: [Field] -> PM Executable
- parseExeFields = lift . parseFields executableFieldDescrs
- storeXFieldsExe emptyExecutable
-
- parseForeignLibFields :: [Field] -> PM ForeignLib
- parseForeignLibFields =
- lift . parseFields foreignLibFieldDescrs
- storeXFieldsForeignLib
- emptyForeignLib
-
- parseTestFields :: LineNo -> [Field] -> PM TestSuite
- parseTestFields line fields = do
- x <- lift $ parseFields testSuiteFieldDescrs storeXFieldsTest
- emptyTestStanza fields
- lift $ validateTestSuite line x
-
- parseBenchmarkFields :: LineNo -> [Field] -> PM Benchmark
- parseBenchmarkFields line fields = do
- x <- lift $ parseFields benchmarkFieldDescrs storeXFieldsBenchmark
- emptyBenchmarkStanza fields
- lift $ validateBenchmark line x
-
- checkForUndefinedFlags ::
- [Flag] ->
- Maybe (CondTree ConfVar [Dependency] Library) ->
- [(UnqualComponentName, CondTree ConfVar [Dependency] Library)] ->
- [(UnqualComponentName, CondTree ConfVar [Dependency] Executable)] ->
- [(UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)] ->
- PM ()
- checkForUndefinedFlags flags mlib sub_libs exes tests = do
- let definedFlags = map flagName flags
- traverse_ (checkCondTreeFlags definedFlags) (maybeToList mlib)
- traverse_ (checkCondTreeFlags definedFlags . snd) sub_libs
- traverse_ (checkCondTreeFlags definedFlags . snd) exes
- traverse_ (checkCondTreeFlags definedFlags . snd) tests
-
- checkCondTreeFlags :: [FlagName] -> CondTree ConfVar c a -> PM ()
- checkCondTreeFlags definedFlags ct = do
- let fv = nub $ freeVars ct
- unless (all (`elem` definedFlags) fv) $
- fail $ "These flags are used without having been defined: "
- ++ intercalate ", " [ unFlagName fn | fn <- fv \\ definedFlags ]
-
--- Check that a property holds on all branches of a condition tree
-onAllBranches :: forall v c a. Monoid a => (a -> Bool) -> CondTree v c a -> Bool
-onAllBranches p = go mempty
- where
- -- If the current level of the tree satisfies the property, then we are
- -- done. If not, then one of the conditional branches below the current node
- -- must satisfy it. Each node may have multiple immediate children; we only
- -- one need one to satisfy the property because the configure step uses
- -- 'mappend' to join together the results of flag resolution.
- go :: a -> CondTree v c a -> Bool
- go acc ct = let acc' = acc `mappend` condTreeData ct
- in p acc' || any (goBranch acc') (condTreeComponents ct)
-
- -- Both the 'true' and the 'false' block must satisfy the property.
- goBranch :: a -> CondBranch v c a -> Bool
- goBranch _ (CondBranch _ _ Nothing) = False
- goBranch acc (CondBranch _ t (Just e)) = go acc t && go acc e
-
--- | Parse a list of fields, given a list of field descriptions,
--- a structure to accumulate the parsed fields, and a function
--- that can decide what to do with fields which don't match any
--- of the field descriptions.
-parseFields :: [FieldDescr a] -- ^ descriptions of fields we know how to
- -- parse
- -> UnrecFieldParser a -- ^ possibly do something with
- -- unrecognized fields
- -> a -- ^ accumulator
- -> [Field] -- ^ fields to be parsed
- -> ParseResult a
-parseFields descrs unrec ini fields =
- do (a, unknowns) <- foldM (parseField descrs unrec) (ini, []) fields
- unless (null unknowns) $ warning $ render $
- text "Unknown fields:" <+>
- commaSep (map (\(l,u) -> u ++ " (line " ++ show l ++ ")")
- (reverse unknowns))
- $+$
- text "Fields allowed in this section:" $$
- nest 4 (commaSep $ map fieldName descrs)
- return a
- where
- commaSep = fsep . punctuate comma . map text
-
-parseField :: [FieldDescr a] -- ^ list of parseable fields
- -> UnrecFieldParser a -- ^ possibly do something with
- -- unrecognized fields
- -> (a,[(Int,String)]) -- ^ accumulated result and warnings
- -> Field -- ^ the field to be parsed
- -> ParseResult (a, [(Int,String)])
-parseField (FieldDescr name _ parser : fields) unrec (a, us) (F line f val)
- | name == f = parser line val a >>= \a' -> return (a',us)
- | otherwise = parseField fields unrec (a,us) (F line f val)
-parseField [] unrec (a,us) (F l f val) = return $
- case unrec (f,val) a of -- no fields matched, see if the 'unrec'
- Just a' -> (a',us) -- function wants to do anything with it
- Nothing -> (a, (l,f):us)
-parseField _ _ _ _ = cabalBug "'parseField' called on a non-field"
-
-deprecatedFields :: [(String,String)]
-deprecatedFields =
- deprecatedFieldsPkgDescr ++ deprecatedFieldsBuildInfo
-
-deprecatedFieldsPkgDescr :: [(String,String)]
-deprecatedFieldsPkgDescr = [ ("other-files", "extra-source-files") ]
-
-deprecatedFieldsBuildInfo :: [(String,String)]
-deprecatedFieldsBuildInfo = [ ("hs-source-dir","hs-source-dirs") ]
-
--- Handle deprecated fields
-deprecField :: Field -> ParseResult Field
-deprecField (F line fld val) = do
- fld' <- case lookup fld deprecatedFields of
- Nothing -> return fld
- Just newName -> do
- warning $ "The field \"" ++ fld
- ++ "\" is deprecated, please use \"" ++ newName ++ "\""
- return newName
- return (F line fld' val)
-deprecField _ = cabalBug "'deprecField' called on a non-field"
-
-
-parseHookedBuildInfo :: String -> ParseResult HookedBuildInfo
-parseHookedBuildInfo inp = do
- fields <- readFields inp
- let ss@(mLibFields:exes) = stanzas fields
- mLib <- parseLib mLibFields
- biExes <- mapM parseExe (maybe ss (const exes) mLib)
- return (mLib, biExes)
- where
- parseLib :: [Field] -> ParseResult (Maybe BuildInfo)
- parseLib (bi@(F _ inFieldName _:_))
- | lowercase inFieldName /= "executable" = liftM Just (parseBI bi)
- parseLib _ = return Nothing
-
- parseExe :: [Field] -> ParseResult (UnqualComponentName, BuildInfo)
- parseExe (F line inFieldName mName:bi)
- | lowercase inFieldName == "executable"
- = do bis <- parseBI bi
- return (mkUnqualComponentName mName, bis)
- | otherwise = syntaxError line "expecting 'executable' at top of stanza"
- parseExe (_:_) = cabalBug "`parseExe' called on a non-field"
- parseExe [] = syntaxError 0 "error in parsing buildinfo file. Expected executable stanza"
-
- parseBI st = parseFields binfoFieldDescrs storeXFieldsBI emptyBuildInfo st
-
--- replace all tabs used as indentation with whitespace, also return where
--- tabs were found
-findIndentTabs :: String -> [(Int,Int)]
-findIndentTabs = concatMap checkLine
- . zip [1..]
- . lines
- where
- checkLine (lineno, l) =
- let (indent, _content) = span isSpace l
- tabCols = map fst . filter ((== '\t') . snd) . zip [0..]
- addLineNo = map (\col -> (lineno,col))
- in addLineNo (tabCols indent)
-
---test_findIndentTabs = findIndentTabs $ unlines $
--- [ "foo", " bar", " \t baz", "\t biz\t", "\t\t \t mib" ]
diff --git a/cabal/Cabal/Distribution/PackageDescription/Parsec.hs b/cabal/Cabal/Distribution/PackageDescription/Parsec.hs
index 53166f7..2a067ef 100644
--- a/cabal/Cabal/Distribution/PackageDescription/Parsec.hs
+++ b/cabal/Cabal/Distribution/PackageDescription/Parsec.hs
@@ -3,7 +3,6 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TupleSections #-}
-----------------------------------------------------------------------------
-- |
-- Module : Distribution.PackageDescription.Parsec
@@ -25,6 +24,9 @@ module Distribution.PackageDescription.Parsec (
ParseResult,
runParseResult,
+ -- * New-style spec-version
+ scanSpecVersion,
+
-- ** Supplementary build information
readHookedBuildInfo,
parseHookedBuildInfo,
@@ -33,64 +35,54 @@ module Distribution.PackageDescription.Parsec (
import Distribution.Compat.Prelude
import Prelude ()
-import Control.Monad.State.Strict (StateT, execStateT)
-import Control.Monad.Trans.Class (lift)
-import qualified Data.ByteString as BS
-import Data.List (partition)
-import qualified Distribution.Compat.Map.Strict as Map
-import Distribution.FieldGrammar
-import Distribution.PackageDescription
-import Distribution.PackageDescription.FieldGrammar
-import Distribution.PackageDescription.Quirks (patchQuirks)
-import Distribution.Parsec.Class (parsec)
-import Distribution.Parsec.Common
-import Distribution.Parsec.ConfVar (parseConditionConfVar)
-import Distribution.Parsec.Field (FieldName, getName)
-import Distribution.Parsec.LexerMonad (LexWarning, toPWarning)
-import Distribution.Parsec.Parser
-import Distribution.Parsec.ParseResult
-import Distribution.Simple.Utils (die', fromUTF8BS, warn)
-import Distribution.Text (display)
-import Distribution.Types.CondTree
-import Distribution.Types.ForeignLib
-import Distribution.Types.UnqualComponentName
- (UnqualComponentName, mkUnqualComponentName)
-import Distribution.Utils.Generic (breakMaybe, unfoldrM)
-import Distribution.Verbosity (Verbosity)
-import Distribution.Version
- (LowerBound (..), Version, asVersionIntervals, mkVersion, orLaterVersion)
-import System.Directory (doesFileExist)
-
-import Distribution.Compat.Lens
+import Control.Monad (guard)
+import Control.Monad.State.Strict (StateT, execStateT)
+import Control.Monad.Trans.Class (lift)
+import Data.List (partition)
+import Distribution.CabalSpecVersion
+import Distribution.Compat.Lens
+import Distribution.FieldGrammar
+import Distribution.FieldGrammar.Parsec (NamelessField (..))
+import Distribution.PackageDescription
+import Distribution.PackageDescription.FieldGrammar
+import Distribution.PackageDescription.Quirks (patchQuirks)
+import Distribution.Parsec.Class (parsec, simpleParsec)
+import Distribution.Parsec.Common
+import Distribution.Parsec.ConfVar (parseConditionConfVar)
+import Distribution.Parsec.Field (FieldName, getName)
+import Distribution.Parsec.FieldLineStream (fieldLineStreamFromBS)
+import Distribution.Parsec.LexerMonad (LexWarning, toPWarnings)
+import Distribution.Parsec.Newtypes (CommaFSep, List, SpecVersion (..), Token)
+import Distribution.Parsec.Parser
+import Distribution.Parsec.ParseResult
+import Distribution.Pretty (prettyShow)
+import Distribution.Simple.Utils (fromUTF8BS)
+import Distribution.Text (display)
+import Distribution.Types.CondTree
+import Distribution.Types.Dependency (Dependency)
+import Distribution.Types.ForeignLib
+import Distribution.Types.ForeignLibType (knownForeignLibTypes)
+import Distribution.Types.GenericPackageDescription (emptyGenericPackageDescription)
+import Distribution.Types.PackageDescription (specVersion')
+import Distribution.Types.UnqualComponentName (UnqualComponentName, mkUnqualComponentName)
+import Distribution.Utils.Generic (breakMaybe, unfoldrM, validateUTF8)
+import Distribution.Verbosity (Verbosity)
+import Distribution.Version
+ (LowerBound (..), Version, asVersionIntervals, mkVersion, orLaterVersion, version0,
+ versionNumbers)
+
+import qualified Data.ByteString as BS
+import qualified Data.ByteString.Char8 as BS8
+import qualified Data.Map.Strict as Map
+import qualified Distribution.Compat.Newtype as Newtype
+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 Text.Parsec as P
-- ---------------------------------------------------------------
-- Parsing
-
--- | Helper combinator to do parsing plumbing for files.
---
--- Given a parser and a filename, return the parse of the file,
--- after checking if the file exists.
---
--- Argument order is chosen to encourage partial application.
-readAndParseFile
- :: (BS.ByteString -> ParseResult a) -- ^ File contents to final value parser
- -> Verbosity -- ^ Verbosity level
- -> FilePath -- ^ File to read
- -> IO a
-readAndParseFile parser verbosity fpath = do
- exists <- doesFileExist fpath
- unless exists $
- die' verbosity $
- "Error Parsing: file \"" ++ fpath ++ "\" doesn't exist. Cannot continue."
- bs <- BS.readFile fpath
- let (warnings, errors, result) = runParseResult (parser bs)
- traverse_ (warn verbosity . showPWarning fpath) warnings
- traverse_ (warn verbosity . showPError fpath) errors
- case result of
- Nothing -> die' verbosity $ "Failing parsing \"" ++ fpath ++ "\"."
- Just x -> return x
+-- ---------------------------------------------------------------
-- | Parse the given package file.
readGenericPackageDescription :: Verbosity -> FilePath -> IO GenericPackageDescription
@@ -103,28 +95,53 @@ readGenericPackageDescription = readAndParseFile parseGenericPackageDescription
-- with sections and possibly indented property descriptions.
--
parseGenericPackageDescription :: BS.ByteString -> ParseResult GenericPackageDescription
-parseGenericPackageDescription bs = case readFields' bs' of
- Right (fs, lexWarnings) -> do
- when patched $
- parseWarning zeroPos PWTQuirkyCabalFile "Legacy cabal file"
- parseGenericPackageDescription' lexWarnings fs
- -- TODO: better marshalling of errors
- Left perr -> parseFatalFailure zeroPos (show perr)
+parseGenericPackageDescription bs = do
+ -- set scanned version
+ setCabalSpecVersion ver
+ -- if we get too new version, fail right away
+ case ver of
+ Just v | v > mkVersion [2,4] -> parseFailure zeroPos
+ "Unsupported cabal-version. See https://github.com/haskell/cabal/issues/4899."
+ _ -> pure ()
+
+ case readFields' bs' of
+ Right (fs, lexWarnings) -> do
+ when patched $
+ parseWarning zeroPos PWTQuirkyCabalFile "Legacy cabal file"
+ -- UTF8 is validated in a prepass step, afterwards parsing is lenient.
+ parseGenericPackageDescription' ver lexWarnings (validateUTF8 bs') fs
+ -- TODO: better marshalling of errors
+ Left perr -> parseFatalFailure pos (show perr) where
+ ppos = P.errorPos perr
+ pos = Position (P.sourceLine ppos) (P.sourceColumn ppos)
where
(patched, bs') = patchQuirks bs
+ ver = scanSpecVersion bs'
-- | 'Maybe' variant of 'parseGenericPackageDescription'
parseGenericPackageDescriptionMaybe :: BS.ByteString -> Maybe GenericPackageDescription
parseGenericPackageDescriptionMaybe =
- trdOf3 . runParseResult . parseGenericPackageDescription
- where
- trdOf3 (_, _, x) = x
+ either (const Nothing) Just . snd . runParseResult . parseGenericPackageDescription
fieldlinesToBS :: [FieldLine ann] -> BS.ByteString
fieldlinesToBS = BS.intercalate "\n" . map (\(FieldLine _ bs) -> bs)
-- Monad in which sections are parsed
-type SectionParser = StateT GenericPackageDescription ParseResult
+type SectionParser = StateT SectionS ParseResult
+
+-- | State of section parser
+data SectionS = SectionS
+ { _stateGpd :: !GenericPackageDescription
+ , _stateCommonStanzas :: !(Map String CondTreeBuildInfo)
+ }
+
+stateGpd :: Lens' SectionS GenericPackageDescription
+stateGpd f (SectionS gpd cs) = (\x -> SectionS x cs) <$> f gpd
+{-# INLINE stateGpd #-}
+
+stateCommonStanzas :: Lens' SectionS (Map String CondTreeBuildInfo)
+stateCommonStanzas f (SectionS gpd cs) = SectionS gpd <$> f cs
+{-# INLINE stateCommonStanzas #-}
-- Note [Accumulating parser]
--
@@ -132,27 +149,59 @@ type SectionParser = StateT GenericPackageDescription ParseResult
-- * first we parse fields of PackageDescription
-- * then we parse sections (libraries, executables, etc)
parseGenericPackageDescription'
- :: [LexWarning]
+ :: Maybe Version
+ -> [LexWarning]
+ -> Maybe Int
-> [Field Position]
-> ParseResult GenericPackageDescription
-parseGenericPackageDescription' lexWarnings fs = do
- parseWarnings (fmap toPWarning lexWarnings)
+parseGenericPackageDescription' cabalVerM lexWarnings utf8WarnPos fs = do
+ parseWarnings (toPWarnings lexWarnings)
+ for_ utf8WarnPos $ \pos ->
+ parseWarning zeroPos PWTUTF $ "UTF8 encoding problem at byte offset " ++ show pos
let (syntax, fs') = sectionizeFields fs
-
- -- PackageDescription
let (fields, sectionFields) = takeFields fs'
- pd <- parseFieldGrammar fields packageDescriptionFieldGrammar
+
+ -- cabal-version
+ cabalVer <- case cabalVerM of
+ Just v -> return v
+ Nothing -> case Map.lookup "cabal-version" fields >>= safeLast of
+ Nothing -> return version0
+ Just (MkNamelessField pos fls) -> do
+ v <- specVersion' . Newtype.unpack' SpecVersion <$> runFieldParser pos parsec cabalSpecLatest fls
+ when (v >= mkVersion [2,1]) $ parseFailure pos $
+ "cabal-version should be at the beginning of the file starting with spec version 2.2. " ++
+ "See https://github.com/haskell/cabal/issues/4899"
+
+ return v
+
+ let specVer
+ | cabalVer >= mkVersion [2,3] = CabalSpecV2_4
+ | cabalVer >= mkVersion [2,1] = CabalSpecV2_2
+ | cabalVer >= mkVersion [1,25] = CabalSpecV2_0
+ | cabalVer >= mkVersion [1,23] = CabalSpecV1_24
+ | cabalVer >= mkVersion [1,21] = CabalSpecV1_22
+ | otherwise = CabalSpecOld
+
+ -- reset cabal version
+ setCabalSpecVersion (Just cabalVer)
+
+ -- Package description
+ pd <- parseFieldGrammar specVer fields packageDescriptionFieldGrammar
+
+ -- Check that scanned and parsed versions match.
+ unless (cabalVer == specVersion pd) $ parseFailure zeroPos $
+ "Scanned and parsed cabal-versions don't match " ++
+ prettyShow cabalVer ++ " /= " ++ prettyShow (specVersion pd)
+
maybeWarnCabalVersion syntax pd
-- Sections
- let gpd = emptyGpd & L.packageDescription .~ pd
+ let gpd = emptyGenericPackageDescription & L.packageDescription .~ pd
- -- elif conditional is accepted if spec version is >= 2.1
- let hasElif = if specVersion pd >= mkVersion [2,1] then HasElif else NoElif
- execStateT (goSections hasElif sectionFields) gpd
+ view stateGpd <$> execStateT (goSections specVer sectionFields) (SectionS gpd Map.empty)
where
- emptyGpd :: GenericPackageDescription
- emptyGpd = GenericPackageDescription emptyPackageDescription [] Nothing [] [] [] [] []
+ safeLast :: [a] -> Maybe a
+ safeLast = listToMaybe . reverse
newSyntaxVersion :: Version
newSyntaxVersion = mkVersion [1, 2]
@@ -160,13 +209,13 @@ parseGenericPackageDescription' lexWarnings fs = do
maybeWarnCabalVersion :: Syntax -> PackageDescription -> ParseResult ()
maybeWarnCabalVersion syntax pkg
| syntax == NewSyntax && specVersion pkg < newSyntaxVersion
- = parseWarning (Position 0 0) PWTNewSyntax $
+ = parseWarning zeroPos PWTNewSyntax $
"A package using section syntax must specify at least\n"
++ "'cabal-version: >= 1.2'."
maybeWarnCabalVersion syntax pkg
| syntax == OldSyntax && specVersion pkg >= newSyntaxVersion
- = parseWarning (Position 0 0) PWTOldSyntax $
+ = parseWarning zeroPos PWTOldSyntax $
"A package using 'cabal-version: "
++ displaySpecVersion (specVersionRaw pkg)
++ "' must use section syntax. See the Cabal user guide for details."
@@ -179,9 +228,8 @@ parseGenericPackageDescription' lexWarnings fs = do
maybeWarnCabalVersion _ _ = return ()
- -- Sections
-goSections :: HasElif -> [Field Position] -> SectionParser ()
-goSections hasElif = traverse_ process
+goSections :: CabalSpecVersion -> [Field Position] -> SectionParser ()
+goSections specVer = traverse_ process
where
process (Field (Name pos name) _) =
lift $ parseWarning pos PWTTrailingFields $
@@ -191,62 +239,123 @@ goSections hasElif = traverse_ process
snoc x xs = xs ++ [x]
+ hasCommonStanzas = specHasCommonStanzas specVer
+
+ -- we need signature, because this is polymorphic, but not-closed
+ parseCondTree'
+ :: FromBuildInfo a
+ => ParsecFieldGrammar' a -- ^ grammar
+ -> Map String CondTreeBuildInfo -- ^ common stanzas
+ -> [Field Position]
+ -> ParseResult (CondTree ConfVar [Dependency] a)
+ parseCondTree' = parseCondTreeWithCommonStanzas specVer
+
parseSection :: Name Position -> [SectionArg Position] -> [Field Position] -> SectionParser ()
parseSection (Name pos name) args fields
+ | hasCommonStanzas == NoCommonStanzas, name == "common" = lift $ do
+ parseWarning pos PWTUnknownSection $ "Ignoring section: common. You should set cabal-version: 2.2 or larger to use common stanzas."
+
+ | name == "common" = do
+ commonStanzas <- use stateCommonStanzas
+ name' <- lift $ parseCommonName pos args
+ biTree <- lift $ parseCondTree' buildInfoFieldGrammar commonStanzas fields
+
+ case Map.lookup name' commonStanzas of
+ Nothing -> stateCommonStanzas .= Map.insert name' biTree commonStanzas
+ Just _ -> lift $ parseFailure pos $
+ "Duplicate common stanza: " ++ name'
+
| name == "library" && null args = do
- lib <- lift $ parseCondTree hasElif (libraryFieldGrammar Nothing) (targetBuildDepends . libBuildInfo) fields
+ commonStanzas <- use stateCommonStanzas
+ lib <- lift $ parseCondTree' (libraryFieldGrammar Nothing) commonStanzas fields
-- TODO: check that library is defined once
- L.condLibrary ?= lib
+ stateGpd . L.condLibrary ?= lib
-- Sublibraries
+ -- TODO: check cabal-version
| name == "library" = do
- -- TODO: check cabal-version
+ commonStanzas <- use stateCommonStanzas
name' <- parseUnqualComponentName pos args
- lib <- lift $ parseCondTree hasElif (libraryFieldGrammar $ Just name') (targetBuildDepends . libBuildInfo) fields
+ lib <- lift $ parseCondTree' (libraryFieldGrammar $ Just name') commonStanzas fields
-- TODO check duplicate name here?
- L.condSubLibraries %= snoc (name', lib)
+ stateGpd . L.condSubLibraries %= snoc (name', lib)
+ -- TODO: check cabal-version
| name == "foreign-library" = do
+ commonStanzas <- use stateCommonStanzas
name' <- parseUnqualComponentName pos args
- flib <- lift $ parseCondTree hasElif (foreignLibFieldGrammar name') (targetBuildDepends . foreignLibBuildInfo) fields
+ flib <- lift $ parseCondTree' (foreignLibFieldGrammar name') commonStanzas fields
+
+ let hasType ts = foreignLibType ts /= foreignLibType mempty
+ unless (onAllBranches hasType flib) $ lift $ parseFailure pos $ concat
+ [ "Foreign library " ++ show (display name')
+ , " is missing required field \"type\" or the field "
+ , "is not present in all conditional branches. The "
+ , "available test types are: "
+ , intercalate ", " (map display knownForeignLibTypes)
+ ]
+
-- TODO check duplicate name here?
- L.condForeignLibs %= snoc (name', flib)
+ stateGpd . L.condForeignLibs %= snoc (name', flib)
| name == "executable" = do
+ commonStanzas <- use stateCommonStanzas
name' <- parseUnqualComponentName pos args
- exe <- lift $ parseCondTree hasElif (executableFieldGrammar name') (targetBuildDepends . buildInfo) fields
+ exe <- lift $ parseCondTree' (executableFieldGrammar name') commonStanzas fields
-- TODO check duplicate name here?
- L.condExecutables %= snoc (name', exe)
+ stateGpd . L.condExecutables %= snoc (name', exe)
| name == "test-suite" = do
+ commonStanzas <- use stateCommonStanzas
name' <- parseUnqualComponentName pos args
- testStanza <- lift $ parseCondTree hasElif testSuiteFieldGrammar (targetBuildDepends . _testStanzaBuildInfo) fields
+ testStanza <- lift $ parseCondTree' testSuiteFieldGrammar commonStanzas fields
testSuite <- lift $ traverse (validateTestSuite pos) testStanza
+
+ let hasType ts = testInterface ts /= testInterface mempty
+ unless (onAllBranches hasType testSuite) $ lift $ parseFailure pos $ concat
+ [ "Test suite " ++ show (display name')
+ , " is missing required field \"type\" or the field "
+ , "is not present in all conditional branches. The "
+ , "available test types are: "
+ , intercalate ", " (map display knownTestTypes)
+ ]
+
-- TODO check duplicate name here?
- L.condTestSuites %= snoc (name', testSuite)
+ stateGpd . L.condTestSuites %= snoc (name', testSuite)
| name == "benchmark" = do
+ commonStanzas <- use stateCommonStanzas
name' <- parseUnqualComponentName pos args
- benchStanza <- lift $ parseCondTree hasElif benchmarkFieldGrammar (targetBuildDepends . _benchmarkStanzaBuildInfo) fields
+ benchStanza <- lift $ parseCondTree' benchmarkFieldGrammar commonStanzas fields
bench <- lift $ traverse (validateBenchmark pos) benchStanza
+
+ let hasType ts = benchmarkInterface ts /= benchmarkInterface mempty
+ unless (onAllBranches hasType bench) $ lift $ parseFailure pos $ concat
+ [ "Benchmark " ++ show (display name')
+ , " is missing required field \"type\" or the field "
+ , "is not present in all conditional branches. The "
+ , "available benchmark types are: "
+ , intercalate ", " (map display knownBenchmarkTypes)
+ ]
+
-- TODO check duplicate name here?
- L.condBenchmarks %= snoc (name', bench)
+ stateGpd . L.condBenchmarks %= snoc (name', bench)
| name == "flag" = do
- name' <- parseName pos args
- name'' <- lift $ runFieldParser' pos parsec name' `recoverWith` mkFlagName ""
- flag <- lift $ parseFields fields (flagFieldGrammar name'')
+ name' <- parseNameBS pos args
+ name'' <- lift $ runFieldParser' pos parsec specVer (fieldLineStreamFromBS name') `recoverWith` mkFlagName ""
+ flag <- lift $ parseFields specVer fields (flagFieldGrammar name'')
-- Check default flag
- L.genPackageFlags %= snoc flag
+ stateGpd . L.genPackageFlags %= snoc flag
| name == "custom-setup" && null args = do
- sbi <- lift $ parseFields fields (setupBInfoFieldGrammar False)
- L.packageDescription . L.setupBuildInfo ?= sbi
+ sbi <- lift $ parseFields specVer fields (setupBInfoFieldGrammar False)
+ stateGpd . L.packageDescription . L.setupBuildInfo ?= sbi
| name == "source-repository" = do
kind <- lift $ case args of
[SecArgName spos secName] ->
- runFieldParser' spos parsec (fromUTF8BS secName) `recoverWith` RepoHead
+ runFieldParser' spos parsec specVer (fieldLineStreamFromBS secName) `recoverWith` RepoHead
[] -> do
parseFailure pos "'source-repository' requires exactly one argument"
pure RepoHead
@@ -254,59 +363,76 @@ goSections hasElif = traverse_ process
parseFailure pos $ "Invalid source-repository kind " ++ show args
pure RepoHead
- sr <- lift $ parseFields fields (sourceRepoFieldGrammar kind)
- L.packageDescription . L.sourceRepos %= snoc sr
+ sr <- lift $ parseFields specVer fields (sourceRepoFieldGrammar kind)
+ stateGpd . L.packageDescription . L.sourceRepos %= snoc sr
| otherwise = lift $
parseWarning pos PWTUnknownSection $ "Ignoring section: " ++ show name
parseName :: Position -> [SectionArg Position] -> SectionParser String
-parseName pos args = case args of
+parseName pos args = fromUTF8BS <$> parseNameBS pos args
+
+parseNameBS :: Position -> [SectionArg Position] -> SectionParser BS.ByteString
+-- TODO: use strict parser
+parseNameBS pos args = case args of
+ [SecArgName _pos secName] ->
+ pure secName
+ [SecArgStr _pos secName] ->
+ pure secName
+ [] -> do
+ lift $ parseFailure pos "name required"
+ pure ""
+ _ -> do
+ -- TODO: pretty print args
+ lift $ parseFailure pos $ "Invalid name " ++ show args
+ pure ""
+
+parseCommonName :: Position -> [SectionArg Position] -> ParseResult String
+parseCommonName pos args = case args of
[SecArgName _pos secName] ->
pure $ fromUTF8BS secName
[SecArgStr _pos secName] ->
pure $ fromUTF8BS secName
[] -> do
- lift $ parseFailure pos $ "name required"
+ parseFailure pos $ "name required"
pure ""
_ -> do
-- TODO: pretty print args
- lift $ parseFailure pos $ "Invalid name " ++ show args
+ parseFailure pos $ "Invalid name " ++ show args
pure ""
+-- TODO: avoid conversion to 'String'.
parseUnqualComponentName :: Position -> [SectionArg Position] -> SectionParser UnqualComponentName
parseUnqualComponentName pos args = mkUnqualComponentName <$> parseName pos args
-- | Parse a non-recursive list of fields.
parseFields
- :: [Field Position] -- ^ fields to be parsed
+ :: CabalSpecVersion
+ -> [Field Position] -- ^ fields to be parsed
-> ParsecFieldGrammar' a
-> ParseResult a
-parseFields fields grammar = do
+parseFields v fields grammar = do
let (fs0, ss) = partitionFields fields
traverse_ (traverse_ warnInvalidSubsection) ss
- parseFieldGrammar fs0 grammar
+ parseFieldGrammar v fs0 grammar
warnInvalidSubsection :: Section Position -> ParseResult ()
warnInvalidSubsection (MkSection (Name pos name) _ _) =
void (parseFailure pos $ "invalid subsection " ++ show name)
-
-data HasElif = HasElif | NoElif
- deriving (Eq, Show)
-
parseCondTree
:: forall a c.
- HasElif -- ^ accept @elif@
+ CabalSpecVersion
+ -> HasElif -- ^ accept @elif@
-> ParsecFieldGrammar' a -- ^ grammar
- -> (a -> c) -- ^ condition extractor
+ -> (a -> c) -- ^ condition extractor
-> [Field Position]
-> ParseResult (CondTree ConfVar c a)
-parseCondTree hasElif grammar cond = go
+parseCondTree v hasElif grammar cond = go
where
go fields = do
let (fs, ss) = partitionFields fields
- x <- parseFieldGrammar fs grammar
+ x <- parseFieldGrammar v fs grammar
branches <- concat <$> traverse parseIfs ss
return (CondNode x (cond x) branches) -- TODO: branches
@@ -333,15 +459,21 @@ parseCondTree hasElif grammar cond = go
sections' <- parseIfs sections
return (Just elseFields, sections')
+
+
parseElseIfs (MkSection (Name _ name) test fields : sections) | hasElif == HasElif, name == "elif" = do
-- TODO: check cabal-version
test' <- parseConditionConfVar test
fields' <- go fields
(elseFields, sections') <- parseElseIfs sections
-- we parse an empty 'Fields', to get empty value for a node
- a <- parseFieldGrammar mempty grammar
+ a <- parseFieldGrammar v mempty grammar
return (Just $ CondNode a (cond a) [CondBranch test' fields' elseFields], sections')
+ parseElseIfs (MkSection (Name pos name) _ _ : sections) | name == "elif" = do
+ parseWarning pos PWTInvalidSubsection $ "invalid subsection \"elif\". You should set cabal-version: 2.2 or larger to use elif-conditionals."
+ (,) Nothing <$> parseIfs sections
+
parseElseIfs sections = (,) Nothing <$> parseIfs sections
{- Note [Accumulating parser]
@@ -367,6 +499,138 @@ with new AST, this all need to be rewritten.
-}
-------------------------------------------------------------------------------
+-- Common stanzas
+-------------------------------------------------------------------------------
+
+-- $commonStanzas
+--
+-- [Note: Common stanzas]
+--
+-- In Cabal 2.2 we support simple common stanzas:
+--
+-- * Commons stanzas define 'BuildInfo'
+--
+-- * import "fields" can only occur at top of other stanzas (think: imports)
+--
+-- In particular __there aren't__
+--
+-- * implicit stanzas
+--
+-- * More specific common stanzas (executable, test-suite).
+--
+--
+-- The approach uses the fact that 'BuildInfo' is a 'Monoid':
+--
+-- @
+-- mergeCommonStanza' :: HasBuildInfo comp => BuildInfo -> comp -> comp
+-- mergeCommonStanza' bi = over L.BuildInfo (bi <>)
+-- @
+--
+-- Real 'mergeCommonStanza' is more complicated as we have to deal with
+-- conditional trees.
+--
+-- The approach is simple, and have good properties:
+--
+-- * Common stanzas are parsed exactly once, even if not-used. Thus we report errors in them.
+--
+type CondTreeBuildInfo = CondTree ConfVar [Dependency] BuildInfo
+
+-- | Create @a@ from 'BuildInfo'.
+--
+-- Law: @view buildInfo . fromBuildInfo = id@
+class L.HasBuildInfo a => FromBuildInfo a where
+ fromBuildInfo :: BuildInfo -> a
+
+instance FromBuildInfo BuildInfo where fromBuildInfo = id
+instance FromBuildInfo Library where fromBuildInfo bi = set L.buildInfo bi emptyLibrary
+instance FromBuildInfo ForeignLib where fromBuildInfo bi = set L.buildInfo bi emptyForeignLib
+instance FromBuildInfo Executable where fromBuildInfo bi = set L.buildInfo bi emptyExecutable
+
+instance FromBuildInfo TestSuiteStanza where
+ fromBuildInfo = TestSuiteStanza Nothing Nothing Nothing
+
+instance FromBuildInfo BenchmarkStanza where
+ fromBuildInfo = BenchmarkStanza Nothing Nothing Nothing
+
+parseCondTreeWithCommonStanzas
+ :: forall a. FromBuildInfo a
+ => CabalSpecVersion
+ -> ParsecFieldGrammar' a -- ^ grammar
+ -> Map String CondTreeBuildInfo -- ^ common stanzas
+ -> [Field Position]
+ -> ParseResult (CondTree ConfVar [Dependency] a)
+parseCondTreeWithCommonStanzas v grammar commonStanzas = goImports []
+ where
+ hasElif = specHasElif v
+ hasCommonStanzas = specHasCommonStanzas v
+
+ getList' :: List CommaFSep Token String -> [String]
+ getList' = Newtype.unpack
+
+ -- parse leading imports
+ -- not supported:
+ goImports acc (Field (Name pos name) _ : fields) | name == "import", hasCommonStanzas == NoCommonStanzas = do
+ parseWarning pos PWTUnknownField "Unknown field: import. You should set cabal-version: 2.2 or larger to use common stanzas"
+ goImports acc fields
+ -- supported:
+ goImports acc (Field (Name pos name) fls : fields) | name == "import" = do
+ names <- getList' <$> runFieldParser pos parsec v fls
+ names' <- for names $ \commonName ->
+ case Map.lookup commonName commonStanzas of
+ Nothing -> do
+ parseFailure pos $ "Undefined common stanza imported: " ++ commonName
+ pure Nothing
+ Just commonTree ->
+ pure (Just commonTree)
+
+ goImports (acc ++ catMaybes names') fields
+
+ -- Go to parsing condTree after first non-import 'Field'.
+ goImports acc fields = go acc fields
+
+ -- parse actual CondTree
+ go :: [CondTreeBuildInfo] -> [Field Position] -> ParseResult (CondTree ConfVar [Dependency] a)
+ go bis fields = do
+ x <- parseCondTree v hasElif grammar (view L.targetBuildDepends) fields
+ pure $ foldr mergeCommonStanza x bis
+
+mergeCommonStanza
+ :: forall a. FromBuildInfo a
+ => CondTree ConfVar [Dependency] BuildInfo
+ -> CondTree ConfVar [Dependency] a
+ -> CondTree ConfVar [Dependency] a
+mergeCommonStanza (CondNode bi _ bis) (CondNode x _ cs) =
+ CondNode x' (x' ^. L.targetBuildDepends) cs'
+ where
+ -- new value is old value with buildInfo field _prepended_.
+ x' = x & L.buildInfo %~ (bi <>)
+
+ -- tree components are appended together.
+ cs' = map (fmap fromBuildInfo) bis ++ cs
+
+-------------------------------------------------------------------------------
+-- Branches
+-------------------------------------------------------------------------------
+
+-- Check that a property holds on all branches of a condition tree
+onAllBranches :: forall v c a. Monoid a => (a -> Bool) -> CondTree v c a -> Bool
+onAllBranches p = go mempty
+ where
+ -- If the current level of the tree satisfies the property, then we are
+ -- done. If not, then one of the conditional branches below the current node
+ -- must satisfy it. Each node may have multiple immediate children; we only
+ -- one need one to satisfy the property because the configure step uses
+ -- 'mappend' to join together the results of flag resolution.
+ go :: a -> CondTree v c a -> Bool
+ go acc ct = let acc' = acc `mappend` condTreeData ct
+ in p acc' || any (goBranch acc') (condTreeComponents ct)
+
+ -- Both the 'true' and the 'false' block must satisfy the property.
+ goBranch :: a -> CondBranch v c a -> Bool
+ goBranch _ (CondBranch _ _ Nothing) = False
+ goBranch acc (CondBranch _ t (Just e)) = go acc t && go acc e
+
+-------------------------------------------------------------------------------
-- Old syntax
-------------------------------------------------------------------------------
@@ -432,6 +696,7 @@ sectionizeFields fs = case classifyFields fs of
data Syntax = OldSyntax | NewSyntax
deriving (Eq, Show)
+-- TODO:
libFieldNames :: [FieldName]
libFieldNames = fieldGrammarKnownFieldList (libraryFieldGrammar Nothing)
@@ -443,22 +708,18 @@ readHookedBuildInfo :: Verbosity -> FilePath -> IO HookedBuildInfo
readHookedBuildInfo = readAndParseFile parseHookedBuildInfo
parseHookedBuildInfo :: BS.ByteString -> ParseResult HookedBuildInfo
-parseHookedBuildInfo bs = case readFields' bs' of
+parseHookedBuildInfo bs = case readFields' bs of
Right (fs, lexWarnings) -> do
- when patched $
- parseWarning zeroPos PWTQuirkyCabalFile "Legacy cabal file"
parseHookedBuildInfo' lexWarnings fs
-- TODO: better marshalling of errors
Left perr -> parseFatalFailure zeroPos (show perr)
- where
- (patched, bs') = patchQuirks bs
parseHookedBuildInfo'
:: [LexWarning]
-> [Field Position]
-> ParseResult HookedBuildInfo
parseHookedBuildInfo' lexWarnings fs = do
- parseWarnings (fmap toPWarning lexWarnings)
+ parseWarnings (toPWarnings lexWarnings)
(mLibFields, exes) <- stanzas fs
mLib <- parseLib mLibFields
biExes <- traverse parseExe exes
@@ -467,11 +728,11 @@ parseHookedBuildInfo' lexWarnings fs = do
parseLib :: Fields Position -> ParseResult (Maybe BuildInfo)
parseLib fields
| Map.null fields = pure Nothing
- | otherwise = Just <$> parseFieldGrammar fields buildInfoFieldGrammar
+ | otherwise = Just <$> parseFieldGrammar cabalSpecLatest fields buildInfoFieldGrammar
parseExe :: (UnqualComponentName, Fields Position) -> ParseResult (UnqualComponentName, BuildInfo)
parseExe (n, fields) = do
- bi <- parseFieldGrammar fields buildInfoFieldGrammar
+ bi <- parseFieldGrammar cabalSpecLatest fields buildInfoFieldGrammar
pure (n, bi)
stanzas :: [Field Position] -> ParseResult (Fields Position, [(UnqualComponentName, Fields Position)])
@@ -491,7 +752,7 @@ parseHookedBuildInfo' lexWarnings fs = do
:: ([FieldLine Position], [Field Position])
-> ParseResult ((UnqualComponentName, Fields Position), Maybe ([FieldLine Position], [Field Position]))
toExe (fss, fields) = do
- name <- runFieldParser zeroPos parsec fss
+ name <- runFieldParser zeroPos parsec cabalSpecLatest fss
let (hdr0, rest) = breakMaybe isExecutableField fields
hdr <- toFields hdr0
pure ((name, hdr), rest)
@@ -500,3 +761,46 @@ parseHookedBuildInfo' lexWarnings fs = do
| name == "executable" = Just fss
| otherwise = Nothing
isExecutableField _ = Nothing
+
+-- | Quickly scan new-style spec-version
+--
+-- A new-style spec-version declaration begins the .cabal file and
+-- follow the following case-insensitive grammar (expressed in
+-- RFC5234 ABNF):
+--
+-- @
+-- newstyle-spec-version-decl = "cabal-version" *WS ":" *WS newstyle-pec-version *WS
+--
+-- spec-version = NUM "." NUM [ "." NUM ]
+--
+-- NUM = DIGIT0 / DIGITP 1*DIGIT0
+-- DIGIT0 = %x30-39
+-- DIGITP = %x31-39
+-- WS = %20
+-- @
+--
+scanSpecVersion :: BS.ByteString -> Maybe Version
+scanSpecVersion bs = do
+ fstline':_ <- pure (BS8.lines bs)
+
+ -- parse <newstyle-spec-version-decl>
+ -- normalise: remove all whitespace, convert to lower-case
+ let fstline = BS.map toLowerW8 $ BS.filter (/= 0x20) fstline'
+ ["cabal-version",vers] <- pure (BS8.split ':' fstline)
+
+ -- parse <spec-version>
+ --
+ -- This is currently more tolerant regarding leading 0 digits.
+ --
+ ver <- simpleParsec (BS8.unpack vers)
+ guard $ case versionNumbers ver of
+ [_,_] -> True
+ [_,_,_] -> True
+ _ -> False
+
+ pure ver
+ where
+ -- | Translate ['A'..'Z'] to ['a'..'z']
+ toLowerW8 :: Word8 -> Word8
+ toLowerW8 w | 0x40 < w && w < 0x5b = w+0x20
+ | otherwise = w
diff --git a/cabal/Cabal/Distribution/PackageDescription/PrettyPrint.hs b/cabal/Cabal/Distribution/PackageDescription/PrettyPrint.hs
index 452aed5..ed82819 100644
--- a/cabal/Cabal/Distribution/PackageDescription/PrettyPrint.hs
+++ b/cabal/Cabal/Distribution/PackageDescription/PrettyPrint.hs
@@ -60,7 +60,7 @@ writeGenericPackageDescription fpath pkg = writeUTF8File fpath (showGenericPacka
-- | Writes a generic package description to a string
showGenericPackageDescription :: GenericPackageDescription -> String
-showGenericPackageDescription = render . ppGenericPackageDescription
+showGenericPackageDescription = render . ($+$ text "") . ppGenericPackageDescription
ppGenericPackageDescription :: GenericPackageDescription -> Doc
ppGenericPackageDescription gpd =
@@ -244,3 +244,4 @@ showHookedBuildInfo (mb_lib_bi, ex_bis) = render $
$$ prettyFieldGrammar buildInfoFieldGrammar bi
| (name, bi) <- ex_bis
]
+ $+$ text ""
diff --git a/cabal/Cabal/Distribution/Parsec/Class.hs b/cabal/Cabal/Distribution/Parsec/Class.hs
index d157cde..d65ea54 100644
--- a/cabal/Cabal/Distribution/Parsec/Class.hs
+++ b/cabal/Cabal/Distribution/Parsec/Class.hs
@@ -1,10 +1,17 @@
-{-# LANGUAGE RankNTypes, FlexibleContexts #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
module Distribution.Parsec.Class (
Parsec(..),
- ParsecParser,
+ ParsecParser (..),
+ runParsecParser,
simpleParsec,
- -- * Warnings
- parsecWarning,
+ lexemeParsec,
+ eitherParsec,
+ explicitEitherParsec,
+ -- * CabalParsing & warnings
+ CabalParsing (..),
PWarnType (..),
-- * Utilities
parsecToken,
@@ -13,47 +20,152 @@ module Distribution.Parsec.Class (
parsecQuoted,
parsecMaybeQuoted,
parsecCommaList,
+ parsecLeadingCommaList,
parsecOptCommaList,
parsecStandard,
parsecUnqualComponentName,
) where
-import Data.Functor.Identity (Identity (..))
-import qualified Distribution.Compat.Parsec as P
-import Distribution.Compat.Prelude
-import Distribution.Parsec.Common (PWarnType (..), PWarning (..), Position (..))
-import Prelude ()
-import qualified Text.Parsec as Parsec
-import qualified Text.Parsec.Language as Parsec
-import qualified Text.Parsec.Token as Parsec
+import Data.Char (digitToInt, intToDigit)
+import Data.Functor.Identity (Identity (..))
+import Data.List (transpose)
+import Distribution.CabalSpecVersion
+import Distribution.Compat.Prelude
+import Distribution.Parsec.FieldLineStream
+import Distribution.Parsec.Common (PWarnType (..), PWarning (..), Position (..))
+import Numeric (showIntAtBase)
+import Prelude ()
+
+import qualified Distribution.Compat.CharParsing as P
+import qualified Distribution.Compat.MonadFail as Fail
+import qualified Distribution.Compat.ReadP as ReadP
+import qualified Text.Parsec as Parsec
-------------------------------------------------------------------------------
-- Class
-------------------------------------------------------------------------------
--- |
---
--- TODO: implementation details: should be careful about consuming
--- trailing whitespace?
--- Should we always consume it?
+-- | Class for parsing with @parsec@. Mainly used for @.cabal@ file fields.
class Parsec a where
- parsec :: ParsecParser a
+ parsec :: CabalParsing m => m a
+
+-- | Parsing class which
+--
+-- * can report Cabal parser warnings.
+--
+-- * knows @cabal-version@ we work with
+--
+class (P.CharParsing m, MonadPlus m) => CabalParsing m where
+ parsecWarning :: PWarnType -> String -> m ()
+
+ parsecHaskellString :: m String
+ parsecHaskellString = stringLiteral
+
+ askCabalSpecVersion :: m CabalSpecVersion
+
+instance t ~ Char => CabalParsing (ReadP.Parser r t) where
+ parsecWarning _ _ = pure ()
+ askCabalSpecVersion = pure cabalSpecLatest
+
+-- | 'parsec' /could/ consume trailing spaces, this function /will/ consume.
+lexemeParsec :: (CabalParsing m, Parsec a) => m a
+lexemeParsec = parsec <* P.spaces
+
+newtype ParsecParser a = PP { unPP
+ :: CabalSpecVersion -> Parsec.Parsec FieldLineStream [PWarning] a
+ }
+
+liftParsec :: Parsec.Parsec FieldLineStream [PWarning] a -> ParsecParser a
+liftParsec p = PP $ \_ -> p
+
+instance Functor ParsecParser where
+ fmap f p = PP $ \v -> fmap f (unPP p v)
+ {-# INLINE fmap #-}
+
+ x <$ p = PP $ \v -> x <$ unPP p v
+ {-# INLINE (<$) #-}
+
+instance Applicative ParsecParser where
+ pure = liftParsec . pure
+ {-# INLINE pure #-}
+
+ f <*> x = PP $ \v -> unPP f v <*> unPP x v
+ {-# INLINE (<*>) #-}
+ f *> x = PP $ \v -> unPP f v *> unPP x v
+ {-# INLINE (*>) #-}
+ f <* x = PP $ \v -> unPP f v <* unPP x v
+ {-# INLINE (<*) #-}
+
+instance Alternative ParsecParser where
+ empty = liftParsec empty
+
+ a <|> b = PP $ \v -> unPP a v <|> unPP b v
+ {-# INLINE (<|>) #-}
+
+ many p = PP $ \v -> many (unPP p v)
+ {-# INLINE many #-}
+
+ some p = PP $ \v -> some (unPP p v)
+ {-# INLINE some #-}
+
+instance Monad ParsecParser where
+ return = pure
+
+ m >>= k = PP $ \v -> unPP m v >>= \x -> unPP (k x) v
+ {-# INLINE (>>=) #-}
+ (>>) = (*>)
+ {-# INLINE (>>) #-}
+
+ fail = Fail.fail
+
+instance MonadPlus ParsecParser where
+ mzero = empty
+ mplus = (<|>)
+
+instance Fail.MonadFail ParsecParser where
+ fail = P.unexpected
+
+instance P.Parsing ParsecParser where
+ try p = PP $ \v -> P.try (unPP p v)
+ p <?> d = PP $ \v -> unPP p v P.<?> d
+ skipMany p = PP $ \v -> P.skipMany (unPP p v)
+ skipSome p = PP $ \v -> P.skipSome (unPP p v)
+ unexpected = liftParsec . P.unexpected
+ eof = liftParsec P.eof
+ notFollowedBy p = PP $ \v -> P.notFollowedBy (unPP p v)
- -- | 'parsec' /could/ consume trailing spaces, this function /must/ consume.
- lexemeParsec :: ParsecParser a
- lexemeParsec = parsec <* P.spaces
+instance P.CharParsing ParsecParser where
+ satisfy = liftParsec . P.satisfy
+ char = liftParsec . P.char
+ notChar = liftParsec . P.notChar
+ anyChar = liftParsec P.anyChar
+ string = liftParsec . P.string
-type ParsecParser a = forall s. P.Stream s Identity Char => P.Parsec s [PWarning] a
+instance CabalParsing ParsecParser where
+ parsecWarning t w = liftParsec $ Parsec.modifyState (PWarning t (Position 0 0) w :)
+ askCabalSpecVersion = PP pure
-- | Parse a 'String' with 'lexemeParsec'.
simpleParsec :: Parsec a => String -> Maybe a
simpleParsec
= either (const Nothing) Just
- . P.runParser (lexemeParsec <* P.eof) [] "<simpleParsec>"
+ . runParsecParser lexemeParsec "<simpleParsec>"
+ . fieldLineStreamFromString
-parsecWarning :: PWarnType -> String -> P.Parsec s [PWarning] ()
-parsecWarning t w =
- Parsec.modifyState (PWarning t (Position 0 0) w :)
+-- | Parse a 'String' with 'lexemeParsec'.
+eitherParsec :: Parsec a => String -> Either String a
+eitherParsec = explicitEitherParsec parsec
+
+-- | Parse a 'String' with given 'ParsecParser'. Trailing whitespace is accepted.
+explicitEitherParsec :: ParsecParser a -> String -> Either String a
+explicitEitherParsec parser
+ = either (Left . show) Right
+ . runParsecParser (parser <* P.spaces) "<eitherParsec>"
+ . fieldLineStreamFromString
+
+-- | Run 'ParsecParser' with 'cabalSpecLatest'.
+runParsecParser :: ParsecParser a -> FilePath -> FieldLineStream -> Either Parsec.ParseError a
+runParsecParser p n = Parsec.runParser (unPP p cabalSpecLatest <* P.eof) [] n
instance Parsec a => Parsec (Identity a) where
parsec = Identity <$> parsec
@@ -73,21 +185,28 @@ instance Parsec Bool where
"Boolean values are case sensitive, use 'True' or 'False'."
-- | @[^ ,]@
-parsecToken :: P.Stream s Identity Char => P.Parsec s [PWarning] String
-parsecToken = parsecHaskellString <|> (P.munch1 (\x -> not (isSpace x) && x /= ',') P.<?> "identifier" )
+parsecToken :: CabalParsing m => m String
+parsecToken = parsecHaskellString <|> ((P.munch1 (\x -> not (isSpace x) && x /= ',') P.<?> "identifier" ) >>= checkNotDoubleDash)
-- | @[^ ]@
-parsecToken' :: P.Stream s Identity Char => P.Parsec s [PWarning] String
-parsecToken' = parsecHaskellString <|> (P.munch1 (not . isSpace) P.<?> "token")
+parsecToken' :: CabalParsing m => m String
+parsecToken' = parsecHaskellString <|> ((P.munch1 (not . isSpace) P.<?> "token") >>= checkNotDoubleDash)
+
+checkNotDoubleDash :: CabalParsing m => String -> m String
+checkNotDoubleDash s = do
+ when (s == "--") $ parsecWarning PWTDoubleDash $ unwords
+ [ "Double-dash token found."
+ , "Note: there are no end-of-line comments in .cabal files, only whole line comments."
+ , "Use \"--\" (quoted double dash) to silence this warning, if you actually want -- token"
+ ]
-parsecFilePath :: P.Stream s Identity Char => P.Parsec s [PWarning] FilePath
+ return s
+
+parsecFilePath :: CabalParsing m => m FilePath
parsecFilePath = parsecToken
-- | Parse a benchmark/test-suite types.
-parsecStandard
- :: (Parsec ver, P.Stream s Identity Char)
- => (ver -> String -> a)
- -> P.Parsec s [PWarning] a
+parsecStandard :: (CabalParsing m, Parsec ver) => (ver -> String -> a) -> m a
parsecStandard f = do
cs <- some $ P.try (component <* P.char '-')
ver <- parsec
@@ -100,57 +219,135 @@ parsecStandard f = do
-- each component must contain an alphabetic character, to avoid
-- ambiguity in identifiers like foo-1 (the 1 is the version number).
-parsecCommaList
- :: P.Stream s Identity Char
- => P.Parsec s [PWarning] a
- -> P.Parsec s [PWarning] [a]
-parsecCommaList p = P.sepBy (p <* P.spaces) (P.char ',' *> P.spaces)
+parsecCommaList :: CabalParsing m => m a -> m [a]
+parsecCommaList p = P.sepBy (p <* P.spaces) (P.char ',' *> P.spaces P.<?> "comma")
+
+-- | Like 'parsecCommaList' but accept leading or trailing comma.
+--
+-- @
+-- p (comma p)* -- p `sepBy` comma
+-- (comma p)* -- leading comma
+-- (p comma)* -- trailing comma
+-- @
+parsecLeadingCommaList :: CabalParsing m => m a -> m [a]
+parsecLeadingCommaList p = do
+ c <- P.optional comma
+ case c of
+ Nothing -> P.sepEndBy1 lp comma <|> pure []
+ Just _ -> P.sepBy1 lp comma
+ where
+ lp = p <* P.spaces
+ comma = P.char ',' *> P.spaces P.<?> "comma"
-parsecOptCommaList
- :: P.Stream s Identity Char
- => P.Parsec s [PWarning] a
- -> P.Parsec s [PWarning] [a]
+parsecOptCommaList :: CabalParsing m => m a -> m [a]
parsecOptCommaList p = P.sepBy (p <* P.spaces) (P.optional comma)
where
comma = P.char ',' *> P.spaces
-- | Content isn't unquoted
-parsecQuoted
- :: P.Stream s Identity Char
- => P.Parsec s [PWarning] a
- -> P.Parsec s [PWarning] a
+parsecQuoted :: CabalParsing m => m a -> m a
parsecQuoted = P.between (P.char '"') (P.char '"')
-- | @parsecMaybeQuoted p = 'parsecQuoted' p <|> p@.
-parsecMaybeQuoted
- :: P.Stream s Identity Char
- => P.Parsec s [PWarning] a
- -> P.Parsec s [PWarning] a
+parsecMaybeQuoted :: CabalParsing m => m a -> m a
parsecMaybeQuoted p = parsecQuoted p <|> p
-parsecHaskellString :: P.Stream s Identity Char => P.Parsec s [PWarning] String
-parsecHaskellString = Parsec.stringLiteral $ Parsec.makeTokenParser Parsec.emptyDef
- { Parsec.commentStart = "{-"
- , Parsec.commentEnd = "-}"
- , Parsec.commentLine = "--"
- , Parsec.nestedComments = True
- , Parsec.identStart = P.satisfy isAlphaNum
- , Parsec.identLetter = P.satisfy isAlphaNum <|> P.oneOf "_'"
- , Parsec.opStart = opl
- , Parsec.opLetter = opl
- , Parsec.reservedOpNames= []
- , Parsec.reservedNames = []
- , Parsec.caseSensitive = True
- }
- where
- opl = P.oneOf ":!#$%&*+./<=>?@\\^|-~"
-
-parsecUnqualComponentName :: P.Stream s Identity Char => P.Parsec s [PWarning] String
+parsecUnqualComponentName :: CabalParsing m => m String
parsecUnqualComponentName = intercalate "-" <$> P.sepBy1 component (P.char '-')
where
- component :: P.Stream s Identity Char => P.Parsec s [PWarning] String
+ component :: CabalParsing m => m String
component = do
cs <- P.munch1 isAlphaNum
if all isDigit cs
then fail "all digits in portion of unqualified component name"
else return cs
+
+stringLiteral :: forall m. P.CharParsing m => m String
+stringLiteral = lit where
+ lit :: m String
+ lit = foldr (maybe id (:)) ""
+ <$> P.between (P.char '"') (P.char '"' P.<?> "end of string") (many stringChar)
+ P.<?> "string"
+
+ stringChar :: m (Maybe Char)
+ stringChar = Just <$> stringLetter
+ <|> stringEscape
+ P.<?> "string character"
+
+ stringLetter :: m Char
+ stringLetter = P.satisfy (\c -> (c /= '"') && (c /= '\\') && (c > '\026'))
+
+ stringEscape :: m (Maybe Char)
+ stringEscape = P.char '\\' *> esc where
+ esc :: m (Maybe Char)
+ esc = Nothing <$ escapeGap
+ <|> Nothing <$ escapeEmpty
+ <|> Just <$> escapeCode
+
+ escapeEmpty, escapeGap :: m Char
+ escapeEmpty = P.char '&'
+ escapeGap = P.skipSpaces1 *> (P.char '\\' P.<?> "end of string gap")
+
+escapeCode :: forall m. P.CharParsing m => m Char
+escapeCode = (charEsc <|> charNum <|> charAscii <|> charControl) P.<?> "escape code"
+ where
+ charControl, charNum :: m Char
+ charControl = (\c -> toEnum (fromEnum c - fromEnum '@')) <$> (P.char '^' *> (P.upper <|> P.char '@'))
+ charNum = toEnum <$> num
+ where
+ num :: m Int
+ num = bounded 10 maxchar
+ <|> (P.char 'o' *> bounded 8 maxchar)
+ <|> (P.char 'x' *> bounded 16 maxchar)
+ maxchar = fromEnum (maxBound :: Char)
+
+ bounded :: Int -> Int -> m Int
+ bounded base bnd = foldl' (\x d -> base * x + digitToInt d) 0
+ <$> bounded' (take base thedigits) (map digitToInt $ showIntAtBase base intToDigit bnd "")
+ where
+ thedigits :: [m Char]
+ thedigits = map P.char ['0'..'9'] ++ map P.oneOf (transpose [['A'..'F'],['a'..'f']])
+
+ toomuch :: m a
+ toomuch = P.unexpected "out-of-range numeric escape sequence"
+
+ bounded', bounded'' :: [m Char] -> [Int] -> m [Char]
+ bounded' dps@(zero:_) bds = P.skipSome zero *> ([] <$ P.notFollowedBy (P.choice dps) <|> bounded'' dps bds)
+ <|> bounded'' dps bds
+ bounded' [] _ = error "bounded called with base 0"
+ bounded'' dps [] = [] <$ P.notFollowedBy (P.choice dps) <|> toomuch
+ bounded'' dps (bd : bds) = let anyd :: m Char
+ anyd = P.choice dps
+
+ nomore :: m ()
+ nomore = P.notFollowedBy anyd <|> toomuch
+
+ (low, ex : high) = splitAt bd dps
+ in ((:) <$> P.choice low <*> atMost (length bds) anyd) <* nomore
+ <|> ((:) <$> ex <*> ([] <$ nomore <|> bounded'' dps bds))
+ <|> if not (null bds)
+ then (:) <$> P.choice high <*> atMost (length bds - 1) anyd <* nomore
+ else empty
+ atMost n p | n <= 0 = pure []
+ | otherwise = ((:) <$> p <*> atMost (n - 1) p) <|> pure []
+
+ charEsc :: m Char
+ charEsc = P.choice $ parseEsc <$> escMap
+
+ parseEsc (c,code) = code <$ P.char c
+ escMap = zip "abfnrtv\\\"\'" "\a\b\f\n\r\t\v\\\"\'"
+
+ charAscii :: m Char
+ charAscii = P.choice $ parseAscii <$> asciiMap
+
+ parseAscii (asc,code) = P.try $ code <$ P.string asc
+ asciiMap = zip (ascii3codes ++ ascii2codes) (ascii3 ++ ascii2)
+ ascii2codes, ascii3codes :: [String]
+ ascii2codes = [ "BS","HT","LF","VT","FF","CR","SO"
+ , "SI","EM","FS","GS","RS","US","SP"]
+ ascii3codes = ["NUL","SOH","STX","ETX","EOT","ENQ","ACK"
+ ,"BEL","DLE","DC1","DC2","DC3","DC4","NAK"
+ ,"SYN","ETB","CAN","SUB","ESC","DEL"]
+ ascii2, ascii3 :: String
+ ascii2 = "\BS\HT\LF\VT\FF\CR\SO\SI\EM\FS\GS\RS\US\SP"
+ ascii3 = "\NUL\SOH\STX\ETX\EOT\ENQ\ACK\BEL\DLE\DC1\DC2\DC3\DC4\NAK\SYN\ETB\CAN\SUB\ESC\DEL"
diff --git a/cabal/Cabal/Distribution/Parsec/Common.hs b/cabal/Cabal/Distribution/Parsec/Common.hs
index 972b1e1..bc569ad 100644
--- a/cabal/Cabal/Distribution/Parsec/Common.hs
+++ b/cabal/Cabal/Distribution/Parsec/Common.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE DeriveGeneric #-}
-- | Module containing small types
module Distribution.Parsec.Common (
-- * Diagnostics
@@ -6,8 +7,6 @@ module Distribution.Parsec.Common (
PWarning (..),
PWarnType (..),
showPWarning,
- -- * Field parser
- FieldParser,
-- * Position
Position (..),
incPos,
@@ -16,14 +15,16 @@ module Distribution.Parsec.Common (
zeroPos,
) where
-import Prelude ()
-import Distribution.Compat.Prelude
-import System.FilePath (normalise)
-import qualified Text.Parsec as Parsec
+import Distribution.Compat.Prelude
+import Prelude ()
+import System.FilePath (normalise)
-- | Parser error.
data PError = PError Position String
- deriving (Show)
+ deriving (Show, Generic)
+
+instance Binary PError
+instance NFData PError where rnf = genericRnf
-- | Type of parser warning. We do classify warnings.
--
@@ -45,12 +46,23 @@ data PWarnType
| PWTExtraBenchmarkModule -- ^ extra benchmark-module field
| PWTLexNBSP
| PWTLexBOM
+ | PWTLexTab
| PWTQuirkyCabalFile -- ^ legacy cabal file that we know how to patch
- deriving (Eq, Ord, Show, Enum, Bounded)
+ | PWTDoubleDash -- ^ Double dash token, most likely it's a mistake - it's not a comment
+ | PWTMultipleSingularField -- ^ e.g. name or version should be specified only once.
+ | PWTBuildTypeDefault -- ^ Workaround for derive-package having build-type: Default. See <https://github.com/haskell/cabal/issues/5020>.
+ | PWTVersionLeadingZeros -- ^ See https://github.com/haskell-infra/hackage-trustees/issues/128
+ deriving (Eq, Ord, Show, Enum, Bounded, Generic)
+
+instance Binary PWarnType
+instance NFData PWarnType where rnf = genericRnf
-- | Parser warning.
data PWarning = PWarning !PWarnType !Position String
- deriving (Show)
+ deriving (Show, Generic)
+
+instance Binary PWarning
+instance NFData PWarning where rnf = genericRnf
showPWarning :: FilePath -> PWarning -> String
showPWarning fpath (PWarning _ pos msg) =
@@ -61,14 +73,6 @@ showPError fpath (PError pos msg) =
normalise fpath ++ ":" ++ showPos pos ++ ": " ++ msg
-------------------------------------------------------------------------------
--- Field parser
--------------------------------------------------------------------------------
-
--- | Field value parsers.
-type FieldParser = Parsec.Parsec String [PWarning] -- :: * -> *
-
-
--------------------------------------------------------------------------------
-- Position
-------------------------------------------------------------------------------
@@ -76,7 +80,10 @@ type FieldParser = Parsec.Parsec String [PWarning] -- :: * -> *
data Position = Position
{-# UNPACK #-} !Int -- row
{-# UNPACK #-} !Int -- column
- deriving (Eq, Ord, Show)
+ deriving (Eq, Ord, Show, Generic)
+
+instance Binary Position
+instance NFData Position where rnf = genericRnf
-- | Shift position by n columns to the right.
incPos :: Int -> Position -> Position
diff --git a/cabal/Cabal/Distribution/Parsec/ConfVar.hs b/cabal/Cabal/Distribution/Parsec/ConfVar.hs
index 43fb7d4..5afbc78 100644
--- a/cabal/Cabal/Distribution/Parsec/ConfVar.hs
+++ b/cabal/Cabal/Distribution/Parsec/ConfVar.hs
@@ -2,22 +2,23 @@
{-# LANGUAGE NoMonoLocalBinds #-}
module Distribution.Parsec.ConfVar (parseConditionConfVar) where
-import Distribution.Compat.Parsec (integral)
-import Distribution.Compat.Prelude
-import Distribution.Parsec.Class (Parsec (..))
-import Distribution.Parsec.Common
-import Distribution.Parsec.Field (SectionArg (..))
-import Distribution.Parsec.ParseResult
-import Distribution.Simple.Utils (fromUTF8BS)
-import Distribution.Types.Condition
-import Distribution.Types.GenericPackageDescription (ConfVar (..))
-import Distribution.Version
- (anyVersion, earlierVersion, intersectVersionRanges, laterVersion,
- majorBoundVersion, mkVersion, noVersion, orEarlierVersion, orLaterVersion,
- thisVersion, unionVersionRanges, withinVersion)
-import Prelude ()
-import qualified Text.Parsec as P
-import qualified Text.Parsec.Error as P
+import Distribution.Compat.CharParsing (char, integral)
+import Distribution.Compat.Prelude
+import Distribution.Parsec.Class (Parsec (..), runParsecParser)
+import Distribution.Parsec.Common
+import Distribution.Parsec.FieldLineStream
+import Distribution.Parsec.Field (SectionArg (..))
+import Distribution.Parsec.ParseResult
+import Distribution.Types.Condition
+import Distribution.Types.GenericPackageDescription (ConfVar (..))
+import Distribution.Version
+ (anyVersion, earlierVersion, intersectVersionRanges, laterVersion, majorBoundVersion,
+ mkVersion, noVersion, orEarlierVersion, orLaterVersion, thisVersion, unionVersionRanges,
+ withinVersion)
+import Prelude ()
+
+import qualified Text.Parsec as P
+import qualified Text.Parsec.Error as P
-- | Parse @'Condition' 'ConfVar'@ from section arguments provided by parsec
-- based outline parser.
@@ -60,7 +61,7 @@ parser = condOr
version = fromParsec
versionStar = mkVersion <$> fromParsec' versionStar' <* oper "*"
- versionStar' = some (integral <* P.char '.')
+ versionStar' = some (integral <* char '.')
versionRange = expr
where
@@ -88,8 +89,8 @@ parser = condOr
("==", thisVersion) ]
-- Number token can have many dots in it: SecArgNum (Position 65 15) "7.6.1"
- ident = tokenPrim $ \t -> case t of
- SecArgName _ s -> Just $ fromUTF8BS s
+ identBS = tokenPrim $ \t -> case t of
+ SecArgName _ s -> Just s
_ -> Nothing
boolLiteral' = tokenPrim $ \t -> case t of
@@ -119,8 +120,6 @@ parser = condOr
fromParsec = fromParsec' parsec
fromParsec' p = do
- i <- ident
- case P.runParser (p <* P.eof) [] "<ident>" i of
- Right x -> pure x
- -- TODO: better lifting or errors / warnings
- Left err -> fail $ show err
+ bs <- identBS
+ let fls = fieldLineStreamFromBS bs
+ either (fail . show) pure (runParsecParser p "<fromParsec'>" fls)
diff --git a/cabal/Cabal/Distribution/Parsec/FieldLineStream.hs b/cabal/Cabal/Distribution/Parsec/FieldLineStream.hs
new file mode 100644
index 0000000..1ac772c
--- /dev/null
+++ b/cabal/Cabal/Distribution/Parsec/FieldLineStream.hs
@@ -0,0 +1,96 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings , ScopedTypeVariables #-}
+{-# OPTIONS_GHC -Wall -Werror #-}
+module Distribution.Parsec.FieldLineStream (
+ FieldLineStream (..),
+ fieldLinesToStream,
+ fieldLineStreamFromString,
+ fieldLineStreamFromBS,
+ ) where
+
+import Data.Bits
+import Data.ByteString (ByteString)
+import Distribution.Compat.Prelude
+import Distribution.Parsec.Field (FieldLine (..))
+import Distribution.Utils.Generic (toUTF8BS)
+import Prelude ()
+
+import qualified Data.ByteString as BS
+import qualified Text.Parsec as Parsec
+
+-- | This is essentially a lazy bytestring, but chunks are glued with newline '\n'.
+data FieldLineStream
+ = FLSLast !ByteString
+ | FLSCons {-# UNPACK #-} !ByteString FieldLineStream
+ deriving Show
+
+fieldLinesToStream :: [FieldLine ann] -> FieldLineStream
+fieldLinesToStream [] = end
+fieldLinesToStream [FieldLine _ bs] = FLSLast bs
+fieldLinesToStream (FieldLine _ bs : fs) = FLSCons bs (fieldLinesToStream fs)
+
+end :: FieldLineStream
+end = FLSLast ""
+
+-- | Convert 'String' to 'FieldLineStream'.
+--
+-- /Note:/ inefficient!
+fieldLineStreamFromString :: String -> FieldLineStream
+fieldLineStreamFromString = FLSLast . toUTF8BS
+
+fieldLineStreamFromBS :: ByteString -> FieldLineStream
+fieldLineStreamFromBS = FLSLast
+
+instance Monad m => Parsec.Stream FieldLineStream m Char where
+ uncons (FLSLast bs) = return $ case BS.uncons bs of
+ Nothing -> Nothing
+ Just (c, bs') -> Just (unconsChar c bs' (\bs'' -> FLSLast bs'') end)
+
+ uncons (FLSCons bs s) = return $ case BS.uncons bs of
+ -- as lines are glued with '\n', we return '\n' here!
+ Nothing -> Just ('\n', s)
+ Just (c, bs') -> Just (unconsChar c bs' (\bs'' -> FLSCons bs'' s) s)
+
+-- Bssed on implementation 'decodeStringUtf8'
+unconsChar :: forall a. Word8 -> ByteString -> (ByteString -> a) -> a -> (Char, a)
+unconsChar c0 bs0 f next
+ | c0 <= 0x7F = (chr (fromIntegral c0), f bs0)
+ | c0 <= 0xBF = (replacementChar, f bs0)
+ | c0 <= 0xDF = twoBytes
+ | c0 <= 0xEF = moreBytes 3 0x800 bs0 (fromIntegral $ c0 .&. 0xF)
+ | c0 <= 0xF7 = moreBytes 4 0x10000 bs0 (fromIntegral $ c0 .&. 0x7)
+ | c0 <= 0xFB = moreBytes 5 0x200000 bs0 (fromIntegral $ c0 .&. 0x3)
+ | c0 <= 0xFD = moreBytes 6 0x4000000 bs0 (fromIntegral $ c0 .&. 0x1)
+ | otherwise = error $ "not implemented " ++ show c0
+ where
+ twoBytes = case BS.uncons bs0 of
+ Nothing -> (replacementChar, next)
+ Just (c1, bs1)
+ | c1 .&. 0xC0 == 0x80 ->
+ if d >= 0x80
+ then (chr d, f bs1)
+ else (replacementChar, f bs1)
+ | otherwise -> (replacementChar, f bs1)
+ where
+ d = (fromIntegral (c0 .&. 0x1F) `shiftL` 6) .|. fromIntegral (c1 .&. 0x3F)
+
+ moreBytes :: Int -> Int -> ByteString -> Int -> (Char, a)
+ moreBytes 1 overlong bs' acc
+ | overlong <= acc, acc <= 0x10FFFF, acc < 0xD800 || 0xDFFF < acc
+ = (chr acc, f bs')
+ | otherwise
+ = (replacementChar, f bs')
+
+ moreBytes byteCount overlong bs' acc = case BS.uncons bs' of
+ Nothing -> (replacementChar, f bs')
+ Just (cn, bs1)
+ | cn .&. 0xC0 == 0x80 -> moreBytes
+ (byteCount-1)
+ overlong
+ bs1
+ ((acc `shiftL` 6) .|. fromIntegral cn .&. 0x3F)
+ | otherwise -> (replacementChar, f bs1)
+
+replacementChar :: Char
+replacementChar = '\xfffd'
diff --git a/cabal/Cabal/Distribution/Parsec/Lexer.hs b/cabal/Cabal/Distribution/Parsec/Lexer.hs
index 720d084..64f5222 100644
--- a/cabal/Cabal/Distribution/Parsec/Lexer.hs
+++ b/cabal/Cabal/Distribution/Parsec/Lexer.hs
@@ -53,7 +53,6 @@ import qualified Data.Text.Encoding as T
import qualified Data.Text.Encoding.Error as T
#endif
-
#if __GLASGOW_HASKELL__ >= 603
#include "ghcconfig.h"
#elif defined(__GLASGOW_HASKELL__)
@@ -85,8 +84,7 @@ alex_deflt :: AlexAddr
alex_deflt = AlexA# "\xff\xff\xff\xff\xff\xff\xff\xff\x2b\x00\x27\x00\x1b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x13\x00\xff\xff\xff\xff\xff\xff\xff\xff\x18\x00\x1b\x00\x1b\x00\x1b\x00\xff\xff\x0d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x27\x00\xff\xff\xff\xff\xff\xff\x2b\x00\xff\xff\xff\xff\xff\xff\xff\xff"#
alex_accept = listArray (0::Int,47) [AlexAcc (alex_action_0),AlexAcc (alex_action_20),AlexAcc (alex_action_16),AlexAcc (alex_action_3),AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAcc (alex_action_1),AlexAcc (alex_action_1),AlexAccSkip,AlexAcc (alex_action_3),AlexAcc (alex_action_4),AlexAcc (alex_action_5),AlexAccSkip,AlexAccSkip,AlexAcc (alex_action_8),AlexAcc (alex_action_8),AlexAcc (alex_action_8),AlexAcc (alex_action_9),AlexAcc (alex_action_9),AlexAcc (alex_action_10),AlexAcc (alex_action_11),AlexAcc (alex_action_12),AlexAcc (alex_action_13),AlexAcc (alex_action_14),AlexAcc (alex_action_15),AlexAcc (alex_action_15),AlexAcc (alex_action_16),AlexAccSkip,AlexAcc (alex_action_18),AlexAcc (alex_action_19),AlexAcc (alex_action_19),AlexAccSkip,AlexAcc (alex_action_22),AlexAcc (alex_action_23),AlexAcc (alex_action_24),AlexAcc (alex_action_25),AlexAcc (alex_action_25)]
-{-# LINE 152 "boot/Lexer.x" #-}
-
+{-# LINE 151 "boot/Lexer.x" #-}
-- | Tokens of outer cabal file structure. Field values are treated opaquely.
data Token = TokSym !ByteString -- ^ Haskell-like identifier, number or operator
@@ -110,10 +108,17 @@ toki t pos len input = return $! L pos (t (B.take len input))
tok :: Token -> Position -> Int -> ByteString -> Lex LToken
tok t pos _len _input = return $! L pos t
+checkLeadingWhitespace :: Int -> ByteString -> Lex Int
+checkLeadingWhitespace len bs
+ | B.any (== 9) (B.take len bs) = do
+ addWarning LexWarningTab
+ checkWhitespace len bs
+ | otherwise = checkWhitespace len bs
+
checkWhitespace :: Int -> ByteString -> Lex Int
checkWhitespace len bs
| B.any (== 194) (B.take len bs) = do
- addWarning LexWarningNBSP "Non-breaking space found"
+ addWarning LexWarningNBSP
return $ len - B.count 194 (B.take len bs)
| otherwise = return len
@@ -159,7 +164,6 @@ lexToken = do
--traceShow t $ return tok
return t
-
checkPosition :: Position -> ByteString -> ByteString -> Int -> Lex ()
#ifdef CABAL_PARSEC_DEBUG
checkPosition pos@(Position lineno colno) inp inp' len_chars = do
@@ -190,7 +194,6 @@ ltest code s =
let (ws, xs) = execLexer (setStartCode code >> lexAll) (B.Char8.pack s)
in traverse_ print ws >> traverse_ print xs
-
mkLexState :: ByteString -> LexState
mkLexState input = LexState
{ curPos = Position 1 1
@@ -216,7 +219,6 @@ lines' s1
-> [l]
#endif
-
bol_field_braces,bol_field_layout,bol_section,in_field_braces,in_field_layout,in_section :: Int
bol_field_braces = 1
bol_field_layout = 2
@@ -225,12 +227,12 @@ in_field_braces = 4
in_field_layout = 5
in_section = 6
alex_action_0 = \_ len _ -> do
- when (len /= 0) $ addWarning LexWarningBOM "Byte-order mark found at the beginning of the file"
+ when (len /= 0) $ addWarning LexWarningBOM
setStartCode bol_section
lexToken
alex_action_1 = \_pos len inp -> checkWhitespace len inp >> adjustPos retPos >> lexToken
-alex_action_3 = \pos len inp -> checkWhitespace len inp >>
+alex_action_3 = \pos len inp -> checkLeadingWhitespace len inp >>
if B.length inp == len
then return (L pos EOF)
else setStartCode in_section
@@ -245,7 +247,7 @@ alex_action_12 = tok Colon
alex_action_13 = tok OpenBrace
alex_action_14 = tok CloseBrace
alex_action_15 = \_ _ _ -> adjustPos retPos >> setStartCode bol_section >> lexToken
-alex_action_16 = \pos len inp -> checkWhitespace len inp >>= \len' ->
+alex_action_16 = \pos len inp -> checkLeadingWhitespace len inp >>= \len' ->
if B.length inp == len
then return (L pos EOF)
else setStartCode in_field_layout
@@ -266,67 +268,9 @@ alex_action_25 = \_ _ _ -> adjustPos retPos >> setStartCode bol_field_braces >>
# 17 "/usr/include/stdc-predef.h" 3 4
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
{-# LINE 10 "<command-line>" #-}
{-# LINE 1 "/opt/ghc/7.10.3/lib/ghc-7.10.3/include/ghcversion.h" #-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
{-# LINE 10 "<command-line>" #-}
{-# LINE 1 "templates/GenericTemplate.hs" #-}
-- -----------------------------------------------------------------------------
@@ -340,10 +284,6 @@ alex_action_25 = \_ _ _ -> adjustPos retPos >> setStartCode bol_field_braces >>
{-# LINE 21 "templates/GenericTemplate.hs" #-}
-
-
-
-
-- Do not remove this comment. Required to fix CPP parsing when using GCC and a clang-compiled alex.
#if __GLASGOW_HASKELL__ > 706
#define GTE(n,m) (tagToEnum# (n >=# m))
@@ -354,7 +294,6 @@ alex_action_25 = \_ _ _ -> adjustPos retPos >> setStartCode bol_field_braces >>
#endif
{-# LINE 51 "templates/GenericTemplate.hs" #-}
-
data AlexAddr = AlexA# Addr#
-- Do not remove this comment. Required to fix CPP parsing when using GCC and a clang-compiled alex.
#if __GLASGOW_HASKELL__ < 503
@@ -374,10 +313,6 @@ alexIndexInt16OffAddr (AlexA# arr) off =
indexInt16OffAddr# arr off
#endif
-
-
-
-
{-# INLINE alexIndexInt32OffAddr #-}
alexIndexInt32OffAddr (AlexA# arr) off =
#ifdef WORDS_BIGENDIAN
@@ -395,11 +330,6 @@ alexIndexInt32OffAddr (AlexA# arr) off =
indexInt32OffAddr# arr off
#endif
-
-
-
-
-
#if __GLASGOW_HASKELL__ < 503
quickIndex arr i = arr ! i
#else
@@ -407,9 +337,6 @@ quickIndex arr i = arr ! i
quickIndex = unsafeAt
#endif
-
-
-
-- -----------------------------------------------------------------------------
-- Main lexing routines
@@ -429,28 +356,19 @@ alexScanUser user input (I# (sc))
case alexGetByte input of
Nothing ->
-
-
AlexEOF
Just _ ->
-
-
AlexError input'
(AlexLastSkip input'' len, _) ->
-
-
AlexSkip input'' len
(AlexLastAcc k input''' len, _) ->
-
-
AlexToken input''' len k
-
-- Push the input through the DFA, remembering the most recent accepting
-- state it encountered.
@@ -464,8 +382,6 @@ alex_scan_tkn user orig_input len input s last_acc =
Nothing -> (new_acc, input)
Just (c, new_input) ->
-
-
case fromIntegral c of { (I# (ord_c)) ->
let
base = alexIndexInt32OffAddr alex_base s
diff --git a/cabal/Cabal/Distribution/Parsec/LexerMonad.hs b/cabal/Cabal/Distribution/Parsec/LexerMonad.hs
index 50fc93f..6eb1085 100644
--- a/cabal/Cabal/Distribution/Parsec/LexerMonad.hs
+++ b/cabal/Cabal/Distribution/Parsec/LexerMonad.hs
@@ -27,15 +27,17 @@ module Distribution.Parsec.LexerMonad (
LexWarning(..),
LexWarningType(..),
addWarning,
- toPWarning,
+ toPWarnings,
) where
import qualified Data.ByteString as B
import Distribution.Compat.Prelude
-import Distribution.Parsec.Common (PWarnType (..), PWarning (..), Position (..))
+import Distribution.Parsec.Common (PWarnType (..), PWarning (..), Position (..), showPos)
import Prelude ()
+import qualified Data.Map.Strict as Map
+
#ifdef CABAL_PARSEC_DEBUG
-- testing only:
import qualified Data.Text as T
@@ -62,19 +64,26 @@ data LexResult a = LexResult {-# UNPACK #-} !LexState a
data LexWarningType
= LexWarningNBSP -- ^ Encountered non breaking space
| LexWarningBOM -- ^ BOM at the start of the cabal file
- deriving (Show)
+ | LexWarningTab -- ^ Leading tags
+ deriving (Eq, Ord, Show)
data LexWarning = LexWarning !LexWarningType
{-# UNPACK #-} !Position
- !String
deriving (Show)
-toPWarning :: LexWarning -> PWarning
-toPWarning (LexWarning t p s) = PWarning t' p s
+toPWarnings :: [LexWarning] -> [PWarning]
+toPWarnings
+ = map (uncurry toWarning)
+ . Map.toList
+ . Map.fromListWith (++)
+ . map (\(LexWarning t p) -> (t, [p]))
where
- t' = case t of
- LexWarningNBSP -> PWTLexNBSP
- LexWarningBOM -> PWTLexBOM
+ toWarning LexWarningBOM poss =
+ PWarning PWTLexBOM (head poss) "Byte-order mark found at the beginning of the file"
+ toWarning LexWarningNBSP poss =
+ PWarning PWTLexNBSP (head poss) $ "Non breaking spaces at " ++ intercalate ", " (map showPos poss)
+ toWarning LexWarningTab poss =
+ PWarning PWTLexTab (head poss) $ "Tabs used as indentation at " ++ intercalate ", " (map showPos poss)
data LexState = LexState {
curPos :: {-# UNPACK #-} !Position, -- ^ position at current input location
@@ -139,6 +148,6 @@ setStartCode :: Int -> Lex ()
setStartCode c = Lex $ \s -> LexResult s{ curCode = c } ()
-- | Add warning at the current position
-addWarning :: LexWarningType -> String -> Lex ()
-addWarning wt msg = Lex $ \s@LexState{ curPos = pos, warnings = ws } ->
- LexResult s{ warnings = LexWarning wt pos msg : ws } ()
+addWarning :: LexWarningType -> Lex ()
+addWarning wt = Lex $ \s@LexState{ curPos = pos, warnings = ws } ->
+ LexResult s{ warnings = LexWarning wt pos : ws } ()
diff --git a/cabal/Cabal/Distribution/Parsec/Newtypes.hs b/cabal/Cabal/Distribution/Parsec/Newtypes.hs
index 3716afd..7f3e138 100644
--- a/cabal/Cabal/Distribution/Parsec/Newtypes.hs
+++ b/cabal/Cabal/Distribution/Parsec/Newtypes.hs
@@ -17,9 +17,10 @@ module Distribution.Parsec.Newtypes (
NoCommaFSep (..),
-- ** Type
List,
- -- * Version
+ -- * Version & License
SpecVersion (..),
TestedWith (..),
+ SpecLicense (..),
-- * Identifiers
Token (..),
Token' (..),
@@ -32,15 +33,19 @@ import Distribution.Compat.Newtype
import Distribution.Compat.Prelude
import Prelude ()
-import Data.Functor.Identity (Identity (..))
-import Data.List (dropWhileEnd)
-import qualified Distribution.Compat.Parsec as P
-import Distribution.Compiler (CompilerFlavor)
-import Distribution.Parsec.Class
-import Distribution.Parsec.Common (PWarning)
-import Distribution.Pretty
-import Distribution.Version (Version, VersionRange, anyVersion)
-import Text.PrettyPrint (Doc, comma, fsep, punctuate, vcat, (<+>))
+import Data.Functor.Identity (Identity (..))
+import Data.List (dropWhileEnd)
+import Distribution.CabalSpecVersion
+import Distribution.Compiler (CompilerFlavor)
+import Distribution.License (License)
+import Distribution.Parsec.Class
+import Distribution.Pretty
+import Distribution.Version
+ (LowerBound (..), Version, VersionRange, anyVersion, asVersionIntervals, mkVersion)
+import Text.PrettyPrint (Doc, comma, fsep, punctuate, vcat, (<+>))
+
+import qualified Distribution.Compat.CharParsing as P
+import qualified Distribution.SPDX as SPDX
-- | Vertical list with commas. Displayed with 'vcat'
data CommaVCat = CommaVCat
@@ -62,25 +67,27 @@ data P sep = P
class Sep sep where
prettySep :: P sep -> [Doc] -> Doc
- parseSep
- :: P sep -> P.Stream s Identity Char
- => P.Parsec s [PWarning] a
- -> P.Parsec s [PWarning] [a]
+
+ parseSep :: CabalParsing m => P sep -> m a -> m [a]
instance Sep CommaVCat where
- prettySep _ = vcat . punctuate comma
- parseSep _ = parsecCommaList
+ prettySep _ = vcat . punctuate comma
+ parseSep _ p = do
+ v <- askCabalSpecVersion
+ if v >= CabalSpecV2_2 then parsecLeadingCommaList p else parsecCommaList p
instance Sep CommaFSep where
prettySep _ = fsep . punctuate comma
- parseSep _ = parsecCommaList
+ parseSep _ p = do
+ v <- askCabalSpecVersion
+ if v >= CabalSpecV2_2 then parsecLeadingCommaList p else parsecCommaList p
instance Sep VCat where
- prettySep _ = vcat
- parseSep _ = parsecOptCommaList
+ prettySep _ = vcat
+ parseSep _ = parsecOptCommaList
instance Sep FSep where
- prettySep _ = fsep
- parseSep _ = parsecOptCommaList
+ prettySep _ = fsep
+ parseSep _ = parsecOptCommaList
instance Sep NoCommaFSep where
- prettySep _ = fsep
+ prettySep _ = fsep
parseSep _ p = many (p <* P.spaces)
-- | List separated with optional commas. Displayed with @sep@, arguments of
@@ -90,7 +97,7 @@ newtype List sep b a = List { getList :: [a] }
-- | 'alaList' and 'alaList'' are simply 'List', with additional phantom
-- arguments to constraint the resulting type
--
--- >>> :t alaList VCat
+-- >>> :t alaList VCat
-- alaList VCat :: [a] -> List VCat (Identity a) a
--
-- >>> :t alaList' FSep Token
@@ -108,7 +115,7 @@ instance Newtype (List sep wrapper a) [a] where
unpack = getList
instance (Newtype b a, Sep sep, Parsec b) => Parsec (List sep b a) where
- parsec = pack . map (unpack :: b -> a) <$> parseSep (P :: P sep) parsec
+ parsec = pack . map (unpack :: b -> a) <$> parseSep (P :: P sep) parsec
instance (Newtype b a, Sep sep, Pretty b) => Pretty (List sep b a) where
pretty = prettySep (P :: P sep) . map (pretty . (pack :: a -> b)) . unpack
@@ -152,7 +159,15 @@ instance Parsec a => Parsec (MQuoted a) where
instance Pretty a => Pretty (MQuoted a) where
pretty = pretty . unpack
--- | Version range or just version
+-- | Version range or just version, i.e. @cabal-version@ field.
+--
+-- There are few things to consider:
+--
+-- * Starting with 2.2 the cabal-version field should be the first field in the
+-- file and only exact version is accepted. Therefore if we get e.g.
+-- @>= 2.2@, we fail.
+-- See <https://github.com/haskell/cabal/issues/4899>
+--
newtype SpecVersion = SpecVersion { getSpecVersion :: Either Version VersionRange }
instance Newtype SpecVersion (Either Version VersionRange) where
@@ -162,11 +177,38 @@ instance Newtype SpecVersion (Either Version VersionRange) where
instance Parsec SpecVersion where
parsec = pack <$> parsecSpecVersion
where
- parsecSpecVersion = Left <$> parsec <|> Right <$> parsec
+ 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
instance Pretty SpecVersion where
pretty = either pretty pretty . unpack
+specVersionFromRange :: VersionRange -> Version
+specVersionFromRange versionRange = case asVersionIntervals versionRange of
+ [] -> mkVersion [0]
+ ((LowerBound version _, _):_) -> version
+
+-- | SPDX License expression or legacy license
+newtype SpecLicense = SpecLicense { getSpecLicense :: Either SPDX.License License }
+
+instance Newtype SpecLicense (Either SPDX.License License) where
+ pack = SpecLicense
+ unpack = getSpecLicense
+
+instance Parsec SpecLicense where
+ parsec = do
+ v <- askCabalSpecVersion
+ if v >= CabalSpecV2_2
+ then SpecLicense . Left <$> parsec
+ else SpecLicense . Right <$> parsec
+
+instance Pretty SpecLicense where
+ pretty = either pretty pretty . unpack
+
-- | Version range or just version
newtype TestedWith = TestedWith { getTestedWith :: (CompilerFlavor, VersionRange) }
@@ -229,7 +271,7 @@ instance Pretty FilePathNT where
-- Internal
-------------------------------------------------------------------------------
-parsecTestedWith :: P.Stream s Identity Char => P.Parsec s [PWarning] (CompilerFlavor, VersionRange)
+parsecTestedWith :: CabalParsing m => m (CompilerFlavor, VersionRange)
parsecTestedWith = do
name <- lexemeParsec
ver <- parsec <|> pure anyVersion
diff --git a/cabal/Cabal/Distribution/Parsec/ParseResult.hs b/cabal/Cabal/Distribution/Parsec/ParseResult.hs
index 421d3d0..26c8cbe 100644
--- a/cabal/Cabal/Distribution/Parsec/ParseResult.hs
+++ b/cabal/Cabal/Distribution/Parsec/ParseResult.hs
@@ -1,6 +1,7 @@
-{-# LANGUAGE BangPatterns #-}
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE RankNTypes #-}
-- | A parse result type for parsers from AST to Haskell types.
module Distribution.Parsec.ParseResult (
ParseResult,
@@ -11,12 +12,22 @@ module Distribution.Parsec.ParseResult (
parseFailure,
parseFatalFailure,
parseFatalFailure',
+ getCabalSpecVersion,
+ setCabalSpecVersion,
+ readAndParseFile,
+ parseString
) where
+import qualified Data.ByteString.Char8 as BS
import Distribution.Compat.Prelude
import Distribution.Parsec.Common
- (PError (..), PWarnType (..), PWarning (..), Position (..), zeroPos)
+ ( PError (..), PWarnType (..), PWarning (..), Position (..), zeroPos
+ , showPWarning, showPError)
+import Distribution.Simple.Utils (die', warn)
+import Distribution.Verbosity (Verbosity)
+import Distribution.Version (Version)
import Prelude ()
+import System.Directory (doesFileExist)
#if MIN_VERSION_base(4,10,0)
import Control.Applicative (Applicative (..))
@@ -26,25 +37,26 @@ import Control.Applicative (Applicative (..))
newtype ParseResult a = PR
{ unPR
:: forall r. PRState
- -> (PRState -> r) -- failure
- -> (PRState -> a -> r) -- success
+ -> (PRState -> r) -- failure, but we were able to recover a new-style spec-version declaration
+ -> (PRState -> a -> r) -- success
-> r
}
-data PRState = PRState ![PWarning] ![PError]
+data PRState = PRState ![PWarning] ![PError] !(Maybe Version)
emptyPRState :: PRState
-emptyPRState = PRState [] []
+emptyPRState = PRState [] [] Nothing
--- | Destruct a 'ParseResult' into the emitted warnings and errors, and
--- possibly the final result if there were no errors.
-runParseResult :: ParseResult a -> ([PWarning], [PError], Maybe a)
+-- | Destruct a 'ParseResult' into the emitted warnings and either
+-- a successful value or
+-- list of errors and possibly recovered a spec-version declaration.
+runParseResult :: ParseResult a -> ([PWarning], Either (Maybe Version, [PError]) a)
runParseResult pr = unPR pr emptyPRState failure success
where
- failure (PRState warns errs) = (warns, errs, Nothing)
- success (PRState warns []) x = (warns, [], Just x)
+ failure (PRState warns errs v) = (warns, Left (v, errs))
+ success (PRState warns [] _) x = (warns, Right x)
-- If there are any errors, don't return the result
- success (PRState warns errs) _ = (warns, errs, Nothing)
+ success (PRState warns errs v) _ = (warns, Left (v, errs))
instance Functor ParseResult where
fmap f (PR pr) = PR $ \ !s failure success ->
@@ -96,33 +108,77 @@ recoverWith :: ParseResult a -> a -> ParseResult a
recoverWith (PR pr) x = PR $ \ !s _failure success ->
pr s (\ !s' -> success s' x) success
+-- | Set cabal spec version.
+setCabalSpecVersion :: Maybe Version -> ParseResult ()
+setCabalSpecVersion v = PR $ \(PRState warns errs _) _failure success ->
+ success (PRState warns errs v) ()
+
+-- | Get cabal spec version.
+getCabalSpecVersion :: ParseResult (Maybe Version)
+getCabalSpecVersion = PR $ \s@(PRState _ _ v) _failure success ->
+ success s v
+
-- | Add a warning. This doesn't fail the parsing process.
parseWarning :: Position -> PWarnType -> String -> ParseResult ()
-parseWarning pos t msg = PR $ \(PRState warns errs) _failure success ->
- success (PRState (PWarning t pos msg : warns) errs) ()
+parseWarning pos t msg = PR $ \(PRState warns errs v) _failure success ->
+ success (PRState (PWarning t pos msg : warns) errs v) ()
-- | Add multiple warnings at once.
parseWarnings :: [PWarning] -> ParseResult ()
-parseWarnings newWarns = PR $ \(PRState warns errs) _failure success ->
- success (PRState (newWarns ++ warns) errs) ()
+parseWarnings newWarns = PR $ \(PRState warns errs v) _failure success ->
+ success (PRState (newWarns ++ warns) errs v) ()
-- | Add an error, but not fail the parser yet.
--
-- For fatal failure use 'parseFatalFailure'
parseFailure :: Position -> String -> ParseResult ()
-parseFailure pos msg = PR $ \(PRState warns errs) _failure success ->
- success (PRState warns (PError pos msg : errs)) ()
+parseFailure pos msg = PR $ \(PRState warns errs v) _failure success ->
+ success (PRState warns (PError pos msg : errs) v) ()
-- | Add an fatal error.
parseFatalFailure :: Position -> String -> ParseResult a
-parseFatalFailure pos msg = PR $ \(PRState warns errs) failure _success ->
- failure (PRState warns (PError pos msg : errs))
+parseFatalFailure pos msg = PR $ \(PRState warns errs v) failure _success ->
+ failure (PRState warns (PError pos msg : errs) v)
-- | A 'mzero'.
parseFatalFailure' :: ParseResult a
parseFatalFailure' = PR pr
where
- pr (PRState warns []) failure _success = failure (PRState warns [err])
- pr s failure _success = failure s
+ pr (PRState warns [] v) failure _success = failure (PRState warns [err] v)
+ pr s failure _success = failure s
err = PError zeroPos "Unknown fatal error"
+
+-- | Helper combinator to do parsing plumbing for files.
+--
+-- Given a parser and a filename, return the parse of the file,
+-- after checking if the file exists.
+--
+-- Argument order is chosen to encourage partial application.
+readAndParseFile
+ :: (BS.ByteString -> ParseResult a) -- ^ File contents to final value parser
+ -> Verbosity -- ^ Verbosity level
+ -> FilePath -- ^ File to read
+ -> IO a
+readAndParseFile parser verbosity fpath = do
+ exists <- doesFileExist fpath
+ unless exists $
+ die' verbosity $
+ "Error Parsing: file \"" ++ fpath ++ "\" doesn't exist. Cannot continue."
+ bs <- BS.readFile fpath
+ parseString parser verbosity fpath bs
+
+parseString
+ :: (BS.ByteString -> ParseResult a) -- ^ File contents to final value parser
+ -> Verbosity -- ^ Verbosity level
+ -> String -- ^ File name
+ -> BS.ByteString
+ -> IO a
+parseString parser verbosity name bs = do
+ let (warnings, result) = runParseResult (parser bs)
+ traverse_ (warn verbosity . showPWarning name) warnings
+ case result of
+ Right x -> return x
+ Left (_, errors) -> do
+ traverse_ (warn verbosity . showPError name) errors
+ die' verbosity $ "Failed parsing \"" ++ name ++ "\"."
diff --git a/cabal/Cabal/Distribution/Parsec/Parser.hs b/cabal/Cabal/Distribution/Parsec/Parser.hs
index 4696cae..742155e 100644
--- a/cabal/Cabal/Distribution/Parsec/Parser.hs
+++ b/cabal/Cabal/Distribution/Parsec/Parser.hs
@@ -221,7 +221,7 @@ elements ilevel = many (element ilevel)
-- An individual element, ie a field or a section. These can either use
-- layout style or braces style. For layout style then it must start on
--- a line on it's own (so that we know its indentation level).
+-- a line on its own (so that we know its indentation level).
--
-- element ::= '\n' name elementInLayoutContext
-- | name elementInNonLayoutContext
diff --git a/cabal/Cabal/Distribution/PrettyUtils.hs b/cabal/Cabal/Distribution/PrettyUtils.hs
index ec354f1..7e1bd8d 100644
--- a/cabal/Cabal/Distribution/PrettyUtils.hs
+++ b/cabal/Cabal/Distribution/PrettyUtils.hs
@@ -9,7 +9,7 @@
--
-- Utilities for pretty printing.
{-# OPTIONS_HADDOCK hide #-}
-module Distribution.PrettyUtils {-# DEPRECATED "Use Distribution.Pretty" #-} (
+module Distribution.PrettyUtils {-# DEPRECATED "Use Distribution.Pretty. This module will be removed in Cabal-3.0 (est. Mar 2019)." #-} (
Separator,
-- * Internal
showFilePath,
diff --git a/cabal/Cabal/Distribution/ReadE.hs b/cabal/Cabal/Distribution/ReadE.hs
index fbe1b03..af60e5e 100644
--- a/cabal/Cabal/Distribution/ReadE.hs
+++ b/cabal/Cabal/Distribution/ReadE.hs
@@ -18,11 +18,12 @@ module Distribution.ReadE (
parsecToReadE,
) where
-import Prelude ()
import Distribution.Compat.Prelude
+import Prelude ()
import Distribution.Compat.ReadP
-import qualified Distribution.Compat.Parsec as P
+import Distribution.Parsec.Class
+import Distribution.Parsec.FieldLineStream
-- | Parser with simple error reporting
newtype ReadE a = ReadE {runReadE :: String -> Either ErrorMsg a}
@@ -47,7 +48,7 @@ parseReadE (ReadE p) = do
readEOrFail :: ReadE a -> String -> a
readEOrFail r = either error id . runReadE r
--- {-# DEPRECATED readP_to_E "Use parsecToReadE" #-}
+-- {-# DEPRECATED readP_to_E "Use parsecToReadE. This symbol will be removed in Cabal-3.0 (est. Mar 2019)." #-}
readP_to_E :: (String -> ErrorMsg) -> ReadP a a -> ReadE a
readP_to_E err r =
ReadE $ \txt -> case [ p | (p, s) <- readP_to_S r txt
@@ -55,9 +56,9 @@ readP_to_E err r =
of [] -> Left (err txt)
(p:_) -> Right p
-parsecToReadE :: (String -> ErrorMsg) -> P.Parsec String [w] a -> ReadE a
+parsecToReadE :: (String -> ErrorMsg) -> ParsecParser a -> ReadE a
parsecToReadE err p = ReadE $ \txt ->
- case P.runParser (p <* P.spaces <* P.eof) [] "<parsecToReadE>" txt of
+ case runParsecParser p "<parsecToReadE>" (fieldLineStreamFromString txt) of
Right x -> Right x
Left _e -> Left (err txt)
-- TODO: use parsec error to make 'ErrorMsg'.
diff --git a/cabal/Cabal/Distribution/SPDX.hs b/cabal/Cabal/Distribution/SPDX.hs
new file mode 100644
index 0000000..f3f4fe2
--- /dev/null
+++ b/cabal/Cabal/Distribution/SPDX.hs
@@ -0,0 +1,40 @@
+-- | This module implements SPDX specification version 2.1 with a version 3.0 license list.
+--
+-- Specification is available on <https://spdx.org/specifications>
+module Distribution.SPDX (
+ -- * License
+ License (..),
+ -- * License expression
+ LicenseExpression (..),
+ SimpleLicenseExpression (..),
+ simpleLicenseExpression,
+ -- * License identifier
+ LicenseId (..),
+ licenseId,
+ licenseName,
+ licenseIsOsiApproved,
+ mkLicenseId,
+ licenseIdList,
+ -- * License exception
+ LicenseExceptionId (..),
+ licenseExceptionId,
+ licenseExceptionName,
+ mkLicenseExceptionId,
+ licenseExceptionIdList,
+ -- * License reference
+ LicenseRef,
+ licenseRef,
+ licenseDocumentRef,
+ mkLicenseRef,
+ mkLicenseRef',
+ -- * License list version
+ LicenseListVersion (..),
+ cabalSpecVersionToSPDXListVersion,
+ ) where
+
+import Distribution.SPDX.LicenseExceptionId
+import Distribution.SPDX.License
+import Distribution.SPDX.LicenseId
+import Distribution.SPDX.LicenseExpression
+import Distribution.SPDX.LicenseReference
+import Distribution.SPDX.LicenseListVersion
diff --git a/cabal/Cabal/Distribution/SPDX/License.hs b/cabal/Cabal/Distribution/SPDX/License.hs
new file mode 100644
index 0000000..ea552e4
--- /dev/null
+++ b/cabal/Cabal/Distribution/SPDX/License.hs
@@ -0,0 +1,64 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric #-}
+module Distribution.SPDX.License (
+ License (..),
+ ) where
+
+import Prelude ()
+import Distribution.Compat.Prelude
+
+import Distribution.Pretty
+import Distribution.Parsec.Class
+import Distribution.SPDX.LicenseExpression
+
+import qualified Distribution.Compat.CharParsing as P
+import qualified Text.PrettyPrint as Disp
+
+-- | Declared license.
+-- See [section 3.15 of SPDX Specification 2.1](https://spdx.org/spdx-specification-21-web-version#h.1hmsyys)
+--
+-- /Note:/ the NOASSERTION case is omitted.
+--
+-- Old 'License' can be migrated using following rules:
+--
+-- * @AllRightsReserved@ and @UnspecifiedLicense@ to 'NONE'.
+-- No license specified which legally defaults to /All Rights Reserved/.
+-- The package may not be legally modified or redistributed by anyone but
+-- the rightsholder.
+--
+-- * @OtherLicense@ can be converted to 'LicenseRef' pointing to the file
+-- in the package.
+--
+-- * @UnknownLicense@ i.e. other licenses of the form @name-x.y@, should be
+-- covered by SPDX license list, otherwise use 'LicenseRef'.
+--
+-- * @PublicDomain@ isn't covered. Consider using CC0.
+-- See <https://wiki.spdx.org/view/Legal_Team/Decisions/Dealing_with_Public_Domain_within_SPDX_Files>
+-- for more information.
+--
+data License
+ = NONE
+ -- ^ if the package contains no license information whatsoever; or
+ | License LicenseExpression
+ -- ^ A valid SPDX License Expression as defined in Appendix IV.
+ deriving (Show, Read, Eq, Ord, Typeable, Data, Generic)
+
+instance Binary License
+
+instance NFData License where
+ rnf NONE = ()
+ rnf (License l) = rnf l
+
+instance Pretty License where
+ pretty NONE = Disp.text "NONE"
+ pretty (License l) = pretty l
+
+-- |
+-- >>> eitherParsec "BSD-3-Clause AND MIT" :: Either String License
+-- Right (License (EAnd (ELicense (ELicenseId BSD_3_Clause) Nothing) (ELicense (ELicenseId MIT) Nothing)))
+--
+-- >>> eitherParsec "NONE" :: Either String License
+-- Right NONE
+--
+instance Parsec License where
+ parsec = NONE <$ P.try (P.string "NONE") <|> License <$> parsec
diff --git a/cabal/Cabal/Distribution/SPDX/LicenseExceptionId.hs b/cabal/Cabal/Distribution/SPDX/LicenseExceptionId.hs
new file mode 100644
index 0000000..4f435ca
--- /dev/null
+++ b/cabal/Cabal/Distribution/SPDX/LicenseExceptionId.hs
@@ -0,0 +1,213 @@
+-- This file is generated. See Makefile's spdx rule
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric #-}
+module Distribution.SPDX.LicenseExceptionId (
+ LicenseExceptionId (..),
+ licenseExceptionId,
+ licenseExceptionName,
+ mkLicenseExceptionId,
+ licenseExceptionIdList,
+ ) where
+
+import Distribution.Compat.Prelude
+import Prelude ()
+
+import Distribution.Pretty
+import Distribution.Parsec.Class
+import Distribution.Utils.Generic (isAsciiAlphaNum)
+import Distribution.SPDX.LicenseListVersion
+
+import qualified Data.Map.Strict as Map
+import qualified Distribution.Compat.CharParsing as P
+import qualified Text.PrettyPrint as Disp
+
+-------------------------------------------------------------------------------
+-- LicenseExceptionId
+-------------------------------------------------------------------------------
+
+-- | SPDX License identifier
+data LicenseExceptionId
+ = DS389_exception -- ^ @389-exception@, 389 Directory Server Exception
+ | Autoconf_exception_2_0 -- ^ @Autoconf-exception-2.0@, Autoconf exception 2.0
+ | Autoconf_exception_3_0 -- ^ @Autoconf-exception-3.0@, Autoconf exception 3.0
+ | Bison_exception_2_2 -- ^ @Bison-exception-2.2@, Bison exception 2.2
+ | Bootloader_exception -- ^ @Bootloader-exception@, Bootloader Distribution Exception
+ | Classpath_exception_2_0 -- ^ @Classpath-exception-2.0@, Classpath exception 2.0
+ | CLISP_exception_2_0 -- ^ @CLISP-exception-2.0@, CLISP exception 2.0
+ | DigiRule_FOSS_exception -- ^ @DigiRule-FOSS-exception@, DigiRule FOSS License Exception
+ | ECos_exception_2_0 -- ^ @eCos-exception-2.0@, eCos exception 2.0
+ | Fawkes_Runtime_exception -- ^ @Fawkes-Runtime-exception@, Fawkes Runtime Exception
+ | FLTK_exception -- ^ @FLTK-exception@, FLTK exception
+ | Font_exception_2_0 -- ^ @Font-exception-2.0@, Font exception 2.0
+ | Freertos_exception_2_0 -- ^ @freertos-exception-2.0@, FreeRTOS Exception 2.0
+ | GCC_exception_2_0 -- ^ @GCC-exception-2.0@, GCC Runtime Library exception 2.0
+ | GCC_exception_3_1 -- ^ @GCC-exception-3.1@, GCC Runtime Library exception 3.1
+ | Gnu_javamail_exception -- ^ @gnu-javamail-exception@, GNU JavaMail exception
+ | I2p_gpl_java_exception -- ^ @i2p-gpl-java-exception@, i2p GPL+Java Exception
+ | Libtool_exception -- ^ @Libtool-exception@, Libtool Exception
+ | Linux_syscall_note -- ^ @Linux-syscall-note@, Linux Syscall Note
+ | LLVM_exception -- ^ @LLVM-exception@, LLVM Exception, SPDX License List 3.2
+ | LZMA_exception -- ^ @LZMA-exception@, LZMA exception
+ | Mif_exception -- ^ @mif-exception@, Macros and Inline Functions Exception
+ | Nokia_Qt_exception_1_1 -- ^ @Nokia-Qt-exception-1.1@, Nokia Qt LGPL exception 1.1
+ | OCCT_exception_1_0 -- ^ @OCCT-exception-1.0@, Open CASCADE Exception 1.0
+ | OpenJDK_assembly_exception_1_0 -- ^ @OpenJDK-assembly-exception-1.0@, OpenJDK Assembly exception 1.0, SPDX License List 3.2
+ | Openvpn_openssl_exception -- ^ @openvpn-openssl-exception@, OpenVPN OpenSSL Exception
+ | PS_or_PDF_font_exception_20170817 -- ^ @PS-or-PDF-font-exception-20170817@, PS/PDF font exception (2017-08-17), SPDX License List 3.2
+ | Qt_GPL_exception_1_0 -- ^ @Qt-GPL-exception-1.0@, Qt GPL exception 1.0, SPDX License List 3.2
+ | Qt_LGPL_exception_1_1 -- ^ @Qt-LGPL-exception-1.1@, Qt LGPL exception 1.1, SPDX License List 3.2
+ | Qwt_exception_1_0 -- ^ @Qwt-exception-1.0@, Qwt exception 1.0
+ | U_boot_exception_2_0 -- ^ @u-boot-exception-2.0@, U-Boot exception 2.0
+ | WxWindows_exception_3_1 -- ^ @WxWindows-exception-3.1@, WxWindows Library Exception 3.1
+ deriving (Eq, Ord, Enum, Bounded, Show, Read, Typeable, Data, Generic)
+
+instance Binary LicenseExceptionId
+
+instance Pretty LicenseExceptionId where
+ pretty = Disp.text . licenseExceptionId
+
+instance Parsec LicenseExceptionId where
+ parsec = do
+ n <- some $ P.satisfy $ \c -> isAsciiAlphaNum c || c == '-' || c == '.'
+ v <- askCabalSpecVersion
+ maybe (fail $ "Unknown SPDX license exception identifier: " ++ n) return $
+ mkLicenseExceptionId (cabalSpecVersionToSPDXListVersion v) n
+
+instance NFData LicenseExceptionId where
+ rnf l = l `seq` ()
+
+-------------------------------------------------------------------------------
+-- License Data
+-------------------------------------------------------------------------------
+
+-- | License SPDX identifier, e.g. @"BSD-3-Clause"@.
+licenseExceptionId :: LicenseExceptionId -> String
+licenseExceptionId DS389_exception = "389-exception"
+licenseExceptionId Autoconf_exception_2_0 = "Autoconf-exception-2.0"
+licenseExceptionId Autoconf_exception_3_0 = "Autoconf-exception-3.0"
+licenseExceptionId Bison_exception_2_2 = "Bison-exception-2.2"
+licenseExceptionId Bootloader_exception = "Bootloader-exception"
+licenseExceptionId Classpath_exception_2_0 = "Classpath-exception-2.0"
+licenseExceptionId CLISP_exception_2_0 = "CLISP-exception-2.0"
+licenseExceptionId DigiRule_FOSS_exception = "DigiRule-FOSS-exception"
+licenseExceptionId ECos_exception_2_0 = "eCos-exception-2.0"
+licenseExceptionId Fawkes_Runtime_exception = "Fawkes-Runtime-exception"
+licenseExceptionId FLTK_exception = "FLTK-exception"
+licenseExceptionId Font_exception_2_0 = "Font-exception-2.0"
+licenseExceptionId Freertos_exception_2_0 = "freertos-exception-2.0"
+licenseExceptionId GCC_exception_2_0 = "GCC-exception-2.0"
+licenseExceptionId GCC_exception_3_1 = "GCC-exception-3.1"
+licenseExceptionId Gnu_javamail_exception = "gnu-javamail-exception"
+licenseExceptionId I2p_gpl_java_exception = "i2p-gpl-java-exception"
+licenseExceptionId Libtool_exception = "Libtool-exception"
+licenseExceptionId Linux_syscall_note = "Linux-syscall-note"
+licenseExceptionId LLVM_exception = "LLVM-exception"
+licenseExceptionId LZMA_exception = "LZMA-exception"
+licenseExceptionId Mif_exception = "mif-exception"
+licenseExceptionId Nokia_Qt_exception_1_1 = "Nokia-Qt-exception-1.1"
+licenseExceptionId OCCT_exception_1_0 = "OCCT-exception-1.0"
+licenseExceptionId OpenJDK_assembly_exception_1_0 = "OpenJDK-assembly-exception-1.0"
+licenseExceptionId Openvpn_openssl_exception = "openvpn-openssl-exception"
+licenseExceptionId PS_or_PDF_font_exception_20170817 = "PS-or-PDF-font-exception-20170817"
+licenseExceptionId Qt_GPL_exception_1_0 = "Qt-GPL-exception-1.0"
+licenseExceptionId Qt_LGPL_exception_1_1 = "Qt-LGPL-exception-1.1"
+licenseExceptionId Qwt_exception_1_0 = "Qwt-exception-1.0"
+licenseExceptionId U_boot_exception_2_0 = "u-boot-exception-2.0"
+licenseExceptionId WxWindows_exception_3_1 = "WxWindows-exception-3.1"
+
+-- | License name, e.g. @"GNU General Public License v2.0 only"@
+licenseExceptionName :: LicenseExceptionId -> String
+licenseExceptionName DS389_exception = "389 Directory Server Exception"
+licenseExceptionName Autoconf_exception_2_0 = "Autoconf exception 2.0"
+licenseExceptionName Autoconf_exception_3_0 = "Autoconf exception 3.0"
+licenseExceptionName Bison_exception_2_2 = "Bison exception 2.2"
+licenseExceptionName Bootloader_exception = "Bootloader Distribution Exception"
+licenseExceptionName Classpath_exception_2_0 = "Classpath exception 2.0"
+licenseExceptionName CLISP_exception_2_0 = "CLISP exception 2.0"
+licenseExceptionName DigiRule_FOSS_exception = "DigiRule FOSS License Exception"
+licenseExceptionName ECos_exception_2_0 = "eCos exception 2.0"
+licenseExceptionName Fawkes_Runtime_exception = "Fawkes Runtime Exception"
+licenseExceptionName FLTK_exception = "FLTK exception"
+licenseExceptionName Font_exception_2_0 = "Font exception 2.0"
+licenseExceptionName Freertos_exception_2_0 = "FreeRTOS Exception 2.0"
+licenseExceptionName GCC_exception_2_0 = "GCC Runtime Library exception 2.0"
+licenseExceptionName GCC_exception_3_1 = "GCC Runtime Library exception 3.1"
+licenseExceptionName Gnu_javamail_exception = "GNU JavaMail exception"
+licenseExceptionName I2p_gpl_java_exception = "i2p GPL+Java Exception"
+licenseExceptionName Libtool_exception = "Libtool Exception"
+licenseExceptionName Linux_syscall_note = "Linux Syscall Note"
+licenseExceptionName LLVM_exception = "LLVM Exception"
+licenseExceptionName LZMA_exception = "LZMA exception"
+licenseExceptionName Mif_exception = "Macros and Inline Functions Exception"
+licenseExceptionName Nokia_Qt_exception_1_1 = "Nokia Qt LGPL exception 1.1"
+licenseExceptionName OCCT_exception_1_0 = "Open CASCADE Exception 1.0"
+licenseExceptionName OpenJDK_assembly_exception_1_0 = "OpenJDK Assembly exception 1.0"
+licenseExceptionName Openvpn_openssl_exception = "OpenVPN OpenSSL Exception"
+licenseExceptionName PS_or_PDF_font_exception_20170817 = "PS/PDF font exception (2017-08-17)"
+licenseExceptionName Qt_GPL_exception_1_0 = "Qt GPL exception 1.0"
+licenseExceptionName Qt_LGPL_exception_1_1 = "Qt LGPL exception 1.1"
+licenseExceptionName Qwt_exception_1_0 = "Qwt exception 1.0"
+licenseExceptionName U_boot_exception_2_0 = "U-Boot exception 2.0"
+licenseExceptionName WxWindows_exception_3_1 = "WxWindows Library Exception 3.1"
+
+-------------------------------------------------------------------------------
+-- Creation
+-------------------------------------------------------------------------------
+
+licenseExceptionIdList :: LicenseListVersion -> [LicenseExceptionId]
+licenseExceptionIdList LicenseListVersion_3_0 =
+ []
+ ++ bulkOfLicenses
+licenseExceptionIdList LicenseListVersion_3_2 =
+ [ LLVM_exception
+ , OpenJDK_assembly_exception_1_0
+ , PS_or_PDF_font_exception_20170817
+ , Qt_GPL_exception_1_0
+ , Qt_LGPL_exception_1_1
+ ]
+ ++ bulkOfLicenses
+
+-- | Create a 'LicenseExceptionId' from a 'String'.
+mkLicenseExceptionId :: LicenseListVersion -> String -> Maybe LicenseExceptionId
+mkLicenseExceptionId LicenseListVersion_3_0 s = Map.lookup s stringLookup_3_0
+mkLicenseExceptionId LicenseListVersion_3_2 s = Map.lookup s stringLookup_3_2
+
+stringLookup_3_0 :: Map String LicenseExceptionId
+stringLookup_3_0 = Map.fromList $ map (\i -> (licenseExceptionId i, i)) $
+ licenseExceptionIdList LicenseListVersion_3_0
+
+stringLookup_3_2 :: Map String LicenseExceptionId
+stringLookup_3_2 = Map.fromList $ map (\i -> (licenseExceptionId i, i)) $
+ licenseExceptionIdList LicenseListVersion_3_2
+
+-- | License exceptions in all SPDX License lists
+bulkOfLicenses :: [LicenseExceptionId]
+bulkOfLicenses =
+ [ DS389_exception
+ , Autoconf_exception_2_0
+ , Autoconf_exception_3_0
+ , Bison_exception_2_2
+ , Bootloader_exception
+ , Classpath_exception_2_0
+ , CLISP_exception_2_0
+ , DigiRule_FOSS_exception
+ , ECos_exception_2_0
+ , Fawkes_Runtime_exception
+ , FLTK_exception
+ , Font_exception_2_0
+ , Freertos_exception_2_0
+ , GCC_exception_2_0
+ , GCC_exception_3_1
+ , Gnu_javamail_exception
+ , I2p_gpl_java_exception
+ , Libtool_exception
+ , Linux_syscall_note
+ , LZMA_exception
+ , Mif_exception
+ , Nokia_Qt_exception_1_1
+ , OCCT_exception_1_0
+ , Openvpn_openssl_exception
+ , Qwt_exception_1_0
+ , U_boot_exception_2_0
+ , WxWindows_exception_3_1
+ ]
diff --git a/cabal/Cabal/Distribution/SPDX/LicenseExpression.hs b/cabal/Cabal/Distribution/SPDX/LicenseExpression.hs
new file mode 100644
index 0000000..4d38a8c
--- /dev/null
+++ b/cabal/Cabal/Distribution/SPDX/LicenseExpression.hs
@@ -0,0 +1,161 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric #-}
+module Distribution.SPDX.LicenseExpression (
+ LicenseExpression (..),
+ SimpleLicenseExpression (..),
+ simpleLicenseExpression,
+ ) where
+
+import Distribution.Compat.Prelude
+import Prelude ()
+
+import Distribution.Parsec.Class
+import Distribution.Pretty
+import Distribution.SPDX.LicenseExceptionId
+import Distribution.SPDX.LicenseId
+import Distribution.SPDX.LicenseListVersion
+import Distribution.SPDX.LicenseReference
+import Distribution.Utils.Generic (isAsciiAlphaNum)
+import Text.PrettyPrint ((<+>))
+
+import qualified Distribution.Compat.CharParsing as P
+import qualified Text.PrettyPrint as Disp
+
+-- | SPDX License Expression.
+--
+-- @
+-- idstring = 1*(ALPHA \/ DIGIT \/ "-" \/ "." )
+-- license id = \<short form license identifier inAppendix I.1>
+-- license exception id = \<short form license exception identifier inAppendix I.2>
+-- license ref = [\"DocumentRef-"1*(idstring)":"]\"LicenseRef-"1*(idstring)
+--
+-- simple expression = license id \/ license id"+" \/ license ref
+--
+-- compound expression = 1*1(simple expression \/
+-- simple expression \"WITH" license exception id \/
+-- compound expression \"AND" compound expression \/
+-- compound expression \"OR" compound expression ) \/
+-- "(" compound expression ")" )
+--
+-- license expression = 1*1(simple expression / compound expression)
+-- @
+data LicenseExpression
+ = ELicense !SimpleLicenseExpression !(Maybe LicenseExceptionId)
+ | EAnd !LicenseExpression !LicenseExpression
+ | EOr !LicenseExpression !LicenseExpression
+ deriving (Show, Read, Eq, Ord, Typeable, Data, Generic)
+
+-- | Simple License Expressions.
+data SimpleLicenseExpression
+ = ELicenseId LicenseId
+ -- ^ An SPDX License List Short Form Identifier. For example: @GPL-2.0-only@
+ | ELicenseIdPlus LicenseId
+ -- ^ An SPDX License List Short Form Identifier with a unary"+" operator suffix to represent the current version of the license or any later version. For example: @GPL-2.0+@
+ | ELicenseRef LicenseRef
+ -- ^ A SPDX user defined license reference: For example: @LicenseRef-23@, @LicenseRef-MIT-Style-1@, or @DocumentRef-spdx-tool-1.2:LicenseRef-MIT-Style-2@
+ deriving (Show, Read, Eq, Ord, Typeable, Data, Generic)
+
+simpleLicenseExpression :: LicenseId -> LicenseExpression
+simpleLicenseExpression i = ELicense (ELicenseId i) Nothing
+
+instance Binary LicenseExpression
+instance Binary SimpleLicenseExpression
+
+instance Pretty LicenseExpression where
+ pretty = go 0
+ where
+ go :: Int -> LicenseExpression -> Disp.Doc
+ go _ (ELicense lic exc) =
+ let doc = pretty lic
+ in maybe id (\e d -> d <+> Disp.text "WITH" <+> pretty e) exc doc
+ go d (EAnd e1 e2) = parens (d < 0) $ go 0 e1 <+> Disp.text "AND" <+> go 0 e2
+ go d (EOr e1 e2) = parens (d < 1) $ go 1 e1 <+> Disp.text "OR" <+> go 1 e2
+
+
+ parens False doc = doc
+ parens True doc = Disp.parens doc
+
+instance Pretty SimpleLicenseExpression where
+ pretty (ELicenseId i) = pretty i
+ pretty (ELicenseIdPlus i) = pretty i <<>> Disp.char '+'
+ pretty (ELicenseRef r) = pretty r
+
+instance Parsec SimpleLicenseExpression where
+ parsec = idstring >>= simple where
+ simple n
+ | Just l <- "LicenseRef-" `isPrefixOfMaybe` n =
+ maybe (fail $ "Incorrect LicenseRef format: " ++ n) (return . ELicenseRef) $ mkLicenseRef Nothing l
+ | Just d <- "DocumentRef-" `isPrefixOfMaybe` n = do
+ _ <- P.string ":LicenseRef-"
+ l <- idstring
+ maybe (fail $ "Incorrect LicenseRef format:" ++ n) (return . ELicenseRef) $ mkLicenseRef (Just d) l
+ | otherwise = do
+ v <- askCabalSpecVersion
+ l <- maybe (fail $ "Unknown SPDX license identifier: '" ++ n ++ "' " ++ licenseIdMigrationMessage n) return $
+ mkLicenseId (cabalSpecVersionToSPDXListVersion v) n
+ orLater <- isJust <$> P.optional (P.char '+')
+ if orLater
+ then return (ELicenseIdPlus l)
+ else return (ELicenseId l)
+
+idstring :: P.CharParsing m => m String
+idstring = P.munch1 $ \c -> isAsciiAlphaNum c || c == '-' || c == '.'
+
+-- returns suffix part
+isPrefixOfMaybe :: Eq a => [a] -> [a] -> Maybe [a]
+isPrefixOfMaybe pfx s
+ | pfx `isPrefixOf` s = Just (drop (length pfx) s)
+ | otherwise = Nothing
+
+instance Parsec LicenseExpression where
+ parsec = expr
+ where
+ expr = compoundOr
+
+ simple = do
+ s <- parsec
+ exc <- exception
+ return $ ELicense s exc
+
+ exception = P.optional $ P.try (spaces1 *> P.string "WITH" *> spaces1) *> parsec
+
+ compoundOr = do
+ x <- compoundAnd
+ l <- P.optional $ P.try (spaces1 *> P.string "OR" *> spaces1) *> compoundOr
+ return $ maybe id (flip EOr) l x
+
+ compoundAnd = do
+ x <- compound
+ l <- P.optional $ P.try (spaces1 *> P.string "AND" *> spaces1) *> compoundAnd
+ return $ maybe id (flip EAnd) l x
+
+ compound = braces <|> simple
+
+ -- NOTE: we require that there's a space around AND & OR operators,
+ -- i.e. @(MIT)AND(MIT)@ will cause parse-error.
+ braces = do
+ _ <- P.char '('
+ _ <- P.spaces
+ x <- expr
+ _ <- P.char ')'
+ return x
+
+ spaces1 = P.space *> P.spaces
+
+-- notes:
+--
+-- There MUST NOT be whitespace between a license­id and any following "+".  This supports easy parsing and
+-- backwards compatibility.  There MUST be whitespace on either side of the operator "WITH".  There MUST be
+-- whitespace and/or parentheses on either side of the operators "AND" and "OR".
+--
+-- We handle that by having greedy 'idstring' parser, so MITAND would parse as invalid license identifier.
+
+instance NFData LicenseExpression where
+ rnf (ELicense s e) = rnf s `seq` rnf e
+ rnf (EAnd x y) = rnf x `seq` rnf y
+ rnf (EOr x y) = rnf x `seq` rnf y
+
+instance NFData SimpleLicenseExpression where
+ rnf (ELicenseId i) = rnf i
+ rnf (ELicenseIdPlus i) = rnf i
+ rnf (ELicenseRef r) = rnf r
diff --git a/cabal/Cabal/Distribution/SPDX/LicenseId.hs b/cabal/Cabal/Distribution/SPDX/LicenseId.hs
new file mode 100644
index 0000000..5516319
--- /dev/null
+++ b/cabal/Cabal/Distribution/SPDX/LicenseId.hs
@@ -0,0 +1,1885 @@
+-- This file is generated. See Makefile's spdx rule
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric #-}
+module Distribution.SPDX.LicenseId (
+ LicenseId (..),
+ licenseId,
+ licenseName,
+ licenseIsOsiApproved,
+ mkLicenseId,
+ licenseIdList,
+ -- * Helpers
+ licenseIdMigrationMessage,
+ ) where
+
+import Distribution.Compat.Prelude
+import Prelude ()
+
+import Distribution.Pretty
+import Distribution.Parsec.Class
+import Distribution.Utils.Generic (isAsciiAlphaNum)
+import Distribution.SPDX.LicenseListVersion
+
+import qualified Data.Map.Strict as Map
+import qualified Distribution.Compat.CharParsing as P
+import qualified Text.PrettyPrint as Disp
+
+-------------------------------------------------------------------------------
+-- LicenseId
+-------------------------------------------------------------------------------
+
+-- | SPDX License identifier
+data LicenseId
+ = NullBSD -- ^ @0BSD@, BSD Zero Clause License
+ | AAL -- ^ @AAL@, Attribution Assurance License
+ | Abstyles -- ^ @Abstyles@, Abstyles License
+ | Adobe_2006 -- ^ @Adobe-2006@, Adobe Systems Incorporated Source Code License Agreement
+ | Adobe_Glyph -- ^ @Adobe-Glyph@, Adobe Glyph List License
+ | ADSL -- ^ @ADSL@, Amazon Digital Services License
+ | AFL_1_1 -- ^ @AFL-1.1@, Academic Free License v1.1
+ | AFL_1_2 -- ^ @AFL-1.2@, Academic Free License v1.2
+ | AFL_2_0 -- ^ @AFL-2.0@, Academic Free License v2.0
+ | AFL_2_1 -- ^ @AFL-2.1@, Academic Free License v2.1
+ | AFL_3_0 -- ^ @AFL-3.0@, Academic Free License v3.0
+ | Afmparse -- ^ @Afmparse@, Afmparse License
+ | AGPL_1_0 -- ^ @AGPL-1.0@, Affero General Public License v1.0, SPDX License List 3.0
+ | AGPL_1_0_only -- ^ @AGPL-1.0-only@, Affero General Public License v1.0 only, SPDX License List 3.2
+ | AGPL_1_0_or_later -- ^ @AGPL-1.0-or-later@, Affero General Public License v1.0 or later, SPDX License List 3.2
+ | AGPL_3_0_only -- ^ @AGPL-3.0-only@, GNU Affero General Public License v3.0 only
+ | AGPL_3_0_or_later -- ^ @AGPL-3.0-or-later@, GNU Affero General Public License v3.0 or later
+ | Aladdin -- ^ @Aladdin@, Aladdin Free Public License
+ | AMDPLPA -- ^ @AMDPLPA@, AMD's plpa_map.c License
+ | AML -- ^ @AML@, Apple MIT License
+ | AMPAS -- ^ @AMPAS@, Academy of Motion Picture Arts and Sciences BSD
+ | ANTLR_PD -- ^ @ANTLR-PD@, ANTLR Software Rights Notice
+ | Apache_1_0 -- ^ @Apache-1.0@, Apache License 1.0
+ | Apache_1_1 -- ^ @Apache-1.1@, Apache License 1.1
+ | Apache_2_0 -- ^ @Apache-2.0@, Apache License 2.0
+ | APAFML -- ^ @APAFML@, Adobe Postscript AFM License
+ | APL_1_0 -- ^ @APL-1.0@, Adaptive Public License 1.0
+ | APSL_1_0 -- ^ @APSL-1.0@, Apple Public Source License 1.0
+ | APSL_1_1 -- ^ @APSL-1.1@, Apple Public Source License 1.1
+ | APSL_1_2 -- ^ @APSL-1.2@, Apple Public Source License 1.2
+ | APSL_2_0 -- ^ @APSL-2.0@, Apple Public Source License 2.0
+ | Artistic_1_0_cl8 -- ^ @Artistic-1.0-cl8@, Artistic License 1.0 w/clause 8
+ | Artistic_1_0_Perl -- ^ @Artistic-1.0-Perl@, Artistic License 1.0 (Perl)
+ | Artistic_1_0 -- ^ @Artistic-1.0@, Artistic License 1.0
+ | Artistic_2_0 -- ^ @Artistic-2.0@, Artistic License 2.0
+ | Bahyph -- ^ @Bahyph@, Bahyph License
+ | Barr -- ^ @Barr@, Barr License
+ | Beerware -- ^ @Beerware@, Beerware License
+ | BitTorrent_1_0 -- ^ @BitTorrent-1.0@, BitTorrent Open Source License v1.0
+ | BitTorrent_1_1 -- ^ @BitTorrent-1.1@, BitTorrent Open Source License v1.1
+ | Borceux -- ^ @Borceux@, Borceux license
+ | BSD_1_Clause -- ^ @BSD-1-Clause@, BSD 1-Clause License
+ | BSD_2_Clause_FreeBSD -- ^ @BSD-2-Clause-FreeBSD@, BSD 2-Clause FreeBSD License
+ | BSD_2_Clause_NetBSD -- ^ @BSD-2-Clause-NetBSD@, BSD 2-Clause NetBSD License
+ | BSD_2_Clause_Patent -- ^ @BSD-2-Clause-Patent@, BSD-2-Clause Plus Patent License
+ | BSD_2_Clause -- ^ @BSD-2-Clause@, BSD 2-Clause "Simplified" License
+ | BSD_3_Clause_Attribution -- ^ @BSD-3-Clause-Attribution@, BSD with attribution
+ | BSD_3_Clause_Clear -- ^ @BSD-3-Clause-Clear@, BSD 3-Clause Clear License
+ | BSD_3_Clause_LBNL -- ^ @BSD-3-Clause-LBNL@, Lawrence Berkeley National Labs BSD variant license
+ | BSD_3_Clause_No_Nuclear_License_2014 -- ^ @BSD-3-Clause-No-Nuclear-License-2014@, BSD 3-Clause No Nuclear License 2014
+ | BSD_3_Clause_No_Nuclear_License -- ^ @BSD-3-Clause-No-Nuclear-License@, BSD 3-Clause No Nuclear License
+ | BSD_3_Clause_No_Nuclear_Warranty -- ^ @BSD-3-Clause-No-Nuclear-Warranty@, BSD 3-Clause No Nuclear Warranty
+ | BSD_3_Clause -- ^ @BSD-3-Clause@, BSD 3-Clause "New" or "Revised" License
+ | BSD_4_Clause_UC -- ^ @BSD-4-Clause-UC@, BSD-4-Clause (University of California-Specific)
+ | BSD_4_Clause -- ^ @BSD-4-Clause@, BSD 4-Clause "Original" or "Old" License
+ | BSD_Protection -- ^ @BSD-Protection@, BSD Protection License
+ | BSD_Source_Code -- ^ @BSD-Source-Code@, BSD Source Code Attribution
+ | BSL_1_0 -- ^ @BSL-1.0@, Boost Software License 1.0
+ | Bzip2_1_0_5 -- ^ @bzip2-1.0.5@, bzip2 and libbzip2 License v1.0.5
+ | Bzip2_1_0_6 -- ^ @bzip2-1.0.6@, bzip2 and libbzip2 License v1.0.6
+ | Caldera -- ^ @Caldera@, Caldera License
+ | CATOSL_1_1 -- ^ @CATOSL-1.1@, Computer Associates Trusted Open Source License 1.1
+ | CC_BY_1_0 -- ^ @CC-BY-1.0@, Creative Commons Attribution 1.0 Generic
+ | CC_BY_2_0 -- ^ @CC-BY-2.0@, Creative Commons Attribution 2.0 Generic
+ | CC_BY_2_5 -- ^ @CC-BY-2.5@, Creative Commons Attribution 2.5 Generic
+ | CC_BY_3_0 -- ^ @CC-BY-3.0@, Creative Commons Attribution 3.0 Unported
+ | CC_BY_4_0 -- ^ @CC-BY-4.0@, Creative Commons Attribution 4.0 International
+ | CC_BY_NC_1_0 -- ^ @CC-BY-NC-1.0@, Creative Commons Attribution Non Commercial 1.0 Generic
+ | CC_BY_NC_2_0 -- ^ @CC-BY-NC-2.0@, Creative Commons Attribution Non Commercial 2.0 Generic