summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergeiTrofimovich <>2016-11-12 21:06:00 (GMT)
committerhdiff <hdiff@hdiff.luite.com>2016-11-12 21:06:00 (GMT)
commit9753b8e83c21bd915e09af89a6ada456250c499e (patch)
tree721de5d1956caa423c1d023b88873c0ec9c647e1
parent284b06fdf5a77ec02bb15958b721d6dab5578c94 (diff)
version 0.5.10.5.1
-rw-r--r--Cabal2Ebuild.hs18
-rw-r--r--Main.hs45
-rw-r--r--Merge.hs72
-rw-r--r--Merge/Dependencies.hs107
-rw-r--r--Portage/Cabal.hs2
-rw-r--r--Portage/EBuild.hs10
-rw-r--r--Portage/EBuild/CabalFeature.hs24
-rw-r--r--Portage/EBuild/Render.hs6
-rw-r--r--Portage/GHCCore.hs117
-rw-r--r--Portage/Overlay.hs6
-rw-r--r--Portage/PackageId.hs6
-rw-r--r--Portage/Version.hs4
-rw-r--r--README.rst5
-rw-r--r--Status.hs52
-rw-r--r--cabal/.mailmap117
-rw-r--r--cabal/.mention-bot6
-rw-r--r--cabal/.travis.yml141
-rw-r--r--cabal/AUTHORS265
-rw-r--r--cabal/Cabal/Cabal.cabal423
-rw-r--r--cabal/Cabal/Distribution/Backpack.hs244
-rw-r--r--cabal/Cabal/Distribution/Backpack/ComponentsGraph.hs77
-rw-r--r--cabal/Cabal/Distribution/Backpack/Configure.hs346
-rw-r--r--cabal/Cabal/Distribution/Backpack/ConfiguredComponent.hs229
-rw-r--r--cabal/Cabal/Distribution/Backpack/FullUnitId.hs26
-rw-r--r--cabal/Cabal/Distribution/Backpack/Id.hs189
-rw-r--r--cabal/Cabal/Distribution/Backpack/LinkedComponent.hs307
-rw-r--r--cabal/Cabal/Distribution/Backpack/MixLink.hs151
-rw-r--r--cabal/Cabal/Distribution/Backpack/ModSubst.hs54
-rw-r--r--cabal/Cabal/Distribution/Backpack/ModuleScope.hs86
-rw-r--r--cabal/Cabal/Distribution/Backpack/ModuleShape.hs83
-rw-r--r--cabal/Cabal/Distribution/Backpack/PreExistingComponent.hs49
-rw-r--r--cabal/Cabal/Distribution/Backpack/ReadyComponent.hs302
-rw-r--r--cabal/Cabal/Distribution/Backpack/UnifyM.hs486
-rw-r--r--cabal/Cabal/Distribution/Compat/Binary.hs27
-rw-r--r--cabal/Cabal/Distribution/Compat/Binary/Class.hs21
-rw-r--r--cabal/Cabal/Distribution/Compat/CopyFile.hs17
-rw-r--r--cabal/Cabal/Distribution/Compat/CreatePipe.hs31
-rw-r--r--cabal/Cabal/Distribution/Compat/DList.hs40
-rw-r--r--cabal/Cabal/Distribution/Compat/Environment.hs68
-rw-r--r--cabal/Cabal/Distribution/Compat/Exception.hs10
-rw-r--r--cabal/Cabal/Distribution/Compat/GetShortPathName.hs59
-rw-r--r--cabal/Cabal/Distribution/Compat/Graph.hs403
-rw-r--r--cabal/Cabal/Distribution/Compat/MonadFail.hs4
-rw-r--r--cabal/Cabal/Distribution/Compat/Parsec.hs73
-rw-r--r--cabal/Cabal/Distribution/Compat/Prelude.hs203
-rw-r--r--cabal/Cabal/Distribution/Compat/Prelude/Internal.hs14
-rw-r--r--cabal/Cabal/Distribution/Compat/ReadP.hs18
-rw-r--r--cabal/Cabal/Distribution/Compat/SnocList.hs33
-rw-r--r--cabal/Cabal/Distribution/Compat/Stack.hs96
-rw-r--r--cabal/Cabal/Distribution/Compat/Time.hs (renamed from cabal/cabal-install/Distribution/Client/Compat/Time.hs)68
-rw-r--r--cabal/Cabal/Distribution/Compiler.hs58
-rw-r--r--cabal/Cabal/Distribution/GetOpt.hs172
-rw-r--r--cabal/Cabal/Distribution/InstalledPackageInfo.hs99
-rw-r--r--cabal/Cabal/Distribution/Lex.hs21
-rw-r--r--cabal/Cabal/Distribution/License.hs28
-rw-r--r--cabal/Cabal/Distribution/Make.hs10
-rw-r--r--cabal/Cabal/Distribution/ModuleName.hs94
-rw-r--r--cabal/Cabal/Distribution/Package.hs373
-rw-r--r--cabal/Cabal/Distribution/Package/TextClass.hs56
-rw-r--r--cabal/Cabal/Distribution/PackageDescription.hs1234
-rw-r--r--cabal/Cabal/Distribution/PackageDescription/Check.hs360
-rw-r--r--cabal/Cabal/Distribution/PackageDescription/Configuration.hs311
-rw-r--r--cabal/Cabal/Distribution/PackageDescription/Parse.hs465
-rw-r--r--cabal/Cabal/Distribution/PackageDescription/Parsec.hs557
-rw-r--r--cabal/Cabal/Distribution/PackageDescription/Parsec/FieldDescr.hs607
-rw-r--r--cabal/Cabal/Distribution/PackageDescription/PrettyPrint.hs237
-rw-r--r--cabal/Cabal/Distribution/ParseUtils.hs124
-rw-r--r--cabal/Cabal/Distribution/Parsec/Class.hs448
-rw-r--r--cabal/Cabal/Distribution/Parsec/ConfVar.hs141
-rw-r--r--cabal/Cabal/Distribution/Parsec/Lexer.x269
-rw-r--r--cabal/Cabal/Distribution/Parsec/LexerMonad.hs145
-rw-r--r--cabal/Cabal/Distribution/Parsec/Parser.hs403
-rw-r--r--cabal/Cabal/Distribution/Parsec/Types/Common.hs89
-rw-r--r--cabal/Cabal/Distribution/Parsec/Types/Field.hs82
-rw-r--r--cabal/Cabal/Distribution/Parsec/Types/FieldDescr.hs238
-rw-r--r--cabal/Cabal/Distribution/Parsec/Types/ParseResult.hs87
-rw-r--r--cabal/Cabal/Distribution/PrettyUtils.hs64
-rw-r--r--cabal/Cabal/Distribution/ReadE.hs4
-rw-r--r--cabal/Cabal/Distribution/Simple.hs225
-rw-r--r--cabal/Cabal/Distribution/Simple/Bench.hs31
-rw-r--r--cabal/Cabal/Distribution/Simple/Build.hs233
-rw-r--r--cabal/Cabal/Distribution/Simple/Build/Macros.hs73
-rw-r--r--cabal/Cabal/Distribution/Simple/Build/PathsModule.hs37
-rw-r--r--cabal/Cabal/Distribution/Simple/BuildPaths.hs62
-rw-r--r--cabal/Cabal/Distribution/Simple/BuildTarget.hs167
-rw-r--r--cabal/Cabal/Distribution/Simple/CCompiler.hs5
-rw-r--r--cabal/Cabal/Distribution/Simple/Command.hs13
-rw-r--r--cabal/Cabal/Distribution/Simple/Compiler.hs95
-rw-r--r--cabal/Cabal/Distribution/Simple/Configure.hs1509
-rw-r--r--cabal/Cabal/Distribution/Simple/GHC.hs774
-rw-r--r--cabal/Cabal/Distribution/Simple/GHC/IPI642.hs10
-rw-r--r--cabal/Cabal/Distribution/Simple/GHC/IPIConvert.hs9
-rw-r--r--cabal/Cabal/Distribution/Simple/GHC/ImplInfo.hs18
-rw-r--r--cabal/Cabal/Distribution/Simple/GHC/Internal.hs232
-rw-r--r--cabal/Cabal/Distribution/Simple/GHCJS.hs191
-rw-r--r--cabal/Cabal/Distribution/Simple/Haddock.hs275
-rw-r--r--cabal/Cabal/Distribution/Simple/HaskellSuite.hs70
-rw-r--r--cabal/Cabal/Distribution/Simple/Hpc.hs24
-rw-r--r--cabal/Cabal/Distribution/Simple/Install.hs106
-rw-r--r--cabal/Cabal/Distribution/Simple/InstallDirs.hs60
-rw-r--r--cabal/Cabal/Distribution/Simple/JHC.hs50
-rw-r--r--cabal/Cabal/Distribution/Simple/LHC.hs179
-rw-r--r--cabal/Cabal/Distribution/Simple/LocalBuildInfo.hs553
-rw-r--r--cabal/Cabal/Distribution/Simple/PackageIndex.hs107
-rw-r--r--cabal/Cabal/Distribution/Simple/PreProcess.hs148
-rw-r--r--cabal/Cabal/Distribution/Simple/PreProcess/Unlit.hs8
-rw-r--r--cabal/Cabal/Distribution/Simple/Program.hs37
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/Ar.hs12
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/Builtin.hs9
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/Db.hs90
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/Find.hs24
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/GHC.hs68
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/HcPkg.hs21
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/Hpc.hs8
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/Internal.hs4
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/Ld.hs6
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/Run.hs43
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/Script.hs6
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/Strip.hs33
-rw-r--r--cabal/Cabal/Distribution/Simple/Program/Types.hs12
-rw-r--r--cabal/Cabal/Distribution/Simple/Register.hs230
-rw-r--r--cabal/Cabal/Distribution/Simple/Setup.hs483
-rw-r--r--cabal/Cabal/Distribution/Simple/SrcDist.hs137
-rw-r--r--cabal/Cabal/Distribution/Simple/Test.hs42
-rw-r--r--cabal/Cabal/Distribution/Simple/Test/ExeV10.hs40
-rw-r--r--cabal/Cabal/Distribution/Simple/Test/LibV09.hs62
-rw-r--r--cabal/Cabal/Distribution/Simple/Test/Log.hs14
-rw-r--r--cabal/Cabal/Distribution/Simple/UHC.hs59
-rw-r--r--cabal/Cabal/Distribution/Simple/UserHooks.hs10
-rw-r--r--cabal/Cabal/Distribution/Simple/Utils.hs311
-rw-r--r--cabal/Cabal/Distribution/System.hs59
-rw-r--r--cabal/Cabal/Distribution/TestSuite.hs6
-rw-r--r--cabal/Cabal/Distribution/Text.hs29
-rw-r--r--cabal/Cabal/Distribution/Types/Benchmark.hs71
-rw-r--r--cabal/Cabal/Distribution/Types/BenchmarkInterface.hs44
-rw-r--r--cabal/Cabal/Distribution/Types/BenchmarkType.hs38
-rw-r--r--cabal/Cabal/Distribution/Types/BuildInfo.hs178
-rw-r--r--cabal/Cabal/Distribution/Types/BuildType.hs48
-rw-r--r--cabal/Cabal/Distribution/Types/Component.hs86
-rw-r--r--cabal/Cabal/Distribution/Types/ComponentLocalBuildInfo.hs118
-rw-r--r--cabal/Cabal/Distribution/Types/ComponentName.hs73
-rw-r--r--cabal/Cabal/Distribution/Types/ComponentRequestedSpec.hs123
-rw-r--r--cabal/Cabal/Distribution/Types/Executable.hs56
-rw-r--r--cabal/Cabal/Distribution/Types/ForeignLib.hs81
-rw-r--r--cabal/Cabal/Distribution/Types/ForeignLibOption.hs32
-rw-r--r--cabal/Cabal/Distribution/Types/ForeignLibType.hs61
-rw-r--r--cabal/Cabal/Distribution/Types/GenericPackageDescription.hs222
-rw-r--r--cabal/Cabal/Distribution/Types/HookedBuildInfo.hs66
-rw-r--r--cabal/Cabal/Distribution/Types/IncludeRenaming.hs59
-rw-r--r--cabal/Cabal/Distribution/Types/Library.hs81
-rw-r--r--cabal/Cabal/Distribution/Types/LocalBuildInfo.hs329
-rw-r--r--cabal/Cabal/Distribution/Types/Mixin.hs32
-rw-r--r--cabal/Cabal/Distribution/Types/ModuleReexport.hs49
-rw-r--r--cabal/Cabal/Distribution/Types/ModuleRenaming.hs91
-rw-r--r--cabal/Cabal/Distribution/Types/PackageDescription.hs411
-rw-r--r--cabal/Cabal/Distribution/Types/SetupBuildInfo.hs38
-rw-r--r--cabal/Cabal/Distribution/Types/SourceRepo.hs166
-rw-r--r--cabal/Cabal/Distribution/Types/TargetInfo.hs33
-rw-r--r--cabal/Cabal/Distribution/Types/TestSuite.hs76
-rw-r--r--cabal/Cabal/Distribution/Types/TestSuiteInterface.hs50
-rw-r--r--cabal/Cabal/Distribution/Types/TestType.hs38
-rw-r--r--cabal/Cabal/Distribution/Utils/Base62.hs22
-rw-r--r--cabal/Cabal/Distribution/Utils/BinaryWithFingerprint.hs87
-rw-r--r--cabal/Cabal/Distribution/Utils/LogProgress.hs41
-rw-r--r--cabal/Cabal/Distribution/Utils/MapAccum.hs34
-rw-r--r--cabal/Cabal/Distribution/Utils/NubList.hs12
-rw-r--r--cabal/Cabal/Distribution/Utils/Progress.hs67
-rw-r--r--cabal/Cabal/Distribution/Utils/ShortText.hs113
-rw-r--r--cabal/Cabal/Distribution/Utils/String.hs85
-rw-r--r--cabal/Cabal/Distribution/Utils/UnionFind.hs102
-rw-r--r--cabal/Cabal/Distribution/Verbosity.hs160
-rw-r--r--cabal/Cabal/Distribution/Version.hs373
-rw-r--r--cabal/Cabal/LICENSE7
-rw-r--r--cabal/Cabal/Language/Haskell/Extension.hs24
-rw-r--r--cabal/Cabal/changelog103
-rw-r--r--cabal/Cabal/doc/Cabal.css49
-rw-r--r--cabal/Cabal/doc/README.md122
-rw-r--r--cabal/Cabal/doc/_templates/layout.html8
-rw-r--r--cabal/Cabal/doc/bugs-and-stability.rst6
-rw-r--r--cabal/Cabal/doc/cabaldomain.py885
-rw-r--r--cabal/Cabal/doc/concepts-and-development.rst7
-rw-r--r--cabal/Cabal/doc/conf.py207
-rw-r--r--cabal/Cabal/doc/config-and-install.rst5
-rw-r--r--cabal/Cabal/doc/developing-packages.markdown2255
-rw-r--r--cabal/Cabal/doc/developing-packages.rst2675
-rw-r--r--cabal/Cabal/doc/images/Cabal-dark.pngbin0 -> 7086 bytes
-rw-r--r--cabal/Cabal/doc/index.rst13
-rw-r--r--cabal/Cabal/doc/installing-packages.markdown1288
-rw-r--r--cabal/Cabal/doc/installing-packages.rst1619
-rw-r--r--cabal/Cabal/doc/intro.rst (renamed from cabal/Cabal/doc/index.markdown)191
-rw-r--r--cabal/Cabal/doc/misc.markdown109
-rw-r--r--cabal/Cabal/doc/misc.rst103
-rw-r--r--cabal/Cabal/doc/nix-local-build-overview.rst32
-rw-r--r--cabal/Cabal/doc/nix-local-build.rst1701
-rw-r--r--cabal/Cabal/doc/references.inc22
-rwxr-xr-xcabal/Cabal/misc/gen-authors.sh3
-rwxr-xr-xcabal/Cabal/misc/gen-extra-source-files.hs119
-rwxr-xr-xcabal/Cabal/misc/gen-extra-source-files.sh22
-rwxr-xr-xcabal/Cabal/misc/travis-diff-files.sh2
-rw-r--r--cabal/HACKING.md159
-rw-r--r--cabal/LICENSE3
-rw-r--r--cabal/README.md218
-rw-r--r--cabal/appveyor.yml20
-rw-r--r--cabal/cabal-install/Distribution/Client/BuildReports/Anonymous.hs41
-rw-r--r--cabal/cabal-install/Distribution/Client/BuildReports/Storage.hs41
-rw-r--r--cabal/cabal-install/Distribution/Client/BuildTarget.hs1670
-rw-r--r--cabal/cabal-install/Distribution/Client/Check.hs2
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdBuild.hs90
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdConfigure.hs97
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdFreeze.hs213
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdHaddock.hs93
-rw-r--r--cabal/cabal-install/Distribution/Client/CmdRepl.hs100
-rw-r--r--cabal/cabal-install/Distribution/Client/Compat/Prelude.hs35
-rw-r--r--cabal/cabal-install/Distribution/Client/Compat/Process.hs9
-rw-r--r--cabal/cabal-install/Distribution/Client/Config.hs231
-rw-r--r--cabal/cabal-install/Distribution/Client/Configure.hs209
-rw-r--r--cabal/cabal-install/Distribution/Client/Dependency.hs411
-rw-r--r--cabal/cabal-install/Distribution/Client/Dependency/Modular/Configured.hs13
-rw-r--r--cabal/cabal-install/Distribution/Client/Dependency/Modular/ConfiguredConversion.hs54
-rw-r--r--cabal/cabal-install/Distribution/Client/Dependency/Modular/Cycles.hs73
-rw-r--r--cabal/cabal-install/Distribution/Client/Dependency/Modular/Explore.hs88
-rw-r--r--cabal/cabal-install/Distribution/Client/Dependency/Modular/Package.hs175
-rw-r--r--cabal/cabal-install/Distribution/Client/Dependency/Modular/Solver.hs100
-rw-r--r--cabal/cabal-install/Distribution/Client/Dependency/Modular/Tree.hs169
-rw-r--r--cabal/cabal-install/Distribution/Client/Dependency/TopDown.hs1081
-rw-r--r--cabal/cabal-install/Distribution/Client/Dependency/TopDown/Constraints.hs599
-rw-r--r--cabal/cabal-install/Distribution/Client/Dependency/TopDown/Types.hs144
-rw-r--r--cabal/cabal-install/Distribution/Client/Dependency/Types.hs258
-rw-r--r--cabal/cabal-install/Distribution/Client/DistDirLayout.hs67
-rw-r--r--cabal/cabal-install/Distribution/Client/Exec.hs8
-rw-r--r--cabal/cabal-install/Distribution/Client/Fetch.hs27
-rw-r--r--cabal/cabal-install/Distribution/Client/FetchUtils.hs98
-rw-r--r--cabal/cabal-install/Distribution/Client/FileMonitor.hs94
-rw-r--r--cabal/cabal-install/Distribution/Client/Freeze.hs64
-rw-r--r--cabal/cabal-install/Distribution/Client/GenBounds.hs34
-rw-r--r--cabal/cabal-install/Distribution/Client/Get.hs42
-rw-r--r--cabal/cabal-install/Distribution/Client/Glob.hs40
-rw-r--r--cabal/cabal-install/Distribution/Client/GlobalFlags.hs47
-rw-r--r--cabal/cabal-install/Distribution/Client/Haddock.hs14
-rw-r--r--cabal/cabal-install/Distribution/Client/HttpUtils.hs136
-rw-r--r--cabal/cabal-install/Distribution/Client/IndexUtils.hs534
-rw-r--r--cabal/cabal-install/Distribution/Client/IndexUtils/Timestamp.hs192
-rw-r--r--cabal/cabal-install/Distribution/Client/Init.hs80
-rw-r--r--cabal/cabal-install/Distribution/Client/Init/Heuristics.hs49
-rw-r--r--cabal/cabal-install/Distribution/Client/Init/Types.hs4
-rw-r--r--cabal/cabal-install/Distribution/Client/Install.hs595
-rw-r--r--cabal/cabal-install/Distribution/Client/InstallPlan.hs1305
-rw-r--r--cabal/cabal-install/Distribution/Client/InstallSymlink.hs91
-rw-r--r--cabal/cabal-install/Distribution/Client/JobControl.hs135
-rw-r--r--cabal/cabal-install/Distribution/Client/List.hs55
-rw-r--r--cabal/cabal-install/Distribution/Client/Manpage.hs2
-rw-r--r--cabal/cabal-install/Distribution/Client/PackageHash.hs140
-rw-r--r--cabal/cabal-install/Distribution/Client/PackageUtils.hs4
-rw-r--r--cabal/cabal-install/Distribution/Client/ParseUtils.hs2
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectBuilding.hs911
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectBuilding/Types.hs206
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectConfig.hs390
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectConfig/Legacy.hs164
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectConfig/Types.hs119
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectOrchestration.hs837
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectPlanOutput.hs821
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectPlanning.hs2570
-rw-r--r--cabal/cabal-install/Distribution/Client/ProjectPlanning/Types.hs608
-rw-r--r--cabal/cabal-install/Distribution/Client/RebuildMonad.hs137
-rw-r--r--cabal/cabal-install/Distribution/Client/Reconfigure.hs212
-rw-r--r--cabal/cabal-install/Distribution/Client/Run.hs50
-rw-r--r--cabal/cabal-install/Distribution/Client/Sandbox.hs132
-rw-r--r--cabal/cabal-install/Distribution/Client/Sandbox/PackageEnvironment.hs12
-rw-r--r--cabal/cabal-install/Distribution/Client/Sandbox/Timestamp.hs68
-rw-r--r--cabal/cabal-install/Distribution/Client/Sandbox/Types.hs8
-rw-r--r--cabal/cabal-install/Distribution/Client/SavedFlags.hs83
-rw-r--r--cabal/cabal-install/Distribution/Client/Security/DNS.hs147
-rw-r--r--cabal/cabal-install/Distribution/Client/Setup.hs335
-rw-r--r--cabal/cabal-install/Distribution/Client/SetupWrapper.hs562
-rw-r--r--cabal/cabal-install/Distribution/Client/SolverInstallPlan.hs446
-rw-r--r--cabal/cabal-install/Distribution/Client/SolverPlanIndex.hs (renamed from cabal/cabal-install/Distribution/Client/PlanIndex.hs)148
-rw-r--r--cabal/cabal-install/Distribution/Client/SourceFiles.hs168
-rw-r--r--cabal/cabal-install/Distribution/Client/SrcDist.hs76
-rw-r--r--cabal/cabal-install/Distribution/Client/Targets.hs87
-rw-r--r--cabal/cabal-install/Distribution/Client/Types.hs197
-rw-r--r--cabal/cabal-install/Distribution/Client/Update.hs2
-rw-r--r--cabal/cabal-install/Distribution/Client/Upload.hs100
-rw-r--r--cabal/cabal-install/Distribution/Client/Utils.hs77
-rw-r--r--cabal/cabal-install/Distribution/Client/Utils/Json.hs225
-rw-r--r--cabal/cabal-install/Distribution/Client/Win32SelfUpgrade.hs2
-rw-r--r--cabal/cabal-install/Distribution/Client/World.hs10
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular.hs (renamed from cabal/cabal-install/Distribution/Client/Dependency/Modular.hs)36
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Assignment.hs (renamed from cabal/cabal-install/Distribution/Client/Dependency/Modular/Assignment.hs)44
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Builder.hs (renamed from cabal/cabal-install/Distribution/Client/Dependency/Modular/Builder.hs)89
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Configured.hs13
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/ConfiguredConversion.hs72
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/ConflictSet.hs171
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Cycles.hs50
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Degree.hs21
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Dependency.hs (renamed from cabal/cabal-install/Distribution/Client/Dependency/Modular/Dependency.hs)255
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Explore.hs181
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Flag.hs (renamed from cabal/cabal-install/Distribution/Client/Dependency/Modular/Flag.hs)28
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Index.hs (renamed from cabal/cabal-install/Distribution/Client/Dependency/Modular/Index.hs)16
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/IndexConversion.hs (renamed from cabal/cabal-install/Distribution/Client/Dependency/Modular/IndexConversion.hs)182
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/LabeledGraph.hs (renamed from cabal/cabal-install/Distribution/Client/Utils/LabeledGraph.hs)2
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Linking.hs (renamed from cabal/cabal-install/Distribution/Client/Dependency/Modular/Linking.hs)251
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Log.hs (renamed from cabal/cabal-install/Distribution/Client/Dependency/Modular/Log.hs)38
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Message.hs (renamed from cabal/cabal-install/Distribution/Client/Dependency/Modular/Message.hs)34
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/PSQ.hs (renamed from cabal/cabal-install/Distribution/Client/Dependency/Modular/PSQ.hs)30
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Package.hs100
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Preference.hs (renamed from cabal/cabal-install/Distribution/Client/Dependency/Modular/Preference.hs)335
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/RetryLog.hs69
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Solver.hs253
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Tree.hs189
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Validate.hs (renamed from cabal/cabal-install/Distribution/Client/Dependency/Modular/Validate.hs)98
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Var.hs46
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/Version.hs (renamed from cabal/cabal-install/Distribution/Client/Dependency/Modular/Version.hs)2
-rw-r--r--cabal/cabal-install/Distribution/Solver/Modular/WeightedPSQ.hs97
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/ComponentDeps.hs (renamed from cabal/cabal-install/Distribution/Client/ComponentDeps.hs)80
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/ConstraintSource.hs74
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/DependencyResolver.hs36
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/InstSolverPackage.hs28
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/InstalledPreference.hs9
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/LabeledPackageConstraint.hs14
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/OptionalStanza.hs28
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/PackageConstraint.hs49
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/PackageFixedDeps.hs23
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/PackageIndex.hs (renamed from cabal/cabal-install/Distribution/Client/PackageIndex.hs)29
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/PackagePath.hs99
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/PackagePreferences.hs22
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/PkgConfigDb.hs (renamed from cabal/cabal-install/Distribution/Client/PkgConfigDb.hs)100
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/Progress.hs43
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/ResolverPackage.hs50
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/Settings.hs48
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/SolverId.hs27
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/SolverPackage.hs34
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/SourcePackage.hs34
-rw-r--r--cabal/cabal-install/Distribution/Solver/Types/Variable.hs14
-rw-r--r--cabal/cabal-install/LICENSE7
-rw-r--r--cabal/cabal-install/Main.hs565
-rw-r--r--cabal/cabal-install/Setup.hs4
-rw-r--r--cabal/cabal-install/bash-completion/cabal31
-rwxr-xr-xcabal/cabal-install/bootstrap.sh166
-rw-r--r--cabal/cabal-install/cabal-install.cabal396
-rw-r--r--cabal/cabal-install/changelog30
-rw-r--r--cabal/cabal-install/tests/IntegrationTests.hs10
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes2-external.sh9
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes2-internal.sh9
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes2/Includes2.cabal41
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes2/cabal.project.external1
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes2/cabal.project.internal1
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes2/exe/Main.hs3
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes2/exe/exe.cabal12
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes2/mylib/Database.hsig3
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes2/mylib/Mine.hs4
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes2/mylib/mylib.cabal13
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes2/mysql/Database/MySQL.hs3
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes2/mysql/mysql.cabal12
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes2/postgresql/Database/PostgreSQL.hs3
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes2/postgresql/postgresql.cabal12
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes2/src/App.hs7
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes2/src/src.cabal15
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes3-external.sh9
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes3-internal.sh9
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes3/Includes3.cabal23
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes3/cabal.project.external1
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes3/cabal.project.internal1
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes3/exe/Main.hs4
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes3/exe/Setup.hs2
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes3/exe/exe.cabal12
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes3/indef/Foo.hs6
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes3/indef/Setup.hs2
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes3/indef/indef.cabal11
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes3/sigs/Data/Map.hsig5
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes3/sigs/Setup.hs2
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/backpack/includes3/sigs/sigs.cabal11
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/common.sh16
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom-setup/Cabal-99998/Cabal.cabal8
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom-setup/Cabal-99998/CabalMessage.hs3
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom-setup/Cabal-99999/Cabal.cabal8
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom-setup/Cabal-99999/CabalMessage.hs3
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom-setup/custom-setup-old-cabal/Setup.hs5
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom-setup/custom-setup-old-cabal/custom-setup-old-cabal.cabal8
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom-setup/custom-setup-without-cabal-defaultMain/Setup.hs3
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom-setup/custom-setup-without-cabal-defaultMain/custom-setup-without-cabal-defaultMain.cabal9
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom-setup/custom-setup-without-cabal/Setup.hs4
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom-setup/custom-setup-without-cabal/custom-setup-without-cabal.cabal9
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom-setup/custom-setup/Setup.hs5
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom-setup/custom-setup/custom-setup.cabal9
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom-setup/custom_setup_without_Cabal_doesnt_allow_Cabal_import.sh12
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom-setup/custom_setup_without_Cabal_doesnt_require_Cabal.sh11
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom-setup/installs_Cabal_as_setup_dep.sh15
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom-setup/new_build_requires_Cabal_1_20.sh9
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom/custom_dep.sh22
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom/custom_dep/client/B.hs2
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom/custom_dep/client/Setup.hs2
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom/custom_dep/client/client.cabal12
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom/custom_dep/custom/A.hs1
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom/custom_dep/custom/Setup.hs2
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom/custom_dep/custom/custom.cabal12
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom/plain.err2
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom/plain.sh15
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom/segfault.sh10
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom/segfault/Setup.hs3
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom/segfault/cabal.project1
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/custom/segfault/plain.cabal14
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/internal-libs/cabal.project1
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/internal-libs/new_build.sh3
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/BuildToolsPath.sh3
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/BuildToolsPath/A.hs5
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/BuildToolsPath/MyCustomPreprocessor.hs11
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/BuildToolsPath/build-tools-path.cabal25
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/BuildToolsPath/cabal.project1
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/BuildToolsPath/hello/Hello.hs6
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/T3460.sh3
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/T3460/C.hs3
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/T3460/Setup.hs2
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/T3460/T3460.cabal22
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/T3460/cabal.project3
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/T3460/sub-package-A/A.hs1
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/T3460/sub-package-A/Setup.hs2
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/T3460/sub-package-A/sub-package-A.cabal22
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/T3460/sub-package-B/B.hs1
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/T3460/sub-package-B/Setup.hs2
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/T3460/sub-package-B/sub-package-B.cabal22
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/T3978.err1
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/T3978.sh3
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/T3978/cabal.project2
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/T3978/p/p.cabal7
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/T3978/q/q.cabal7
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/T4017.sh3
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/T4017/cabal.project2
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/T4017/p/p.cabal7
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/T4017/q/q.cabal7
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/executable/Main.hs1
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/executable/Setup.hs2
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/executable/Test.hs1
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/executable/a.cabal15
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/executable/cabal.project1
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/external_build_tools.sh3
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/external_build_tools/cabal.project1
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/external_build_tools/client/Hello.hs8
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/external_build_tools/client/client.cabal13
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/external_build_tools/happy/MyCustomPreprocessor.hs11
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/external_build_tools/happy/happy.cabal12
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/monitor_cabal_files.sh8
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/monitor_cabal_files/cabal.project4
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/monitor_cabal_files/p/P.hs1
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/monitor_cabal_files/p/Setup.hs2
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/monitor_cabal_files/p/p.cabal12
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/monitor_cabal_files/q/Main.hs4
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/monitor_cabal_files/q/Setup.hs2
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/monitor_cabal_files/q/q-broken.cabal.in12
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/new-build/monitor_cabal_files/q/q-fixed.cabal.in12
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/regression/t2755.sh6
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/regression/t2755/A.hs1
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/regression/t2755/Setup.hs2
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/regression/t2755/test-t2755.cabal13
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/regression/t3199.sh12
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/regression/t3199/Main.hs4
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/regression/t3199/Setup.hs2
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/regression/t3199/test-3199.cabal27
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/regression/t3827.sh4
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/regression/t3827/cabal.project4
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/regression/t3827/p/P.hs2
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/regression/t3827/p/p.cabal8
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/regression/t3827/q/Main.hs3
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/regression/t3827/q/q.cabal8
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/sandbox-reinstalls/p/Main.hs4
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/sandbox-reinstalls/p/p.cabal8
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/sandbox-reinstalls/q/Q.hs4
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/sandbox-reinstalls/q/q.cabal8
-rw-r--r--cabal/cabal-install/tests/IntegrationTests/sandbox-reinstalls/reinstall-modified-source.sh16
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2.hs452
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/build/keep-going/cabal.project1
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/build/keep-going/p/P.hs4
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/build/keep-going/p/p.cabal8
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/build/keep-going/q/Q.hs4
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/build/keep-going/q/q.cabal9
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/build/setup-custom1/A.hs4
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/build/setup-custom1/Setup.hs2
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/build/setup-custom1/a.cabal13
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/build/setup-custom2/A.hs4
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/build/setup-custom2/Setup.hs2
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/build/setup-custom2/a.cabal11
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/build/setup-simple/A.hs4
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/build/setup-simple/Setup.hs2
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/build/setup-simple/a.cabal9
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/exception/bad-config/cabal.project4
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/exception/build/Main.hs1
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/exception/build/a.cabal8
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/exception/configure/a.cabal9
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/exception/no-pkg/empty.in1
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/exception/no-pkg2/cabal.project1
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/regression/3324/cabal.project1
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/regression/3324/p/P.hs4
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/regression/3324/p/p.cabal8
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/regression/3324/q/Q.hs6
-rw-r--r--cabal/cabal-install/tests/IntegrationTests2/regression/3324/q/q.cabal9
-rw-r--r--cabal/cabal-install/tests/SolverQuickCheck.hs6
-rw-r--r--cabal/cabal-install/tests/UnitTests.hs80
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/ArbitraryInstances.hs19
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/Compat/Time.hs49
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/Dependency/Modular/DSL.hs455
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/Dependency/Modular/Solver.hs588
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/FileMonitor.hs101
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/Glob.hs21
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/IndexUtils/Timestamp.hs60
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/InstallPlan.hs311
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/JobControl.hs193
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs246
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/Sandbox/Timestamp.hs2
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/Targets.hs8
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Client/UserConfig.hs4
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL.hs608
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/PSQ.hs (renamed from cabal/cabal-install/tests/UnitTests/Distribution/Client/Dependency/Modular/PSQ.hs)4
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck.hs (renamed from cabal/cabal-install/tests/UnitTests/Distribution/Client/Dependency/Modular/QuickCheck.hs)180
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/RetryLog.hs72
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs1192
-rw-r--r--cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/WeightedPSQ.hs54
-rw-r--r--cabal/cabal-testsuite/LICENSE31
-rw-r--r--cabal/cabal-testsuite/PackageTests.hs329
-rw-r--r--cabal/cabal-testsuite/PackageTests/AllowNewer/AllowNewer.cabal25
-rw-r--r--cabal/cabal-testsuite/PackageTests/AllowNewer/benchmarks/Bench.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/AllowNewer/src/Foo.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/AllowNewer/tests/Test.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/AllowOlder/AllowOlder.cabal25
-rw-r--r--cabal/cabal-testsuite/PackageTests/AllowOlder/benchmarks/Bench.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/AllowOlder/src/Foo.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/AllowOlder/tests/Test.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Ambiguity/p/Dupe.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Ambiguity/p/p.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/Ambiguity/package-import/A.hs7
-rw-r--r--cabal/cabal-testsuite/PackageTests/Ambiguity/package-import/package-import.cabal13
-rw-r--r--cabal/cabal-testsuite/PackageTests/Ambiguity/q/Dupe.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Ambiguity/q/q.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/Ambiguity/reexport-test/Main.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/Ambiguity/reexport-test/reexport-test.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/Ambiguity/reexport/reexport.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/Package/Check.hs51
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/Package/Dummy.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/Package/LICENSE1
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/Package/MyBenchModule.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/Package/MyExeModule.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/Package/MyLibModule.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/Package/MyLibrary.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/Package/MyTestModule.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/Package/my.cabal60
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/Package/tmp0
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/Check.hs104
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/Dummy.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/LICENSE1
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/MyBenchModule.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/MyExeModule.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/MyLibModule.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/MyLibrary.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/MyTestModule.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/list-sources.txt0
-rw-r--r--cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/my.cabal60
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes1/A.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes1/B.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes1/Includes1.cabal13
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/Includes2.cabal41
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/exe/Main.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/exe/exe.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/fail.cabal35
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/mylib/Database.hsig3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/mylib/Mine.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/mylib/mylib.cabal13
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/mysql/Database/MySQL.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/mysql/mysql.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/postgresql/Database/PostgreSQL.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/postgresql/postgresql.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/src/App.hs7
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes2/src/src.cabal15
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes3/Includes3.cabal23
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes3/exe/Main.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes3/exe/exe.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes3/indef/Foo.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes3/indef/indef.cabal11
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes3/sigs/Data/Map.hsig5
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes3/sigs/sigs.cabal11
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes4/Includes4.cabal25
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes4/Main.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes4/impl/A.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes4/impl/A.hs-boot3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes4/impl/B.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes4/impl/Rec.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes4/indef/A.hsig2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes4/indef/B.hsig2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes4/indef/C.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes4/indef/Rec.hsig3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes5/A.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes5/B.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes5/Includes5.cabal25
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes5/impl/Foobar.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Includes5/impl/Quxbaz.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Indef1/Indef1.cabal13
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Indef1/Map.hsig5
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Indef1/Provide.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Reexport1/p/P.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Reexport1/p/p.cabal14
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Reexport1/q/Q.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Backpack/Reexport1/q/q.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/BenchmarkExeV10/Foo.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/BenchmarkExeV10/benchmarks/bench-Foo.hs8
-rw-r--r--cabal/cabal-testsuite/PackageTests/BenchmarkExeV10/my.cabal15
-rw-r--r--cabal/cabal-testsuite/PackageTests/BenchmarkOptions/BenchmarkOptions.cabal20
-rw-r--r--cabal/cabal-testsuite/PackageTests/BenchmarkOptions/test-BenchmarkOptions.hs11
-rw-r--r--cabal/cabal-testsuite/PackageTests/BenchmarkStanza/Check.hs29
-rw-r--r--cabal/cabal-testsuite/PackageTests/BenchmarkStanza/my.cabal19
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/GlobalBuildDepsNotAdditive1/Check.hs22
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/GlobalBuildDepsNotAdditive1/GlobalBuildDepsNotAdditive1.cabal20
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/GlobalBuildDepsNotAdditive1/MyLibrary.hs10
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/GlobalBuildDepsNotAdditive2/Check.hs22
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/GlobalBuildDepsNotAdditive2/GlobalBuildDepsNotAdditive2.cabal20
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/GlobalBuildDepsNotAdditive2/lemon.hs7
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary0/MyLibrary.hs10
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary0/my.cabal24
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary0/programs/lemon.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary1/MyLibrary.hs10
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary1/my.cabal23
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary1/programs/lemon.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary2/MyLibrary.hs10
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary2/my.cabal23
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary2/programs/lemon.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary2/to-install/MyLibrary.hs10
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary2/to-install/my.cabal18
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary3/MyLibrary.hs10
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary3/my.cabal23
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary3/programs/lemon.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary3/to-install/MyLibrary.hs10
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary3/to-install/my.cabal18
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary4/MyLibrary.hs10
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary4/my.cabal23
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary4/programs/lemon.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary4/to-install/MyLibrary.hs10
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/InternalLibrary4/to-install/my.cabal18
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/SameDepsAllRound/MyLibrary.hs10
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/SameDepsAllRound/SameDepsAllRound.cabal31
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/SameDepsAllRound/lemon.hs7
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/SameDepsAllRound/pineapple.hs7
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/TargetSpecificDeps1/MyLibrary.hs10
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/TargetSpecificDeps1/lemon.hs7
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/TargetSpecificDeps1/my.cabal22
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/TargetSpecificDeps2/MyLibrary.hs10
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/TargetSpecificDeps2/lemon.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/TargetSpecificDeps2/my.cabal24
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/TargetSpecificDeps3/MyLibrary.hs10
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/TargetSpecificDeps3/lemon.hs7
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildDeps/TargetSpecificDeps3/my.cabal22
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildTargetErrors/BuildTargetErrors.cabal10
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildTargetErrors/Main.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildTestSuiteDetailedV09/Dummy2.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildToolsPath/A.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildToolsPath/MyCustomPreprocessor.hs11
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildToolsPath/build-tools-path.cabal25
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildToolsPath/hello/Hello.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildableField/BuildableField.cabal16
-rw-r--r--cabal/cabal-testsuite/PackageTests/BuildableField/Main.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/CMain/Bar.hs7
-rw-r--r--cabal/cabal-testsuite/PackageTests/CMain/foo.c13
-rw-r--r--cabal/cabal-testsuite/PackageTests/CMain/my.cabal10
-rw-r--r--cabal/cabal-testsuite/PackageTests/CaretOperator/Check.hs34
-rw-r--r--cabal/cabal-testsuite/PackageTests/CaretOperator/my.cabal15
-rw-r--r--cabal/cabal-testsuite/PackageTests/Configure/A.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Configure/Setup.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Configure/configure.ac20
-rw-r--r--cabal/cabal-testsuite/PackageTests/Configure/include/HsZlibConfig.h.in49
-rw-r--r--cabal/cabal-testsuite/PackageTests/Configure/zlib.buildinfo.in3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Configure/zlib.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/ConfigureComponent/Exe/Bad.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/ConfigureComponent/Exe/Exe.cabal18
-rw-r--r--cabal/cabal-testsuite/PackageTests/ConfigureComponent/Exe/Good.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/ConfigureComponent/SubLib/Lib.cabal18
-rw-r--r--cabal/cabal-testsuite/PackageTests/ConfigureComponent/SubLib/Lib.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/ConfigureComponent/SubLib/exe/Exe.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/ConfigureComponent/Test/Lib.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/ConfigureComponent/Test/Test.cabal18
-rw-r--r--cabal/cabal-testsuite/PackageTests/ConfigureComponent/Test/testlib/TestLib.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/ConfigureComponent/Test/testlib/testlib.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/ConfigureComponent/Test/tests/Test.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/CopyComponent/Exe/Main.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/CopyComponent/Exe/Main2.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/CopyComponent/Exe/myprog.cabal15
-rw-r--r--cabal/cabal-testsuite/PackageTests/CopyComponent/Lib/Main.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/CopyComponent/Lib/p.cabal17
-rw-r--r--cabal/cabal-testsuite/PackageTests/CopyComponent/Lib/src/P.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomPreProcess/A.pre4
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomPreProcess/Hello.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomPreProcess/MyCustomPreprocessor.hs9
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomPreProcess/Setup.hs36
-rw-r--r--cabal/cabal-testsuite/PackageTests/CustomPreProcess/internal-preprocessor-test.cabal31
-rw-r--r--cabal/cabal-testsuite/PackageTests/DeterministicAr/Check.hs85
-rw-r--r--cabal/cabal-testsuite/PackageTests/DeterministicAr/Lib.hs5
-rw-r--r--cabal/cabal-testsuite/PackageTests/DeterministicAr/my.cabal17
-rw-r--r--cabal/cabal-testsuite/PackageTests/DuplicateModuleName/DuplicateModuleName.cabal25
-rw-r--r--cabal/cabal-testsuite/PackageTests/DuplicateModuleName/src/Foo.hs12
-rw-r--r--cabal/cabal-testsuite/PackageTests/DuplicateModuleName/tests/Foo.hs18
-rw-r--r--cabal/cabal-testsuite/PackageTests/DuplicateModuleName/tests2/Foo.hs18
-rw-r--r--cabal/cabal-testsuite/PackageTests/EmptyLib/empty/empty.cabal6
-rw-r--r--cabal/cabal-testsuite/PackageTests/ForeignLibs/Check.hs55
-rw-r--r--cabal/cabal-testsuite/PackageTests/ForeignLibs/LICENSE0
-rw-r--r--cabal/cabal-testsuite/PackageTests/ForeignLibs/UseLib.c9
-rw-r--r--cabal/cabal-testsuite/PackageTests/ForeignLibs/csrc/MyForeignLibWrapper.c23
-rw-r--r--cabal/cabal-testsuite/PackageTests/ForeignLibs/my-foreign-lib.cabal26
-rw-r--r--cabal/cabal-testsuite/PackageTests/ForeignLibs/src/MyForeignLib/AnotherVal.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/ForeignLibs/src/MyForeignLib/Hello.hs13
-rw-r--r--cabal/cabal-testsuite/PackageTests/ForeignLibs/src/MyForeignLib/SomeBindings.hsc10
-rw-r--r--cabal/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/SameDirectory.cabal11
-rwxr-xr-xcabal/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/ghc6
-rwxr-xr-xcabal/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectory/ghc-pkg3
-rw-r--r--cabal/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/SameDirectory.cabal11
-rwxr-xr-xcabal/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/ghc-7.106
-rwxr-xr-xcabal/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/ghc-pkg-ghc-7.103
-rw-r--r--cabal/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/SameDirectory.cabal11
-rwxr-xr-xcabal/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/ghc-7.106
-rwxr-xr-xcabal/cabal-testsuite/PackageTests/GhcPkgGuess/SameDirectoryVersion/ghc-pkg-7.103
-rw-r--r--cabal/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/SameDirectory.cabal11
-rwxr-xr-xcabal/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/bin/ghc6
-rwxr-xr-xcabal/cabal-testsuite/PackageTests/GhcPkgGuess/Symlink/bin/ghc-pkg3
-rw-r--r--cabal/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/SameDirectory.cabal11
-rwxr-xr-xcabal/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/bin/ghc-7.106
-rwxr-xr-xcabal/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkGhcVersion/bin/ghc-pkg-7.103
-rw-r--r--cabal/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/SameDirectory.cabal11
-rwxr-xr-xcabal/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/bin/ghc-7.106
-rwxr-xr-xcabal/cabal-testsuite/PackageTests/GhcPkgGuess/SymlinkVersion/bin/ghc-pkg-ghc-7.103
-rw-r--r--cabal/cabal-testsuite/PackageTests/Haddock/CPP.hs9
-rw-r--r--cabal/cabal-testsuite/PackageTests/Haddock/Literate.lhs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Haddock/NoCPP.hs8
-rw-r--r--cabal/cabal-testsuite/PackageTests/Haddock/Simple.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Haddock/my.cabal16
-rw-r--r--cabal/cabal-testsuite/PackageTests/HaddockNewline/A.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/HaddockNewline/ChangeLog.md5
-rw-r--r--cabal/cabal-testsuite/PackageTests/HaddockNewline/HaddockNewline.cabal20
-rw-r--r--cabal/cabal-testsuite/PackageTests/HaddockNewline/LICENSE30
-rw-r--r--cabal/cabal-testsuite/PackageTests/HaddockNewline/Setup.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/Executable/exe/Main.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/Executable/foo.cabal18
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/Executable/src/Foo.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/Library/fooexe/Main.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/Library/fooexe/fooexe.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/Library/foolib/Foo.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/Library/foolib/foolib.cabal17
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/Library/foolib/private/Internal.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/p/Foo.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/p/p.cabal23
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/p/p/P.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/p/q/Q.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/q/Q.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/q/q.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/r/R.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/InternalLibraries/r/r.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/Macros/A.hs10
-rw-r--r--cabal/cabal-testsuite/PackageTests/Macros/B.hs10
-rw-r--r--cabal/cabal-testsuite/PackageTests/Macros/Main.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Macros/macros.cabal23
-rw-r--r--cabal/cabal-testsuite/PackageTests/Macros/src/C.hs10
-rw-r--r--cabal/cabal-testsuite/PackageTests/Options.hs19
-rw-r--r--cabal/cabal-testsuite/PackageTests/OrderFlags/Foo.hs8
-rw-r--r--cabal/cabal-testsuite/PackageTests/OrderFlags/my.cabal20
-rw-r--r--cabal/cabal-testsuite/PackageTests/PackageTester.hs832
-rw-r--r--cabal/cabal-testsuite/PackageTests/PathsModule/Executable/Main.hs8
-rw-r--r--cabal/cabal-testsuite/PackageTests/PathsModule/Executable/my.cabal16
-rw-r--r--cabal/cabal-testsuite/PackageTests/PathsModule/Library/my.cabal15
-rw-r--r--cabal/cabal-testsuite/PackageTests/PreProcess/Foo.hsc1
-rw-r--r--cabal/cabal-testsuite/PackageTests/PreProcess/Main.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/PreProcess/my.cabal32
-rw-r--r--cabal/cabal-testsuite/PackageTests/PreProcessExtraSources/Foo.hsc9
-rw-r--r--cabal/cabal-testsuite/PackageTests/PreProcessExtraSources/Main.hs8
-rw-r--r--cabal/cabal-testsuite/PackageTests/PreProcessExtraSources/my.cabal32
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReexportedModules/containers-dupe/Data/Map.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReexportedModules/containers-dupe/containers-dupe.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReexportedModules/p/Private.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReexportedModules/p/Public.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReexportedModules/p/fail-ambiguous.cabal10
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReexportedModules/p/fail-missing.cabal10
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReexportedModules/p/fail-other.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReexportedModules/p/p.cabal17
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReexportedModules/q/A.hs7
-rw-r--r--cabal/cabal-testsuite/PackageTests/ReexportedModules/q/q.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T2971/p/include/T2971test.h0
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T2971/p/p.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T2971/q/Bar.hsc3
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T2971/q/Foo.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T2971/q/q.cabal14
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T2971a/Main.hsc2
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T2971a/T2971a.cabal16
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T2971a/include/T2971a.h0
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3294/T3294.cabal12
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3847/Main.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T3847/T3847.cabal13
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4025/A.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4025/T4025.cabal13
-rw-r--r--cabal/cabal-testsuite/PackageTests/Regression/T4025/exe/Main.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/TemplateHaskell/dynamic/Exe.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/TemplateHaskell/dynamic/Lib.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/TemplateHaskell/dynamic/TH.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/TemplateHaskell/dynamic/my.cabal15
-rw-r--r--cabal/cabal-testsuite/PackageTests/TemplateHaskell/profiling/Exe.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/TemplateHaskell/profiling/Lib.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/TemplateHaskell/profiling/TH.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/TemplateHaskell/profiling/my.cabal15
-rw-r--r--cabal/cabal-testsuite/PackageTests/TemplateHaskell/vanilla/Exe.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/TemplateHaskell/vanilla/Lib.hs6
-rw-r--r--cabal/cabal-testsuite/PackageTests/TemplateHaskell/vanilla/TH.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/TemplateHaskell/vanilla/my.cabal15
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestNameCollision/child/Child.hs2
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestNameCollision/child/child.cabal19
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestNameCollision/child/tests/Test.hs13
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestNameCollision/parent/Parent.hs1
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestNameCollision/parent/parent.cabal13
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestOptions/TestOptions.cabal20
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestOptions/test-TestOptions.hs11
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestStanza/Check.hs28
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestStanza/my.cabal19
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/Check.hs129
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/Foo.hs4
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/my.cabal21
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/tests/test-Foo.hs12
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestSuiteTests/ExeV10/tests/test-Short.hs11
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestSuiteTests/LibV09/Lib.hs11
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestSuiteTests/LibV09/LibV09.cabal21
-rw-r--r--cabal/cabal-testsuite/PackageTests/TestSuiteTests/LibV09/tests/Deadlock.hs8
-rw-r--r--cabal/cabal-testsuite/PackageTests/Tests.hs750
-rw-r--r--cabal/cabal-testsuite/PackageTests/UniqueIPID/P1/M.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/UniqueIPID/P1/my.cabal15
-rw-r--r--cabal/cabal-testsuite/PackageTests/UniqueIPID/P2/M.hs3
-rw-r--r--cabal/cabal-testsuite/PackageTests/UniqueIPID/P2/my.cabal15
-rw-r--r--cabal/cabal-testsuite/PackageTests/multInst/my.cabal16
-rw-r--r--cabal/cabal-testsuite/README.md54
-rw-r--r--cabal/cabal-testsuite/Setup.hs10
-rw-r--r--cabal/cabal-testsuite/cabal-testsuite.cabal350
-rw-r--r--cabal/cabal.project17
-rw-r--r--cabal/cabal.project.travis13
-rw-r--r--cabal/id_rsa_cabal_website.aes256.encbin0 -> 3248 bytes
-rwxr-xr-xcabal/setup-dev.sh36
-rw-r--r--cabal/stack.yaml67
-rwxr-xr-xcabal/travis-bootstrap.sh52
-rw-r--r--cabal/travis-common.sh33
-rwxr-xr-xcabal/travis-deploy.sh27
-rwxr-xr-xcabal/travis-install.sh79
-rwxr-xr-xcabal/travis-meta.sh20
-rwxr-xr-xcabal/travis-script.sh176
-rwxr-xr-xcabal/travis-solver-debug-flags.sh16
-rwxr-xr-xcabal/travis-stack.sh17
-rwxr-xr-xcabal/update-cabal-files.sh4
-rw-r--r--hackage-security/.travis.yml9
-rw-r--r--hackage-security/hackage-repo-tool/hackage-repo-tool.cabal2
-rw-r--r--hackage-security/hackage-root-tool/Main.hs24
-rw-r--r--hackage-security/hackage-root-tool/hackage-root-tool.cabal2
-rw-r--r--hackage-security/hackage-security-http-client/hackage-security-http-client.cabal2
-rw-r--r--hackage-security/hackage-security/ChangeLog.md34
-rw-r--r--hackage-security/hackage-security/hackage-security.cabal25
-rw-r--r--hackage-security/hackage-security/src/Hackage/Security/Client.hs21
-rw-r--r--hackage-security/hackage-security/src/Hackage/Security/Client/Formats.hs1
-rw-r--r--hackage-security/hackage-security/src/Hackage/Security/Client/Repository.hs7
-rw-r--r--hackage-security/hackage-security/src/Hackage/Security/Client/Repository/Cache.hs53
-rw-r--r--hackage-security/hackage-security/src/Hackage/Security/Client/Repository/Local.hs6
-rw-r--r--hackage-security/hackage-security/src/Hackage/Security/Client/Repository/Remote.hs35
-rw-r--r--hackage-security/hackage-security/src/Hackage/Security/Key.hs11
-rw-r--r--hackage-security/hackage-security/src/Hackage/Security/TUF/FileInfo.hs48
-rw-r--r--hackage-security/hackage-security/src/Hackage/Security/TUF/FileMap.hs7
-rw-r--r--hackage-security/hackage-security/src/Hackage/Security/TUF/Layout/Index.hs23
-rw-r--r--hackage-security/hackage-security/src/Hackage/Security/TUF/Paths.hs4
-rw-r--r--hackage-security/hackage-security/src/Hackage/Security/TUF/Patterns.hs2
-rw-r--r--hackage-security/hackage-security/src/Hackage/Security/Util/Checked.hs3
-rw-r--r--hackage-security/hackage-security/src/Hackage/Security/Util/JSON.hs16
-rw-r--r--hackage-security/hackage-security/src/Hackage/Security/Util/Path.hs108
-rw-r--r--hackage-security/hackage-security/src/Text/JSON/Canonical.hs93
-rw-r--r--hackage-security/hackage-security/tests/TestSuite.hs71
-rw-r--r--hackage-security/hackage-security/tests/TestSuite/InMemCache.hs48
-rw-r--r--hackage-security/hackage-security/tests/TestSuite/InMemRepo.hs39
-rw-r--r--hackage-security/hackage-security/tests/TestSuite/InMemRepository.hs4
-rw-r--r--hackage-security/hackage-security/tests/TestSuite/JSON.hs77
l---------hackport1
-rw-r--r--hackport.cabal7
-rw-r--r--tests/resolveCat.hs2
873 files changed, 52978 insertions, 19504 deletions
diff --git a/Cabal2Ebuild.hs b/Cabal2Ebuild.hs
index 3fd9c32..539e4a1 100644
--- a/Cabal2Ebuild.hs
+++ b/Cabal2Ebuild.hs
@@ -29,11 +29,13 @@ import qualified Distribution.Version as Cabal (VersionRange, foldVersionRange'
import Distribution.Text (display)
import Data.Char (isUpper)
+import Data.Maybe
import Portage.Dependency
import qualified Portage.Cabal as Portage
import qualified Portage.PackageId as Portage
import qualified Portage.EBuild as Portage
+import qualified Portage.EBuild.CabalFeature as Portage
import qualified Portage.Resolve as Portage
import qualified Portage.EBuild as E
import qualified Portage.Overlay as O
@@ -54,20 +56,21 @@ cabal2ebuild cat pkg = Portage.ebuildTemplate {
E.slot = (E.slot E.ebuildTemplate) ++ (if hasLibs then "/${PV}" else ""),
E.my_pn = if any isUpper cabalPkgName then Just cabalPkgName else Nothing,
E.features = E.features E.ebuildTemplate
- ++ (if hasExe then ["bin"]
- else [])
- ++ (if hasLibs then (["lib","profile","haddock","hoogle"]
+ ++ (if hasLibs then ([ Portage.Lib
+ , Portage.Profile
+ , Portage.Haddock
+ , Portage.Hoogle
+ ]
++ if cabalPkgName == "hscolour"
then []
- else ["hscolour"])
+ else [Portage.HsColour])
else [])
- ++ (if hasTests then ["test-suite"]
+ ++ (if hasTests then [Portage.TestSuite]
else [])
} where
cabal_pn = Cabal.pkgName $ Cabal.package pkg
cabalPkgName = display cabal_pn
- hasLibs = Cabal.libraries pkg /= []
- hasExe = (not . null) (Cabal.executables pkg)
+ hasLibs = isJust (Cabal.library pkg)
hasTests = (not . null) (Cabal.testSuites pkg)
thisHomepage = if (null $ Cabal.homepage pkg)
then E.homepage E.ebuildTemplate
@@ -96,6 +99,7 @@ convertDependency overlay category (Cabal.Dependency pname versionRange)
)(\v -> mk_p (DRange (NonstrictLB (p_v v)) InfinityB) -- ^ @\">= v\"@
)(\v -> mk_p (DRange ZeroB (NonstrictUB (p_v v))) -- ^ @\"<= v\"@
)(\v1 v2 -> mk_p (DRange (NonstrictLB (p_v v1)) (StrictUB (p_v v2))) -- ^ @\"== v.*\"@ wildcard. (incl lower, excl upper)
+ )(\v1 v2 -> mk_p (DRange (NonstrictLB (p_v v1)) (StrictUB (p_v v2))) -- ^ @\"^>= v\"@ major upper bound
)(\g1 g2 -> DependAnyOf [g1, g2] -- ^ @\"_ || _\"@ union
)(\r1 r2 -> DependAllOf [r1, r2] -- ^ @\"_ && _\"@ intersection
)(\dp -> dp -- ^ @\"(_)\"@ parentheses
diff --git a/Main.hs b/Main.hs
index bf75383..7e8324d 100644
--- a/Main.hs
+++ b/Main.hs
@@ -23,8 +23,10 @@ import Distribution.Text (display, simpleParse)
import Distribution.Client.Types
import Distribution.Client.Update
-import qualified Distribution.Client.PackageIndex as Index
-import qualified Distribution.Client.IndexUtils as Index
+
+import qualified Distribution.Client.IndexUtils as CabalInstall
+import qualified Distribution.Solver.Types.SourcePackage as CabalInstall
+import qualified Distribution.Solver.Types.PackageIndex as CabalInstall
import Portage.Overlay as Overlay ( loadLazy, inOverlay )
import Portage.Host as Host ( getInfo, portage_dir )
@@ -92,11 +94,11 @@ listAction flags extraArgs globalFlags = do
let verbosity = fromFlag (listVerbosity flags)
H.withHackPortContext verbosity globalFlags $ \repoContext -> do
overlayPath <- getOverlayPath verbosity (fromFlag $ H.globalPathToOverlay globalFlags)
- index <- fmap packageIndex (Index.getSourcePackages verbosity repoContext)
+ index <- fmap packageIndex (CabalInstall.getSourcePackages verbosity repoContext)
overlay <- Overlay.loadLazy overlayPath
- let pkgs | null extraArgs = Index.allPackages index
- | otherwise = concatMap (concatMap snd . Index.searchByNameSubstring index) extraArgs
- normalized = map (normalizeCabalPackageId . packageInfoId) pkgs
+ let pkgs | null extraArgs = CabalInstall.allPackages index
+ | otherwise = concatMap (concatMap snd . CabalInstall.searchByNameSubstring index) extraArgs
+ normalized = map (normalizeCabalPackageId . CabalInstall.packageInfoId) pkgs
let decorated = map (\p -> (Overlay.inOverlay overlay p, p)) normalized
mapM_ (putStrLn . pretty) decorated
where
@@ -356,11 +358,30 @@ getPortageDir verbosity globalFlags = do
globalCommand :: CommandUI H.GlobalFlags
globalCommand = CommandUI {
commandName = "",
- commandSynopsis = "",
- commandDescription = Nothing,
- commandNotes = Nothing,
- commandUsage = \_ -> [],
+ commandSynopsis = "HackPort is an .ebuild generator from .cabal files with hackage index support",
+ commandDescription = Just $ \pname ->
+ let
+ commands' = commands ++ [commandAddAction helpCommandUI undefined]
+ cmdDescs = getNormalCommandDescriptions commands'
+ maxlen = maximum $ [length name | (name, _) <- cmdDescs]
+ align str = str ++ replicate (maxlen - length str) ' '
+ in
+ "Commands:\n"
+ ++ unlines [ " " ++ align name ++ " " ++ descr
+ | (name, descr) <- cmdDescs ]
+ ++ "\n"
+ ++ "For more information about a command use\n"
+ ++ " " ++ pname ++ " COMMAND --help\n\n"
+ ++ "Typical steps for generating ebuilds from hackage packages:\n"
+ ++ concat [ " " ++ pname ++ " " ++ x ++ "\n"
+ | x <- ["update", "merge <package>"]]
+ ++ "\n"
+ ++ "Advanced usage:\n"
+ ++ concat [ " " ++ pname ++ " " ++ x ++ "\n"
+ | x <- ["update", "make-ebuild <ebuild.name> <CATEGORY>"]],
+ commandNotes = Nothing,
+ commandUsage = \pname -> "Usage: " ++ pname ++ " [GLOBAL FLAGS] [COMMAND [FLAGS]]\n",
commandDefaultFlags = H.defaultGlobalFlags,
commandOptions = \_showOrParseArgs ->
[ option ['V'] ["version"]
@@ -412,7 +433,9 @@ mainWorker args =
errorHandler :: HackPortError -> IO ()
errorHandler e = do
putStrLn (hackPortShowError e)
- commands =
+
+commands :: [Command (H.GlobalFlags -> IO ())]
+commands =
[ listCommand `commandAddAction` listAction
, makeEbuildCommand `commandAddAction` makeEbuildAction
, statusCommand `commandAddAction` statusAction
diff --git a/Merge.hs b/Merge.hs
index f25dc85..1efbdfb 100644
--- a/Merge.hs
+++ b/Merge.hs
@@ -8,22 +8,17 @@ import Control.Exception
import qualified Data.ByteString.Lazy.Char8 as BL
import Data.Function (on)
import Data.Maybe
-import Data.Monoid
import qualified Data.List as L
import qualified Data.Set as S
import qualified Data.Time.Clock as TC
-import Data.Version
-- cabal
import qualified Distribution.Package as Cabal
import qualified Distribution.Version as Cabal
-import qualified Distribution.PackageDescription as Cabal ( PackageDescription(..)
- , Flag(..)
- , FlagAssignment
- , FlagName(..)
- , GenericPackageDescription(..)
- )
-import qualified Distribution.PackageDescription.Parse as Cabal (showPackageDescription)
+import qualified Distribution.PackageDescription as Cabal
+import qualified Distribution.PackageDescription.PrettyPrint as Cabal (showPackageDescription)
+import qualified Distribution.Solver.Types.SourcePackage as CabalInstall
+import qualified Distribution.Solver.Types.PackageIndex as CabalInstall
import Distribution.Text (display)
import Distribution.Verbosity
@@ -32,7 +27,6 @@ import Distribution.Simple.Utils
-- cabal-install
import Distribution.Client.IndexUtils ( getSourcePackages )
import qualified Distribution.Client.GlobalFlags as CabalInstall
-import qualified Distribution.Client.PackageIndex as Index
import Distribution.Client.Types
-- others
@@ -96,10 +90,10 @@ readPackageString args = do
-- return the available package with that version. Latest version is chosen
-- if no preference.
resolveVersion :: [UnresolvedSourcePackage] -> Maybe Cabal.Version -> Maybe UnresolvedSourcePackage
-resolveVersion avails Nothing = Just $ L.maximumBy (comparing (Cabal.pkgVersion . packageInfoId)) avails
+resolveVersion avails Nothing = Just $ L.maximumBy (comparing (Cabal.pkgVersion . CabalInstall.packageInfoId)) avails
resolveVersion avails (Just ver) = listToMaybe (filter match avails)
where
- match avail = ver == Cabal.pkgVersion (packageInfoId avail)
+ match avail = ver == Cabal.pkgVersion (CabalInstall.packageInfoId avail)
merge :: Verbosity -> CabalInstall.RepoContext -> [String] -> FilePath -> Maybe String -> IO ()
merge verbosity repoContext args overlayPath users_cabal_flags = do
@@ -117,7 +111,7 @@ merge verbosity repoContext args overlayPath users_cabal_flags = do
debug verbosity $ "Package: " ++ show user_pName
debug verbosity $ "Version: " ++ show m_version
- let (Cabal.PackageName user_pname_str) = user_pName
+ let user_pname_str = Cabal.unPackageName user_pName
overlay <- Overlay.loadLazy overlayPath
-- portage_path <- Host.portage_dir `fmap` Host.getInfo
@@ -126,17 +120,15 @@ merge verbosity repoContext args overlayPath users_cabal_flags = do
-- find all packages that maches the user specified package name
availablePkgs <-
- case map snd (Index.searchByName index user_pname_str) of
+ case map snd (CabalInstall.searchByName index user_pname_str) of
[] -> throwEx (PackageNotFound user_pname_str)
[pkg] -> return pkg
- pkgs -> do let cabal_pkg_to_pn pkg =
- case Cabal.pkgName (packageInfoId pkg) of
- Cabal.PackageName pn -> pn
+ pkgs -> do let cabal_pkg_to_pn pkg = Cabal.unPackageName $ Cabal.pkgName (CabalInstall.packageInfoId pkg)
names = map (cabal_pkg_to_pn . L.head) pkgs
notice verbosity $ "Ambiguous names: " ++ L.intercalate ", " names
forM_ pkgs $ \ps ->
do let p_name = (cabal_pkg_to_pn . L.head) ps
- notice verbosity $ p_name ++ ": " ++ (L.intercalate ", " $ map (showVersion . Cabal.pkgVersion . packageInfoId) ps)
+ notice verbosity $ p_name ++ ": " ++ (L.intercalate ", " $ map (display . Cabal.pkgVersion . CabalInstall.packageInfoId) ps)
return $ concat pkgs
-- select a single package taking into account the user specified version
@@ -145,21 +137,21 @@ merge verbosity repoContext args overlayPath users_cabal_flags = do
Nothing -> do
putStrLn "No such version for that package, available versions:"
forM_ availablePkgs $ \ avail ->
- putStrLn (display . packageInfoId $ avail)
+ putStrLn (display . CabalInstall.packageInfoId $ avail)
throwEx (ArgumentError "no such version for that package")
Just avail -> return avail
-- print some info
info verbosity "Selecting package:"
forM_ availablePkgs $ \ avail -> do
- let match_text | packageInfoId avail == packageInfoId selectedPkg = "* "
+ let match_text | CabalInstall.packageInfoId avail == CabalInstall.packageInfoId selectedPkg = "* "
| otherwise = "- "
- info verbosity $ match_text ++ (display . packageInfoId $ avail)
+ info verbosity $ match_text ++ (display . CabalInstall.packageInfoId $ avail)
- let cabal_pkgId = packageInfoId selectedPkg
+ let cabal_pkgId = CabalInstall.packageInfoId selectedPkg
norm_pkgName = Cabal.packageName (Portage.normalizeCabalPackageId cabal_pkgId)
cat <- maybe (Portage.resolveCategory verbosity overlay norm_pkgName) return m_category
- mergeGenericPackageDescription verbosity overlayPath cat (packageDescription selectedPkg) True users_cabal_flags
+ mergeGenericPackageDescription verbosity overlayPath cat (CabalInstall.packageDescription selectedPkg) True users_cabal_flags
first_just_of :: [Maybe a] -> Maybe a
first_just_of = msum
@@ -181,7 +173,8 @@ mergeGenericPackageDescription verbosity overlayPath cat pkgGenericDesc fetch us
| ((cf, _), Just b) <- cn_in_mb
]
user_renames = [ (cfn, ein)
- | ((Cabal.FlagName cfn, ein), Nothing) <- cn_in_mb
+ | ((cabal_cfn, ein), Nothing) <- cn_in_mb
+ , let cfn = Cabal.unFlagName cabal_cfn
]
cn_in_mb = map read_fa $ DLS.splitOn "," user_fas_s
read_fa :: String -> ((Cabal.FlagName, String), Maybe Bool)
@@ -194,8 +187,8 @@ mergeGenericPackageDescription verbosity overlayPath cat pkgGenericDesc fetch us
where get_rename :: String -> (Cabal.FlagName, String)
get_rename s =
case DLS.splitOn ":" s of
- [cabal_flag_name] -> (Cabal.FlagName cabal_flag_name, cabal_flag_name)
- [cabal_flag_name, iuse_name] -> (Cabal.FlagName cabal_flag_name, iuse_name)
+ [cabal_flag_name] -> (Cabal.mkFlagName cabal_flag_name, cabal_flag_name)
+ [cabal_flag_name, iuse_name] -> (Cabal.mkFlagName cabal_flag_name, iuse_name)
_ -> error $ "get_rename: too many components" ++ show (s)
(user_specified_fas, cf_to_iuse_rename) = read_fas requested_cabal_flags
@@ -232,7 +225,8 @@ mergeGenericPackageDescription verbosity overlayPath cat pkgGenericDesc fetch us
pp_fa :: Cabal.FlagAssignment -> String
pp_fa fa = L.intercalate ", " [ (if b then '+' else '-') : f
- | (Cabal.FlagName f, b) <- fa
+ | (cabal_f, b) <- fa
+ , let f = Cabal.unFlagName cabal_f
]
@@ -322,7 +316,7 @@ mergeGenericPackageDescription verbosity overlayPath cat pkgGenericDesc fetch us
}
liftFlags :: Cabal.FlagAssignment -> Portage.Dependency -> Portage.Dependency
- liftFlags fs e = let k = foldr (\(y,b) x -> Portage.mkUseDependency (b, Portage.Use . cfn_to_iuse . unFlagName $ y) . x)
+ liftFlags fs e = let k = foldr (\(y,b) x -> Portage.mkUseDependency (b, Portage.Use . cfn_to_iuse . Cabal.unFlagName $ y) . x)
id fs
in k e
@@ -336,16 +330,17 @@ mergeGenericPackageDescription verbosity overlayPath cat pkgGenericDesc fetch us
notice verbosity $ "Accepted depends: " ++ show (map display accepted_deps)
notice verbosity $ "Skipped depends: " ++ show (map display skipped_deps)
notice verbosity $ "Dead flags: " ++ show (map pp_fa irresolvable_flag_assignments)
- notice verbosity $ "Dropped flags: " ++ show (map (unFlagName.fst) common_fa)
- notice verbosity $ "Active flags: " ++ show (map unFlagName active_flags)
- notice verbosity $ "Irrelevant flags: " ++ show (map unFlagName irrelevant_flags)
+ notice verbosity $ "Dropped flags: " ++ show (map (Cabal.unFlagName.fst) common_fa)
+ notice verbosity $ "Active flags: " ++ show (map Cabal.unFlagName active_flags)
+ notice verbosity $ "Irrelevant flags: " ++ show (map Cabal.unFlagName irrelevant_flags)
-- mapM_ print tdeps
forM_ ghc_packages $
- \(Cabal.PackageName name) -> info verbosity $ "Excluded packages (comes with ghc): " ++ name
+ \name -> info verbosity $ "Excluded packages (comes with ghc): " ++ Cabal.unPackageName name
- let pp_fn (Cabal.FlagName fn, True) = fn
- pp_fn (Cabal.FlagName fn, False) = '-':fn
+ let pp_fn (cabal_fn, yesno) = b yesno ++ Cabal.unFlagName cabal_fn
+ where b True = ""
+ b False = "-"
-- appends 's' to each line except the last one
-- handy to build multiline shell expressions
@@ -365,9 +360,9 @@ mergeGenericPackageDescription verbosity overlayPath cat pkgGenericDesc fetch us
selected_flags (active_fns, users_fas) = map snd (L.sortBy (compare `on` fst) flag_pairs)
where flag_pairs :: [(String, String)]
flag_pairs = active_pairs ++ users_pairs
- active_pairs = map (\fn -> (fn, "$(cabal_flag " ++ cfn_to_iuse fn ++ " " ++ fn ++ ")")) $ map unFlagName active_fns
- users_pairs = map (\fa -> ((unFlagName . fst) fa, "--flag=" ++ pp_fn fa)) users_fas
- to_iuse x = let fn = unFlagName $ Cabal.flagName x
+ active_pairs = map (\fn -> (fn, "$(cabal_flag " ++ cfn_to_iuse fn ++ " " ++ fn ++ ")")) $ map Cabal.unFlagName active_fns
+ users_pairs = map (\fa -> ((Cabal.unFlagName . fst) fa, "--flag=" ++ pp_fn fa)) users_fas
+ to_iuse x = let fn = Cabal.unFlagName $ Cabal.flagName x
p = if Cabal.flagDefault x then "+" else ""
in p ++ cfn_to_iuse fn
@@ -457,6 +452,3 @@ mergeEbuild verbosity existing_meta pkgdir ebuild = do
else do current_meta <- BL.readFile mpath
when (current_meta /= default_meta) $
notice verbosity $ "Default and current " ++ emeta ++ " differ."
-
-unFlagName :: Cabal.FlagName -> String
-unFlagName (Cabal.FlagName fname) = fname
diff --git a/Merge/Dependencies.hs b/Merge/Dependencies.hs
index a9cc01b..eec3c7a 100644
--- a/Merge/Dependencies.hs
+++ b/Merge/Dependencies.hs
@@ -1,45 +1,5 @@
{- | Merge a package from hackage to an ebuild.
-
-Merging a library
-=================
-
-Compile time:
- ghc
- cabal
- build tools
- deps (haskell dependencies)
- extra-libs (c-libs)
- pkg-config (c-libs)
-
-Run time:
- ghc
- deps (haskell dependencies)
- extra-libs (c-libs)
- pkg-config (c-libs)
-
-RDEPEND="ghc ${DEPS} ${EXTRALIBS}"
-DEPEND="${RDEPEND} cabal ${BUILDTOOLS}"
-
-Merging an executable
-=====================
-Packages with both executable and library must be treated as libraries, as it will impose a stricter DEPEND.
-
-Compile time:
- ghc
- cabal
- build tools
- deps (haskell dependencies)
- extra-libs (c-libs)
- pkg-config (c-libs)
-
-Run time:
- extra-libs (c-libs)
- pkg-config (c-libs)
-
-RDEPEND="${EXTRALIBS}"
-DEPEND="${RDEPEND} ghc cabal ${DEPS} ${BUILDTOOLS}"
-
--}
+ -}
module Merge.Dependencies
( EDep(..)
, resolveDependencies
@@ -66,6 +26,7 @@ import qualified Data.Set as S
import qualified Distribution.Package as Cabal
import qualified Distribution.PackageDescription as Cabal
import qualified Distribution.Version as Cabal
+import qualified Distribution.Text as Cabal
import qualified Distribution.Compiler as Cabal
@@ -114,7 +75,7 @@ resolveDependencies overlay pkg compiler_info ghc_package_names merged_cabal_pkg
where
-- hasBuildableExes p = any (buildable . buildInfo) . executables $ p
treatAsLibrary :: Bool
- treatAsLibrary = Cabal.libraries pkg /= []
+ treatAsLibrary = isJust (Cabal.library pkg)
-- without slot business
raw_haskell_deps :: Portage.Dependency
raw_haskell_deps = PN.normalize_depend $ Portage.DependAllOf $ haskellDependencies overlay (buildDepends pkg)
@@ -139,12 +100,18 @@ resolveDependencies overlay pkg compiler_info ghc_package_names merged_cabal_pkg
else [any_c_p "virtual" "pkgconfig"]
build_tools :: Portage.Dependency
build_tools = Portage.DependAllOf $ pkg_config_tools : buildToolsDependencies pkg
+
+ setup_deps :: Portage.Dependency
+ setup_deps = PN.normalize_depend $ Portage.DependAllOf $
+ setupDependencies overlay pkg ghc_package_names merged_cabal_pkg_name
+
edeps :: EDep
edeps
| treatAsLibrary = mempty
{
dep = Portage.DependAllOf
[ cabal_dep
+ , setup_deps
, build_tools
, test_deps
],
@@ -160,6 +127,7 @@ resolveDependencies overlay pkg compiler_info ghc_package_names merged_cabal_pkg
{
dep = Portage.DependAllOf
[ cabal_dep
+ , setup_deps
, build_tools
, test_deps
],
@@ -174,7 +142,19 @@ resolveDependencies overlay pkg compiler_info ghc_package_names merged_cabal_pkg
add_profile = Portage.addDepUseFlag (Portage.mkQUse (Portage.Use "profile"))
---------------------------------------------------------------
+-- Custom-setup dependencies
+-- TODO: move partitioning part to Merge:mergeGenericPackageDescription
+---------------------------------------------------------------
+
+setupDependencies :: Portage.Overlay -> PackageDescription -> [Cabal.PackageName] -> Cabal.PackageName -> [Portage.Dependency]
+setupDependencies overlay pkg ghc_package_names merged_cabal_pkg_name = deps
+ where cabalDeps = maybe [] id $ Cabal.setupDepends `fmap` setupBuildInfo pkg
+ cabalDeps' = fst $ Portage.partition_depends ghc_package_names merged_cabal_pkg_name cabalDeps
+ deps = C2E.convertDependencies overlay (Portage.Category "dev-haskell") cabalDeps'
+
+---------------------------------------------------------------
-- Test-suite dependencies
+-- TODO: move partitioning part to Merge:mergeGenericPackageDescription
---------------------------------------------------------------
testDependencies :: Portage.Overlay -> PackageDescription -> [Cabal.PackageName] -> Cabal.PackageName -> [Portage.Dependency]
@@ -200,13 +180,14 @@ haskellDependencies overlay deps =
cabalDependency :: Portage.Overlay -> PackageDescription -> Cabal.CompilerInfo -> Portage.Dependency
cabalDependency overlay pkg ~(Cabal.CompilerInfo {
Cabal.compilerInfoId =
- Cabal.CompilerId Cabal.GHC (Cabal.Version versionNumbers _)
+ Cabal.CompilerId Cabal.GHC cabal_version
}) =
C2E.convertDependency overlay
(Portage.Category "dev-haskell")
- (Cabal.Dependency (Cabal.PackageName "Cabal")
+ (Cabal.Dependency (Cabal.mkPackageName "Cabal")
finalCabalDep)
where
+ versionNumbers = Cabal.versionNumbers cabal_version
userCabalVersion = Cabal.orLaterVersion (specVersion pkg)
shippedCabalVersion = GHCCore.cabalFromGHC versionNumbers
shippedCabalDep = maybe Cabal.anyVersion Cabal.orLaterVersion shippedCabalVersion
@@ -222,22 +203,22 @@ cabalDependency overlay pkg ~(Cabal.CompilerInfo {
compilerInfoToDependency :: Cabal.CompilerInfo -> Portage.Dependency
compilerInfoToDependency ~(Cabal.CompilerInfo {
Cabal.compilerInfoId =
- Cabal.CompilerId Cabal.GHC versionNumbers}) =
- at_least_c_p_v "dev-lang" "ghc" (Cabal.versionBranch versionNumbers)
+ Cabal.CompilerId Cabal.GHC cabal_version}) =
+ at_least_c_p_v "dev-lang" "ghc" (Cabal.versionNumbers cabal_version)
---------------------------------------------------------------
-- C Libraries
---------------------------------------------------------------
findCLibs :: PackageDescription -> [Portage.Dependency]
-findCLibs (PackageDescription { libraries = libs, executables = exes }) =
+findCLibs (PackageDescription { library = lib, executables = exes }) =
[ trace ("WARNING: This package depends on a C library we don't know the portage name for: " ++ p ++ ". Check the generated ebuild.")
(any_c_p "unknown-c-lib" p)
| p <- notFound
] ++
found
where
- libE = concatMap (extraLibs . libBuildInfo) libs
+ libE = concatMap (extraLibs . libBuildInfo) $ maybe [] return lib
exeE = concatMap extraLibs (filter buildable (map buildInfo exes))
allE = libE ++ exeE
@@ -358,6 +339,8 @@ staticTranslateExtraLib lib = lookup lib m
, ("SDL_image", any_c_p "media-libs" "sdl-image")
, ("SDL_ttf", any_c_p "media-libs" "sdl-ttf")
, ("odbc", any_c_p "dev-db" "unixODBC")
+ , ("uuid", any_c_p "sys-apps" "util-linux")
+ , ("notify", any_c_p "x11-libs" "libnotify")
]
---------------------------------------------------------------
@@ -365,19 +348,19 @@ staticTranslateExtraLib lib = lookup lib m
---------------------------------------------------------------
buildToolsDependencies :: PackageDescription -> [Portage.Dependency]
-buildToolsDependencies (PackageDescription { libraries = libs, executables = exes }) = nub $
+buildToolsDependencies (PackageDescription { library = lib, executables = exes }) = nub $
[ case pkg of
Just p -> p
- Nothing -> trace ("WARNING: Unknown build tool '" ++ pn ++ "'. Check the generated ebuild.")
+ Nothing -> trace ("WARNING: Unknown build tool '" ++ Cabal.display exe ++ "'. Check the generated ebuild.")
(any_c_p "unknown-build-tool" pn)
- | Cabal.Dependency (Cabal.PackageName pn) _range <- cabalDeps
+ | exe@(Cabal.LegacyExeDependency pn _range) <- cabalDeps
, pkg <- return (lookup pn buildToolsTable)
]
where
cabalDeps = filter notProvided $ depL ++ depE
- depL = concatMap (buildTools . libBuildInfo) libs
+ depL = concatMap (buildTools . libBuildInfo) $ maybe [] return lib
depE = concatMap buildTools (filter buildable (map buildInfo exes))
- notProvided (Cabal.Dependency (Cabal.PackageName pn) _range) = pn `notElem` buildToolsProvided
+ notProvided (Cabal.LegacyExeDependency pn _range) = pn `notElem` buildToolsProvided
buildToolsTable :: [(String, Portage.Dependency)]
buildToolsTable =
@@ -406,23 +389,25 @@ buildToolsProvided = ["hsc2hs"]
---------------------------------------------------------------
pkgConfigDependencies :: Portage.Overlay -> PackageDescription -> [Portage.Dependency]
-pkgConfigDependencies overlay (PackageDescription { libraries = libs, executables = exes }) = nub $ resolvePkgConfigs overlay cabalDeps
+pkgConfigDependencies overlay (PackageDescription { library = lib, executables = exes }) = nub $ resolvePkgConfigs overlay cabalDeps
where
cabalDeps = depL ++ depE
- depL = concatMap (pkgconfigDepends . libBuildInfo) libs
+ depL = concatMap (pkgconfigDepends . libBuildInfo) $ maybe [] return lib
depE = concatMap pkgconfigDepends (filter buildable (map buildInfo exes))
-resolvePkgConfigs :: Portage.Overlay -> [Cabal.Dependency] -> [Portage.Dependency]
+resolvePkgConfigs :: Portage.Overlay -> [Cabal.PkgconfigDependency] -> [Portage.Dependency]
resolvePkgConfigs overlay cdeps =
[ case resolvePkgConfig overlay pkg of
Just d -> d
- Nothing -> trace ("WARNING: Could not resolve pkg-config: " ++ pn ++ ". Check generated ebuild.")
+ Nothing -> trace ("WARNING: Could not resolve pkg-config: " ++ Cabal.display pkg ++ ". Check generated ebuild.")
(any_c_p "unknown-pkg-config" pn)
- | pkg@(Cabal.Dependency (Cabal.PackageName pn) _range) <- cdeps ]
+ | pkg@(Cabal.PkgconfigDependency cabal_pn _range) <- cdeps
+ , let pn = Cabal.unPkgconfigName cabal_pn
+ ]
-resolvePkgConfig :: Portage.Overlay -> Cabal.Dependency -> Maybe Portage.Dependency
-resolvePkgConfig _overlay (Cabal.Dependency (Cabal.PackageName pn) _cabalVersion) = do
- (cat,portname, slot) <- lookup pn pkgconfig_table
+resolvePkgConfig :: Portage.Overlay -> Cabal.PkgconfigDependency -> Maybe Portage.Dependency
+resolvePkgConfig _overlay (Cabal.PkgconfigDependency cabal_pn _cabalVersion) = do
+ (cat,portname, slot) <- lookup (Cabal.unPkgconfigName cabal_pn) pkgconfig_table
return $ any_c_p_s_u cat portname slot []
pkgconfig_table :: [(String, (String, String, Portage.SlotDepend))]
diff --git a/Portage/Cabal.hs b/Portage/Cabal.hs
index a25092f..ff02f5a 100644
--- a/Portage/Cabal.hs
+++ b/Portage/Cabal.hs
@@ -7,7 +7,7 @@ module Portage.Cabal
import qualified Data.List as L
import qualified Data.Map as Map
-import qualified Distribution.Client.PackageIndex as Cabal
+import qualified Distribution.Simple.PackageIndex as Cabal
import qualified Distribution.License as Cabal
import qualified Distribution.Package as Cabal
import qualified Distribution.Text as Cabal
diff --git a/Portage/EBuild.hs b/Portage/EBuild.hs
index 96b53d7..abad20f 100644
--- a/Portage/EBuild.hs
+++ b/Portage/EBuild.hs
@@ -7,6 +7,8 @@ module Portage.EBuild
) where
import Portage.Dependency
+import Portage.EBuild.CabalFeature
+import Portage.EBuild.Render
import qualified Portage.Dependency.Normalize as PN
import Data.String.Utils
@@ -37,9 +39,9 @@ data EBuild = EBuild {
depend :: Dependency,
depend_extra :: [String],
rdepend :: Dependency,
- rdepend_extra :: [String],
- features :: [String],
- my_pn :: Maybe String -- ^ Just 'myOldName' if the package name contains upper characters
+ rdepend_extra :: [String]
+ , features :: [CabalFeature]
+ , my_pn :: Maybe String -- ^ Just 'myOldName' if the package name contains upper characters
, src_prepare :: [String] -- ^ raw block for src_prepare() contents
, src_configure :: [String] -- ^ raw block for src_configure() contents
, used_options :: [(String, String)] -- ^ hints to ebuild writers/readers
@@ -98,7 +100,7 @@ showEBuild now ebuild =
ss ("# ebuild generated by hackport " ++ hackportVersion ebuild). nl.
sconcat (map (\(k, v) -> ss "#hackport: " . ss k . ss ": " . ss v . nl) $ used_options ebuild).
nl.
- ss "CABAL_FEATURES=". quote' (sepBy " " $ features ebuild). nl.
+ ss "CABAL_FEATURES=". quote' (sepBy " " $ map render (features ebuild)). nl.
ss "inherit haskell-cabal". nl.
nl.
(case my_pn ebuild of
diff --git a/Portage/EBuild/CabalFeature.hs b/Portage/EBuild/CabalFeature.hs
new file mode 100644
index 0000000..db84ba5
--- /dev/null
+++ b/Portage/EBuild/CabalFeature.hs
@@ -0,0 +1,24 @@
+{-# LANGUAGE LambdaCase #-}
+
+-- CABAL_FEATURES="..." in haskell-cabal .ebuild files
+-- see haskell-cabal.eclass for details on each of those
+module Portage.EBuild.CabalFeature (CabalFeature(..)) where
+
+import Portage.EBuild.Render
+
+data CabalFeature = Lib
+ | Profile
+ | Haddock
+ | Hoogle
+ | HsColour
+ | TestSuite
+ deriving Eq
+
+instance Render CabalFeature where
+ render = \case
+ Lib -> "lib"
+ Profile -> "profile"
+ Haddock -> "haddock"
+ Hoogle -> "hoogle"
+ HsColour -> "hscolour"
+ TestSuite -> "test-suite"
diff --git a/Portage/EBuild/Render.hs b/Portage/EBuild/Render.hs
new file mode 100644
index 0000000..cb860bd
--- /dev/null
+++ b/Portage/EBuild/Render.hs
@@ -0,0 +1,6 @@
+-- CABAL_FEATURES="..." in haskell-cabal .ebuild files
+module Portage.EBuild.Render (Render(..)) where
+
+class Render a where
+ render :: a -> String
+
diff --git a/Portage/GHCCore.hs b/Portage/GHCCore.hs
index 8a98edc..e9a7c8b 100644
--- a/Portage/GHCCore.hs
+++ b/Portage/GHCCore.hs
@@ -9,7 +9,8 @@ module Portage.GHCCore
) where
import qualified Distribution.Compiler as DC
-import Distribution.Package
+import qualified Distribution.Package as Cabal
+import qualified Distribution.Version as Cabal
import Distribution.Version
import Distribution.Simple.PackageIndex
import Distribution.InstalledPackageInfo as IPI
@@ -23,7 +24,6 @@ import Distribution.Text
import Data.Maybe
import Data.List ( nub )
-import Data.Version
import Debug.Trace
@@ -31,35 +31,36 @@ 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]
+ where modern_ghcs = [ghc741, ghc742, ghc761, ghc762, ghc782, ghc7101, ghc7102, ghc801]
-cabalFromGHC :: [Int] -> Maybe Version
+cabalFromGHC :: [Int] -> Maybe Cabal.Version
cabalFromGHC ver = lookup ver table
where
- table = [ ([7,4,2], Version [1,14,0] [])
- , ([7,6,1], Version [1,16,0] [])
- , ([7,6,2], Version [1,16,0] [])
- , ([7,8,2], Version [1,18,1,3] [])
- , ([7,10,1], Version [1,22,2,0] [])
- , ([7,10,2], Version [1,22,4,0] [])
+ 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])
+ , ([7,10,2], Cabal.mkVersion [1,22,4,0])
+ , ([8,0,1], Cabal.mkVersion [1,24,0,0])
]
platform :: Platform
platform = Platform X86_64 Linux
-packageIsCore :: InstalledPackageIndex -> PackageName -> Bool
+packageIsCore :: InstalledPackageIndex -> Cabal.PackageName -> Bool
packageIsCore index pn = not . null $ lookupPackageName index pn
-packageIsCoreInAnyGHC :: PackageName -> Bool
+packageIsCoreInAnyGHC :: Cabal.PackageName -> Bool
packageIsCoreInAnyGHC pn = any (flip packageIsCore pn) (map snd ghcs)
-- | Check if a dependency is satisfiable given a 'PackageIndex'
-- representing the core packages in a GHC version.
-- Packages that are not core will always be accepted, packages that are
-- core in any ghc must be satisfied by the 'PackageIndex'.
-dependencySatisfiable :: InstalledPackageIndex -> Dependency -> Bool
-dependencySatisfiable pindex dep@(Dependency pn _rang)
- | pn == PackageName "Win32" = False -- only exists on windows, not in linux
+dependencySatisfiable :: InstalledPackageIndex -> Cabal.Dependency -> Bool
+dependencySatisfiable pindex dep@(Cabal.Dependency pn _rang)
+ | Cabal.unPackageName pn == "Win32" = False -- only exists on windows, not in linux
| not . null $ lookupDependency pindex dep = True -- the package index satisfies the dep
| packageIsCoreInAnyGHC pn = False -- some other ghcs support the dependency
| otherwise = True -- the dep is not related with core packages, accept the dep
@@ -68,7 +69,7 @@ packageBuildableWithGHCVersion
:: GenericPackageDescription
-> FlagAssignment
-> (DC.CompilerInfo, InstalledPackageIndex)
- -> Either [Dependency] (PackageDescription, FlagAssignment)
+ -> 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
where trace_failure v = case v of
@@ -81,31 +82,38 @@ packageBuildableWithGHCVersion pkg user_specified_fas (compiler_info, pkgIndex)
]
) v
show_deps = show . map display
- show_compiler (DC.CompilerInfo { DC.compilerInfoId = CompilerId GHC v }) = "ghc-" ++ showVersion v
+ show_compiler (DC.CompilerInfo { DC.compilerInfoId = CompilerId GHC v }) = "ghc-" ++ display v
show_compiler c = show c
-- | Given a 'GenericPackageDescription' it returns the miminum GHC version
-- to build a package, and a list of core packages to that GHC version.
-minimumGHCVersionToBuildPackage :: GenericPackageDescription -> FlagAssignment -> Maybe (DC.CompilerInfo, [PackageName], PackageDescription, FlagAssignment, InstalledPackageIndex)
+minimumGHCVersionToBuildPackage :: GenericPackageDescription -> FlagAssignment -> Maybe ( DC.CompilerInfo
+ , [Cabal.PackageName]
+ , PackageDescription
+ , FlagAssignment
+ , InstalledPackageIndex)
minimumGHCVersionToBuildPackage gpd user_specified_fas =
listToMaybe [ (cinfo, packageNamesFromPackageIndex pix, pkg_desc, picked_flags, pix)
| g@(cinfo, pix) <- ghcs
, Right (pkg_desc, picked_flags) <- return (packageBuildableWithGHCVersion gpd user_specified_fas g)]
-mkIndex :: [PackageIdentifier] -> InstalledPackageIndex
+mkIndex :: [Cabal.PackageIdentifier] -> InstalledPackageIndex
mkIndex pids = fromList
[ emptyInstalledPackageInfo
{ sourcePackageId = pindex
, exposed = True
}
- | pindex@(PackageIdentifier name version) <- pids ]
+ | pindex@(Cabal.PackageIdentifier _name _version) <- pids ]
-packageNamesFromPackageIndex :: InstalledPackageIndex -> [PackageName]
+packageNamesFromPackageIndex :: InstalledPackageIndex -> [Cabal.PackageName]
packageNamesFromPackageIndex pix = nub $ map fst $ allPackagesByName pix
ghc :: [Int] -> DC.CompilerInfo
ghc nrs = DC.unknownCompilerInfo c_id DC.NoAbiTag
- where c_id = CompilerId GHC (Version nrs [])
+ where c_id = CompilerId GHC (mkVersion nrs)
+
+ghc801 :: (DC.CompilerInfo, InstalledPackageIndex)
+ghc801 = (ghc [8,0,1], mkIndex ghc801_pkgs)
ghc7102 :: (DC.CompilerInfo, InstalledPackageIndex)
ghc7102 = (ghc [7,10,2], mkIndex ghc7102_pkgs)
@@ -132,11 +140,38 @@ ghc741 = (ghc [7,4,1], mkIndex ghc741_pkgs)
-- Source: http://haskell.org/haskellwiki/Libraries_released_with_GHC
-- and our binary tarballs (package.conf.d.initial subdir)
-ghc7102_pkgs :: [PackageIdentifier]
+ghc801_pkgs :: [Cabal.PackageIdentifier]
+ghc801_pkgs =
+ [ p "array" [0,5,1,1]
+ , p "base" [4,9,0,0]
+ , p "binary" [0,8,3,0] -- used by libghc
+ , p "bytestring" [0,10,8,0]
+-- , p "Cabal" [1,24,0,0] package is upgradeable
+ , p "containers" [0,5,7,1]
+ , p "deepseq" [1,4,2,0] -- used by time
+ , p "directory" [1,2,6,2]
+ , p "filepath" [1,4,1,0]
+ , p "ghc-boot" [8,0,1]
+ , p "ghc-prim" [0,5,0,0]
+ , p "ghci" [8,0,1]
+ , p "hoopl" [3,10,2,1] -- used by libghc
+ , p "hpc" [0,6,0,3] -- used by libghc
+ , p "integer-gmp" [1,0,0,1]
+ , p "pretty" [1,1,3,3]
+ , p "process" [1,4,2,0]
+ , p "template-haskell" [2,11,0,0] -- used by libghc
+ -- , p "terminfo" [0,4,0,2]
+ , p "time" [1,6,0,1] -- used by unix, directory, hpc, ghc. unsafe to upgrade
+ , p "transformers" [0,5,2,0] -- used by libghc
+ , p "unix" [2,7,2,0]
+-- , p "xhtml" [3000,2,1]
+ ]
+
+ghc7102_pkgs :: [Cabal.PackageIdentifier]
ghc7102_pkgs =
[ p "array" [0,5,1,0]
, p "base" [4,8,1,0]
--- , p "binary" [0,7,3,0] package is upgradeable
+ , p "binary" [0,7,3,0] -- used by libghc
, p "bytestring" [0,10,6,0]
-- , p "Cabal" [1,18,1,3] package is upgradeable
, p "containers" [0,5,6,2]
@@ -155,15 +190,15 @@ ghc7102_pkgs =
, p "process" [1,2,3,0]
, p "template-haskell" [2,10,0,0] -- used by libghc
, p "time" [1,5,0,1] -- used by haskell98, unix, directory, hpc, ghc. unsafe to upgrade
--- , p "transformers" [0,4,2,0] -- used by libghc
+ , p "transformers" [0,4,2,0] -- used by libghc
, p "unix" [2,7,1,0]
]
-ghc7101_pkgs :: [PackageIdentifier]
+ghc7101_pkgs :: [Cabal.PackageIdentifier]
ghc7101_pkgs =
[ p "array" [0,5,1,0]
, p "base" [4,8,0,0]
--- , p "binary" [0,7,3,0] package is upgradeable
+ , p "binary" [0,7,3,0] -- used by libghc
, p "bytestring" [0,10,6,0]
-- , p "Cabal" [1,18,1,3] package is upgradeable
, p "containers" [0,5,6,2]
@@ -182,15 +217,15 @@ ghc7101_pkgs =
, p "process" [1,2,3,0]
, p "template-haskell" [2,10,0,0] -- used by libghc
, p "time" [1,5,0,1] -- used by haskell98, unix, directory, hpc, ghc. unsafe to upgrade
--- , p "transformers" [0,4,2,0] -- used by libghc
+ , p "transformers" [0,4,2,0] -- used by libghc
, p "unix" [2,7,1,0]
]
-ghc782_pkgs :: [PackageIdentifier]
+ghc782_pkgs :: [Cabal.PackageIdentifier]
ghc782_pkgs =
[ p "array" [0,5,0,0]
, p "base" [4,7,0,0]
--- , p "binary" [0,7,1,0] package is upgradeable
+ , p "binary" [0,7,1,0] -- used by libghc
, p "bytestring" [0,10,4,0]
-- , p "Cabal" [1,18,1,3] package is upgradeable
, p "containers" [0,5,5,1]
@@ -209,15 +244,15 @@ ghc782_pkgs =
, p "process" [1,2,0,0]
, p "template-haskell" [2,9,0,0] -- used by libghc
, p "time" [1,4,2] -- used by haskell98, unix, directory, hpc, ghc. unsafe to upgrade
--- , p "transformers" [0,3,0,0] -- used by libghc
+ , p "transformers" [0,3,0,0] -- used by libghc
, p "unix" [2,7,0,1]
]
-ghc762_pkgs :: [PackageIdentifier]
+ghc762_pkgs :: [Cabal.PackageIdentifier]
ghc762_pkgs =
[ p "array" [0,4,0,1]
, p "base" [4,6,0,1]
--- , p "binary" [0,5,1,1] package is upgradeable
+ , p "binary" [0,5,1,1] -- used by libghc
, p "bytestring" [0,10,0,2]
-- , p "Cabal" [1,16,0] package is upgradeable
, p "containers" [0,5,0,0]
@@ -239,11 +274,11 @@ ghc762_pkgs =
, p "unix" [2,6,0,1]
]
-ghc761_pkgs :: [PackageIdentifier]
+ghc761_pkgs :: [Cabal.PackageIdentifier]
ghc761_pkgs =
[ p "array" [0,4,0,1]
, p "base" [4,6,0,0]
--- , p "binary" [0,5,1,1] package is upgradeable
+ , 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]
@@ -265,11 +300,11 @@ ghc761_pkgs =
, p "unix" [2,6,0,0]
]
-ghc742_pkgs :: [PackageIdentifier]
+ghc742_pkgs :: [Cabal.PackageIdentifier]
ghc742_pkgs =
[ p "array" [0,4,0,0]
, p "base" [4,5,1,0]
--- , p "binary" [0,5,1,0] package is upgradeable
+ , p "binary" [0,5,1,0] -- used by libghc
, p "bytestring" [0,9,2,1]
-- , p "Cabal" [1,14,0] package is upgradeable
, p "containers" [0,4,2,1]
@@ -292,11 +327,11 @@ ghc742_pkgs =
, p "unix" [2,5,1,1]
]
-ghc741_pkgs :: [PackageIdentifier]
+ghc741_pkgs :: [Cabal.PackageIdentifier]
ghc741_pkgs =
[ p "array" [0,4,0,0]
, p "base" [4,5,0,0]
--- , p "binary" [0,5,1,0] package is upgradeable
+ , p "binary" [0,5,1,0] -- used by libghc
, p "bytestring" [0,9,2,1]
-- , p "Cabal" [1,14,0] package is upgradeable
, p "containers" [0,4,2,1]
@@ -319,5 +354,5 @@ ghc741_pkgs =
, p "unix" [2,5,1,0]
]
-p :: String -> [Int] -> PackageIdentifier
-p pn vs = PackageIdentifier (PackageName pn) (Version vs [])
+p :: String -> [Int] -> Cabal.PackageIdentifier
+p pn vs = Cabal.PackageIdentifier (Cabal.mkPackageName pn) (mkVersion vs)
diff --git a/Portage/Overlay.hs b/Portage/Overlay.hs
index 2fa8aaf..8200e88 100644
--- a/Portage/Overlay.hs
+++ b/Portage/Overlay.hs
@@ -34,7 +34,11 @@ data ExistingEbuild = ExistingEbuild {
ebuildPath :: FilePath
} deriving (Show,Ord,Eq)
-instance Cabal.Package ExistingEbuild where packageId = ebuildCabalId
+instance Cabal.Package ExistingEbuild where
+ packageId = ebuildCabalId
+
+instance Cabal.HasUnitId ExistingEbuild where
+ installedUnitId _ = error "Portage.Cabal.installedUnitId: FIXME: should not be used"
data Overlay = Overlay {
overlayPath :: FilePath,
diff --git a/Portage/PackageId.hs b/Portage/PackageId.hs
index a337b17..f97148c 100644
--- a/Portage/PackageId.hs
+++ b/Portage/PackageId.hs
@@ -62,7 +62,7 @@ packageIdToFilePath (PackageId (PackageName cat pn) version) =
a <.> b = a ++ '.':b
mkPackageName :: String -> String -> PackageName
-mkPackageName cat package = PackageName (Category cat) (Cabal.PackageName package)
+mkPackageName cat package = PackageName (Category cat) (Cabal.mkPackageName package)
fromCabalPackageId :: Category -> Cabal.PackageIdentifier -> PackageId
fromCabalPackageId category (Cabal.PackageIdentifier name version) =
@@ -70,8 +70,8 @@ fromCabalPackageId category (Cabal.PackageIdentifier name version) =
(Portage.fromCabalVersion version)
normalizeCabalPackageName :: Cabal.PackageName -> Cabal.PackageName
-normalizeCabalPackageName (Cabal.PackageName name) =
- Cabal.PackageName (map Char.toLower name)
+normalizeCabalPackageName =
+ Cabal.mkPackageName . map Char.toLower . Cabal.unPackageName
normalizeCabalPackageId :: Cabal.PackageIdentifier -> Cabal.PackageIdentifier
normalizeCabalPackageId (Cabal.PackageIdentifier name version) =
diff --git a/Portage/Version.hs b/Portage/Version.hs
index fec60c1..772343f 100644
--- a/Portage/Version.hs
+++ b/Portage/Version.hs
@@ -50,10 +50,10 @@ data Suffix = Alpha Int | Beta Int | Pre Int | RC Int | P Int
deriving (Eq, Ord, Show, Read)
fromCabalVersion :: Cabal.Version -> Version
-fromCabalVersion (Cabal.Version nums _tags) = Version nums Nothing [] 0
+fromCabalVersion cabal_version = Version (Cabal.versionNumbers cabal_version) Nothing [] 0
toCabalVersion :: Version -> Maybe Cabal.Version
-toCabalVersion (Version nums Nothing [] _) = Just (Cabal.Version nums [])
+toCabalVersion (Version nums Nothing [] _) = Just (Cabal.mkVersion nums)
toCabalVersion _ = Nothing
instance Text Version where
diff --git a/README.rst b/README.rst
index 1a758c7..1755370 100644
--- a/README.rst
+++ b/README.rst
@@ -62,9 +62,8 @@ Features
KEYWORDS
Defaults to ~amd64 ~x86
CABAL_FEATURES
- Set to "bin" for executables, and "lib haddock profile" for
- libraries. Packages that contains both a binary and library will
- get the union.
+ Populates the following features (see haskell-cabal.eclass):
+ lib, profile, haddock, hoogle, hscolour, test-suite
DEPEND
GHC dependency defaults to >=dev-lang/ghc-6.6.1.
Cabal dependency is fetched from Cabal field 'Cabal-Version'.
diff --git a/Status.hs b/Status.hs
index fe77248..3fa5478 100644
--- a/Status.hs
+++ b/Status.hs
@@ -28,15 +28,16 @@ import Control.Applicative
import Control.Monad
-- cabal
-import Distribution.Client.Types ( SourcePackageDb(..), SourcePackage(..) )
-import Distribution.Verbosity
-import Distribution.Package (pkgName)
-import Distribution.Simple.Utils (comparing, die, equating)
-import Distribution.Text ( display, simpleParse )
+import qualified Distribution.Verbosity as Cabal
+import qualified Distribution.Package as Cabal (pkgName)
+import qualified Distribution.Simple.Utils as Cabal (comparing, die, equating)
+import qualified Distribution.Text as Cabal ( display, simpleParse )
import qualified Distribution.Client.GlobalFlags as CabalInstall
import qualified Distribution.Client.IndexUtils as CabalInstall
-import qualified Distribution.Client.PackageIndex as CabalInstall
+import qualified Distribution.Client.Types as CabalInstall ( SourcePackageDb(..) )
+import qualified Distribution.Solver.Types.PackageIndex as CabalInstall
+import qualified Distribution.Solver.Types.SourcePackage as CabalInstall ( SourcePackage(..) )
data StatusDirection
= PortagePlusOverlay
@@ -53,7 +54,7 @@ data FileStatus a
deriving (Show,Eq)
instance Ord a => Ord (FileStatus a) where
- compare = comparing fromStatus
+ compare = Cabal.comparing fromStatus
instance Functor FileStatus where
fmap f st =
@@ -75,20 +76,20 @@ fromStatus fs =
-loadHackage :: Verbosity -> CabalInstall.RepoContext -> Overlay -> IO [[PackageId]]
+loadHackage :: Cabal.Verbosity -> CabalInstall.RepoContext -> Overlay -> IO [[PackageId]]
loadHackage verbosity repoContext overlay = do
- SourcePackageDb { packageIndex = pindex } <- CabalInstall.getSourcePackages verbosity repoContext
- let get_cat cabal_pkg = case resolveCategories overlay (pkgName cabal_pkg) of
+ CabalInstall.SourcePackageDb { packageIndex = pindex } <- CabalInstall.getSourcePackages verbosity repoContext
+ let get_cat cabal_pkg = case resolveCategories overlay (Cabal.pkgName cabal_pkg) of
[] -> Category "dev-haskell"
[cat] -> cat
_ -> {- ambig -} Category "dev-haskell"
pkg_infos = map ( reverse . take 3 . reverse -- hackage usually has a ton of older versions
. map ((\p -> fromCabalPackageId (get_cat p) p)
- . packageInfoId))
+ . CabalInstall.packageInfoId))
(CabalInstall.allPackagesByName pindex)
return pkg_infos
-status :: Verbosity -> FilePath -> FilePath -> CabalInstall.RepoContext -> IO (Map PackageName [FileStatus ExistingEbuild])
+status :: Cabal.Verbosity -> FilePath -> FilePath -> CabalInstall.RepoContext -> IO (Map PackageName [FileStatus ExistingEbuild])
status verbosity portdir overlaydir repoContext = do
overlay <- loadLazy overlaydir
hackage <- loadHackage verbosity repoContext overlay
@@ -112,8 +113,15 @@ status verbosity portdir overlaydir repoContext = do
mk_fake_ee :: [PackageId] -> (PackageName, [ExistingEbuild])
mk_fake_ee ~pkgs@(p:_) = (packageId p, map p_to_ee pkgs)
- map_diff = Map.differenceWith (\le re -> Just $ foldr (List.deleteBy (equating ebuildId)) le re)
- hack = ((Map.fromList $ map mk_fake_ee hackage) `map_diff` overlayMap overlay) `map_diff` overlayMap portage
+ map_diff = Map.differenceWith (\le re -> Just $ foldr (List.deleteBy (Cabal.equating ebuildId)) le re)
+ hack = (( -- We merge package names as we do case-insensitive match.
+ -- Hackage contains the following 2 package names:
+ -- ... Cabal-1.24.0.0 Cabal-1.24.1.0
+ -- cabal-0.0.0.0
+ -- We need to pick both lists of versions, not the first.
+ -- TODO: have a way to distict between them in the output.
+ Map.fromListWith (++) $
+ map mk_fake_ee hackage) `map_diff` overlayMap overlay) `map_diff` overlayMap portage
meld = Map.unionsWith (\a b -> List.sort (a++b))
[ Map.map (map PortageOnly) port
@@ -130,15 +138,15 @@ lookupEbuildWith overlay pkgid = do
ebuilds <- Map.lookup (packageId pkgid) overlay
List.find (\e -> ebuildId e == pkgid) ebuilds
-runStatus :: Verbosity -> FilePath -> FilePath -> StatusDirection -> [String] -> CabalInstall.RepoContext -> IO ()
+runStatus :: Cabal.Verbosity -> FilePath -> FilePath -> StatusDirection -> [String] -> CabalInstall.RepoContext -> IO ()
runStatus verbosity portdir overlaydir direction pkgs repoContext = do
let pkgFilter = case direction of
OverlayToPortage -> toPortageFilter
PortagePlusOverlay -> id
HackageToOverlay -> fromHackageFilter
pkgs' <- forM pkgs $ \p ->
- case simpleParse p of
- Nothing -> die ("Could not parse package name: " ++ p ++ ". Format cat/pkg")
+ case Cabal.simpleParse p of
+ Nothing -> Cabal.die ("Could not parse package name: " ++ p ++ ". Format cat/pkg")
Just pn -> return pn
tree0 <- status verbosity portdir overlaydir repoContext
let tree = pkgFilter tree0
@@ -196,10 +204,10 @@ statusPrinter packages = do
let (PackageName c p) = pkg
putStr (bold (show ix))
putStr " "
- putStr $ display c ++ '/' : bold (display p)
+ putStr $ Cabal.display c ++ '/' : bold (Cabal.display p)
putStr " "
forM_ ebuilds $ \e -> do
- putStr $ toColor (fmap (display . pkgVersion . ebuildId) e)
+ putStr $ toColor (fmap (Cabal.display . pkgVersion . ebuildId) e)
putChar ' '
putStrLn ""
@@ -215,12 +223,12 @@ toColor st = inColor c False Default (fromStatus st)
portageDiff :: EMap -> EMap -> (EMap, EMap, EMap)
portageDiff p1 p2 = (in1, ins, in2)
- where ins = Map.filter (not . null) $ Map.intersectionWith (List.intersectBy $ equating ebuildId) p1 p2
+ where ins = Map.filter (not . null) $ Map.intersectionWith (List.intersectBy $ Cabal.equating ebuildId) p1 p2
in1 = difference p1 p2
in2 = difference p2 p1
difference x y = Map.filter (not . null) $
Map.differenceWith (\xs ys ->
- let lst = foldr (List.deleteBy (equating ebuildId)) xs ys in
+ let lst = foldr (List.deleteBy (Cabal.equating ebuildId)) xs ys in
if null lst
then Nothing
else Just lst
@@ -236,7 +244,7 @@ equals fp1 fp2 = do
return (equal' f1 f2)
equal' :: BS.ByteString -> BS.ByteString -> Bool
-equal' = equating essence
+equal' = Cabal.equating essence
where
essence = filter (not . isEmpty) . filter (not . isComment) . BS.lines
isComment = BS.isPrefixOf (BS.pack "#") . BS.dropWhile isSpace
diff --git a/cabal/.mailmap b/cabal/.mailmap
new file mode 100644
index 0000000..6bb714a
--- /dev/null
+++ b/cabal/.mailmap
@@ -0,0 +1,117 @@
+# See 'git help shortlog' for more details.
+# Formats: Proper Name [<proper@email.xx> [Commit Name]] <commit@email.xx>
+#
+# Show result: 'git shortlog -se'.
+# Should be empty list: 'git shortlog -se | cut -f2 | cut -d'<' -f1 | uniq -d'.
+
+Adam Langley <agl@imperialviolet.org>
+Alistair Bailey <alistair@abayley.org> alistair <alistair@abayley.org>
+Alson Kemp <alson@alsonkemp.com> alson <alson@alsonkemp.com>
+Andy Craze <accraze@gmail.com>
+Andres Löh <andres.loeh@gmail.com>
+Andres Löh <andres.loeh@gmail.com> <andres@cs.uu.nl>
+Andres Löh <andres.loeh@gmail.com> <andres@well-typed.com>
+Andres Löh <andres.loeh@gmail.com> <ksgithub@andres-loeh.de>
+Andres Löh <andres.loeh@gmail.com> <mail@andres-loeh.de>
+Audrey Tang <audreyt@audreyt.org> audreyt <audreyt@audreyt.org>
+Austin Seipp <aseipp@pobox.com>
+Austin Seipp <aseipp@pobox.com> <aseipp@well-typed.com>
+Austin Seipp <aseipp@pobox.com> austin seipp <as@0xff.ath.cx>
+Ben Gamari <ben@smart-cactus.org>
+Ben Gamari <ben@smart-cactus.org> <ben@well-typed.com>
+Ben Gamari <ben@smart-cactus.org> <bgamari.foss@gmail.com>
+Ben Millwood <thebenmachine+git@gmail.com> <haskell@benmachine.co.uk>
+Benedikt Huber <benedikt.huber@gmail.com> benedikt.huber <benedikt.huber@gmail.com>
+Benno Fünfstück <benno.fuenfstueck@gmail.com> <bneno.fuenfstueck@gmail.com>
+Björn Bringert <bjorn@bringert.net>
+Björn Bringert <bjorn@bringert.net> bjorn <bjorn@maggie>
+Björn Bringert <bjorn@bringert.net> bringert <bringert@cs.chalmers.se>
+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>
+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>
+Duncan Coutts <duncan@community.haskell.org>
+Duncan Coutts <duncan@community.haskell.org> <Duncan Coutts duncan@community.haskell.org>
+Duncan Coutts <duncan@community.haskell.org> <duncan.coutts@worc.ox.ac.uk>
+Duncan Coutts <duncan@community.haskell.org> <duncan@community.haskell.org>
+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@mit.edu>
+Einar Karttunen <ekarttun@cs.helsinki.fi>
+Federico Mastellone <fmaste@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>
+Gershom Bazerman <gershomb@gmail.com>
+Gershom Bazerman <gershomb@gmail.com> Gershom <gershom@mbp.local>
+Gershom Bazerman <gershomb@gmail.com> U-CIQDEV\gbazerman <gbazerman@GBAZERMAN-T35.ciqdev.com>
+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>
+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>
+Henning Günther <der_eq@freenet.de>
+Henning Thielemann <lemming@henning-thielemann.de> <haskell@henning-thielemann.de>
+Henning Thielemann <lemming@henning-thielemann.de> cabal <cabal@henning-thielemann.de>
+Ian Lynagh <igloo@earth.li> <ian@well-typed.com>
+Isaac Potoczny-Jones <ijones@syntaxpolice.org>
+JP Moresmau <jp@moresmau.fr>
+Jacco Krijnen <jaccokrijnen@gmail.com>
+Jake Wheat <jakewheatmail@gmail.com>
+Jean-Philippe Bernardy <jeanphilippe.bernardy@gmail.com> jeanphilippe.bernardy <jeanphilippe.bernardy@gmail.com>
+Jens Petersen <juhpetersen@gmail.com> <juhp@community.haskell.org>
+Jens Petersen <juhpetersen@gmail.com> <petersen@haskell.org>
+Jens Petersen <juhpetersen@gmail.com> <petersen@redhat.com>
+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 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>
+Josh Hoyt <josh.hoyt@galois.com>
+Judah Jacobson <judah.jacobson@gmail.com>
+Jürgen Nicklisch-Franken <jnf@arcor.de>
+Ken Bateman <novadenizen@gmail.com>
+Keegan McAllister <mcallister.keegan@gmail.com> mcallister.keegan <mcallister.keegan@gmail.com>
+Kido Takahiro <shelarcy@gmail.com>
+Krasimir Angelov <kr.angelov@gmail.com>
+Krasimir Angelov <kr.angelov@gmail.com> ka2_mail <ka2_mail@yahoo.com>
+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>
+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> <the.dead.shall.rise@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>
+Peter Higley <phigley@gmail.com>
+Peter Simons <simons@cryp.to>
+Peter Trško <peter.trsko@gmail.com> Peter Trsko <peter.trsko@ixperta.com>
+Philipp Schuster <pschuster@uni-koblenz.de>
+Randy Polen <randen@users.noreply.github.com>
+Ryan Scott <ryan.gl.scott@gmail.com> <ryan.gl.scott@ku.edu>
+Samuel Gélineau <gelisam+github@gmail.com>
+Sergei Trofimovich <slyfox@community.haskell.org> <slyfox@gentoo.org>
+Sigbjorn Finne <sof@galois.com>
+Simon Marlow <marlowsd@gmail.com> <simonmar@microsoft.com>
+Simon Marlow <marlowsd@gmail.com> <smarlow@fb.com>
+Simon Peyton Jones <simonpj@microsoft.com>
+Simon Peyton Jones <simonpj@microsoft.com> simonpj <simonpj@microsoft/com>
+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>
+Sven Panne <sven.panne@aedion.de>
+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>
diff --git a/cabal/.mention-bot b/cabal/.mention-bot
new file mode 100644
index 0000000..c936d2e
--- /dev/null
+++ b/cabal/.mention-bot
@@ -0,0 +1,6 @@
+{
+ "userBlacklist": [
+ "BardurArantsson"
+ , "SyntaxPolice"
+ ]
+}
diff --git a/cabal/.travis.yml b/cabal/.travis.yml
index 67f87a4..770a53b 100644
--- a/cabal/.travis.yml
+++ b/cabal/.travis.yml
@@ -1,28 +1,107 @@
# NB: don't set `language: haskell` here
+# We specify language: c, so it doesn't default to e.g. ruby
+language: c
+
+sudo: false
+
+# Remember to add release branches
+# we whitelist branches, as we don't really need to build dev-branches.
+branches:
+ only:
+ - master
+ - "1.24"
+ - "1.22"
+ - "1.20"
+ - "1.18"
# The following enables several GHC versions to be tested; often it's enough to
# test only against the last release in a major GHC version. Feel free to omit
# lines listings versions you don't need/want testing for.
-env:
- - GHCVER=7.4.2
- - GHCVER=7.6.3
- - GHCVER=7.8.4
- - GHCVER=7.10.3
- - GHCVER=8.0.1 TEST_OLDER=YES
+matrix:
+ include:
+ - env: GHCVER=8.0.1 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
+ os: linux
+ sudo: required
+ - env: GHCVER=7.6.3 SCRIPT=script
+ os: linux
+ sudo: required
+ - env: GHCVER=7.8.4 SCRIPT=script
+ os: linux
+ sudo: required
+ # Ugh, we'd like to drop 'sudo: required' and use the
+ # apt plugin for the next two
+ # but the GCE instance we get has more memory, which makes
+ # a big difference
+ - env: GHCVER=7.10.3 SCRIPT=script
+ os: linux
+ sudo: required
+ - env: GHCVER=8.0.1 SCRIPT=script DEPLOY_DOCS=YES TEST_OTHER_VERSIONS=YES
+ sudo: required
+ os: linux
+ - env: GHCVER=8.0.1 SCRIPT=solver-debug-flags
+ sudo: required
+ os: linux
+ - env: GHCVER=8.0.1 SCRIPT=script PARSEC=YES TEST_OTHER_VERSIONS=YES
+ os: linux
+ sudo: required
+ - env: GHCVER=8.0.1 SCRIPT=bootstrap
+ sudo: required
+ os: linux
+
+ # We axed GHC 7.6 and earlier because it's not worth the trouble to
+ # make older GHC work with clang's cpp. See
+ # https://ghc.haskell.org/trac/ghc/ticket/8493
+ - env: GHCVER=7.8.4 SCRIPT=script
+ os: osx
+ osx_image: xcode6.4 # We need 10.10
+
+ # TODO: We might want to specify OSX version
+ # https://docs.travis-ci.com/user/osx-ci-environment/#OS-X-Version
+ - env: GHCVER=7.10.3 SCRIPT=script
+ os: osx
+ - env: GHCVER=8.0.1 SCRIPT=script
+ os: osx
+ - env: GHCVER=8.0.1 SCRIPT=bootstrap
+ os: osx
+
+ - env: GHCVER=via-stack SCRIPT=stack STACKAGE_RESOLVER=lts
+ os: linux
+ addons:
+ apt:
+ packages:
+ - libgmp-dev
+
+ allow_failures:
+ - env: GHCVER=via-stack SCRIPT=stack STACKAGE_RESOLVER=lts
+
# TODO add PARSEC_BUNDLED=YES when it's so
- - GHCVER=head
+ # It seems pointless to run head if we're going to ignore the results.
+ #- GHCVER=head
# Note: the distinction between `before_install` and `install` is not important.
before_install:
- - travis_retry sudo add-apt-repository -y ppa:hvr/ghc
- - travis_retry sudo apt-get update
- - travis_retry sudo apt-get install cabal-install-1.24 ghc-$GHCVER-prof ghc-$GHCVER-dyn happy
- - if [ "$TEST_OLDER" == "YES" ]; then travis_retry sudo apt-get install ghc-7.0.4-prof ghc-7.0.4-dyn ghc-7.2.2-prof ghc-7.2.2-dyn; fi
- - export PATH=$HOME/.cabal/bin:/opt/ghc/$GHCVER/bin:/opt/cabal/1.24/bin:$PATH
- - git version
+ - export PATH=/opt/ghc/$GHCVER/bin:$PATH
+ - export PATH=$HOME/.ghc-install/$GHCVER/bin:$PATH
+ - export PATH=$HOME/bin:$PATH
+ - export PATH=$HOME/.cabal/bin:$PATH
+ - export PATH=$HOME/.local/bin:$PATH
+ - export PATH=/opt/cabal/1.24/bin:$PATH
+ - export PATH=/opt/happy/1.19.5/bin:$PATH
+ - export PATH=/opt/alex/3.1.7/bin:$PATH
+ - ./travis-install.sh
+
+ # Set up deployment to the haskell/cabal-website repo.
+ # NB: these commands MUST be in .travis.yml, otherwise the secret key can be
+ # leaked! See https://github.com/travis-ci/travis.rb/issues/423.
+ # umask to get the permissions to be 400.
+ - if [ "x$TRAVIS_REPO_SLUG" = "xhaskell/cabal" -a "x$TRAVIS_PULL_REQUEST" = "xfalse" -a "x$TRAVIS_BRANCH" = "xmaster" -a "x$DEPLOY_DOCS" = "xYES" ]; then (umask 377 && openssl aes-256-cbc -K $encrypted_edaf6551664d_key -iv $encrypted_edaf6551664d_iv -in id_rsa_cabal_website.aes256.enc -out ~/.ssh/id_rsa -d); fi
install:
- - cabal update
# We intentionally do not install anything before trying to build Cabal because
# it should build with each supported GHC version out-of-the-box.
@@ -31,8 +110,34 @@ install:
# ./dist/setup/setup here instead of cabal-install to avoid breakage when the
# build config format changed.
script:
- - ./travis-script.sh
+ - ./travis-${SCRIPT}.sh
-matrix:
- allow_failures:
- - env: GHCVER=head
+cache:
+ directories:
+ - $HOME/.cabal/packages
+ - $HOME/.cabal/store
+ - $HOME/.cabal/bin
+
+ - $HOME/.stack/bin
+ - $HOME/.stack/precompiled
+ - $HOME/.stack/programs
+ - $HOME/.stack/setup-exe-cache
+ - $HOME/.stack/snapshots
+
+# We remove the index because it churns quite a bit and we don't want
+# to pay the cost of repeatedly caching it even though we don't care
+# about most changing packages.
+before_cache:
+ - rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log
+ - rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index*
+ - rm -fv $HOME/.cabal/packages/hackage.haskell.org/*.json
+
+# Deploy Haddocks to the haskell/cabal-website repo.
+after_success:
+ - ./travis-deploy.sh
+
+notifications:
+ irc:
+ channels:
+ - "chat.freenode.net##haskell-cabal"
+ slack: haskell-cabal:sCq6GLfy9N8MJrInosg871n4
diff --git a/cabal/AUTHORS b/cabal/AUTHORS
new file mode 100644
index 0000000..121b7f9
--- /dev/null
+++ b/cabal/AUTHORS
@@ -0,0 +1,265 @@
+Abhinav Gupta <mail@abhinavg.net>
+Adam Bergmark <adam@bergmark.nl>
+Adam C. Foltzer <acfoltzer@galois.com>
+Adam Gundry <adam@well-typed.com>
+Adam Langley <agl@imperialviolet.org>
+Adam Sandberg Eriksson <adam@sandbergericsson.se>
+Alan Zimmerman <alan.zimm@gmail.com>
+Albert Krewinkel <tarleb@moltkeplatz.de>
+Alexander Kjeldaas <alexander.kjeldaas@gmail.com>
+Alexander Vershilov <alexander.vershilov@gmail.com>
+Alistair Bailey <alistair@abayley.org>
+Alson Kemp <alson@alsonkemp.com>
+Anders Kaseorg <andersk@mit.edu>
+Andrea Vezzosi <sanzhiyan@gmail.com>
+Andres Löh <andres.loeh@gmail.com>
+Andrzej Rybczak <electricityispower@gmail.com>
+Andrés Sicard-Ramírez <andres.sicard.ramirez@gmail.com>
+Andy Craze <accraze@gmail.com>
+Angus Lepper <angus.lepper@gmail.com>
+Antoine Latter <aslatter@gmail.com>
+Anton Dessiatov <anton.dessiatov@gmail.com>
+Antonio Nikishaev <a@lelf.me>
+Arian van Putten <aeroboy94@gmail.com>
+Arun Tejasvi Chaganty <arunchaganty@gmail.com>
+Atze Dijkstra <atze@cs.uu.nl>
+Audrey Tang <audreyt@audreyt.org>
+Austin Seipp <aseipp@pobox.com>
+Bardur Arantsson <bardur@scientician.net>
+Bartosz Nitka <bnitka@fb.com>
+Bas van Dijk <v.dijk.bas@gmail.com>
+Ben Armston <ben.armston@googlemail.com>
+Ben Doyle <benjamin.peter.doyle@gmail.com>
+Ben Gamari <ben@smart-cactus.org>
+Ben Millwood <thebenmachine+git@gmail.com>
+Benedikt Huber <benedikt.huber@gmail.com>
+Benjamin Herr <ben@0x539.de>
+Benno Fünfstück <benno.fuenfstueck@gmail.com>
+Bertram Felgenhauer <int-e@gmx.de>
+Björn Bringert <bjorn@bringert.net>
+Björn Peemöller <bjp@informatik.uni-kiel.de>
+Bob Ippolito <bob@redivi.com>
+Bram Schuur <bramschuur@gmail.com>
+Brendan Hay <brendan.g.hay@gmail.com>
+Brent Yorgey <byorgey@gmail.com>
+Brian Smith <brianlsmith@gmail.com>
+Bryan O'Sullivan <bos@serpentine.com>
+Bryan Richter <bryan.richter@gmail.com>
+Carter Tazio Schonwald <carter.schonwald@gmail.com>
+Chris Allen <cma@bitemyapp.com>
+Chris Wong <lambda.fairy@gmail.com>
+Christiaan Baaij <christiaan.baaij@gmail.com>
+Clemens Fruhwirth <clemens@endorphin.org>
+Clint Adams <clint@debian.org>
+Conal Elliott <conal@conal.net>
+Curtis Gagliardi <curtis@curtis.io>
+Dan Burton <danburton.email@gmail.com>
+Daniel Buckmaster <dan.buckmaster@gmail.com>
+Daniel Trstenjak <daniel.trstenjak@gmail.com>
+Daniel Velkov <norcobg@gmail.com>
+Daniel Wagner <daniel@wagner-home.com>
+Danny Navarro <j@dannynavarro.net>
+David Feuer <David.Feuer@gmail.com>
+David Fox <dsf@seereason.com>
+David Himmelstrup <lemmih@gmail.com>
+David Lazar <lazar6@illinois.edu>
+David Luposchainsky <dluposchainsky@gmail.com>
+David McFarland <corngood@gmail.com>
+David Terei <davidterei@gmail.com>
+David Waern <davve@dtek.chalmers.se>
+Dennis Gosnell <cdep.illabout@gmail.com>
+Dino Morelli <dino@ui3.info>
+Dmitry Astapov <dastapov@gmail.com>
+Dominic Steinitz <dominic@steinitz.org>
+Don Stewart <dons@galois.com>
+Doug Beardsley <mightybyte@gmail.com>
+Duncan Coutts <duncan@community.haskell.org>
+Echo Nolan <echo@echonolan.net>
+Edsko de Vries <edsko@well-typed.com>
+Edward Z. Yang <ezyang@cs.stanford.edu>
+Einar Karttunen <ekarttun@cs.helsinki.fi>
+Eric Kow <eric.kow@gmail.com>
+Eric Seidel <gridaphobe@gmail.com>
+Erik Hesselink <hesselink@gmail.com>
+Erik Rantapaa <erantapaa@gmail.com>
+Erik de Castro Lopo <erikd@mega-nerd.com>
+Esa Ilari Vuokko <ei@vuokko.info>
+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>
+Florian Hartwig <florian.j.hartwig@gmail.com>
+Franz Thoma <franz.thoma@tngtech.com>
+Fujimura Daisuke <me@fujimuradaisuke.com>
+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>
+Gershom Bazerman <gershomb@gmail.com>
+Getty Ritter <gdritter@galois.com>
+Gleb Alexeev <gleb.alexeev@gmail.com>
+Gregory Collins <greg@gregorycollins.net>
+Gwern Branwen <gwern0@gmail.com>
+Haisheng.Wu <freizl@gmail.com>
+Harry Garrood <harry@garrood.me>
+Heather <heather@live.ru>
+Henk-Jan van Tuyl <hjgtuyl@chello.nl>
+Henning Günther <der_eq@freenet.de>
+Henning Thielemann <lemming@henning-thielemann.de>
+Herbert Valerio Riedel <hvr@gnu.org>
+Iain Nicol <iain@iainnicol.com>
+Ian D. Bollinger <ian.bollinger@gmail.com>
+Ian Lynagh <igloo@earth.li>
+Ian Ross <ian@skybluetrades.net>
+Ilya Smelkov <triplepointfive@gmail.com>
+Isaac Potoczny-Jones <ijones@syntaxpolice.org>
+Isamu Mogi <saturday6c@gmail.com>
+Iustin Pop <iusty@k1024.org>
+Iñaki García Etxebarria <garetxe@gmail.com>
+JP Moresmau <jp@moresmau.fr>
+Jacco Krijnen <jaccokrijnen@gmail.com>
+Jack Henahan <jhenahan@uvm.edu>
+Jake Wheat <jakewheatmail@gmail.com>
+Jason Dagit <dagitj@gmail.com>
+Jean-Philippe Bernardy <jeanphilippe.bernardy@gmail.com>
+Jens Petersen <juhpetersen@gmail.com>
+Jeremy Shaw <jeremy.shaw@linspireinc.com>
+Jim Burton <jim@sdf-eu.org>
+Joachim Breitner <mail@joachim-breitner.de>
+Joe Quinn <headprogrammingczar@gmail.com>
+Joel Stanley <intractable@gmail.com>
+Joeri van Eekelen <tchakkazulu@gmail.com>
+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 Lato <jwlato@tsurucapital.com>
+John Wiegley <johnw@fpcomplete.com>
+Jonathan Daugherty <jtd@galois.com>
+Jookia <166291@gmail.com>
+Josef Svenningsson <josef.svenningsson@gmail.com>
+Josh Hoyt <josh.hoyt@galois.com>
+Judah Jacobson <judah.jacobson@gmail.com>
+Jürgen Nicklisch-Franken <jnf@arcor.de>
+Karel Gardas <karel.gardas@centrum.cz>
+Keegan McAllister <mcallister.keegan@gmail.com>
+Ken Bateman <novadenizen@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>
+Leonid Onokhov <sopvop@gmail.com>
+Liyang HU <git@liyang.hu>
+Luite Stegeman <stegeman@gmail.com>
+Luke Iannini <lukexi@me.com>
+M Farkas-Dyck <strake888@gmail.com>
+Maciek Makowski <maciek.makowski@gmail.com>
+Magnus Jonsson <magnus@smartelectronix.com>
+Malcolm Wallace <Malcolm.Wallace@me.com>
+Mark Lentczner <markl@glyphic.com>
+Mark Weber <marco-oweber@gmx.de>
+Markus Pfeiffer <markusp@mcs.st-andrews.ac.uk>
+Martin Sjögren <msjogren@gmail.com>
+Martin Vlk <martin@vlkk.cz>
+Masahiro Yamauchi <sgt.yamauchi@gmail.com>
+Mathieu Boespflug <mboes@tweag.net>
+Matthew William Cox <matt@mattcox.ca>
+Matthias Fischmann <mf@zerobuzz.net>
+Matthias Kilian <kili@outback.escape.de>
+Matthias Pronk <git@masida.nl>
+Max Amanshauser <max@lambdalifting.org>
+Max Bolingbroke <batterseapower@hotmail.com>
+Maximilian Tagher <feedback.tagher@gmail.com>
+Maxwell Swadling <maxwellswadling@gmail.com>
+Merijn Verstraaten <merijn@inconsistent.nl>
+Michael Sloan <mgsloan@gmail.com>
+Michael Snoyman <michael@snoyman.com>
+Michael Thompson <what_is_it_to_do_anything@yahoo.com>
+Michael Tolly <miketolly@gmail.com>
+Mike Craig <mcraig@groupon.com>
+Mikhail Glushenkov <mikhail.glushenkov@gmail.com>
+Misty De Meo <mistydemeo@gmail.com>
+Miëtek Bak <mietek@bak.io>
+Mohit Agarwal <mohit@sdf.org>
+Moritz Kiefer <moritz.kiefer@purelyfunctional.org>
+Nathan Howell <nhowell@alphaheavy.com>
+Neil Mitchell <ndmitchell@gmail.com>
+Neil Vice <sardonicpresence@gmail.com>
+Nick Alexander <ncalexan@uci.edu>
+Nick Smallbone <nick.smallbone@gmail.com>
+Nikita Karetnikov <nikita@karetnikov.org>
+Niklas Broberg <niklas.broberg@gmail.com>
+Niklas Hambüchen <mail@nh2.me>
+Oleg Grenrus <oleg.grenrus@iki.fi>
+Oleksandr Manzyuk <manzyuk@gmail.com>
+Omar Mefire <omefire@gmail.com>
+Owen Stephens <owen@owenstephens.co.uk>
+Paolo Capriotti <p.capriotti@gmail.com>
+Paolo G. Giarrusso <p.giarrusso@gmail.com>
+Paolo Losi <paolo.losi@gmail.com>
+Paolo Martini <paolo@nemail.it>
+Patrick Premont <ppremont@cognimeta.com>
+Patryk Zadarnowski <pat@jantar.org>
+Pepe Iborra <mnislaih@gmail.com>
+Peter Higley <phigley@gmail.com>
+Peter Robinson <thaldyron@gmail.com>
+Peter Selinger <selinger@mathstat.dal.ca>
+Peter Simons <simons@cryp.to>
+Peter Trško <peter.trsko@gmail.com>
+Phil Ruffwind <rf@rufflewind.com>
+Philipp Schuster <pschuster@uni-koblenz.de>
+Prayag Verma <prayag.verma@gmail.com>
+Randy Polen <randen@users.noreply.github.com>
+Reid Barton <rwbarton@gmail.com>
+Richard Eisenberg <eir@cis.upenn.edu>
+Ricky Elrod <ricky@elrod.me>
+Robert Collins <robertc@robertcollins.net>
+Roberto Zunino <zunrob@users.sf.net>
+Robin Green <greenrd@greenrd.org>
+Robin KAY <komadori@gekkou.co.uk>
+Roman Cheplyaka <roma@ro-che.info>
+Ross Paterson <ross@soi.city.ac.uk>
+Rudy Matela <rudy@matela.com.br>
+Ryan Desfosses <ryan@desfo.org>
+Ryan Mulligan <ryan@ryantm.com>
+Ryan Newton <rrnewton@gmail.com>
+Ryan Scott <ryan.gl.scott@gmail.com>
+Ryan Trinkle <ryan.trinkle@gmail.com>
+RyanGlScott <ryan.gl.scott@gmail.com>
+Samuel Bronson <naesten@gmail.com>
+Samuel Gélineau <gelisam+github@gmail.com>
+Sergei Trofimovich <slyfox@community.haskell.org>
+Sergey Vinokurov <serg.foo@gmail.com>
+Sigbjorn Finne <sof@galois.com>
+Simon Hengel <sol@typeful.net>
+Simon Jakobi <simon.jakobi@gmail.com>
+Simon Marlow <marlowsd@gmail.com>
+Simon Meier <iridcode@gmail.com>
+Simon Peyton Jones <simonpj@microsoft.com>
+Spencer Janssen <sjanssen@cse.unl.edu>
+Stephen Blackheath <stephen.blackheath@ipwnstudios.com>
+Sven Panne <sven.panne@aedion.de>
+Sönke Hahn <shahn@joyridelabs.de>
+Taru Karttunen <taruti@taruti.net>
+Thomas Dziedzic <gostrc@gmail.com>
+Thomas M. DuBuisson <thomas.dubuisson@gmail.com>
+Thomas Miedema <thomasmiedema@gmail.com>
+Thomas Schilling <nominolo@gmail.com>
+Thomas Tuegel <ttuegel@gmail.com>
+Tillmann Rendel <rendel@informatik.uni-marburg.de>
+Tim Chevalier <chevalier@alum.wellesley.edu>
+Tim Humphries <tim.humphries@ambiata.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>
+Vincent Hanquez <vincent@snarc.org>
+Vo Minh Thu <noteed@gmail.com>
+Wojciech Danilo <wojtek.danilo@gmail.com>
+Yitzchak Gale <gale@sefer.org>
+Yuras Shumovich <shumovichy@gmail.com>
+capsjac <capsjac@gmail.com>
+Łukasz Dąbek <sznurek@gmail.com>
diff --git a/cabal/Cabal/Cabal.cabal b/cabal/Cabal/Cabal.cabal
index 47dd82d..9a1e219 100644
--- a/cabal/Cabal/Cabal.cabal
+++ b/cabal/Cabal/Cabal.cabal
@@ -1,15 +1,13 @@
-name: Cabal
-version: 1.25.0.0
-copyright: 2003-2006, Isaac Jones
- 2005-2011, Duncan Coutts
-license: BSD3
-license-file: LICENSE
-author: Isaac Jones <ijones@syntaxpolice.org>
- Duncan Coutts <duncan@community.haskell.org>
-maintainer: cabal-devel@haskell.org
-homepage: http://www.haskell.org/cabal/
-bug-reports: https://github.com/haskell/cabal/issues
-synopsis: A framework for packaging Haskell software
+name: Cabal
+version: 1.25.0.0
+copyright: 2003-2016, Cabal Development Team (see AUTHORS file)
+license: BSD3
+license-file: LICENSE
+author: Cabal Development Team <cabal-devel@haskell.org>
+maintainer: cabal-devel@haskell.org
+homepage: http://www.haskell.org/cabal/
+bug-reports: https://github.com/haskell/cabal/issues
+synopsis: A framework for packaging Haskell software
description:
The Haskell Common Architecture for Building Applications and
Libraries: a framework defining a common interface for authors to more
@@ -17,187 +15,37 @@ description:
.
The Haskell Cabal is part of a larger infrastructure for distributing,
organizing, and cataloging Haskell libraries and tools.
-category: Distribution
-cabal-version: >=1.10
-build-type: Simple
+category: Distribution
+cabal-version: >=1.10
+build-type: Simple
-- If we use a new Cabal feature, this needs to be changed to Custom so
-- we can bootstrap.
extra-source-files:
README.md tests/README.md changelog
- doc/developing-packages.markdown doc/index.markdown
- doc/installing-packages.markdown
- doc/misc.markdown
+ 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
-- Generated with 'misc/gen-extra-source-files.sh'
-- Do NOT edit this section manually; instead, run the script.
-- BEGIN gen-extra-source-files
- tests/PackageTests/AllowNewer/AllowNewer.cabal
- tests/PackageTests/AllowNewer/benchmarks/Bench.hs
- tests/PackageTests/AllowNewer/src/Foo.hs
- tests/PackageTests/AllowNewer/tests/Test.hs
- tests/PackageTests/BenchmarkExeV10/Foo.hs
- tests/PackageTests/BenchmarkExeV10/benchmarks/bench-Foo.hs
- tests/PackageTests/BenchmarkExeV10/my.cabal
- tests/PackageTests/BenchmarkOptions/BenchmarkOptions.cabal
- tests/PackageTests/BenchmarkOptions/test-BenchmarkOptions.hs
- tests/PackageTests/BenchmarkStanza/my.cabal
- tests/PackageTests/BuildDeps/GlobalBuildDepsNotAdditive1/GlobalBuildDepsNotAdditive1.cabal
- tests/PackageTests/BuildDeps/GlobalBuildDepsNotAdditive1/MyLibrary.hs
- tests/PackageTests/BuildDeps/GlobalBuildDepsNotAdditive2/GlobalBuildDepsNotAdditive2.cabal
- tests/PackageTests/BuildDeps/GlobalBuildDepsNotAdditive2/lemon.hs
- tests/PackageTests/BuildDeps/InternalLibrary0/MyLibrary.hs
- tests/PackageTests/BuildDeps/InternalLibrary0/my.cabal
- tests/PackageTests/BuildDeps/InternalLibrary0/programs/lemon.hs
- tests/PackageTests/BuildDeps/InternalLibrary1/MyLibrary.hs
- tests/PackageTests/BuildDeps/InternalLibrary1/my.cabal
- tests/PackageTests/BuildDeps/InternalLibrary1/programs/lemon.hs
- tests/PackageTests/BuildDeps/InternalLibrary2/MyLibrary.hs
- tests/PackageTests/BuildDeps/InternalLibrary2/my.cabal
- tests/PackageTests/BuildDeps/InternalLibrary2/programs/lemon.hs
- tests/PackageTests/BuildDeps/InternalLibrary2/to-install/MyLibrary.hs
- tests/PackageTests/BuildDeps/InternalLibrary2/to-install/my.cabal
- tests/PackageTests/BuildDeps/InternalLibrary3/MyLibrary.hs
- tests/PackageTests/BuildDeps/InternalLibrary3/my.cabal
- tests/PackageTests/BuildDeps/InternalLibrary3/programs/lemon.hs
- tests/PackageTests/BuildDeps/InternalLibrary3/to-install/MyLibrary.hs
- tests/PackageTests/BuildDeps/InternalLibrary3/to-install/my.cabal
- tests/PackageTests/BuildDeps/InternalLibrary4/MyLibrary.hs
- tests/PackageTests/BuildDeps/InternalLibrary4/my.cabal
- tests/PackageTests/BuildDeps/InternalLibrary4/programs/lemon.hs
- tests/PackageTests/BuildDeps/InternalLibrary4/to-install/MyLibrary.hs
- tests/PackageTests/BuildDeps/InternalLibrary4/to-install/my.cabal
- tests/PackageTests/BuildDeps/SameDepsAllRound/MyLibrary.hs
- tests/PackageTests/BuildDeps/SameDepsAllRound/SameDepsAllRound.cabal
- tests/PackageTests/BuildDeps/SameDepsAllRound/lemon.hs
- tests/PackageTests/BuildDeps/SameDepsAllRound/pineapple.hs
- tests/PackageTests/BuildDeps/TargetSpecificDeps1/MyLibrary.hs
- tests/PackageTests/BuildDeps/TargetSpecificDeps1/lemon.hs
- tests/PackageTests/BuildDeps/TargetSpecificDeps1/my.cabal
- tests/PackageTests/BuildDeps/TargetSpecificDeps2/MyLibrary.hs
- tests/PackageTests/BuildDeps/TargetSpecificDeps2/lemon.hs
- tests/PackageTests/BuildDeps/TargetSpecificDeps2/my.cabal
- tests/PackageTests/BuildDeps/TargetSpecificDeps3/MyLibrary.hs
- tests/PackageTests/BuildDeps/TargetSpecificDeps3/lemon.hs
- tests/PackageTests/BuildDeps/TargetSpecificDeps3/my.cabal
- tests/PackageTests/BuildTestSuiteDetailedV09/Dummy2.hs
- tests/PackageTests/BuildableField/BuildableField.cabal
- tests/PackageTests/BuildableField/Main.hs
- tests/PackageTests/CMain/Bar.hs
- tests/PackageTests/CMain/foo.c
- tests/PackageTests/CMain/my.cabal
- tests/PackageTests/Configure/A.hs
- tests/PackageTests/Configure/Setup.hs
- tests/PackageTests/Configure/X11.cabal
- tests/PackageTests/CopyComponent/Exe/Main.hs
- tests/PackageTests/CopyComponent/Exe/Main2.hs
- tests/PackageTests/CopyComponent/Exe/myprog.cabal
- tests/PackageTests/CopyComponent/Lib/Main.hs
- tests/PackageTests/CopyComponent/Lib/p.cabal
- tests/PackageTests/CopyComponent/Lib/src/P.hs
- tests/PackageTests/CustomPreProcess/Hello.hs
- tests/PackageTests/CustomPreProcess/MyCustomPreprocessor.hs
- tests/PackageTests/CustomPreProcess/Setup.hs
- tests/PackageTests/CustomPreProcess/internal-preprocessor-test.cabal
- tests/PackageTests/DeterministicAr/Lib.hs
- tests/PackageTests/DeterministicAr/my.cabal
- tests/PackageTests/DuplicateModuleName/DuplicateModuleName.cabal
- tests/PackageTests/DuplicateModuleName/src/Foo.hs
- tests/PackageTests/DuplicateModuleName/tests/Foo.hs
- tests/PackageTests/DuplicateModuleName/tests2/Foo.hs
- tests/PackageTests/EmptyLib/empty/empty.cabal
- tests/PackageTests/GhcPkgGuess/SameDirectory/SameDirectory.cabal
- tests/PackageTests/GhcPkgGuess/SameDirectory/ghc
- tests/PackageTests/GhcPkgGuess/SameDirectory/ghc-pkg
- tests/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/SameDirectory.cabal
- tests/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/ghc-7.10
- tests/PackageTests/GhcPkgGuess/SameDirectoryGhcVersion/ghc-pkg-ghc-7.10
- tests/PackageTests/GhcPkgGuess/SameDirectoryVersion/SameDirectory.cabal
- tests/PackageTests/GhcPkgGuess/SameDirectoryVersion/ghc-7.10
- tests/PackageTests/GhcPkgGuess/SameDirectoryVersion/ghc-pkg-7.10
- tests/PackageTests/GhcPkgGuess/Symlink/SameDirectory.cabal
- tests/PackageTests/GhcPkgGuess/Symlink/bin/ghc
- tests/PackageTests/GhcPkgGuess/Symlink/bin/ghc-pkg
- tests/PackageTests/GhcPkgGuess/SymlinkGhcVersion/SameDirectory.cabal
- tests/PackageTests/GhcPkgGuess/SymlinkGhcVersion/bin/ghc-7.10
- tests/PackageTests/GhcPkgGuess/SymlinkGhcVersion/bin/ghc-pkg-7.10
- tests/PackageTests/GhcPkgGuess/SymlinkVersion/SameDirectory.cabal
- tests/PackageTests/GhcPkgGuess/SymlinkVersion/bin/ghc-7.10
- tests/PackageTests/GhcPkgGuess/SymlinkVersion/bin/ghc-pkg-ghc-7.10
- tests/PackageTests/Haddock/CPP.hs
- tests/PackageTests/Haddock/Literate.lhs
- tests/PackageTests/Haddock/NoCPP.hs
- tests/PackageTests/Haddock/Simple.hs
- tests/PackageTests/Haddock/my.cabal
- tests/PackageTests/HaddockNewline/A.hs
- tests/PackageTests/HaddockNewline/HaddockNewline.cabal
- tests/PackageTests/HaddockNewline/Setup.hs
- tests/PackageTests/InternalLibraries/Executable/exe/Main.hs
- tests/PackageTests/InternalLibraries/Executable/foo.cabal
- tests/PackageTests/InternalLibraries/Executable/src/Foo.hs
- tests/PackageTests/InternalLibraries/Library/fooexe/Main.hs
- tests/PackageTests/InternalLibraries/Library/fooexe/fooexe.cabal
- tests/PackageTests/InternalLibraries/Library/foolib/Foo.hs
- tests/PackageTests/InternalLibraries/Library/foolib/foolib.cabal
- tests/PackageTests/InternalLibraries/Library/foolib/private/Internal.hs
- tests/PackageTests/InternalLibraries/p/Foo.hs
- tests/PackageTests/InternalLibraries/p/p.cabal
- tests/PackageTests/InternalLibraries/p/p/P.hs
- tests/PackageTests/InternalLibraries/p/q/Q.hs
- tests/PackageTests/InternalLibraries/q/Q.hs
- tests/PackageTests/InternalLibraries/q/q.cabal
- tests/PackageTests/Macros/A.hs
- tests/PackageTests/Macros/B.hs
- tests/PackageTests/Macros/Main.hs
- tests/PackageTests/Macros/macros.cabal
- tests/PackageTests/Macros/src/C.hs
- tests/PackageTests/Options.hs
- tests/PackageTests/OrderFlags/Foo.hs
- tests/PackageTests/OrderFlags/my.cabal
- tests/PackageTests/PathsModule/Executable/Main.hs
- tests/PackageTests/PathsModule/Executable/my.cabal
- tests/PackageTests/PathsModule/Library/my.cabal
- tests/PackageTests/PreProcess/Foo.hsc
- tests/PackageTests/PreProcess/Main.hs
- tests/PackageTests/PreProcess/my.cabal
- tests/PackageTests/PreProcessExtraSources/Foo.hsc
- tests/PackageTests/PreProcessExtraSources/Main.hs
- tests/PackageTests/PreProcessExtraSources/my.cabal
- tests/PackageTests/ReexportedModules/ReexportedModules.cabal
- tests/PackageTests/TemplateHaskell/dynamic/Exe.hs
- tests/PackageTests/TemplateHaskell/dynamic/Lib.hs
- tests/PackageTests/TemplateHaskell/dynamic/TH.hs
- tests/PackageTests/TemplateHaskell/dynamic/my.cabal
- tests/PackageTests/TemplateHaskell/profiling/Exe.hs
- tests/PackageTests/TemplateHaskell/profiling/Lib.hs
- tests/PackageTests/TemplateHaskell/profiling/TH.hs
- tests/PackageTests/TemplateHaskell/profiling/my.cabal
- tests/PackageTests/TemplateHaskell/vanilla/Exe.hs
- tests/PackageTests/TemplateHaskell/vanilla/Lib.hs
- tests/PackageTests/TemplateHaskell/vanilla/TH.hs
- tests/PackageTests/TemplateHaskell/vanilla/my.cabal
- tests/PackageTests/TestNameCollision/child/Child.hs
- tests/PackageTests/TestNameCollision/child/child.cabal
- tests/PackageTests/TestNameCollision/child/tests/Test.hs
- tests/PackageTests/TestNameCollision/parent/Parent.hs
- tests/PackageTests/TestNameCollision/parent/parent.cabal
- tests/PackageTests/TestOptions/TestOptions.cabal
- tests/PackageTests/TestOptions/test-TestOptions.hs
- tests/PackageTests/TestStanza/my.cabal
- tests/PackageTests/TestSuiteTests/ExeV10/Foo.hs
- tests/PackageTests/TestSuiteTests/ExeV10/my.cabal
- tests/PackageTests/TestSuiteTests/ExeV10/tests/test-Foo.hs
- tests/PackageTests/TestSuiteTests/ExeV10/tests/test-Short.hs
- tests/PackageTests/TestSuiteTests/LibV09/Lib.hs
- tests/PackageTests/TestSuiteTests/LibV09/LibV09.cabal
- tests/PackageTests/TestSuiteTests/LibV09/tests/Deadlock.hs
- tests/PackageTests/Tests.hs
- tests/PackageTests/UniqueIPID/P1/M.hs
- tests/PackageTests/UniqueIPID/P1/my.cabal
- tests/PackageTests/UniqueIPID/P2/M.hs
- tests/PackageTests/UniqueIPID/P2/my.cabal
- tests/PackageTests/multInst/my.cabal
- tests/Setup.hs
+ tests/ParserTests/warnings/bom.cabal
+ tests/ParserTests/warnings/bool.cabal
+ tests/ParserTests/warnings/deprecatedfield.cabal
+ tests/ParserTests/warnings/extratestmodule.cabal
+ tests/ParserTests/warnings/gluedop.cabal
+ tests/ParserTests/warnings/nbsp.cabal
+ tests/ParserTests/warnings/newsyntax.cabal
+ tests/ParserTests/warnings/oldsyntax.cabal
+ tests/ParserTests/warnings/subsection.cabal
+ tests/ParserTests/warnings/trailingfield.cabal
+ tests/ParserTests/warnings/unknownfield.cabal
+ tests/ParserTests/warnings/unknownsection.cabal
+ tests/ParserTests/warnings/utf8.cabal
+ tests/ParserTests/warnings/versiontag.cabal
tests/hackage/check.sh
tests/hackage/download.sh
tests/hackage/unpack.sh
@@ -212,6 +60,20 @@ source-repository head
flag bundled-binary-generic
default: False
+flag old-directory
+ description: Use directory < 1.2 and old-time
+ default: False
+
+flag parsec
+ description: Use parsec parser
+ default: False
+ manual: True
+
+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,
@@ -219,12 +81,18 @@ library
bytestring >= 0.9 && < 1,
containers >= 0.4 && < 0.6,
deepseq >= 1.3 && < 1.5,
- directory >= 1.1 && < 1.3,
filepath >= 1.3 && < 1.5,
pretty >= 1.1 && < 1.2,
process >= 1.1.0.1 && < 1.5,
time >= 1.4 && < 1.7
+ 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.3,
+ process >= 1.1.0.2 && < 1.5
+
if flag(bundled-binary-generic)
build-depends: binary >= 0.5 && < 0.7
else
@@ -248,18 +116,34 @@ library
-Wnoncanonical-monadfail-instances
exposed-modules:
+ Distribution.Backpack
+ Distribution.Backpack.Configure
+ Distribution.Backpack.ComponentsGraph
+ Distribution.Backpack.ConfiguredComponent
+ Distribution.Backpack.FullUnitId
+ Distribution.Backpack.LinkedComponent
+ Distribution.Backpack.ModSubst
+ Distribution.Backpack.ModuleShape
+ Distribution.Utils.LogProgress
+ Distribution.Utils.MapAccum
Distribution.Compat.CreatePipe
Distribution.Compat.Environment
Distribution.Compat.Exception
+ Distribution.Compat.Graph
Distribution.Compat.Internal.TempFile
+ Distribution.Compat.Prelude.Internal
Distribution.Compat.ReadP
Distribution.Compat.Semigroup
+ Distribution.Compat.Stack
+ Distribution.Compat.Time
+ Distribution.Compat.DList
Distribution.Compiler
Distribution.InstalledPackageInfo
Distribution.License
Distribution.Make
Distribution.ModuleName
Distribution.Package
+ Distribution.Package.TextClass
Distribution.PackageDescription
Distribution.PackageDescription.Check
Distribution.PackageDescription.Configuration
@@ -267,6 +151,7 @@ library
Distribution.PackageDescription.PrettyPrint
Distribution.PackageDescription.Utils
Distribution.ParseUtils
+ Distribution.PrettyUtils
Distribution.ReadE
Distribution.Simple
Distribution.Simple.Bench
@@ -319,17 +204,81 @@ library
Distribution.System
Distribution.TestSuite
Distribution.Text
+ Distribution.Types.Benchmark
+ Distribution.Types.BenchmarkInterface
+ Distribution.Types.BenchmarkType
+ Distribution.Types.BuildInfo
+ Distribution.Types.BuildType
+ Distribution.Types.Executable
+ Distribution.Types.Library
+ Distribution.Types.ForeignLib
+ Distribution.Types.ForeignLibType
+ Distribution.Types.ForeignLibOption
+ Distribution.Types.ModuleReexport
+ Distribution.Types.ModuleRenaming
+ Distribution.Types.IncludeRenaming
+ Distribution.Types.Mixin
+ Distribution.Types.SetupBuildInfo
+ Distribution.Types.TestSuite
+ Distribution.Types.TestSuiteInterface
+ Distribution.Types.TestType
+ Distribution.Types.ComponentName
+ Distribution.Types.GenericPackageDescription
+ Distribution.Types.HookedBuildInfo
+ Distribution.Types.PackageDescription
+ Distribution.Types.SourceRepo
+ Distribution.Types.Component
+ Distribution.Types.ComponentLocalBuildInfo
+ Distribution.Types.LocalBuildInfo
+ Distribution.Types.ComponentRequestedSpec
+ Distribution.Types.TargetInfo
Distribution.Utils.NubList
+ Distribution.Utils.ShortText
+ Distribution.Utils.Progress
+ Distribution.Utils.BinaryWithFingerprint
Distribution.Verbosity
Distribution.Version
Language.Haskell.Extension
Distribution.Compat.Binary
+ if flag(parsec)
+ cpp-options: -DCABAL_PARSEC
+ build-depends:
+ transformers,
+ parsec >= 3.1.9 && <3.2
+ build-tools:
+ alex >=3.1.4 && <3.3
+ exposed-modules:
+ Distribution.Compat.Parsec
+ Distribution.PackageDescription.Parsec
+ Distribution.PackageDescription.Parsec.FieldDescr
+ Distribution.Parsec.Class
+ Distribution.Parsec.ConfVar
+ Distribution.Parsec.Lexer
+ Distribution.Parsec.LexerMonad
+ Distribution.Parsec.Parser
+ Distribution.Parsec.Types.Common
+ Distribution.Parsec.Types.Field
+ Distribution.Parsec.Types.FieldDescr
+ Distribution.Parsec.Types.ParseResult
+
other-modules:
+ Distribution.Backpack.PreExistingComponent
+ Distribution.Backpack.ReadyComponent
+ Distribution.Backpack.MixLink
+ Distribution.Backpack.ModuleScope
+ Distribution.Backpack.UnifyM
+ Distribution.Backpack.Id
+ Distribution.Utils.UnionFind
+ Distribution.Utils.Base62
Distribution.Compat.CopyFile
+ Distribution.Compat.GetShortPathName
Distribution.Compat.MonadFail
+ Distribution.Compat.Prelude
+ Distribution.Compat.SnocList
Distribution.GetOpt
Distribution.Lex
+ Distribution.Utils.String
Distribution.Simple.GHC.Internal
Distribution.Simple.GHC.IPI642
Distribution.Simple.GHC.IPIConvert
@@ -341,10 +290,36 @@ library
Distribution.Compat.Binary.Class
Distribution.Compat.Binary.Generic
- default-language: Haskell98
- -- starting with GHC 7.0, rely on {-# LANGUAGE CPP #-} instead
- if !impl(ghc >= 7.0)
- default-extensions: CPP
+ default-language: Haskell2010
+ other-extensions:
+ BangPatterns
+ CPP
+ DefaultSignatures
+ DeriveDataTypeable
+ DeriveFoldable
+ DeriveFunctor
+ DeriveGeneric
+ DeriveTraversable
+ ExistentialQuantification
+ FlexibleContexts
+ FlexibleInstances
+ GeneralizedNewtypeDeriving
+ ImplicitParams
+ KindSignatures
+ NondecreasingIndentation
+ OverloadedStrings
+ RankNTypes
+ RecordWildCards
+ ScopedTypeVariables
+ StandaloneDeriving
+ Trustworthy
+ TypeFamilies
+ TypeOperators
+ TypeSynonymInstances
+ UndecidableInstances
+
+ if impl(ghc >= 7.11)
+ other-extensions: PatternSynonyms
-- Small, fast running tests.
test-suite unit-tests
@@ -355,51 +330,77 @@ test-suite unit-tests
Test.QuickCheck.Utils
UnitTests.Distribution.Compat.CreatePipe
UnitTests.Distribution.Compat.ReadP
+ UnitTests.Distribution.Compat.Time
+ UnitTests.Distribution.Compat.Graph
UnitTests.Distribution.Simple.Program.Internal
UnitTests.Distribution.Simple.Utils
UnitTests.Distribution.System
UnitTests.Distribution.Utils.NubList
+ UnitTests.Distribution.Utils.ShortText
UnitTests.Distribution.Version
main-is: UnitTests.hs
build-depends:
+ array,
base,
+ containers,
directory,
+ filepath,
tasty,
tasty-hunit,
tasty-quickcheck,
+ tagged,
pretty,
- QuickCheck >= 2.7 && < 2.9,
+ QuickCheck >= 2.7 && < 2.10,
Cabal
ghc-options: -Wall
- default-language: Haskell98
+ default-language: Haskell2010
+
+test-suite parser-tests
+ if !flag(parsec)
+ buildable: False
--- Large, system tests that build packages.
-test-suite package-tests
type: exitcode-stdio-1.0
- main-is: PackageTests.hs
- other-modules:
- PackageTests.BenchmarkStanza.Check
- PackageTests.TestStanza.Check
- PackageTests.DeterministicAr.Check
- PackageTests.TestSuiteTests.ExeV10.Check
- PackageTests.PackageTester
hs-source-dirs: tests
+ main-is: ParserTests.hs
build-depends:
base,
- containers,
- tagged,
+ bytestring,
+ filepath,
tasty,
tasty-hunit,
- transformers,
- Cabal,
- process,
+ tasty-quickcheck,
+ Cabal
+ ghc-options: -Wall
+ default-language: Haskell2010
+
+test-suite parser-hackage-tests
+ if !flag(parsec)
+ buildable: False
+
+ type: exitcode-stdio-1.0
+ main-is: ParserHackageTests.hs
+
+ hs-source-dirs: tests
+ build-depends:
+ base,
+ containers,
+ tar >=0.5 && <0.6,
+ bytestring,
directory,
filepath,
- bytestring,
- regex-posix,
- old-time
- if !os(windows)
- build-depends: unix
+ Cabal
+
+ if flag(parsec-struct-diff)
+ build-depends:
+ generics-sop ==0.2.*,
+ these >=0.7.1 && <0.8,
+ singleton-bool >=0.1.1.0 && <0.2,
+ keys
+ other-modules:
+ DiffInstances
+ StructDiff
+ cpp-options: -DHAS_STRUCT_DIFF
+
ghc-options: -Wall -rtsopts
default-extensions: CPP
- default-language: Haskell98
+ default-language: Haskell2010
diff --git a/cabal/Cabal/Distribution/Backpack.hs b/cabal/Cabal/Distribution/Backpack.hs
new file mode 100644
index 0000000..aadb48f
--- /dev/null
+++ b/cabal/Cabal/Distribution/Backpack.hs
@@ -0,0 +1,244 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE PatternGuards #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+-- | This module defines the core data types for Backpack. For more
+-- details, see:
+--
+-- <https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst>
+
+module Distribution.Backpack (
+ -- * OpenUnitId
+ OpenUnitId(..),
+ openUnitIdFreeHoles,
+ mkOpenUnitId,
+
+ -- * DefUnitId
+ DefUnitId,
+ unDefUnitId,
+ mkDefUnitId,
+
+ -- * OpenModule
+ OpenModule(..),
+ openModuleFreeHoles,
+
+ -- * OpenModuleSubst
+ OpenModuleSubst,
+ dispOpenModuleSubst,
+ dispOpenModuleSubstEntry,
+ parseOpenModuleSubst,
+ parseOpenModuleSubstEntry,
+ openModuleSubstFreeHoles,
+
+ -- * Conversions to 'UnitId'
+ abstractUnitId,
+ 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.ModuleName
+import Distribution.Package
+import Distribution.Text
+import Distribution.Utils.Base62
+
+import qualified Data.Map as Map
+import Data.Set (Set)
+import qualified Data.Set as Set
+
+-----------------------------------------------------------------------
+-- OpenUnitId
+
+-- | An 'OpenUnitId' describes a (possibly partially) instantiated
+-- Backpack component, with a description of how the holes are filled
+-- in. Unlike 'OpenUnitId', the 'ModuleSubst' is kept in a structured
+-- form that allows for substitution (which fills in holes.) This form
+-- of unit cannot be installed. It must first be converted to a
+-- 'UnitId'.
+--
+-- In the absence of Backpack, there are no holes to fill, so any such
+-- component always has an empty module substitution; thus we can lossly
+-- represent it as an 'OpenUnitId uid'.
+--
+-- For a source component using Backpack, however, there is more
+-- structure as components may be parametrized over some signatures, and
+-- these \"holes\" may be partially or wholly filled.
+--
+-- OpenUnitId plays an important role when we are mix-in linking,
+-- and is recorded to the installed packaged database for indefinite
+-- packages; however, for compiled packages that are fully instantiated,
+-- we instantiate 'OpenUnitId' into 'UnitId'.
+--
+-- For more details see the Backpack spec
+-- <https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst>
+--
+
+data OpenUnitId
+ -- | Identifies a component which may have some unfilled holes;
+ -- specifying its 'ComponentId' and its 'OpenModuleSubst'.
+ -- TODO: Invariant that 'OpenModuleSubst' is non-empty?
+ -- See also the Text instance.
+ = IndefFullUnitId ComponentId OpenModuleSubst
+ -- | Identifies a fully instantiated component, which has
+ -- been compiled and abbreviated as a hash. The embedded 'UnitId'
+ -- MUST NOT be for an indefinite component; an 'OpenUnitId'
+ -- is guaranteed not to have any holes.
+ | DefiniteUnitId DefUnitId
+ deriving (Generic, Read, Show, Eq, Ord, Typeable, Data)
+-- TODO: cache holes?
+
+instance Binary OpenUnitId
+
+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)
+ -- 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
+ parse = parseOpenUnitId <++ fmap DefiniteUnitId parse
+ where
+ parseOpenUnitId = do
+ cid <- parse
+ insts <- Parse.between (Parse.char '[') (Parse.char ']')
+ parseOpenModuleSubst
+ return (IndefFullUnitId cid insts)
+
+-- | Get the set of holes ('ModuleVar') embedded in a 'UnitId'.
+openUnitIdFreeHoles :: OpenUnitId -> Set ModuleName
+openUnitIdFreeHoles (IndefFullUnitId _ insts) = openModuleSubstFreeHoles insts
+openUnitIdFreeHoles _ = Set.empty
+
+-- | Safe constructor from a UnitId. The only way to do this safely
+-- is if the instantiation is provided.
+mkOpenUnitId :: UnitId -> ComponentId -> OpenModuleSubst -> OpenUnitId
+mkOpenUnitId uid cid insts =
+ if Set.null (openModuleSubstFreeHoles insts)
+ then DefiniteUnitId (unsafeMkDefUnitId uid) -- invariant holds!
+ else IndefFullUnitId cid insts
+
+-----------------------------------------------------------------------
+-- DefUnitId
+
+-- | Create a 'DefUnitId' from a 'ComponentId' and an instantiation
+-- with no holes.
+mkDefUnitId :: ComponentId -> Map ModuleName Module -> DefUnitId
+mkDefUnitId cid insts =
+ unsafeMkDefUnitId (mkUnitId
+ (unComponentId cid ++ maybe "" ("+"++) (hashModuleSubst insts)))
+ -- impose invariant!
+
+-----------------------------------------------------------------------
+-- OpenModule
+
+-- | Unlike a 'Module', an 'OpenModule' is either an ordinary
+-- module from some unit, OR an 'OpenModuleVar', representing a
+-- hole that needs to be filled in. Substitutions are over
+-- module variables.
+data OpenModule
+ = OpenModule OpenUnitId ModuleName
+ | OpenModuleVar ModuleName
+ deriving (Generic, Read, Show, Eq, Ord, Typeable, Data)
+
+instance Binary OpenModule
+
+instance NFData OpenModule where
+ rnf (OpenModule uid mod_name) = rnf uid `seq` rnf mod_name
+ rnf (OpenModuleVar mod_name) = rnf 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
+ uid <- parse
+ _ <- Parse.char ':'
+ mod_name <- parse
+ return (OpenModule uid mod_name)
+ parseModuleVar = do
+ _ <- Parse.char '<'
+ mod_name <- parse
+ _ <- Parse.char '>'
+ return (OpenModuleVar mod_name)
+
+-- | Get the set of holes ('ModuleVar') embedded in a 'Module'.
+openModuleFreeHoles :: OpenModule -> Set ModuleName
+openModuleFreeHoles (OpenModuleVar mod_name) = Set.singleton mod_name
+openModuleFreeHoles (OpenModule uid _n) = openUnitIdFreeHoles uid
+
+-----------------------------------------------------------------------
+-- OpenModuleSubst
+
+-- | An explicit substitution on modules.
+--
+-- NB: These substitutions are NOT idempotent, for example, a
+-- valid substitution is (A -> B, B -> A).
+type OpenModuleSubst = Map ModuleName OpenModule
+
+-- | Pretty-print the entries of a module substitution, suitable
+-- for embedding into a 'OpenUnitId' or passing to GHC via @--instantiate-with@.
+dispOpenModuleSubst :: OpenModuleSubst -> Disp.Doc
+dispOpenModuleSubst subst
+ = Disp.hcat
+ . Disp.punctuate Disp.comma
+ $ map dispOpenModuleSubstEntry (Map.toAscList subst)
+
+-- | Pretty-print a single entry of a module substitution.
+dispOpenModuleSubstEntry :: (ModuleName, OpenModule) -> Disp.Doc
+dispOpenModuleSubstEntry (k, v) = disp k <<>> Disp.char '=' <<>> disp v
+
+-- | Inverse to 'dispModSubst'.
+parseOpenModuleSubst :: ReadP r OpenModuleSubst
+parseOpenModuleSubst = fmap Map.fromList
+ . flip Parse.sepBy (Parse.char ',')
+ $ parseOpenModuleSubstEntry
+
+-- | Inverse to 'dispModSubstEntry'.
+parseOpenModuleSubstEntry :: ReadP r (ModuleName, OpenModule)
+parseOpenModuleSubstEntry =
+ do k <- parse
+ _ <- Parse.char '='
+ v <- parse
+ 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
+openModuleSubstFreeHoles insts = Set.unions (map openModuleFreeHoles (Map.elems insts))
+
+-----------------------------------------------------------------------
+-- Conversions to UnitId
+
+-- | When typechecking, we don't demand that a freshly instantiated
+-- 'IndefFullUnitId' be compiled; instead, we just depend on the
+-- installed indefinite unit installed at the 'ComponentId'.
+abstractUnitId :: OpenUnitId -> UnitId
+abstractUnitId (DefiniteUnitId def_uid) = unDefUnitId def_uid
+abstractUnitId (IndefFullUnitId cid _) = newSimpleUnitId cid
+
+-- | Take a module substitution and hash it into a string suitable for
+-- 'UnitId'. Note that since this takes 'Module', not 'OpenModule',
+-- you are responsible for recursively converting 'OpenModule'
+-- into 'Module'. See also "Distribution.Backpack.ReadyComponent".
+hashModuleSubst :: Map ModuleName Module -> Maybe String
+hashModuleSubst subst
+ | Map.null subst = Nothing
+ | otherwise =
+ Just . hashToBase62 $
+ concat [ display mod_name ++ "=" ++ display m ++ "\n"
+ | (mod_name, m) <- Map.toList subst]
diff --git a/cabal/Cabal/Distribution/Backpack/ComponentsGraph.hs b/cabal/Cabal/Distribution/Backpack/ComponentsGraph.hs
new file mode 100644
index 0000000..1489fcc
--- /dev/null
+++ b/cabal/Cabal/Distribution/Backpack/ComponentsGraph.hs
@@ -0,0 +1,77 @@
+-- | See <https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst>
+
+module Distribution.Backpack.ComponentsGraph (
+ ComponentsGraph,
+ dispComponentsGraph,
+ toComponentsGraph,
+ componentCycleMsg
+) where
+
+import Distribution.Package
+import Distribution.PackageDescription as PD hiding (Flag)
+import Distribution.Simple.LocalBuildInfo
+import Distribution.Types.ComponentRequestedSpec
+import Distribution.Simple.Utils
+import Distribution.Compat.Graph (Node(..))
+import qualified Distribution.Compat.Graph as Graph
+
+import Distribution.Text
+ ( Text(disp) )
+import Text.PrettyPrint
+
+------------------------------------------------------------------------------
+-- Components graph
+------------------------------------------------------------------------------
+
+-- | A components graph is a source level graph tracking the
+-- dependencies between components in a package.
+type ComponentsGraph = [(Component, [ComponentName])]
+
+-- | Pretty-print a 'ComponentsGraph'.
+dispComponentsGraph :: ComponentsGraph -> Doc
+dispComponentsGraph graph =
+ vcat [ hang (text "component" <+> disp (componentName c)) 4
+ (vcat [ text "dependency" <+> disp cdep | cdep <- cdeps ])
+ | (c, cdeps) <- graph ]
+
+-- | Given the package description and a 'PackageDescription' (used
+-- to determine if a package name is internal or not), create a graph of
+-- dependencies between the components. This is NOT necessarily the
+-- build order (although it is in the absence of Backpack.)
+toComponentsGraph :: ComponentRequestedSpec
+ -> PackageDescription
+ -> Either [ComponentName] ComponentsGraph
+toComponentsGraph enabled pkg_descr =
+ let g = Graph.fromList [ N c (componentName c) (componentDeps c)
+ | c <- pkgBuildableComponents pkg_descr
+ , componentEnabled enabled c ]
+ in case Graph.cycles g of
+ [] -> Right (map (\(N c _ cs) -> (c, cs)) (Graph.revTopSort g))
+ ccycles -> Left [ componentName c | N c _ _ <- concat ccycles ]
+ where
+ -- The dependencies for the given component
+ componentDeps component =
+ [ CExeName toolname
+ | LegacyExeDependency name _ <- buildTools bi
+ , let toolname = mkUnqualComponentName name
+ , toolname `elem` map exeName (executables pkg_descr) ]
+
+ ++ [ if pkgname == packageName pkg_descr
+ then CLibName
+ else CSubLibName toolname
+ | Dependency pkgname _ <- targetBuildDepends bi
+ , let toolname = packageNameToUnqualComponentName pkgname
+ , toolname `elem` internalPkgDeps ]
+ where
+ bi = componentBuildInfo component
+ internalPkgDeps = map (conv . libName) (allLibraries pkg_descr)
+ conv Nothing = packageNameToUnqualComponentName $ packageName pkg_descr
+ conv (Just s) = s
+
+-- | Error message when there is a cycle; takes the SCC of components.
+componentCycleMsg :: [ComponentName] -> Doc
+componentCycleMsg cnames =
+ text $ "Components in the package depend on each other in a cyclic way:\n "
+ ++ intercalate " depends on "
+ [ "'" ++ showComponentName cname ++ "'"
+ | cname <- cnames ++ [head cnames] ]
diff --git a/cabal/Cabal/Distribution/Backpack/Configure.hs b/cabal/Cabal/Distribution/Backpack/Configure.hs
new file mode 100644
index 0000000..71da11e
--- /dev/null
+++ b/cabal/Cabal/Distribution/Backpack/Configure.hs
@@ -0,0 +1,346 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE PatternGuards #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE NoMonoLocalBinds #-}
+{-# LANGUAGE NondecreasingIndentation #-}
+
+-- | See <https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst>
+--
+-- WARNING: The contents of this module are HIGHLY experimental.
+-- We may refactor it under you.
+module Distribution.Backpack.Configure (
+ configureComponentLocalBuildInfos,
+) where
+
+import Prelude ()
+import Distribution.Compat.Prelude hiding ((<>))
+
+import Distribution.Backpack
+import Distribution.Backpack.FullUnitId
+import Distribution.Backpack.PreExistingComponent
+import Distribution.Backpack.ConfiguredComponent
+import Distribution.Backpack.LinkedComponent
+import Distribution.Backpack.ReadyComponent
+import Distribution.Backpack.ComponentsGraph
+
+import Distribution.Simple.Compiler hiding (Flag)
+import Distribution.Package
+import qualified Distribution.InstalledPackageInfo as Installed
+import Distribution.InstalledPackageInfo (InstalledPackageInfo
+ ,emptyInstalledPackageInfo)
+import qualified Distribution.Simple.PackageIndex as PackageIndex
+import Distribution.Simple.PackageIndex (InstalledPackageIndex)
+import Distribution.PackageDescription as PD hiding (Flag)
+import Distribution.ModuleName
+import Distribution.Simple.Setup as Setup
+import Distribution.Simple.LocalBuildInfo
+import Distribution.Types.ComponentRequestedSpec
+import Distribution.Verbosity
+import qualified Distribution.Compat.Graph as Graph
+import Distribution.Compat.Graph (Graph, IsNode(..))
+import Distribution.Utils.Progress
+import Distribution.Utils.LogProgress
+
+import Data.Either
+ ( lefts )
+import qualified Data.Set as Set
+import qualified Data.Map as Map
+import Distribution.Text
+ ( display )
+import Text.PrettyPrint
+
+------------------------------------------------------------------------------
+-- Pipeline
+------------------------------------------------------------------------------
+
+configureComponentLocalBuildInfos
+ :: Verbosity
+ -> Bool -- use_external_internal_deps
+ -> ComponentRequestedSpec
+ -> Flag String -- configIPID
+ -> Flag ComponentId -- configCID
+ -> PackageDescription
+ -> [PreExistingComponent]
+ -> FlagAssignment -- configConfigurationsFlags
+ -> [(ModuleName, Module)] -- configInstantiateWith
+ -> InstalledPackageIndex
+ -> Compiler
+ -> LogProgress ([ComponentLocalBuildInfo], InstalledPackageIndex)
+configureComponentLocalBuildInfos
+ verbosity use_external_internal_deps enabled ipid_flag cid_flag pkg_descr
+ prePkgDeps flagAssignment instantiate_with installedPackageSet comp = do
+ -- NB: In single component mode, this returns a *single* component.
+ -- In this graph, the graph is NOT closed.
+ graph0 <- case toComponentsGraph enabled pkg_descr of
+ Left ccycle -> failProgress (componentCycleMsg ccycle)
+ Right comps -> return comps
+ infoProgress $ hang (text "Source component graph:") 4
+ (dispComponentsGraph graph0)
+
+ let conf_pkg_map = Map.fromList
+ [(pc_pkgname pkg, (pc_cid pkg, pc_pkgid pkg))
+ | pkg <- prePkgDeps]
+ graph1 = toConfiguredComponents use_external_internal_deps
+ flagAssignment
+ ipid_flag cid_flag pkg_descr
+ conf_pkg_map (map fst graph0)
+ infoProgress $ hang (text "Configured component graph:") 4
+ (vcat (map dispConfiguredComponent graph1))
+
+ let shape_pkg_map = Map.fromList
+ [ (pc_cid pkg, (pc_open_uid pkg, pc_shape pkg))
+ | pkg <- prePkgDeps]
+ uid_lookup def_uid
+ | Just pkg <- PackageIndex.lookupUnitId installedPackageSet uid
+ = FullUnitId (Installed.installedComponentId pkg)
+ (Map.fromList (Installed.instantiatedWith pkg))
+ | otherwise = error ("uid_lookup: " ++ display uid)
+ where uid = unDefUnitId def_uid
+ graph2 <- toLinkedComponents verbosity uid_lookup
+ (package pkg_descr) shape_pkg_map graph1
+
+ infoProgress $
+ hang (text "Linked component graph:") 4
+ (vcat (map dispLinkedComponent graph2))
+
+ let pid_map = Map.fromList $
+ [ (pc_uid pkg, pc_pkgid pkg)
+ | pkg <- prePkgDeps] ++
+ [ (Installed.installedUnitId pkg, Installed.sourcePackageId pkg)
+ | (_, Module uid _) <- instantiate_with
+ , Just pkg <- [PackageIndex.lookupUnitId
+ installedPackageSet (unDefUnitId uid)] ]
+ subst = Map.fromList instantiate_with
+ graph3 = toReadyComponents pid_map subst graph2
+ graph4 = Graph.revTopSort (Graph.fromList graph3)
+
+ infoProgress $ hang (text "Ready component graph:") 4
+ (vcat (map dispReadyComponent graph4))
+
+ toComponentLocalBuildInfos comp installedPackageSet pkg_descr prePkgDeps graph4
+
+------------------------------------------------------------------------------
+-- ComponentLocalBuildInfo
+------------------------------------------------------------------------------
+
+toComponentLocalBuildInfos
+ :: Compiler
+ -> InstalledPackageIndex -- FULL set
+ -> PackageDescription
+ -> [PreExistingComponent] -- external package deps
+ -> [ReadyComponent]
+ -> LogProgress ([ComponentLocalBuildInfo],
+ InstalledPackageIndex) -- only relevant packages
+toComponentLocalBuildInfos
+ comp installedPackageSet pkg_descr externalPkgDeps graph = do
+ -- Check and make sure that every instantiated component exists.
+ -- We have to do this now, because prior to linking/instantiating
+ -- we don't actually know what the full set of 'UnitId's we need
+ -- are.
+ let -- TODO: This is actually a bit questionable performance-wise,
+ -- since we will pay for the ALL installed packages even if
+ -- they are not related to what we are building. This was true
+ -- in the old configure code.
+ external_graph :: Graph (Either InstalledPackageInfo ReadyComponent)
+ external_graph = Graph.fromList
+ . map Left
+ $ PackageIndex.allPackages installedPackageSet
+ internal_graph :: Graph (Either InstalledPackageInfo ReadyComponent)
+ internal_graph = Graph.fromList
+ . map Right
+ $ graph
+ combined_graph = Graph.unionRight external_graph internal_graph
+ Just local_graph = Graph.closure combined_graph (map nodeKey graph)
+ -- The database of transitively reachable installed packages that the
+ -- external components the package (as a whole) depends on. This will be
+ -- used in several ways:
+ --
+ -- * We'll use it to do a consistency check so we're not depending
+ -- on multiple versions of the same package (TODO: someday relax
+ -- this for private dependencies.) See right below.
+ --
+ -- * We'll pass it on in the LocalBuildInfo, where preprocessors
+ -- and other things will incorrectly use it to determine what
+ -- the include paths and everything should be.
+ --
+ packageDependsIndex = PackageIndex.fromList (lefts local_graph)
+ fullIndex = Graph.fromList local_graph
+ case Graph.broken fullIndex of
+ [] -> return ()
+ broken ->
+ -- TODO: ppr this
+ failProgress . text $
+ "The following packages are broken because other"
+ ++ " packages they depend on are missing. These broken "
+ ++ "packages must be rebuilt before they can be used.\n"
+ -- TODO: Undupe.
+ ++ unlines [ "installed package "
+ ++ display (packageId pkg)
+ ++ " is broken due to missing package "
+ ++ intercalate ", " (map display deps)
+ | (Left pkg, deps) <- broken ]
+ ++ unlines [ "planned package "
+ ++ display (packageId pkg)
+ ++ " is broken due to missing package "
+ ++ intercalate ", " (map display deps)
+ | (Right pkg, deps) <- broken ]
+
+ -- In this section, we'd like to look at the 'packageDependsIndex'
+ -- and see if we've picked multiple versions of the same
+ -- installed package (this is bad, because it means you might
+ -- get an error could not match foo-0.1:Type with foo-0.2:Type).
+ --
+ -- What is pseudoTopPkg for? I have no idea. It was used
+ -- in the very original commit which introduced checking for
+ -- inconsistencies 5115bb2be4e13841ea07dc9166b9d9afa5f0d012,
+ -- and then moved out of PackageIndex and put here later.
+ -- TODO: Try this code without it...
+ --
+ -- TODO: Move this into a helper function
+ --
+ -- TODO: This is probably wrong for Backpack
+ let pseudoTopPkg :: InstalledPackageInfo
+ pseudoTopPkg = emptyInstalledPackageInfo {
+ Installed.installedUnitId =
+ mkLegacyUnitId (packageId pkg_descr),
+ Installed.sourcePackageId = packageId pkg_descr,
+ Installed.depends =
+ map pc_uid externalPkgDeps
+ }
+ case PackageIndex.dependencyInconsistencies
+ . PackageIndex.insert pseudoTopPkg
+ $ packageDependsIndex of
+ [] -> return ()
+ inconsistencies ->
+ warnProgress . text $
+ "This package indirectly depends on multiple versions of the same "
+ ++ "package. This is highly likely to cause a compile failure.\n"
+ ++ unlines [ "package " ++ display pkg ++ " requires "
+ ++ display (PackageIdentifier name ver)
+ | (name, uses) <- inconsistencies
+ , (pkg, ver) <- uses ]
+ let clbis = mkLinkedComponentsLocalBuildInfo comp graph
+ -- forM clbis $ \(clbi,deps) -> info verbosity $ "UNIT" ++ hashUnitId (componentUnitId clbi) ++ "\n" ++ intercalate "\n" (map hashUnitId deps)
+ return (clbis, packageDependsIndex)
+
+-- Build ComponentLocalBuildInfo for each component we are going
+-- to build.
+--
+-- This conversion is lossy; we lose some invariants from ReadyComponent
+mkLinkedComponentsLocalBuildInfo
+ :: Compiler
+ -> [ReadyComponent]
+ -> [ComponentLocalBuildInfo]
+mkLinkedComponentsLocalBuildInfo comp rcs = map go rcs
+ where
+ internalUnits = Set.fromList (map rc_uid rcs)
+ isInternal x = Set.member x internalUnits
+ go rc =
+ case rc_component rc of
+ CLib _ ->
+ let convModuleExport (modname', (Module uid modname))
+ | this_uid == unDefUnitId uid
+ , modname' == modname
+ = Installed.ExposedModule modname' Nothing
+ | otherwise
+ = Installed.ExposedModule modname'
+ (Just (OpenModule (DefiniteUnitId uid) modname))
+ convOpenModuleExport (modname', modu@(OpenModule uid modname))
+ | uid == this_open_uid
+ , modname' == modname
+ = Installed.ExposedModule modname' Nothing
+ | otherwise
+ = Installed.ExposedModule modname' (Just modu)
+ convOpenModuleExport (_, OpenModuleVar _)
+ = error "convOpenModuleExport: top-level modvar"
+ exports =
+ -- Loses invariants
+ case rc_i rc of
+ Left indefc -> map convOpenModuleExport
+ $ Map.toList (indefc_provides indefc)
+ Right instc -> map convModuleExport
+ $ Map.toList (instc_provides instc)
+ insts =
+ case rc_i rc of
+ Left indefc -> [ (m, OpenModuleVar m) | m <- indefc_requires indefc ]
+ Right instc -> [ (m, OpenModule (DefiniteUnitId uid') m')
+ | (m, Module uid' m') <- instc_insts instc ]
+ in LibComponentLocalBuildInfo {
+ componentPackageDeps = cpds,
+ componentUnitId = this_uid,
+ componentComponentId = this_cid,
+ componentInstantiatedWith = insts,
+ componentIsIndefinite_ = is_indefinite,
+ componentLocalName = cname,
+ componentInternalDeps = internal_deps,
+ componentExeDeps = map unDefUnitId (rc_internal_build_tools rc),
+ componentIncludes = includes,
+ componentExposedModules = exports,
+ componentIsPublic = rc_public rc,
+ componentCompatPackageKey = rc_compat_key rc comp,
+ componentCompatPackageName = rc_compat_name rc
+ }
+ CFLib _ ->
+ FLibComponentLocalBuildInfo {
+ componentUnitId = this_uid,
+ componentComponentId = this_cid,
+ componentLocalName = cname,
+ componentPackageDeps = cpds,
+ componentExeDeps = map unDefUnitId $ rc_internal_build_tools rc,
+ componentInternalDeps = internal_deps,
+ componentIncludes = includes
+ }
+ CExe _ ->
+ ExeComponentLocalBuildInfo {
+ componentUnitId = this_uid,
+ componentComponentId = this_cid,
+ componentLocalName = cname,
+ componentPackageDeps = cpds,
+ componentExeDeps = map unDefUnitId $ rc_internal_build_tools rc,
+ componentInternalDeps = internal_deps,
+ componentIncludes = includes
+ }
+ CTest _ ->
+ TestComponentLocalBuildInfo {
+ componentUnitId = this_uid,
+ componentComponentId = this_cid,
+ componentLocalName = cname,
+ componentPackageDeps = cpds,
+ componentExeDeps = map unDefUnitId $ rc_internal_build_tools rc,
+ componentInternalDeps = internal_deps,
+ componentIncludes = includes
+ }
+ CBench _ ->
+ BenchComponentLocalBuildInfo {
+ componentUnitId = this_uid,
+ componentComponentId = this_cid,
+ componentLocalName = cname,
+ componentPackageDeps = cpds,
+ componentExeDeps = map unDefUnitId $ rc_internal_build_tools rc,
+ componentInternalDeps = internal_deps,
+ componentIncludes = includes
+ }
+ where
+ this_uid = rc_uid rc
+ this_open_uid = rc_open_uid rc
+ this_cid = rc_cid rc
+ cname = componentName (rc_component rc)
+ cpds = rc_depends rc
+ is_indefinite =
+ case rc_i rc of
+ Left _ -> True
+ Right _ -> False
+ includes =
+ case rc_i rc of
+ Left indefc ->
+ indefc_includes indefc
+ Right instc ->
+ map (\(x,y) -> (DefiniteUnitId x,y)) (instc_includes instc)
+ internal_deps =
+ filter isInternal (nodeNeighbors rc)
+ ++ map unDefUnitId (rc_internal_build_tools rc)
+
+
diff --git a/cabal/Cabal/Distribution/Backpack/ConfiguredComponent.hs b/cabal/Cabal/Distribution/Backpack/ConfiguredComponent.hs
new file mode 100644
index 0000000..1ae9b44
--- /dev/null
+++ b/cabal/Cabal/Distribution/Backpack/ConfiguredComponent.hs
@@ -0,0 +1,229 @@
+{-# LANGUAGE PatternGuards #-}
+-- | See <https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst>
+module Distribution.Backpack.ConfiguredComponent (
+ ConfiguredComponent(..),
+ toConfiguredComponent,
+ toConfiguredComponents,
+ dispConfiguredComponent,
+
+ ConfiguredComponentMap,
+ extendConfiguredComponentMap,
+
+ -- TODO: Should go somewhere else
+ newPackageDepsBehaviour
+) where
+
+import Prelude ()
+import Distribution.Compat.Prelude hiding ((<>))
+
+import Distribution.Backpack.Id
+
+import Distribution.Types.IncludeRenaming
+import Distribution.Types.Mixin
+import Distribution.Package
+import Distribution.PackageDescription as PD hiding (Flag)
+import Distribution.Simple.Setup as Setup
+import Distribution.Simple.LocalBuildInfo
+import Distribution.Version
+
+import qualified Data.Set as Set
+import qualified Data.Map as Map
+import Data.Traversable
+ ( mapAccumL )
+import Distribution.Text
+import Text.PrettyPrint
+
+-- | A configured component, we know exactly what its 'ComponentId' is,
+-- and the 'ComponentId's of the things it depends on.
+data ConfiguredComponent
+ = ConfiguredComponent {
+ cc_cid :: ComponentId,
+ -- The package this component came from.
+ cc_pkgid :: PackageId,
+ cc_component :: Component,
+ cc_public :: Bool,
+ -- ^ Is this the public library component of the package?
+ -- (THIS is what the hole instantiation applies to.)
+ -- Note that in one-component configure mode, this is
+ -- always True, because any component is the "public" one.)
+ cc_internal_build_tools :: [ComponentId],
+ -- Not resolved yet; component configuration only looks at ComponentIds.
+ cc_includes :: [(ComponentId, PackageId, IncludeRenaming)]
+ }
+
+cc_name :: ConfiguredComponent -> ComponentName
+cc_name = componentName . cc_component
+
+dispConfiguredComponent :: ConfiguredComponent -> Doc
+dispConfiguredComponent cc =
+ hang (text "component" <+> disp (cc_cid cc)) 4
+ (vcat [ hsep $ [ text "include", disp cid, disp incl_rn ]
+ | (cid, _, incl_rn) <- cc_includes cc
+ ])
+
+
+-- | Construct a 'ConfiguredComponent', given that the 'ComponentId'
+-- and library/executable dependencies are known. The primary
+-- work this does is handling implicit @backpack-include@ fields.
+mkConfiguredComponent
+ :: PackageId
+ -> ComponentId
+ -> [(PackageName, (ComponentId, PackageId))]
+ -> [ComponentId]
+ -> Component
+ -> ConfiguredComponent
+mkConfiguredComponent this_pid this_cid lib_deps exe_deps component =
+ ConfiguredComponent {
+ cc_cid = this_cid,
+ cc_pkgid = this_pid,
+ cc_component = component,
+ cc_public = is_public,
+ cc_internal_build_tools = exe_deps,
+ cc_includes = explicit_includes ++ implicit_includes
+ }
+ where
+ bi = componentBuildInfo component
+ deps = map snd lib_deps
+ deps_map = Map.fromList lib_deps
+
+ -- Resolve each @backpack-include@ into the actual dependency
+ -- from @lib_deps@.
+ explicit_includes
+ = [ (cid, pid { pkgName = name }, rns)
+ | Mixin name rns <- mixins bi
+ , Just (cid, pid) <- [Map.lookup name deps_map] ]
+
+ -- Any @build-depends@ which is not explicitly mentioned in
+ -- @backpack-include@ is converted into an "implicit" include.
+ used_explicitly = Set.fromList (map (\(cid,_,_) -> cid) explicit_includes)
+ implicit_includes
+ = map (\(cid, pid) -> (cid, pid, defaultIncludeRenaming))
+ $ filter (flip Set.notMember used_explicitly . fst) deps
+
+ is_public = componentName component == CLibName
+
+type ConfiguredComponentMap =
+ (Map PackageName (ComponentId, PackageId), -- libraries
+ Map UnqualComponentName ComponentId) -- executables
+
+-- Executable map must be different because an executable can
+-- have the same name as a library. Ew.
+
+-- | Given some ambient environment of package names that
+-- are "in scope", looks at the 'BuildInfo' to decide
+-- what the packages actually resolve to, and then builds
+-- a 'ConfiguredComponent'.
+toConfiguredComponent
+ :: PackageDescription
+ -> ComponentId
+ -> Map PackageName (ComponentId, PackageId) -- external
+ -> ConfiguredComponentMap
+ -> Component
+ -> ConfiguredComponent
+toConfiguredComponent pkg_descr this_cid
+ external_lib_map (lib_map, exe_map) component =
+ mkConfiguredComponent
+ (package pkg_descr) this_cid
+ lib_deps exe_deps component
+ where
+ bi = componentBuildInfo component
+ find_it :: PackageName -> (ComponentId, PackageId)
+ find_it name =
+ fromMaybe (error ("toConfiguredComponent: " ++ display (packageName pkg_descr) ++
+ " " ++ display name)) $
+ Map.lookup name lib_map <|>
+ Map.lookup name external_lib_map
+ lib_deps
+ | newPackageDepsBehaviour pkg_descr
+ = [ (name, find_it name)
+ | Dependency name _ <- targetBuildDepends bi ]
+ | otherwise
+ = Map.toList external_lib_map
+ exe_deps = [ cid
+ | LegacyExeDependency name _ <- buildTools bi
+ , Just cid <- [ Map.lookup (mkUnqualComponentName name) exe_map ] ]
+
+-- | Also computes the 'ComponentId', and sets cc_public if necessary.
+-- This is Cabal-only; cabal-install won't use this.
+toConfiguredComponent'
+ :: Bool -- use_external_internal_deps
+ -> FlagAssignment
+ -> PackageDescription
+ -> Flag String -- configIPID (todo: remove me)
+ -> Flag ComponentId -- configCID
+ -> Map PackageName (ComponentId, PackageId) -- external
+ -> ConfiguredComponentMap
+ -> Component
+ -> ConfiguredComponent
+toConfiguredComponent' use_external_internal_deps flags
+ pkg_descr ipid_flag cid_flag
+ external_lib_map (lib_map, exe_map) component =
+ let cc = toConfiguredComponent
+ pkg_descr this_cid
+ external_lib_map (lib_map, exe_map) component
+ in if use_external_internal_deps
+ then cc { cc_public = True }
+ else cc
+ where
+ this_cid = computeComponentId ipid_flag cid_flag (package pkg_descr)
+ (componentName component) (Just (deps, flags))
+ deps = [ cid | (cid, _) <- Map.elems external_lib_map ]
+
+extendConfiguredComponentMap
+ :: ConfiguredComponent
+ -> ConfiguredComponentMap
+ -> ConfiguredComponentMap
+extendConfiguredComponentMap cc (lib_map, exe_map) =
+ (lib_map', exe_map')
+ where
+ lib_map'
+ = case cc_name cc of
+ CLibName ->
+ Map.insert (pkgName (cc_pkgid cc))
+ (cc_cid cc, cc_pkgid cc) lib_map
+ CSubLibName str ->
+ Map.insert (unqualComponentNameToPackageName str)
+ (cc_cid cc, cc_pkgid cc) lib_map
+ _ -> lib_map
+ exe_map'
+ = case cc_name cc of
+ CExeName str ->
+ Map.insert str (cc_cid cc) exe_map
+ _ -> exe_map
+
+-- Compute the 'ComponentId's for a graph of 'Component's. The
+-- 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.
+toConfiguredComponents
+ :: Bool -- use_external_internal_deps
+ -> FlagAssignment
+ -> Flag String -- configIPID
+ -> Flag ComponentId -- configCID
+ -> PackageDescription
+ -> Map PackageName (ComponentId, PackageId)
+ -> [Component]
+ -> [ConfiguredComponent]
+toConfiguredComponents
+ use_external_internal_deps flags ipid_flag cid_flag pkg_descr
+ external_lib_map comps
+ = snd (mapAccumL go (Map.empty, Map.empty) comps)
+ where
+ go m component = (extendConfiguredComponentMap cc m, cc)
+ where cc = toConfiguredComponent'
+ use_external_internal_deps flags pkg_descr ipid_flag cid_flag
+ external_lib_map m component
+
+
+newPackageDepsBehaviourMinVersion :: Version
+newPackageDepsBehaviourMinVersion = mkVersion [1,7,1]
+
+
+-- In older cabal versions, there was only one set of package dependencies for
+-- the whole package. In this version, we can have separate dependencies per
+-- target, but we only enable this behaviour if the minimum cabal version
+-- specified is >= a certain minimum. Otherwise, for compatibility we use the
+-- old behaviour.
+newPackageDepsBehaviour :: PackageDescription -> Bool
+newPackageDepsBehaviour pkg =
+ specVersion pkg >= newPackageDepsBehaviourMinVersion
diff --git a/cabal/Cabal/Distribution/Backpack/FullUnitId.hs b/cabal/Cabal/Distribution/Backpack/FullUnitId.hs
new file mode 100644
index 0000000..cb5e3bf
--- /dev/null
+++ b/cabal/Cabal/Distribution/Backpack/FullUnitId.hs
@@ -0,0 +1,26 @@
+{-# LANGUAGE DeriveGeneric #-}
+module Distribution.Backpack.FullUnitId (
+ FullUnitId(..),
+ FullDb,
+ expandOpenUnitId,
+ expandUnitId
+) where
+
+import Distribution.Backpack
+import Distribution.Package
+import Distribution.Compat.Prelude
+
+-- Unlike OpenUnitId, which could direct to a UnitId.
+data FullUnitId = FullUnitId ComponentId OpenModuleSubst
+ deriving (Show, Generic)
+
+type FullDb = DefUnitId -> FullUnitId
+
+expandOpenUnitId :: FullDb -> OpenUnitId -> FullUnitId
+expandOpenUnitId _db (IndefFullUnitId cid subst)
+ = FullUnitId cid subst
+expandOpenUnitId db (DefiniteUnitId uid)
+ = expandUnitId db uid
+
+expandUnitId :: FullDb -> DefUnitId -> FullUnitId
+expandUnitId db uid = db uid
diff --git a/cabal/Cabal/Distribution/Backpack/Id.hs b/cabal/Cabal/Distribution/Backpack/Id.hs
new file mode 100644
index 0000000..a299163
--- /dev/null
+++ b/cabal/Cabal/Distribution/Backpack/Id.hs
@@ -0,0 +1,189 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE PatternGuards #-}
+-- | See <https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst>
+module Distribution.Backpack.Id(
+ computeComponentId,
+ computeCompatPackageKey,
+ computeCompatPackageName,
+) where
+
+import Prelude ()
+import Distribution.Compat.Prelude
+
+import Distribution.Simple.Compiler hiding (Flag)
+import Distribution.Package
+import Distribution.PackageDescription as PD hiding (Flag)
+import Distribution.Simple.Setup as Setup
+import qualified Distribution.Simple.InstallDirs as InstallDirs
+import Distribution.Simple.LocalBuildInfo
+import Distribution.Utils.Base62
+import Distribution.Version
+
+import Distribution.Text
+ ( display, simpleParse )
+
+-- | This method computes a default, "good enough" 'ComponentId'
+-- for a package. The intent is that cabal-install (or the user) will
+-- specify a more detailed IPID via the @--ipid@ flag if necessary.
+computeComponentId
+ :: Flag String
+ -> Flag ComponentId
+ -> PackageIdentifier
+ -> ComponentName
+ -- This is used by cabal-install's legacy codepath
+ -> Maybe ([ComponentId], FlagAssignment)
+ -> ComponentId
+computeComponentId mb_ipid mb_cid pid cname mb_details =
+ -- show is found to be faster than intercalate and then replacement of
+ -- special character used in intercalating. We cannot simply hash by
+ -- doubly concating list, as it just flatten out the nested list, so
+ -- different sources can produce same hash
+ let hash_suffix
+ | Just (dep_ipids, flags) <- mb_details
+ = "-" ++ hashToBase62
+ -- For safety, include the package + version here
+ -- for GHC 7.10, where just the hash is used as
+ -- the package key
+ ( display pid
+ ++ show dep_ipids
+ ++ show flags )
+ | otherwise = ""
+ generated_base = display pid ++ hash_suffix
+ explicit_base cid0 = fromPathTemplate (InstallDirs.substPathTemplate env
+ (toPathTemplate cid0))
+ -- Hack to reuse install dirs machinery
+ -- NB: no real IPID available at this point
+ where env = packageTemplateEnv pid (mkUnitId "")
+ actual_base = case mb_ipid of
+ Flag ipid0 -> explicit_base ipid0
+ NoFlag -> generated_base
+ in case mb_cid of
+ Flag cid -> cid
+ NoFlag -> mkComponentId $ actual_base
+ ++ (case componentNameString cname of
+ Nothing -> ""
+ Just s -> "-" ++ unUnqualComponentName s)
+
+-- | Computes the package name for a library. If this is the public
+-- library, it will just be the original package name; otherwise,
+-- it will be a munged package name recording the original package
+-- name as well as the name of the internal library.
+--
+-- A lot of tooling in the Haskell ecosystem assumes that if something
+-- is installed to the package database with the package name 'foo',
+-- then it actually is an entry for the (only public) library in package
+-- 'foo'. With internal packages, this is not necessarily true:
+-- a public library as well as arbitrarily many internal libraries may
+-- come from the same package. To prevent tools from getting confused
+-- in this case, the package name of these internal libraries is munged
+-- so that they do not conflict the public library proper. A particular
+-- case where this matters is ghc-pkg: if we don't munge the package
+-- name, the inplace registration will OVERRIDE a different internal
+-- library.
+--
+-- We munge into a reserved namespace, "z-", and encode both the
+-- component name and the package name of an internal library using the
+-- following format:
+--
+-- compat-pkg-name ::= "z-" package-name "-z-" library-name
+--
+-- where package-name and library-name have "-" ( "z" + ) "-"
+-- segments encoded by adding an extra "z".
+--
+-- When we have the public library, the compat-pkg-name is just the
+-- package-name, no surprises there!
+--
+computeCompatPackageName :: PackageName -> ComponentName -> PackageName
+-- First handle the cases where we can just use the original 'PackageName'.
+-- This is for the PRIMARY library, and it is non-Backpack, or the
+-- indefinite package for us.
+computeCompatPackageName pkg_name CLibName = pkg_name
+computeCompatPackageName pkg_name cname
+ = mkPackageName $ "z-" ++ zdashcode (display pkg_name)
+ ++ (case componentNameString cname of
+ Just cname_u -> "-z-" ++ zdashcode cname_str
+ where cname_str = unUnqualComponentName cname_u
+ Nothing -> "")
+
+zdashcode :: String -> String
+zdashcode s = go s (Nothing :: Maybe Int) []
+ where go [] _ r = reverse r
+ go ('-':z) (Just n) r | n > 0 = go z (Just 0) ('-':'z':r)
+ go ('-':z) _ r = go z (Just 0) ('-':r)
+ go ('z':z) (Just n) r = go z (Just (n+1)) ('z':r)
+ go (c:z) _ r = go z Nothing (c:r)
+
+-- | In GHC 8.0, the string we pass to GHC to use for symbol
+-- names for a package can be an arbitrary, IPID-compatible string.
+-- However, prior to GHC 8.0 there are some restrictions on what
+-- format this string can be (due to how ghc-pkg parsed the key):
+--
+-- 1. In GHC 7.10, the string had either be of the form
+-- foo_ABCD, where foo is a non-semantic alphanumeric/hyphenated
+-- prefix and ABCD is two base-64 encoded 64-bit integers,
+-- or a GHC 7.8 style identifier.
+--
+-- 2. In GHC 7.8, the string had to be a valid package identifier
+-- like foo-0.1.
+--
+-- So, the problem is that Cabal, in general, has a general IPID,
+-- but needs to figure out a package key / package ID that the
+-- old ghc-pkg will actually accept. But there's an EVERY WORSE
+-- problem: if ghc-pkg decides to parse an identifier foo-0.1-xxx
+-- as if it were a package identifier, which means it will SILENTLY
+-- DROP the "xxx" (because it's a tag, and Cabal does not allow tags.)
+-- So we must CONNIVE to ensure that we don't pick something that
+-- looks like this.
+--
+-- So this function attempts to define a mapping into the old formats.
+--
+-- The mapping for GHC 7.8 and before:
+--
+-- * We use the *compatibility* package name and version. For
+-- public libraries this is just the package identifier; for
+-- internal libraries, it's something like "z-pkgname-z-libname-0.1".
+-- See 'computeCompatPackageName' for more details.
+--
+-- The mapping for GHC 7.10:
+--
+-- * For CLibName:
+-- If the IPID is of the form foo-0.1-ABCDEF where foo_ABCDEF would
+-- validly parse as a package key, we pass "ABCDEF". (NB: not
+-- all hashes parse this way, because GHC 7.10 mandated that
+-- these hashes be two base-62 encoded 64 bit integers),
+-- but hashes that Cabal generated using 'computeComponentId'
+-- are guaranteed to have this form.
+--
+-- If it is not of this form, we rehash the IPID into the
+-- correct form and pass that.
+--
+-- * For sub-components, we rehash the IPID into the correct format
+-- and pass that.
+--
+computeCompatPackageKey
+ :: Compiler
+ -> PackageName
+ -> Version
+ -> UnitId
+ -> String
+computeCompatPackageKey comp pkg_name pkg_version uid
+ | not (packageKeySupported comp) =
+ display pkg_name ++ "-" ++ display pkg_version
+ | not (unifiedIPIDRequired comp) =
+ let str = unUnitId uid -- assume no Backpack support
+ mb_verbatim_key
+ = case simpleParse str :: Maybe PackageId of
+ -- Something like 'foo-0.1', use it verbatim.
+ -- (NB: hash tags look like tags, so they are parsed,
+ -- so the extra equality check tests if a tag was dropped.)
+ Just pid0 | display pid0 == str -> Just str
+ _ -> Nothing
+ mb_truncated_key
+ = let cand = reverse (takeWhile isAlphaNum (reverse str))
+ in if length cand == 22 && all isAlphaNum cand
+ then Just cand
+ else Nothing
+ rehashed_key = hashToBase62 str
+ in fromMaybe rehashed_key (mb_verbatim_key `mplus` mb_truncated_key)
+ | otherwise = display uid
diff --git a/cabal/Cabal/Distribution/Backpack/LinkedComponent.hs b/cabal/Cabal/Distribution/Backpack/LinkedComponent.hs
new file mode 100644
index 0000000..c379a6b
--- /dev/null
+++ b/cabal/Cabal/Distribution/Backpack/LinkedComponent.hs
@@ -0,0 +1,307 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeFamilies #-}
+-- | See <https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst>
+module Distribution.Backpack.LinkedComponent (
+ LinkedComponent(..),
+ toLinkedComponent,
+ toLinkedComponents,
+ dispLinkedComponent,
+ LinkedComponentMap,
+ extendLinkedComponentMap,
+) where
+
+import Prelude ()
+import Distribution.Compat.Prelude hiding ((<>))
+
+import Distribution.Backpack
+import Distribution.Backpack.FullUnitId
+import Distribution.Backpack.ConfiguredComponent
+import Distribution.Backpack.ModSubst
+import Distribution.Backpack.ModuleShape
+import Distribution.Backpack.ModuleScope
+import Distribution.Backpack.UnifyM
+import Distribution.Backpack.MixLink
+import Distribution.Utils.MapAccum
+
+import Distribution.Types.ModuleRenaming
+import Distribution.Types.IncludeRenaming
+import Distribution.Package
+import Distribution.PackageDescription as PD hiding (Flag)
+import Distribution.ModuleName
+import Distribution.Simple.LocalBuildInfo
+import Distribution.Verbosity
+import Distribution.Utils.Progress
+import Distribution.Utils.LogProgress
+
+import qualified Data.Set as Set
+import qualified Data.Map as Map
+import Data.Traversable
+ ( mapM )
+import Distribution.Text
+ ( Text(disp) )
+import Text.PrettyPrint
+
+-- | A linked component, we know how it is instantiated and thus how we are
+-- going to build it.
+data LinkedComponent
+ = LinkedComponent {
+ lc_uid :: OpenUnitId,
+ lc_cid :: ComponentId,
+ lc_pkgid :: PackageId,
+ lc_insts :: [(ModuleName, OpenModule)],
+ lc_component :: Component,
+ lc_shape :: ModuleShape,
+ -- | Local buildTools dependencies
+ lc_internal_build_tools :: [OpenUnitId],
+ lc_public :: Bool,
+ lc_includes :: [(OpenUnitId, ModuleRenaming)],
+ -- PackageId here is a bit dodgy, but its just for
+ -- BC so it shouldn't matter.
+ lc_depends :: [(OpenUnitId, PackageId)]
+ }
+
+dispLinkedComponent :: LinkedComponent -> Doc
+dispLinkedComponent lc =
+ hang (text "unit" <+> disp (lc_uid lc)) 4 $
+ vcat [ text "include" <+> disp uid <+> disp prov_rn
+ | (uid, prov_rn) <- lc_includes lc ]
+ -- YARRR $+$ dispModSubst (modShapeProvides (lc_shape lc))
+
+instance Package LinkedComponent where
+ packageId = lc_pkgid
+
+instance ModSubst LinkedComponent where
+ modSubst subst lc
+ = lc {
+ lc_uid = modSubst subst (lc_uid lc),
+ lc_insts = modSubst subst (lc_insts lc),
+ lc_shape = modSubst subst (lc_shape lc),
+ lc_includes = map (\(uid, rns) -> (modSubst subst uid, rns)) (lc_includes lc),
+ lc_depends = map (\(uid, pkgid) -> (modSubst subst uid, pkgid)) (lc_depends lc)
+ }
+
+{-
+instance IsNode LinkedComponent where
+ type Key LinkedComponent = UnitId
+ nodeKey = lc_uid
+ nodeNeighbors n =
+ if Set.null (openUnitIdFreeHoles (lc_uid n))
+ then map fst (lc_depends n)
+ else ordNub (map (generalizeUnitId . fst) (lc_depends n))
+-}
+
+-- We can't cache these values because they need to be changed
+-- when we substitute over a 'LinkedComponent'. By varying
+-- these over 'UnitId', we can support old GHCs. Nice!
+
+toLinkedComponent
+ :: Verbosity
+ -> FullDb
+ -> PackageId
+ -> LinkedComponentMap
+ -> ConfiguredComponent
+ -> LogProgress LinkedComponent
+toLinkedComponent verbosity db this_pid pkg_map ConfiguredComponent {
+ cc_cid = this_cid,
+ cc_pkgid = pkgid,
+ cc_component = component,
+ cc_internal_build_tools = btools,
+ cc_public = is_public,
+ cc_includes = cid_includes
+ } = do
+ let
+ -- The explicitly specified requirements, provisions and
+ -- reexports from the Cabal file. These are only non-empty for
+ -- libraries; everything else is trivial.
+ (src_reqs :: [ModuleName],
+ src_provs :: [ModuleName],
+ src_reexports :: [ModuleReexport]) =
+ case component of
+ CLib lib -> (signatures lib,
+ exposedModules lib,
+ reexportedModules lib)
+ _ -> ([], [], [])
+
+ -- Take each included ComponentId and resolve it into an
+ -- *unlinked* unit identity. We will use unification (relying
+ -- on the ModuleShape) to resolve these into linked identities.
+ unlinked_includes :: [((OpenUnitId, ModuleShape), PackageId, IncludeRenaming)]
+ unlinked_includes = [ (lookupUid cid, pid, rns)
+ | (cid, pid, rns) <- cid_includes ]
+
+ lookupUid :: ComponentId -> (OpenUnitId, ModuleShape)
+ lookupUid cid = fromMaybe (error "linkComponent: lookupUid")
+ (Map.lookup cid pkg_map)
+
+ let orErr (Right x) = return x
+ orErr (Left err) = failProgress (text err)
+
+ -- OK, actually do unification
+ -- TODO: the unification monad might return errors, in which
+ -- case we have to deal. Use monadic bind for now.
+ (linked_shape0 :: ModuleScope,
+ linked_deps :: [(OpenUnitId, PackageId)],
+ linked_includes :: [(OpenUnitId, ModuleRenaming)]) <- orErr $ runUnifyM verbosity db $ do
+ -- The unification monad is implemented using mutable
+ -- references. Thus, we must convert our *pure* data
+ -- structures into mutable ones to perform unification.
+ --
+ let convertReq :: ModuleName -> UnifyM s (ModuleScopeU s)
+ convertReq req = do
+ req_u <- convertModule (OpenModuleVar req)
+ return (Map.empty, Map.singleton req req_u)
+ -- NB: We DON'T convert locally defined modules, as in the
+ -- absence of mutual recursion across packages they
+ -- cannot participate in mix-in linking.
+ (shapes_u, includes_u) <- fmap unzip (mapM convertInclude unlinked_includes)
+ src_reqs_u <- mapM convertReq src_reqs
+ -- Mix-in link everything! mixLink is the real workhorse.
+ shape_u <- foldM mixLink emptyModuleScopeU (shapes_u ++ src_reqs_u)
+ -- Read out all the final results by converting back
+ -- into a pure representation.
+ let convertIncludeU (uid_u, pid, rns) = do
+ uid <- convertUnitIdU uid_u
+ return ((uid, rns), (uid, pid))
+ shape <- convertModuleScopeU shape_u
+ includes_deps <- mapM convertIncludeU includes_u
+ let (incls, deps) = unzip includes_deps
+ return (shape, deps, incls)
+
+ -- linked_shape0 is almost complete, but it doesn't contain
+ -- the actual modules we export ourselves. Add them!
+ let reqs = modScopeRequires linked_shape0
+ -- check that there aren't pre-filled requirements...
+ insts = [ (req, OpenModuleVar req)
+ | req <- Set.toList reqs ]
+ this_uid = IndefFullUnitId this_cid . Map.fromList $ insts
+
+ -- add the local exports to the scope
+ local_exports = Map.fromListWith (++) $
+ [ (mod_name, [ModuleSource (packageName this_pid)
+ defaultIncludeRenaming
+ (OpenModule this_uid mod_name)])
+ | mod_name <- src_provs ]
+ -- NB: do NOT include hidden modules here: GHC 7.10's ghc-pkg
+ -- won't allow it (since someone could directly synthesize
+ -- an 'InstalledPackageInfo' that violates abstraction.)
+ -- Though, maybe it should be relaxed?
+ linked_shape = linked_shape0 {
+ modScopeProvides =
+ Map.unionWith (++)
+ local_exports
+ (modScopeProvides linked_shape0)
+ }
+
+ -- OK, compute the reexports
+ -- TODO: This code reports the errors for reexports one reexport at
+ -- a time. Better to collect them all up and report them all at
+ -- once.
+ reexports_list <- for src_reexports $ \reex@(ModuleReexport mb_pn from to) -> do
+ let err :: Doc -> LogProgress a
+ err s = failProgress
+ $ hang (text "Problem with module re-export" <> quotes (disp reex)
+ <+> colon) 2 s
+ case Map.lookup from (modScopeProvides linked_shape) of
+ Just cands@(x0:xs0) -> do
+ -- Make sure there is at least one candidate
+ (x, xs) <-
+ case mb_pn of
+ Just pn ->
+ case filter ((pn==) . msrc_pkgname) cands of
+ (x1:xs1) -> return (x1, xs1)
+ _ -> err (brokenReexportMsg reex)
+ Nothing -> return (x0, xs0)
+ -- Test that all the candidates are consistent
+ case filter (\x' -> msrc_module x /= msrc_module x') xs of
+ [] -> return ()
+ _ -> err $ ambiguousReexportMsg reex (x:xs)
+ return (to, msrc_module x)
+ _ ->
+ err (brokenReexportMsg reex)
+
+ -- TODO: maybe check this earlier; it's syntactically obvious.
+ let build_reexports m (k, v)
+ | Map.member k m =
+ failProgress $ hsep
+ [ text "Module name ", disp k, text " is exported multiple times." ]
+ | otherwise = return (Map.insert k v m)
+ provs <- foldM build_reexports Map.empty $
+ -- TODO: doublecheck we have checked for
+ -- src_provs duplicates already!
+ [ (mod_name, OpenModule this_uid mod_name) | mod_name <- src_provs ] ++
+ reexports_list
+
+ let final_linked_shape = ModuleShape provs (modScopeRequires linked_shape)
+
+ return $ LinkedComponent {
+ lc_uid = this_uid,
+ lc_cid = this_cid,
+ lc_insts = insts,
+ lc_pkgid = pkgid,
+ lc_component = component,
+ lc_public = is_public,
+ -- These must be executables
+ lc_internal_build_tools = map (\cid -> IndefFullUnitId cid Map.empty) btools,
+ lc_shape = final_linked_shape,
+ lc_includes = linked_includes,
+ lc_depends = linked_deps
+ }
+
+-- Handle mix-in linking for components. In the absence of Backpack,
+-- every ComponentId gets converted into a UnitId by way of SimpleUnitId.
+toLinkedComponents
+ :: Verbosity
+ -> FullDb
+ -> PackageId
+ -> LinkedComponentMap
+ -> [ConfiguredComponent]
+ -> LogProgress [LinkedComponent]
+toLinkedComponents verbosity db this_pid lc_map0 comps
+ = fmap snd (mapAccumM go lc_map0 comps)
+ where
+ go :: Map ComponentId (OpenUnitId, ModuleShape)
+ -> ConfiguredComponent
+ -> LogProgress (Map ComponentId (OpenUnitId, ModuleShape), LinkedComponent)
+ go lc_map cc = do
+ lc <- toLinkedComponent verbosity db this_pid lc_map cc
+ return (extendLinkedComponentMap lc lc_map, lc)
+
+type LinkedComponentMap = Map ComponentId (OpenUnitId, ModuleShape)
+
+extendLinkedComponentMap :: LinkedComponent
+ -> LinkedComponentMap
+ -> LinkedComponentMap
+extendLinkedComponentMap lc m =
+ Map.insert (lc_cid lc) (lc_uid lc, lc_shape lc) m
+
+brokenReexportMsg :: ModuleReexport -> Doc
+brokenReexportMsg (ModuleReexport (Just pn) from _to) =
+ text "The package" <+> disp pn <+>
+ text "does not export a module" <+> disp from
+brokenReexportMsg (ModuleReexport Nothing from _to) =
+ text "The module" <+> disp from <+>
+ text "is not exported by any suitable package." <+>
+ text "It occurs in neither the 'exposed-modules' of this package," <+>
+ text "nor any of its 'build-depends' dependencies."
+
+ambiguousReexportMsg :: ModuleReexport -> [ModuleSource] -> Doc
+ambiguousReexportMsg (ModuleReexport mb_pn from _to) ys =
+ text "The module" <+> disp from <+>
+ text "is (differently) exported by more than one package" <+>
+ parens (hsep (punctuate comma [displaySource y | y <- ys])) <+>
+ text "making the re-export ambiguous." <+> help_msg mb_pn
+ where
+ help_msg Nothing =
+ text "The ambiguity can be resolved by qualifying the" <+>
+ text "re-export with a package name." <+>
+ text "The syntax is 'packagename:ModuleName [as NewName]'."
+ -- Qualifying won't help that much.
+ help_msg (Just _) =
+ text "The ambiguity can be resolved by introducing a" <+>
+ text "backpack-include field to rename one of the module" <+>
+ text "names differently."
+ displaySource y
+ | not (isDefaultIncludeRenaming (msrc_renaming y))
+ = disp (msrc_pkgname y) <+> text "with renaming" <+>
+ disp (includeProvidesRn (msrc_renaming y))
+ | otherwise = disp (msrc_pkgname y)
diff --git a/cabal/Cabal/Distribution/Backpack/MixLink.hs b/cabal/Cabal/Distribution/Backpack/MixLink.hs
new file mode 100644
index 0000000..06e6352
--- /dev/null
+++ b/cabal/Cabal/Distribution/Backpack/MixLink.hs
@@ -0,0 +1,151 @@
+-- | See <https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst>
+module Distribution.Backpack.MixLink (
+ mixLink,
+) where
+
+import Prelude ()
+import Distribution.Compat.Prelude hiding (mod)
+
+import Distribution.Backpack
+import Distribution.Backpack.UnifyM
+import Distribution.Backpack.FullUnitId
+
+import qualified Distribution.Utils.UnionFind as UnionFind
+import Distribution.ModuleName
+import Distribution.Text
+import Distribution.Types.IncludeRenaming
+import Distribution.Package
+
+import Control.Monad
+import qualified Data.Map as Map
+import qualified Data.Foldable as F
+
+-----------------------------------------------------------------------
+-- Linking
+
+-- | Given to scopes of provisions and requirements, link them together.
+mixLink :: ModuleScopeU s -> ModuleScopeU s -> UnifyM s (ModuleScopeU s)
+mixLink (provs1, reqs1) (provs2, reqs2) = do
+ F.sequenceA_ (Map.intersectionWithKey linkProvision provs1 reqs2)
+ F.sequenceA_ (Map.intersectionWithKey linkProvision provs2 reqs1)
+ -- TODO: would be more efficient to collapse provision lists when we
+ -- unify them.
+ return (Map.unionWith (++) provs1 provs2,
+ -- NB: NOT the difference of the unions. That implies
+ -- self-unification not allowed. (But maybe requirement prov is disjoint
+ -- from reqs makes this a moot point?)
+ Map.union (Map.difference reqs1 provs2)
+ (Map.difference reqs2 provs1))
+
+displaySource :: ModuleSourceU s -> String
+displaySource src
+ | isDefaultIncludeRenaming (usrc_renaming src)
+ = display (usrc_pkgname src)
+ | otherwise
+ = display (usrc_pkgname src) ++ " with renaming " ++ display (usrc_renaming src)
+
+-- | Link a list of possibly provided modules to a single
+-- requirement. This applies a side-condition that all
+-- of the provided modules at the same name are *actually*
+-- the same module.
+linkProvision :: ModuleName -> [ModuleSourceU s] -> ModuleU s
+ -> UnifyM s [ModuleSourceU s]
+linkProvision _ [] _reqs = error "linkProvision"
+linkProvision mod_name ret@(prov:provs) req = do
+ forM_ provs $ \prov' -> do
+ let msg = "Ambiguous module " ++ display mod_name ++ " " ++
+ "when trying to fill requirement. It could refer to " ++
+ "a module included from " ++ displaySource prov ++ " " ++
+ "or module included from " ++ displaySource prov' ++ ". " ++
+ "Ambiguity occurred because "
+ withContext msg (usrc_module prov) (usrc_module prov') $
+ unifyModule (usrc_module prov) (usrc_module prov')
+ let msg = "Could not fill requirement " ++ display mod_name ++ "because "
+ withContext msg (usrc_module prov) req $
+ unifyModule (usrc_module prov) req
+ return ret
+
+
+
+-----------------------------------------------------------------------
+-- The unification algorithm
+
+-- This is based off of https://gist.github.com/amnn/559551517d020dbb6588
+-- which is a translation from Huet's thesis.
+
+unifyUnitId :: UnitIdU s -> UnitIdU s -> UnifyM s ()
+unifyUnitId uid1_u uid2_u
+ | uid1_u == uid2_u = return ()
+ | otherwise = do
+ xuid1 <- liftST $ UnionFind.find uid1_u
+ xuid2 <- liftST $ UnionFind.find uid2_u
+ case (xuid1, xuid2) of
+ (UnitIdThunkU u1, UnitIdThunkU u2)
+ | u1 == u2 -> return ()
+ | otherwise ->
+ unifyFail $
+ "pre-installed unit IDs " ++ display u1 ++
+ " and " ++ display u2 ++ " do not match."
+ (UnitIdThunkU uid1, UnitIdU _ cid2 insts2)
+ -> unifyThunkWith cid2 insts2 uid2_u uid1 uid1_u
+ (UnitIdU _ cid1 insts1, UnitIdThunkU uid2)
+ -> unifyThunkWith cid1 insts1 uid1_u uid2 uid2_u
+ (UnitIdU _ cid1 insts1, UnitIdU _ cid2 insts2)
+ -> unifyInner cid1 insts1 uid1_u cid2 insts2 uid2_u
+
+unifyThunkWith :: ComponentId
+ -> Map ModuleName (ModuleU s)
+ -> UnitIdU s
+ -> DefUnitId
+ -> UnitIdU s
+ -> UnifyM s ()
+unifyThunkWith cid1 insts1 uid1_u uid2 uid2_u = do
+ db <- fmap unify_db getUnifEnv
+ let FullUnitId cid2 insts2' = expandUnitId db uid2
+ insts2 <- convertModuleSubst insts2'
+ unifyInner cid1 insts1 uid1_u cid2 insts2 uid2_u
+
+unifyInner :: ComponentId
+ -> Map ModuleName (ModuleU s)
+ -> UnitIdU s
+ -> ComponentId
+ -> Map ModuleName (ModuleU s)
+ -> UnitIdU s
+ -> UnifyM s ()
+unifyInner cid1 insts1 uid1_u cid2 insts2 uid2_u = do
+ when (cid1 /= cid2) $
+ -- TODO: if we had a package identifier, could be an
+ -- easier to understand error message.
+ unifyFail $
+ "component IDs " ++
+ display cid1 ++ " and " ++ display cid2 ++ " do not match."
+ -- The KEY STEP which makes this a Huet-style unification
+ -- algorithm. (Also a payoff of using union-find.)
+ -- We can build infinite unit IDs this way, which is necessary
+ -- for support mutual recursion. NB: union keeps the SECOND
+ -- descriptor, so we always arrange for a UnitIdThunkU to live
+ -- there.
+ liftST $ UnionFind.union uid1_u uid2_u
+ F.sequenceA_ $ Map.intersectionWith unifyModule insts1 insts2
+
+-- | Imperatively unify two modules.
+unifyModule :: ModuleU s -> ModuleU s -> UnifyM s ()
+unifyModule mod1_u mod2_u
+ | mod1_u == mod2_u = return ()
+ | otherwise = do
+ mod1 <- liftST $ UnionFind.find mod1_u
+ mod2 <- liftST $ UnionFind.find mod2_u
+ case (mod1, mod2) of
+ (ModuleVarU _, _) -> liftST $ UnionFind.union mod1_u mod2_u
+ (_, ModuleVarU _) -> liftST $ UnionFind.union mod2_u mod1_u
+ (ModuleU uid1 mod_name1, ModuleU uid2 mod_name2) -> do
+ when (mod_name1 /= mod_name2) $
+ unifyFail $
+ "module names " ++
+ display mod_name1 ++ " and " ++
+ display mod_name2 ++ " disagree."
+ -- NB: this is not actually necessary (because we'll
+ -- detect loops eventually in 'unifyUnitId'), but it
+ -- seems harmless enough
+ liftST $ UnionFind.union mod1_u mod2_u
+ unifyUnitId uid1 uid2
diff --git a/cabal/Cabal/Distribution/Backpack/ModSubst.hs b/cabal/Cabal/Distribution/Backpack/ModSubst.hs
new file mode 100644
index 0000000..4f04ad3
--- /dev/null
+++ b/cabal/Cabal/Distribution/Backpack/ModSubst.hs
@@ -0,0 +1,54 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE PatternGuards #-}
+
+-- | A type class 'ModSubst' for objects which can have 'ModuleSubst'
+-- applied to them.
+--
+-- See also <https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst>
+
+module Distribution.Backpack.ModSubst (
+ ModSubst(..),
+) where
+
+import Prelude ()
+import Distribution.Compat.Prelude hiding (mod)
+
+import Distribution.ModuleName
+
+import Distribution.Backpack
+
+import qualified Data.Map as Map
+import Data.Set (Set)
+import qualified Data.Set as Set
+
+-- | Applying module substitutions to semantic objects.
+class ModSubst a where
+ -- In notation, substitution is postfix, which implies
+ -- putting it on the right hand side, but for partial
+ -- application it's more convenient to have it on the left
+ -- hand side.
+ modSubst :: OpenModuleSubst -> a -> a
+
+instance ModSubst OpenModule where
+ modSubst subst (OpenModule cid mod_name) = OpenModule (modSubst subst cid) mod_name
+ modSubst subst mod@(OpenModuleVar mod_name)
+ | Just mod' <- Map.lookup mod_name subst = mod'
+ | otherwise = mod
+
+instance ModSubst OpenUnitId where
+ modSubst subst (IndefFullUnitId cid insts) = IndefFullUnitId cid (modSubst subst insts)
+ modSubst _subst uid = uid
+
+instance ModSubst (Set ModuleName) where
+ modSubst subst reqs
+ = Set.union (Set.difference reqs (Map.keysSet subst))
+ (openModuleSubstFreeHoles subst)
+
+-- Substitutions are functorial. NB: this means that
+-- there is an @instance 'ModSubst' 'ModuleSubst'@!
+instance ModSubst a => ModSubst (Map k a) where
+ modSubst subst = fmap (modSubst subst)
+instance ModSubst a => ModSubst [a] where
+ modSubst subst = fmap (modSubst subst)
+instance ModSubst a => ModSubst (k, a) where
+ modSubst subst (x,y) = (x, modSubst subst y)
diff --git a/cabal/Cabal/Distribution/Backpack/ModuleScope.hs b/cabal/Cabal/Distribution/Backpack/ModuleScope.hs
new file mode 100644
index 0000000..f2477a7
--- /dev/null
+++ b/cabal/Cabal/Distribution/Backpack/ModuleScope.hs
@@ -0,0 +1,86 @@
+-- | See <https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst>
+module Distribution.Backpack.ModuleScope (
+ -- * Module scopes
+ ModuleScope(..),
+ ModuleProvides,
+ ModuleSource(..),
+ emptyModuleScope,
+) where
+
+import Prelude ()
+
+import Distribution.ModuleName
+import Distribution.Package
+import Distribution.Types.IncludeRenaming
+
+import Distribution.Backpack
+import Distribution.Backpack.ModSubst
+
+import Data.Map (Map)
+import qualified Data.Map as Map
+import Data.Set (Set)
+import qualified Data.Set as Set
+
+
+-----------------------------------------------------------------------
+-- Module scopes
+
+-- Why is ModuleProvides so complicated? The basic problem is that
+-- we want to support this:
+--
+-- package p where
+-- include q (A)
+-- include r (A)
+-- module B where
+-- import "q" A
+-- import "r" A
+--
+-- Specifically, in Cabal today it is NOT an error have two modules in
+-- scope with the same identifier. So we need to preserve this for
+-- Backpack. The modification is that an ambiguous module name is
+-- OK... as long as it is NOT used to fill a requirement!
+--
+-- So as a first try, we might try deferring unifying provisions that
+-- are being glommed together, and check for equality after the fact.
+-- But this doesn't work, because what if a multi-module provision
+-- is used to fill a requirement?! So you do the equality test
+-- IMMEDIATELY before a requirement fill happens... or never at all.
+--
+-- Alternate strategy: go ahead and unify, and then if it is revealed
+-- that some requirements got filled "out-of-thin-air", error.
+
+
+-- | A 'ModuleScope' describes the modules and requirements that
+-- are in-scope as we are processing a Cabal package. Unlike
+-- a 'ModuleShape', there may be multiple modules in scope at
+-- the same 'ModuleName'; this is only an error if we attempt
+-- to use those modules to fill a requirement. A 'ModuleScope'
+-- can influence the 'ModuleShape' via a reexport.
+data ModuleScope = ModuleScope {
+ modScopeProvides :: ModuleProvides,
+ modScopeRequires :: Set ModuleName
+ }
+
+-- | Every 'Module' in scope at a 'ModuleName' is annotated with
+-- the 'PackageName' it comes from.
+type ModuleProvides = Map ModuleName [ModuleSource]
+data ModuleSource =
+ ModuleSource {
+ -- We don't have line numbers, but if we did the
+ -- package name and renaming could be associated
+ -- with that as well
+ msrc_pkgname :: PackageName,
+ msrc_renaming :: IncludeRenaming,
+ msrc_module :: OpenModule
+ }
+
+instance ModSubst ModuleScope where
+ modSubst subst (ModuleScope provs reqs)
+ = ModuleScope (modSubst subst provs) (modSubst subst reqs)
+
+-- | An empty 'ModuleScope'.
+emptyModuleScope :: ModuleScope
+emptyModuleScope = ModuleScope Map.empty Set.empty
+
+instance ModSubst ModuleSource where
+ modSubst subst src = src { msrc_module = modSubst subst (msrc_module src) }
diff --git a/cabal/Cabal/Distribution/Backpack/ModuleShape.hs b/cabal/Cabal/Distribution/Backpack/ModuleShape.hs
new file mode 100644
index 0000000..df98ceb
--- /dev/null
+++ b/cabal/Cabal/Distribution/Backpack/ModuleShape.hs
@@ -0,0 +1,83 @@
+{-# LANGUAGE DeriveGeneric #-}
+-- | See <https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst>
+module Distribution.Backpack.ModuleShape (
+ -- * Module shapes
+ ModuleShape(..),
+ emptyModuleShape,
+ shapeInstalledPackage,
+) where
+
+import Prelude ()
+import Distribution.Compat.Prelude hiding (mod)
+
+import Distribution.ModuleName
+import Distribution.InstalledPackageInfo as IPI
+
+import Distribution.Backpack.ModSubst
+import Distribution.Backpack
+
+import qualified Data.Map as Map
+import Data.Set (Set)
+import qualified Data.Set as Set
+
+-----------------------------------------------------------------------
+-- Module shapes
+
+-- | A 'ModuleShape' describes the provisions and requirements of
+-- a library. We can extract a 'ModuleShape' from an
+-- 'InstalledPackageInfo'.
+data ModuleShape = ModuleShape {
+ modShapeProvides :: OpenModuleSubst,
+ modShapeRequires :: Set ModuleName
+ }
+ deriving (Eq, Show, Generic)
+
+instance Binary ModuleShape
+
+instance ModSubst ModuleShape where
+ modSubst subst (ModuleShape provs reqs)
+ = ModuleShape (modSubst subst provs) (modSubst subst reqs)
+
+-- | The default module shape, with no provisions and no requirements.
+emptyModuleShape :: ModuleShape
+emptyModuleShape = ModuleShape Map.empty Set.empty
+
+-- Food for thought: suppose we apply the Merkel tree optimization.
+-- Imagine this situation:
+--
+-- component p
+-- signature H
+-- module P
+-- component h
+-- module H
+-- component a
+-- signature P
+-- module A
+-- component q(P)
+-- include p
+-- include h
+-- component r
+-- include q (P)
+-- include p (P) requires (H)
+-- include h (H)
+-- include a (A) requires (P)
+--
+-- Component r should not have any conflicts, since after mix-in linking
+-- the two P imports will end up being the same, so we can properly
+-- instantiate it. But to know that q's P is p:P instantiated with h:H,
+-- we have to be able to expand its unit id. Maybe we can expand it
+-- lazily but in some cases it will need to be expanded.
+--
+-- FWIW, the way that GHC handles this is by improving unit IDs as
+-- soon as it sees an improved one in the package database. This
+-- is a bit disgusting.
+shapeInstalledPackage :: IPI.InstalledPackageInfo -> ModuleShape
+shapeInstalledPackage ipi = ModuleShape (Map.fromList provs) reqs
+ where
+ uid = installedOpenUnitId ipi
+ provs = map shapeExposedModule (IPI.exposedModules ipi)
+ reqs = requiredSignatures ipi
+ shapeExposedModule (IPI.ExposedModule mod_name Nothing)
+ = (mod_name, OpenModule uid mod_name)
+ shapeExposedModule (IPI.ExposedModule mod_name (Just mod))
+ = (mod_name, mod)
diff --git a/cabal/Cabal/Distribution/Backpack/PreExistingComponent.hs b/cabal/Cabal/Distribution/Backpack/PreExistingComponent.hs
new file mode 100644
index 0000000..099481b
--- /dev/null
+++ b/cabal/Cabal/Distribution/Backpack/PreExistingComponent.hs
@@ -0,0 +1,49 @@
+-- | See <https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst>
+module Distribution.Backpack.PreExistingComponent (
+ PreExistingComponent(..),
+ ipiToPreExistingComponent,
+) where
+
+import Prelude ()
+
+import Distribution.Backpack.ModuleShape
+import Distribution.Backpack
+
+import qualified Data.Map as Map
+import Distribution.Package
+import qualified Distribution.InstalledPackageInfo as Installed
+import Distribution.InstalledPackageInfo (InstalledPackageInfo)
+
+-- | Stripped down version of 'LinkedComponent' for things
+-- we don't need to know how to build.
+data PreExistingComponent
+ = PreExistingComponent {
+ -- | The 'PackageName' that, when we see it in 'PackageDescription',
+ -- we should map this to. This may DISAGREE with 'pc_pkgid' for
+ -- internal dependencies: e.g., an internal component @lib@
+ -- may be munged to @z-pkg-z-lib@, but we still want to use
+ -- it when we see @lib@ in @build-depends@
+ pc_pkgname :: PackageName,
+ pc_pkgid :: PackageId,
+ pc_uid :: UnitId,
+ pc_cid :: ComponentId,
+ pc_open_uid :: OpenUnitId,
+ pc_shape :: ModuleShape
+ }
+
+-- | Convert an 'InstalledPackageInfo' into a 'PreExistingComponent',
+-- which was brought into scope under the 'PackageName' (important for
+-- a package qualified reference.)
+ipiToPreExistingComponent :: (PackageName, InstalledPackageInfo) -> PreExistingComponent
+ipiToPreExistingComponent (pn, ipi) =
+ PreExistingComponent {
+ pc_pkgname = pn,
+ pc_pkgid = Installed.sourcePackageId ipi,
+ pc_uid = Installed.installedUnitId ipi,
+ pc_cid = Installed.installedComponentId ipi,
+ pc_open_uid =
+ IndefFullUnitId (Installed.installedComponentId ipi)
+ (Map.fromList (Installed.instantiatedWith ipi)),
+ pc_shape = shapeInstalledPackage ipi
+ }
+
diff --git a/cabal/Cabal/Distribution/Backpack/ReadyComponent.hs b/cabal/Cabal/Distribution/Backpack/ReadyComponent.hs
new file mode 100644
index 0000000..bd9e8b7
--- /dev/null
+++ b/cabal/Cabal/Distribution/Backpack/ReadyComponent.hs
@@ -0,0 +1,302 @@
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PatternGuards #-}
+-- | See <https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst>
+module Distribution.Backpack.ReadyComponent (
+ ReadyComponent(..),
+ InstantiatedComponent(..),
+ IndefiniteComponent(..),
+ rc_compat_name,
+ rc_compat_key,
+ dispReadyComponent,
+ toReadyComponents,
+) where
+
+import Prelude ()
+import Distribution.Compat.Prelude hiding ((<>))
+
+import Distribution.Backpack
+import Distribution.Backpack.Id
+import Distribution.Backpack.LinkedComponent
+import Distribution.Backpack.ModuleShape
+
+import Distribution.Types.ModuleRenaming
+import Distribution.Types.Component
+import Distribution.Compat.Graph (IsNode(..))
+
+import Distribution.ModuleName
+import Distribution.Package
+import Distribution.Simple.Utils
+import Distribution.Simple.Compiler
+
+import qualified Control.Applicative as A
+import qualified Data.Traversable as T
+
+import Control.Monad
+import Text.PrettyPrint
+import qualified Data.Map as Map
+
+import Distribution.Version
+import Distribution.Text
+
+-- | An instantiated component is simply a linked component which
+-- may have a fully instantiated 'UnitId'. When we do mix-in linking,
+-- we only do each component in its most general form; instantiation
+-- then takes all of the fully instantiated components and recursively
+-- discovers what other instantiated components we need to build
+-- before we can build them.
+--
+
+data InstantiatedComponent
+ = InstantiatedComponent {
+ instc_insts :: [(ModuleName, Module)],
+ instc_provides :: Map ModuleName Module,
+ instc_includes :: [(DefUnitId, ModuleRenaming)]
+ }
+
+data IndefiniteComponent
+ = IndefiniteComponent {
+ indefc_requires :: [ModuleName],
+ indefc_provides :: Map ModuleName OpenModule,
+ indefc_includes :: [(OpenUnitId, ModuleRenaming)]
+ }
+
+data ReadyComponent
+ = ReadyComponent {
+ rc_uid :: UnitId,
+ rc_open_uid :: OpenUnitId,
+ rc_cid :: ComponentId,
+ rc_pkgid :: PackageId,
+ rc_component :: Component,
+ -- build-tools don't participate in mix-in linking.
+ -- (but what if they cold?)
+ rc_internal_build_tools :: [DefUnitId],
+ rc_public :: Bool,
+ -- PackageId here is a bit dodgy, but its just for
+ -- BC so it shouldn't matter.
+ rc_depends :: [(UnitId, PackageId)],
+ rc_i :: Either IndefiniteComponent InstantiatedComponent
+ }
+
+instance Package ReadyComponent where
+ packageId = rc_pkgid
+
+instance HasUnitId ReadyComponent where
+ installedUnitId = rc_uid
+
+instance IsNode ReadyComponent where
+ type Key ReadyComponent = UnitId
+ nodeKey = rc_uid
+ nodeNeighbors rc =
+ (case rc_i rc of
+ Right inst | [] <- instc_insts inst
+ -> []
+ | otherwise
+ -> [newSimpleUnitId (rc_cid rc)]
+ _ -> []) ++
+ ordNub (map fst (rc_depends rc))
+
+rc_compat_name :: ReadyComponent -> PackageName
+rc_compat_name ReadyComponent{
+ rc_pkgid = PackageIdentifier pkg_name _,
+ rc_component = component
+ }
+ = computeCompatPackageName pkg_name (componentName component)
+
+rc_compat_key :: ReadyComponent -> Compiler -> String
+rc_compat_key rc@ReadyComponent {
+ rc_pkgid = PackageIdentifier _ pkg_ver,
+ rc_uid = uid
+ } comp -- TODO: A wart. But the alternative is to store
+ -- the Compiler in the LinkedComponent
+ = computeCompatPackageKey comp (rc_compat_name rc) pkg_ver uid
+
+dispReadyComponent :: ReadyComponent -> Doc
+dispReadyComponent rc =
+ hang (text (case rc_i rc of
+ Left _ -> "indefinite"
+ Right _ -> "definite")
+ <+> disp (nodeKey rc)
+ {- <+> dispModSubst (Map.fromList (lc_insts lc)) -} ) 4 $
+ vcat [ text "depends" <+> disp uid
+ | uid <- nodeNeighbors rc ]
+
+-- | The state of 'InstM'; a mapping from 'UnitId's to their
+-- ready component, or @Nothing@ if its an external
+-- component which we don't know how to build.
+type InstS = Map UnitId (Maybe ReadyComponent)
+
+-- | A state monad for doing instantiations (can't use actual
+-- State because that would be an extra dependency.)
+newtype InstM a = InstM { runInstM :: InstS -> (a, InstS) }
+
+instance Functor InstM where
+ fmap f (InstM m) = InstM $ \s -> let (x, s') = m s
+ in (f x, s')
+
+instance A.Applicative InstM where
+ pure a = InstM $ \s -> (a, s)
+ InstM f <*> InstM x = InstM $ \s -> let (f', s') = f s
+ (x', s'') = x s'
+ in (f' x', s'')
+
+instance Monad InstM where
+ return = A.pure
+ InstM m >>= f = InstM $ \s -> let (x, s') = m s
+ in runInstM (f x) s'
+
+-- | Given a list of 'LinkedComponent's, expand the module graph
+-- so that we have an instantiated graph containing all of the
+-- instantiated components we need to build.
+--
+-- Instantiation intuitively follows the following algorithm:
+--
+-- instantiate a definite unit id p[S]:
+-- recursively instantiate each module M in S
+-- recursively instantiate modules exported by this unit
+-- recursively instantiate dependencies substituted by S
+--
+-- The implementation is a bit more involved to memoize instantiation
+-- if we have done it already.
+--
+-- We also call 'improveUnitId' during this process, so that fully
+-- instantiated components are given 'HashedUnitId'.
+--
+toReadyComponents
+ :: Map UnitId PackageId
+ -> Map ModuleName Module -- subst for the public component
+ -> [LinkedComponent]
+ -> [ReadyComponent]
+toReadyComponents pid_map subst0 comps
+ = catMaybes (Map.elems ready_map)
+ where
+ cmap = Map.fromList [ (lc_cid lc, lc) | lc <- comps ]
+
+ instantiateUnitId :: ComponentId -> Map ModuleName Module
+ -> InstM DefUnitId
+ instantiateUnitId cid insts = InstM $ \s ->
+ case Map.lookup uid s of
+ Nothing ->
+ -- Knot tied
+ let (r, s') = runInstM (instantiateComponent uid cid insts)
+ (Map.insert uid r s)
+ in (def_uid, Map.insert uid r s')
+ Just _ -> (def_uid, s)
+ where
+ -- The mkDefUnitId here indicates that we assume
+ -- that Cabal handles unit id hash allocation.
+ -- Good thing about hashing here: map is only on string.
+ -- Bad thing: have to repeatedly hash.
+ def_uid = mkDefUnitId cid insts
+ uid = unDefUnitId def_uid
+
+ instantiateComponent
+ :: UnitId -> ComponentId -> Map ModuleName Module
+ -> InstM (Maybe ReadyComponent)
+ instantiateComponent uid cid insts
+ | Just lc <- Map.lookup cid cmap = do
+ deps <- forM (lc_depends lc) $ \(x, y) -> do
+ x' <- substUnitId insts x
+ return (x', y)
+ provides <- T.mapM (substModule insts) (modShapeProvides (lc_shape lc))
+ includes <- forM (lc_includes lc) $ \(x, y) -> do
+ x' <- substUnitId insts x
+ return (x', y)
+ build_tools <- mapM (substUnitId insts) (lc_internal_build_tools lc)
+ s <- InstM $ \s -> (s, s)
+ let getDep (Module dep_def_uid _)
+ | let dep_uid = unDefUnitId dep_def_uid
+ -- Lose DefUnitId invariant for rc_depends
+ = [(dep_uid,
+ fromMaybe err_pid $
+ Map.lookup dep_uid pid_map A.<|>
+ fmap rc_pkgid (join (Map.lookup dep_uid s)))]
+ where
+ err_pid =
+ PackageIdentifier
+ (mkPackageName "nonexistent-package-this-is-a-cabal-bug")
+ (mkVersion [0])
+ instc = InstantiatedComponent {
+ instc_insts = Map.toList insts,
+ instc_provides = provides,
+ instc_includes = includes
+ }
+ return $ Just ReadyComponent {
+ rc_uid = uid,
+ rc_open_uid = DefiniteUnitId (unsafeMkDefUnitId uid),
+ rc_cid = lc_cid lc,
+ rc_pkgid = lc_pkgid lc,
+ rc_component = lc_component lc,
+ rc_internal_build_tools = build_tools,
+ rc_public = lc_public lc,
+ rc_depends = ordNub $
+ -- NB: don't put the dep on the indef
+ -- package here, since we DO NOT want
+ -- to put it in 'depends' in the IPI
+ map (\(x,y) -> (unDefUnitId x, y)) deps ++
+ concatMap getDep (Map.elems insts),
+ rc_i = Right instc
+ }
+ | otherwise = return Nothing
+
+ substUnitId :: Map ModuleName Module -> OpenUnitId -> InstM DefUnitId
+ substUnitId _ (DefiniteUnitId uid) =
+ return uid
+ substUnitId subst (IndefFullUnitId cid insts) = do
+ insts' <- substSubst subst insts
+ instantiateUnitId cid insts'
+
+ -- NB: NOT composition
+ substSubst :: Map ModuleName Module
+ -> Map ModuleName OpenModule
+ -> InstM (Map ModuleName Module)
+ substSubst subst insts = T.mapM (substModule subst) insts
+
+ substModule :: Map ModuleName Module -> OpenModule -> InstM Module
+ substModule subst (OpenModuleVar mod_name)
+ | Just m <- Map.lookup mod_name subst = return m
+ | otherwise = error "substModule: non-closing substitution"
+ substModule subst (OpenModule uid mod_name) = do
+ uid' <- substUnitId subst uid
+ return (Module uid' mod_name)
+
+ indefiniteUnitId :: ComponentId -> InstM UnitId
+ indefiniteUnitId cid = do
+ let uid = newSimpleUnitId cid
+ r <- indefiniteComponent uid cid
+ InstM $ \s -> (uid, Map.insert uid r s)
+
+ indefiniteComponent :: UnitId -> ComponentId -> InstM (Maybe ReadyComponent)
+ indefiniteComponent uid cid
+ | Just lc <- Map.lookup cid cmap = do
+ -- TODO: Goofy
+ build_tools <- mapM (substUnitId Map.empty) (lc_internal_build_tools lc)
+ let indefc = IndefiniteComponent {
+ indefc_requires = map fst (lc_insts lc),
+ indefc_provides = modShapeProvides (lc_shape lc),
+ indefc_includes = lc_includes lc
+ }
+ return $ Just ReadyComponent {
+ rc_uid = uid,
+ rc_open_uid = lc_uid lc,
+ rc_cid = lc_cid lc,
+ rc_pkgid = lc_pkgid lc,
+ rc_component = lc_component lc,
+ rc_internal_build_tools = build_tools,
+ rc_public = lc_public lc,
+ rc_depends = ordNub (map (\(x,y) -> (abstractUnitId x, y)) (lc_depends lc)),
+ rc_i = Left indefc
+ }
+ | otherwise = return Nothing
+
+ ready_map = snd $ runInstM work Map.empty
+
+ work
+ | not (Map.null subst0)
+ , [lc] <- filter lc_public (Map.elems cmap)
+ = do _ <- instantiateUnitId (lc_cid lc) subst0
+ return ()
+ | otherwise
+ = forM_ (Map.elems cmap) $ \lc ->
+ if null (lc_insts lc)
+ then instantiateUnitId (lc_cid lc) Map.empty >> return ()
+ else indefiniteUnitId (lc_cid lc) >> return ()
diff --git a/cabal/Cabal/Distribution/Backpack/UnifyM.hs b/cabal/Cabal/Distribution/Backpack/UnifyM.hs
new file mode 100644
index 0000000..b8cee90
--- /dev/null
+++ b/cabal/Cabal/Distribution/Backpack/UnifyM.hs
@@ -0,0 +1,486 @@
+{-# LANGUAGE Rank2Types #-}
+-- | See <https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst>
+module Distribution.Backpack.UnifyM (
+ -- * Unification monad
+ UnifyM,
+ runUnifyM,
+ unifyFail,
+ withContext,
+ liftST,
+
+ UnifEnv(..),
+ getUnifEnv,
+
+ -- * Modules and unit IDs
+ ModuleU,
+ ModuleU'(..),
+ convertModule,
+ convertModuleU,
+
+ UnitIdU,
+ UnitIdU'(..),
+ convertUnitId,
+ convertUnitIdU,
+
+ ModuleSubstU,
+ convertModuleSubstU,
+ convertModuleSubst,
+
+ ModuleScopeU,
+ emptyModuleScopeU,
+ convertModuleScopeU,
+
+ ModuleSourceU(..),
+
+ convertInclude,
+ convertModuleProvides,
+ convertModuleProvidesU,
+
+) where
+
+import Prelude ()
+import Distribution.Compat.Prelude hiding (mod)
+
+import Distribution.Backpack.ModuleShape
+import Distribution.Backpack.ModuleScope
+import Distribution.Backpack.ModSubst
+import Distribution.Backpack.FullUnitId
+import Distribution.Backpack
+
+import qualified Distribution.Utils.UnionFind as UnionFind
+import Distribution.ModuleName
+import Distribution.Package
+import Distribution.PackageDescription
+import Distribution.Text
+import Distribution.Types.IncludeRenaming
+import Distribution.Verbosity
+
+import Data.STRef
+import Control.Monad.ST
+import Control.Monad
+import qualified Data.Map as Map
+import qualified Data.Set as Set
+import Data.IntMap (IntMap)
+import qualified Data.IntMap as IntMap
+import qualified Data.Traversable as T
+
+-- TODO: more detailed trace output on high verbosity would probably
+-- be appreciated by users debugging unification errors. Collect
+-- some good examples!
+
+-- | The unification monad, this monad encapsulates imperative
+-- unification.
+newtype UnifyM s a = UnifyM { unUnifyM :: UnifEnv s -> ST s (Either String a) }
+
+-- | Run a computation in the unification monad.
+runUnifyM :: Verbosity -> FullDb -> (forall s. UnifyM s a) -> Either String a
+runUnifyM verbosity db m
+ = runST $ do i <- newSTRef 0
+ hmap <- newSTRef Map.empty
+ unUnifyM m (UnifEnv i hmap verbosity Nothing db)
+-- NB: GHC 7.6 throws a hissy fit if you pattern match on 'm'.
+
+-- | The unification environment.
+data UnifEnv s = UnifEnv {
+ -- | A supply of unique integers to label 'UnitIdU'
+ -- cells. This is used to determine loops in unit
+ -- identifiers (which can happen with mutual recursion.)
+ unify_uniq :: UnifRef s UnitIdUnique,
+ -- | The set of requirements in scope. When
+ -- a provision is brought into scope, we unify with
+ -- the requirement at the same module name to fill it.
+ -- This mapping grows monotonically.
+ unify_reqs :: UnifRef s (Map ModuleName (ModuleU s)),
+ -- | How verbose the error message should be
+ unify_verbosity :: Verbosity,
+ -- | The error reporting context
+ unify_ctx :: Maybe (String, ModuleU s, ModuleU s),
+ -- | The package index for expanding unit identifiers
+ unify_db :: FullDb
+ }
+
+instance Functor (UnifyM s) where
+ fmap f (UnifyM m) = UnifyM (fmap (fmap (fmap f)) m)
+
+instance Applicative (UnifyM s) where
+ pure = UnifyM . pure . pure . pure
+ UnifyM f <*> UnifyM x = UnifyM $ \r -> do
+ f' <- f r
+ case f' of
+ Left err -> return (Left err)
+ Right f'' -> do
+ x' <- x r
+ case x' of
+ Left err -> return (Left err)
+ Right x'' -> return (Right (f'' x''))
+
+instance Monad (UnifyM s) where
+ return = pure
+ UnifyM m >>= f = UnifyM $ \r -> do
+ x <- m r
+ case x of
+ Left err -> return (Left err)
+ Right x' -> unUnifyM (f x') r
+
+-- | Lift a computation from 'ST' monad to 'UnifyM' monad.
+-- Internal use only.
+liftST :: ST s a -> UnifyM s a
+liftST m = UnifyM $ \_ -> fmap Right m
+
+unifyFail :: String -> UnifyM s a
+unifyFail err = do
+ env <- getUnifEnv
+ msg <- case unify_ctx env of
+ Nothing -> return ("Unspecified unification error: " ++ err)
+ Just (ctx, mod1, mod2)
+ | unify_verbosity env > normal
+ -> do mod1' <- convertModuleU mod1
+ mod2' <- convertModuleU mod2
+ let extra = " (was unifying " ++ display mod1'
+ ++ " and " ++ display mod2' ++ ")"
+ return (ctx ++ err ++ extra)
+ | otherwise
+ -> return (ctx ++ err ++ " (for more information, pass -v flag)")
+ UnifyM $ \_ -> return (Left msg)
+
+-- | A convenient alias for mutable references in the unification monad.
+type UnifRef s a = STRef s a
+
+-- | Imperatively read a 'UnifRef'.
+readUnifRef :: UnifRef s a -> UnifyM s a
+readUnifRef = liftST . readSTRef
+
+-- | Imperatively write a 'UnifRef'.
+writeUnifRef :: UnifRef s a -> a -> UnifyM s ()
+writeUnifRef x = liftST . writeSTRef x
+
+-- | Get the current unification environment.
+getUnifEnv :: UnifyM s (UnifEnv s)
+getUnifEnv = UnifyM $ \r -> return (Right r)
+
+-- | Run a unification in some context
+withContext :: String -> ModuleU s -> ModuleU s -> UnifyM s a -> UnifyM s a
+withContext ctx mod1 mod2 m =
+ UnifyM $ \r -> unUnifyM m r { unify_ctx = Just (ctx, mod1, mod2) }
+
+-----------------------------------------------------------------------
+-- The "unifiable" variants of the data types
+--
+-- In order to properly do unification over infinite trees, we
+-- need to union find over 'Module's and 'UnitId's. The pure
+-- representation is ill-equipped to do this, so we convert
+-- from the pure representation into one which is indirected
+-- through union-find. 'ModuleU' handles hole variables;
+-- 'UnitIdU' handles mu-binders.
+
+-- | Contents of a mutable 'ModuleU' reference.
+data ModuleU' s
+ = ModuleU (UnitIdU s) ModuleName
+ | ModuleVarU ModuleName
+
+-- | Contents of a mutable 'UnitIdU' reference.
+data UnitIdU' s
+ = UnitIdU UnitIdUnique ComponentId (Map ModuleName (ModuleU s))
+ | UnitIdThunkU DefUnitId
+
+-- | A mutable version of 'Module' which can be imperatively unified.
+type ModuleU s = UnionFind.Point s (ModuleU' s)
+
+-- | A mutable version of 'UnitId' which can be imperatively unified.
+type UnitIdU s = UnionFind.Point s (UnitIdU' s)
+
+-- | An integer for uniquely labeling 'UnitIdU' nodes. We need
+-- these labels in order to efficiently serialize 'UnitIdU's into
+-- 'UnitId's (we use the label to check if any parent is the
+-- node in question, and if so insert a deBruijn index instead.)
+-- These labels must be unique across all 'UnitId's/'Module's which
+-- participate in unification!
+type UnitIdUnique = Int
+
+
+-----------------------------------------------------------------------
+-- Conversion to the unifiable data types
+
+-- An environment for tracking the mu-bindings in scope.
+-- The invariant for a state @(m, i)@ is that [0..i] are
+-- keys of @m@; in fact, the @i-k@th entry is the @k@th
+-- de Bruijn index (this saves us from having to shift as
+-- we enter mu-binders.)
+type MuEnv s = (IntMap (UnitIdU s), Int)
+
+extendMuEnv :: MuEnv s -> UnitIdU s -> MuEnv s
+extendMuEnv (m, i) x =
+ (IntMap.insert (i + 1) x m, i + 1)
+
+{-
+lookupMuEnv :: MuEnv s -> Int {- de Bruijn index -} -> UnitIdU s
+lookupMuEnv (m, i) k =
+ case IntMap.lookup (i - k) m of
+ -- Technically a user can trigger this by giving us a
+ -- bad 'UnitId', so handle this better.
+ Nothing -> error "lookupMuEnv: out of bounds (malformed de Bruijn index)"
+ Just v -> v
+-}
+
+emptyMuEnv :: MuEnv s
+emptyMuEnv = (IntMap.empty, -1)
+
+-- The workhorse functions. These share an environment:
+-- * @UnifRef s UnitIdUnique@ - the unique label supply for 'UnitIdU' nodes
+-- * @UnifRef s (Map ModuleName moduleU)@ - the (lazily initialized)
+-- environment containing the implicitly universally quantified
+-- @hole:A@ binders.
+-- * @MuEnv@ - the environment for mu-binders.
+
+convertUnitId' :: MuEnv s
+ -> OpenUnitId
+ -> UnifyM s (UnitIdU s)
+-- TODO: this could be more lazy if we know there are no internal
+-- references
+convertUnitId' _ (DefiniteUnitId uid) =
+ liftST $ UnionFind.fresh (UnitIdThunkU uid)
+convertUnitId' stk (IndefFullUnitId cid insts) = do
+ fs <- fmap unify_uniq getUnifEnv
+ x <- liftST $ UnionFind.fresh (error "convertUnitId") -- tie the knot later
+ insts_u <- T.forM insts $ convertModule' (extendMuEnv stk x)
+ u <- readUnifRef fs
+ writeUnifRef fs (u+1)
+ y <- liftST $ UnionFind.fresh (UnitIdU u cid insts_u)
+ liftST $ UnionFind.union x y
+ return y
+-- convertUnitId' stk (UnitIdVar i) = return (lookupMuEnv stk i)
+
+convertModule' :: MuEnv s
+ -> OpenModule -> UnifyM s (ModuleU s)
+convertModule' _stk (OpenModuleVar mod_name) = do
+ hmap <- fmap unify_reqs getUnifEnv
+ hm <- readUnifRef hmap
+ case Map.lookup mod_name hm of
+ Nothing -> do mod <- liftST $ UnionFind.fresh (ModuleVarU mod_name)
+ writeUnifRef hmap (Map.insert mod_name mod hm)
+ return mod
+ Just mod -> return mod
+convertModule' stk (OpenModule uid mod_name) = do
+ uid_u <- convertUnitId' stk uid
+ liftST $ UnionFind.fresh (ModuleU uid_u mod_name)
+
+convertUnitId :: OpenUnitId -> UnifyM s (UnitIdU s)
+convertUnitId = convertUnitId' emptyMuEnv
+
+convertModule :: OpenModule -> UnifyM s (ModuleU s)
+convertModule = convertModule' emptyMuEnv
+
+
+
+-----------------------------------------------------------------------
+-- Substitutions
+
+-- | The mutable counterpart of a 'ModuleSubst' (not defined here).
+type ModuleSubstU s = Map ModuleName (ModuleU s)
+
+-- | Conversion of 'ModuleSubst' to 'ModuleSubstU'
+convertModuleSubst :: Map ModuleName OpenModule -> UnifyM s (Map ModuleName (ModuleU s))
+convertModuleSubst = T.mapM convertModule
+
+-- | Conversion of 'ModuleSubstU' to 'ModuleSubst'
+convertModuleSubstU :: ModuleSubstU s -> UnifyM s OpenModuleSubst
+convertModuleSubstU = T.mapM convertModuleU
+
+-----------------------------------------------------------------------
+-- Conversion from the unifiable data types
+
+-- An environment for tracking candidates for adding a mu-binding.
+-- The invariant for a state @(m, i)@, is that if we encounter a node
+-- labeled @k@ such that @m[k -> v]@, then we can replace this
+-- node with the de Bruijn index @i-v@ referring to an enclosing
+-- mu-binder; furthermore, @range(m) = [0..i]@.
+type MooEnv = (IntMap Int, Int)
+
+emptyMooEnv :: MooEnv
+emptyMooEnv = (IntMap.empty, -1)
+
+extendMooEnv :: MooEnv -> UnitIdUnique -> MooEnv
+extendMooEnv (m, i) k = (IntMap.insert k (i + 1) m, i + 1)
+
+lookupMooEnv :: MooEnv -> UnitIdUnique -> Maybe Int
+lookupMooEnv (m, i) k =
+ case IntMap.lookup k m of
+ Nothing -> Nothing
+ Just v -> Just (i-v) -- de Bruijn indexize
+
+-- The workhorse functions
+
+convertUnitIdU' :: MooEnv -> UnitIdU s -> UnifyM s OpenUnitId
+convertUnitIdU' stk uid_u = do
+ x <- liftST $ UnionFind.find uid_u
+ case x of
+ UnitIdThunkU uid -> return (DefiniteUnitId uid)
+ UnitIdU u cid insts_u ->
+ case lookupMooEnv stk u of
+ Just _i -> error "convertUnitIdU': mutual recursion" -- return (UnitIdVar i)
+ Nothing -> do
+ insts <- T.forM insts_u $ convertModuleU' (extendMooEnv stk u)
+ return (IndefFullUnitId cid insts)
+
+convertModuleU' :: MooEnv -> ModuleU s -> UnifyM s OpenModule
+convertModuleU' stk mod_u = do
+ mod <- liftST $ UnionFind.find mod_u
+ case mod of
+ ModuleVarU mod_name -> return (OpenModuleVar mod_name)
+ ModuleU uid_u mod_name -> do
+ uid <- convertUnitIdU' stk uid_u
+ return (OpenModule uid mod_name)
+
+-- Helper functions
+
+convertUnitIdU :: UnitIdU s -> UnifyM s OpenUnitId
+convertUnitIdU = convertUnitIdU' emptyMooEnv
+
+convertModuleU :: ModuleU s -> UnifyM s OpenModule
+convertModuleU = convertModuleU' emptyMooEnv
+
+-- | An empty 'ModuleScopeU'.
+emptyModuleScopeU :: ModuleScopeU s
+emptyModuleScopeU = (Map.empty, Map.empty)
+
+
+-- | The mutable counterpart of 'ModuleScope'.
+type ModuleScopeU s = (ModuleProvidesU s, ModuleSubstU s)
+-- | The mutable counterpart of 'ModuleProvides'
+type ModuleProvidesU s = Map ModuleName [ModuleSourceU s]
+data ModuleSourceU s =
+ ModuleSourceU {
+ -- We don't have line numbers, but if we did the
+ -- package name and renaming could be associated
+ -- with that as well
+ usrc_pkgname :: PackageName,
+ usrc_renaming :: IncludeRenaming,
+ usrc_module :: ModuleU s
+ }
+
+-- | Convert a 'ModuleShape' into a 'ModuleScopeU', so we can do
+-- unification on it.
+convertInclude
+ :: ((OpenUnitId, ModuleShape), PackageId, IncludeRenaming)
+ -> UnifyM s (ModuleScopeU s, (UnitIdU s, PackageId, ModuleRenaming))
+convertInclude ((uid, ModuleShape provs reqs), pid, incl@(IncludeRenaming prov_rns req_rns)) = do
+ let pn = packageName pid
+
+ -- Suppose our package has two requirements A and B, and
+ -- we include it with @requires (A as X)@
+ -- There are three closely related things we compute based
+ -- off of @reqs@ and @reqs_rns@:
+ --
+ -- 1. The requirement renaming (A -> X)
+ -- 2. The requirement substitution (A -> <X>, B -> <B>)
+
+ -- Requirement renaming. This is read straight off the syntax:
+ --
+ -- [nothing] ==> [empty]
+ -- requires (B as Y) ==> B -> Y
+ --
+ -- Requirement renamings are NOT injective: if two requirements
+ -- are mapped to the same name, the intent is to merge them
+ -- together. But they are *functions*, so @B as X, B as Y@ is
+ -- illegal.
+ let insertDistinct m (k,v) =
+ if Map.member k m
+ then error ("Duplicate requirement renaming " ++ display k)
+ else return (Map.insert k v m)
+ req_rename <- foldM insertDistinct Map.empty =<<
+ case req_rns of
+ DefaultRenaming -> return []
+ -- Not valid here, but whatever
+ HidingRenaming _ -> error "Cannot use hiding in requirement renaming"
+ ModuleRenaming rns -> return rns
+ let req_rename_fn k = case Map.lookup k req_rename of
+ Nothing -> k
+ Just v -> v
+
+ -- Requirement substitution.
+ --
+ -- A -> X ==> A -> <X>
+ let req_subst = fmap OpenModuleVar req_rename
+
+ uid_u <- convertUnitId (modSubst req_subst uid)
+
+ -- Requirement mapping. This is just taking the range of the
+ -- requirement substitution, and making a mapping so that it is
+ -- convenient to merge things together. It INCLUDES the implicit
+ -- mappings.
+ --
+ -- A -> X ==> X -> <X>, B -> <B>
+ reqs_u <- convertModuleSubst . Map.fromList $
+ [ (k, OpenModuleVar k)
+ | k <- map req_rename_fn (Set.toList reqs)
+ ]
+
+ -- Provision computation is more complex.
+ -- For example, if we have:
+ --
+ -- include p (A as X) requires (B as Y)
+ -- where A -> q[B=<B>]:A
+ --
+ -- Then we need:
+ --
+ -- X -> [("p", q[B=<B>]:A)]
+ --
+ -- There are a bunch of clever ways to present the algorithm
+ -- but here is the simple one:
+ --
+ -- 1. If we have a default renaming, apply req_subst
+ -- to provs and use that.
+ --
+ -- 2. Otherwise, build a map by successively looking
+ -- up the referenced modules in the renaming in provs.
+ --
+ -- Importantly, overlapping rename targets get accumulated
+ -- together. It's not an (immediate) error.
+ (pre_prov_scope, prov_rns') <-
+ case prov_rns of
+ DefaultRenaming -> return (Map.toList provs, prov_rns)
+ HidingRenaming hides ->
+ let hides_set = Set.fromList hides
+ in let r = [ (k,v)
+ | (k,v) <- Map.toList provs
+ , not (k `Set.member` hides_set) ]
+ -- GHC doesn't understand hiding, so expand it out!
+ in return (r, ModuleRenaming (map ((\x -> (x,x)).fst) r))
+ ModuleRenaming rns -> do
+ r <- sequence
+ [ case Map.lookup from provs of
+ Just m -> return (to, m)
+ Nothing -> error ("Tried to rename non-existent module " ++ display from)
+ | (from, to) <- rns ]
+ return (r, prov_rns)
+ let prov_scope = modSubst req_subst
+ $ Map.fromListWith (++)
+ [ (k, [ModuleSource pn incl v])
+ | (k, v) <- pre_prov_scope ]
+
+ provs_u <- convertModuleProvides prov_scope
+
+ return ((provs_u, reqs_u), (uid_u, pid, prov_rns'))
+
+-- | Convert a 'ModuleScopeU' to a 'ModuleScope'.
+convertModuleScopeU :: ModuleScopeU s -> UnifyM s ModuleScope
+convertModuleScopeU (provs_u, reqs_u) = do
+ provs <- convertModuleProvidesU provs_u
+ reqs <- convertModuleSubstU reqs_u
+ -- TODO: Test that the requirements are still free. If they
+ -- are not, they got unified, and that's dodgy at best.
+ return (ModuleScope provs (Map.keysSet reqs))
+
+-- | Convert a 'ModuleProvides' to a 'ModuleProvidesU'
+convertModuleProvides :: ModuleProvides -> UnifyM s (ModuleProvidesU s)
+convertModuleProvides = T.mapM $ \ms ->
+ mapM (\(ModuleSource pn incl m)
+ -> do m' <- convertModule m
+ return (ModuleSourceU pn incl m')) ms
+
+-- | Convert a 'ModuleProvidesU' to a 'ModuleProvides'
+convertModuleProvidesU :: ModuleProvidesU s -> UnifyM s ModuleProvides
+convertModuleProvidesU = T.mapM $ \ms ->
+ mapM (\(ModuleSourceU pn incl m)
+ -> do m' <- convertModuleU m
+ return (ModuleSource pn incl m')) ms
diff --git a/cabal/Cabal/Distribution/Compat/Binary.hs b/cabal/Cabal/Distribution/Compat/Binary.hs
index 5b842c7..00abe08 100644
--- a/cabal/Cabal/Distribution/Compat/Binary.hs
+++ b/cabal/Cabal/Distribution/Compat/Binary.hs
@@ -9,14 +9,19 @@
module Distribution.Compat.Binary
( decodeOrFailIO
+ , decodeFileOrFail'
#if __GLASGOW_HASKELL__ >= 708 || MIN_VERSION_binary(0,7,0)
, module Data.Binary
#else
, Binary(..)
- , decode, encode
+ , decode, encode, encodeFile
#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)
@@ -25,23 +30,25 @@ import Control.Exception (ErrorCall(..))
#endif
import Data.ByteString.Lazy (ByteString)
-#if __GLASGOW_HASKELL__ < 706
-import Prelude hiding (catch)
-#endif
-
#if __GLASGOW_HASKELL__ >= 708 || MIN_VERSION_binary(0,7,0)
import Data.Binary
+-- | Lazily reconstruct a value previously written to a file.
+decodeFileOrFail' :: Binary a => FilePath -> IO (Either String a)
+decodeFileOrFail' f = either (Left . snd) Right `fmap` decodeFileOrFail f
+
#else
import Data.Binary.Get
import Data.Binary.Put
+import qualified Data.ByteString.Lazy as BSL
import Distribution.Compat.Binary.Class
import Distribution.Compat.Binary.Generic ()
--- | Decode a value from a lazy ByteString, reconstructing the original structure.
+-- | Decode a value from a lazy ByteString, reconstructing the
+-- original structure.
--
decode :: Binary a => ByteString -> a
decode = runGet get
@@ -52,6 +59,14 @@ encode :: Binary a => a -> ByteString
encode = runPut . put
{-# INLINE encode #-}
+-- | Lazily reconstruct a value previously written to a file.
+decodeFileOrFail' :: Binary a => FilePath -> IO (Either String a)
+decodeFileOrFail' f = decodeOrFailIO =<< BSL.readFile f
+
+-- | Lazily serialise a value to a file
+encodeFile :: Binary a => FilePath -> a -> IO ()
+encodeFile f = BSL.writeFile f . encode
+
#endif
decodeOrFailIO :: Binary a => ByteString -> IO (Either String a)
diff --git a/cabal/Cabal/Distribution/Compat/Binary/Class.hs b/cabal/Cabal/Distribution/Compat/Binary/Class.hs
index 117c1d3..833e080 100644
--- a/cabal/Cabal/Distribution/Compat/Binary/Class.hs
+++ b/cabal/Cabal/Distribution/Compat/Binary/Class.hs
@@ -36,8 +36,9 @@ import Foreign
import Data.ByteString.Lazy (ByteString)
import qualified Data.ByteString.Lazy as L
-import Data.Char (chr,ord)
-import Data.List (unfoldr)
+import Data.Char (chr,ord)
+import Data.List (unfoldr)
+import Data.Foldable (traverse_)
-- And needed for the instances:
import qualified Data.ByteString as B
@@ -389,7 +390,7 @@ instance (Binary a, Binary b, Binary c, Binary d, Binary e,
-- Container types
instance Binary a => Binary [a] where
- put l = put (length l) >> mapM_ put l
+ put l = put (length l) >> traverse_ put l
get = do n <- get :: Get Int
getMany n
@@ -444,26 +445,26 @@ instance Binary ByteString where
-- Maps and Sets
instance (Binary a) => Binary (Set.Set a) where
- put s = put (Set.size s) >> mapM_ put (Set.toAscList s)
+ put s = put (Set.size s) >> traverse_ put (Set.toAscList s)
get = liftM Set.fromDistinctAscList get
instance (Binary k, Binary e) => Binary (Map.Map k e) where
- put m = put (Map.size m) >> mapM_ put (Map.toAscList m)
+ put m = put (Map.size m) >> traverse_ put (Map.toAscList m)
get = liftM Map.fromDistinctAscList get
instance Binary IntSet.IntSet where
- put s = put (IntSet.size s) >> mapM_ put (IntSet.toAscList s)
+ put s = put (IntSet.size s) >> traverse_ put (IntSet.toAscList s)
get = liftM IntSet.fromDistinctAscList get
instance (Binary e) => Binary (IntMap.IntMap e) where
- put m = put (IntMap.size m) >> mapM_ put (IntMap.toAscList m)
+ put m = put (IntMap.size m) >> traverse_ put (IntMap.toAscList m)
get = liftM IntMap.fromDistinctAscList get
------------------------------------------------------------------------
-- Queues and Sequences
instance (Binary e) => Binary (Seq.Seq e) where
- put s = put (Seq.length s) >> Fold.mapM_ put s
+ put s = put (Seq.length s) >> Fold.traverse_ put s
get = do n <- get :: Get Int
rep Seq.empty n get
where rep xs 0 _ = return $! xs
@@ -496,7 +497,7 @@ instance (Binary i, Ix i, Binary e) => Binary (Array i e) where
put a = do
put (bounds a)
put (rangeSize $ bounds a) -- write the length
- mapM_ put (elems a) -- now the elems.
+ traverse_ put (elems a) -- now the elems.
get = do
bs <- get
n <- get -- read the length
@@ -510,7 +511,7 @@ instance (Binary i, Ix i, Binary e, IArray UArray e) => Binary (UArray i e) wher
put a = do
put (bounds a)
put (rangeSize $ bounds a) -- now write the length
- mapM_ put (elems a)
+ traverse_ put (elems a)
get = do
bs <- get
n <- get
diff --git a/cabal/Cabal/Distribution/Compat/CopyFile.hs b/cabal/Cabal/Distribution/Compat/CopyFile.hs
index 486a209..1bf9553 100644
--- a/cabal/Cabal/Distribution/Compat/CopyFile.hs
+++ b/cabal/Cabal/Distribution/Compat/CopyFile.hs
@@ -11,11 +11,12 @@ module Distribution.Compat.CopyFile (
setDirOrdinary,
) where
+import Prelude ()
+import Distribution.Compat.Prelude
+
import Distribution.Compat.Exception
import Distribution.Compat.Internal.TempFile
-import Control.Monad
- ( when, unless )
import Control.Exception
( bracketOnError, throwIO )
import qualified Data.ByteString.Lazy as BSL
@@ -41,16 +42,16 @@ import Foreign.C
( throwErrnoPathIfMinus1_ )
#endif /* mingw32_HOST_OS */
-copyOrdinaryFile, copyExecutableFile :: FilePath -> FilePath -> IO ()
+copyOrdinaryFile, copyExecutableFile :: FilePath -> FilePath -> NoCallStackIO ()
copyOrdinaryFile src dest = copyFile src dest >> setFileOrdinary dest
copyExecutableFile src dest = copyFile src dest >> setFileExecutable dest
-setFileOrdinary, setFileExecutable, setDirOrdinary :: FilePath -> IO ()
+setFileOrdinary, setFileExecutable, setDirOrdinary :: FilePath -> NoCallStackIO ()
#ifndef mingw32_HOST_OS
setFileOrdinary path = setFileMode path 0o644 -- file perms -rw-r--r--
setFileExecutable path = setFileMode path 0o755 -- file perms -rwxr-xr-x
-setFileMode :: FilePath -> FileMode -> IO ()
+setFileMode :: FilePath -> FileMode -> NoCallStackIO ()
setFileMode name m =
withFilePath name $ \s -> do
throwErrnoPathIfMinus1_ "setFileMode" name (c_chmod s m)
@@ -63,7 +64,7 @@ setDirOrdinary = setFileExecutable
-- | Copies a file to a new destination.
-- Often you should use `copyFileChanged` instead.
-copyFile :: FilePath -> FilePath -> IO ()
+copyFile :: FilePath -> FilePath -> NoCallStackIO ()
copyFile fromFPath toFPath =
copy
`catchIO` (\ioe -> throwIO (ioeSetLocation ioe "copyFile"))
@@ -87,14 +88,14 @@ copyFile fromFPath toFPath =
-- | Like `copyFile`, but does not touch the target if source and destination
-- are already byte-identical. This is recommended as it is useful for
-- time-stamp based recompilation avoidance.
-copyFileChanged :: FilePath -> FilePath -> IO ()
+copyFileChanged :: FilePath -> FilePath -> NoCallStackIO ()
copyFileChanged src dest = do
equal <- filesEqual src dest
unless equal $ copyFile src dest
-- | Checks if two files are byte-identical.
-- Returns False if either of the files do not exist.
-filesEqual :: FilePath -> FilePath -> IO Bool
+filesEqual :: FilePath -> FilePath -> NoCallStackIO Bool
filesEqual f1 f2 = do
ex1 <- doesFileExist f1
ex2 <- doesFileExist f2
diff --git a/cabal/Cabal/Distribution/Compat/CreatePipe.hs b/cabal/Cabal/Distribution/Compat/CreatePipe.hs
index 22b3b2e..b9e3267 100644
--- a/cabal/Cabal/Distribution/Compat/CreatePipe.hs
+++ b/cabal/Cabal/Distribution/Compat/CreatePipe.hs
@@ -1,10 +1,18 @@
-{-# LANGUAGE CPP, ForeignFunctionInterface #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE RankNTypes #-}
+
module Distribution.Compat.CreatePipe (createPipe) where
import System.IO (Handle, hSetEncoding, localeEncoding)
+import Prelude ()
+import Distribution.Compat.Prelude
+import Distribution.Compat.Stack
+
-- The mingw32_HOST_OS CPP macro is GHC-specific
-#if mingw32_HOST_OS
+#ifdef mingw32_HOST_OS
+import qualified Prelude
import Control.Exception (onException)
import Foreign.C.Error (throwErrnoIfMinus1_)
import Foreign.C.Types (CInt(..), CUInt(..))
@@ -15,7 +23,7 @@ import GHC.IO.FD (mkFD)
import GHC.IO.Device (IODeviceType(Stream))
import GHC.IO.Handle.FD (mkHandleFromFD)
import System.IO (IOMode(ReadMode, WriteMode))
-#elif ghcjs_HOST_OS
+#elif defined ghcjs_HOST_OS
#else
import System.Posix.IO (fdToHandle)
import qualified System.Posix.IO as Posix
@@ -23,7 +31,7 @@ import qualified System.Posix.IO as Posix
createPipe :: IO (Handle, Handle)
-- The mingw32_HOST_OS CPP macro is GHC-specific
-#if mingw32_HOST_OS
+#ifdef mingw32_HOST_OS
createPipe = do
(readfd, writefd) <- allocaArray 2 $ \ pfds -> do
throwErrnoIfMinus1_ "_pipe" $ c__pipe pfds 2 ({- _O_BINARY -} 32768)
@@ -36,21 +44,26 @@ createPipe = do
hSetEncoding writeh localeEncoding
return (readh, writeh)) `onException` (close readfd >> close writefd)
where
- fdToHandle :: CInt -> IOMode -> IO Handle
+ fdToHandle :: CInt -> IOMode -> NoCallStackIO Handle
fdToHandle fd mode = do
(fd', deviceType) <- mkFD fd mode (Just (Stream, 0, 0)) False False
mkHandleFromFD fd' deviceType "" mode False Nothing
close :: CInt -> IO ()
close = throwErrnoIfMinus1_ "_close" . c__close
+ where _ = callStack -- TODO: attach call stack to exception
+
+ _ = callStack -- TODO: attach call stack to exceptions
foreign import ccall "io.h _pipe" c__pipe ::
- Ptr CInt -> CUInt -> CInt -> IO CInt
+ Ptr CInt -> CUInt -> CInt -> Prelude.IO CInt
foreign import ccall "io.h _close" c__close ::
- CInt -> IO CInt
-#elif ghcjs_HOST_OS
+ CInt -> Prelude.IO CInt
+#elif defined ghcjs_HOST_OS
createPipe = error "createPipe"
+ where
+ _ = callStack
#else
createPipe = do
(readfd, writefd) <- Posix.createPipe
@@ -59,4 +72,6 @@ createPipe = do
hSetEncoding readh localeEncoding
hSetEncoding writeh localeEncoding
return (readh, writeh)
+ where
+ _ = callStack
#endif
diff --git a/cabal/Cabal/Distribution/Compat/DList.hs b/cabal/Cabal/Distribution/Compat/DList.hs
new file mode 100644
index 0000000..48005bb
--- /dev/null
+++ b/cabal/Cabal/Distribution/Compat/DList.hs
@@ -0,0 +1,40 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module : Distribution.Compat.DList
+-- Copyright : (c) Ben Gamari 2015-2019
+-- License : BSD3
+--
+-- Maintainer : cabal-dev@haskell.org
+-- Stability : experimental
+-- Portability : portable
+--
+-- A very simple difference list.
+module Distribution.Compat.DList (
+ DList,
+ runDList,
+ singleton,
+ snoc,
+) where
+
+import Prelude ()
+import Distribution.Compat.Prelude
+
+-- | Difference list.
+newtype DList a = DList ([a] -> [a])
+
+runDList :: DList a -> [a]
+runDList (DList run) = run []
+
+-- | Make 'DList' with containing single element.
+singleton :: a -> DList a
+singleton a = DList (a:)
+
+snoc :: DList a -> a -> DList a
+snoc xs x = xs <> singleton x
+
+instance Monoid (DList a) where
+ mempty = DList id
+ mappend = (<>)
+
+instance Semigroup (DList a) where
+ DList a <> DList b = DList (a . b)
diff --git a/cabal/Cabal/Distribution/Compat/Environment.hs b/cabal/Cabal/Distribution/Compat/Environment.hs
index 69cde27..13900ba 100644
--- a/cabal/Cabal/Distribution/Compat/Environment.hs
+++ b/cabal/Cabal/Distribution/Compat/Environment.hs
@@ -1,21 +1,36 @@
{-# LANGUAGE CPP #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# OPTIONS_HADDOCK hide #-}
module Distribution.Compat.Environment
- ( getEnvironment, lookupEnv, setEnv )
+ ( getEnvironment, lookupEnv, setEnv, unsetEnv )
where
+import Prelude ()
+import qualified Prelude
+import Distribution.Compat.Prelude
+
+#ifndef mingw32_HOST_OS
+#if __GLASGOW_HASKELL__ < 708
+import Foreign.C.Error (throwErrnoIf_)
+#endif
+#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 Control.Monad
-import qualified Data.Char as Char (toUpper)
import Foreign.C
import GHC.Windows
#else
@@ -25,7 +40,7 @@ import Foreign.C.Error (throwErrnoIfMinus1_)
import System.Posix.Internals ( withFilePath )
#endif /* mingw32_HOST_OS */
-getEnvironment :: IO [(String, String)]
+getEnvironment :: NoCallStackIO [(String, String)]
#ifdef mingw32_HOST_OS
-- On Windows, the names of environment variables are case-insensitive, but are
-- often given in mixed-case (e.g. "PATH" is "Path"), so we have to normalise
@@ -33,7 +48,7 @@ getEnvironment :: IO [(String, String)]
getEnvironment = fmap upcaseVars System.getEnvironment
where
upcaseVars = map upcaseVar
- upcaseVar (var, val) = (map Char.toUpper var, val)
+ upcaseVar (var, val) = (map toUpper var, val)
#else
getEnvironment = System.getEnvironment
#endif
@@ -50,9 +65,7 @@ lookupEnv name = (Just `fmap` System.getEnv name) `catchIO` const (return Nothin
-- Throws `Control.Exception.IOException` if either @name@ or @value@ is the
-- empty string or contains an equals sign.
setEnv :: String -> String -> IO ()
-setEnv key value_
- | null value = error "Distribuiton.Compat.setEnv: empty string"
- | otherwise = setEnv_ key value
+setEnv key value_ = setEnv_ key value
where
-- NOTE: Anything that follows NUL is ignored on both POSIX and Windows. We
-- still strip it manually so that the null check above succeeds if a value
@@ -66,6 +79,8 @@ setEnv_ :: String -> String -> IO ()
setEnv_ key value = withCWString key $ \k -> withCWString value $ \v -> do
success <- c_SetEnvironmentVariable k v
unless success (throwGetLastError "setEnv")
+ where
+ _ = callStack -- TODO: attach CallStack to exception
# if defined(i386_HOST_ARCH)
# define WINDOWS_CCONV stdcall
@@ -76,14 +91,47 @@ setEnv_ key value = withCWString key $ \k -> withCWString value $ \v -> do
# endif /* i386_HOST_ARCH */
foreign import WINDOWS_CCONV unsafe "windows.h SetEnvironmentVariableW"
- c_SetEnvironmentVariable :: LPTSTR -> LPTSTR -> IO Bool
+ c_SetEnvironmentVariable :: LPTSTR -> LPTSTR -> Prelude.IO Bool
#else
setEnv_ key value = do
withFilePath key $ \ keyP ->
withFilePath value $ \ valueP ->
throwErrnoIfMinus1_ "setenv" $
c_setenv keyP valueP (fromIntegral (fromEnum True))
+ where
+ _ = callStack -- TODO: attach CallStack to exception
foreign import ccall unsafe "setenv"
- c_setenv :: CString -> CString -> CInt -> IO CInt
+ c_setenv :: CString -> CString -> CInt -> Prelude.IO CInt
#endif /* mingw32_HOST_OS */
+
+#if __GLASGOW_HASKELL__ < 708
+
+-- | @unsetEnv name@ removes the specified environment variable from the
+-- environment of the current process.
+--
+-- Throws `Control.Exception.IOException` if @name@ is the empty string or
+-- contains an equals sign.
+--
+-- @since 4.7.0.0
+unsetEnv :: String -> IO ()
+#ifdef mingw32_HOST_OS
+unsetEnv key = withCWString key $ \k -> do
+ success <- c_SetEnvironmentVariable k nullPtr
+ unless success $ do
+ -- We consider unsetting an environment variable that does not exist not as
+ -- an error, hence we ignore eRROR_ENVVAR_NOT_FOUND.
+ err <- c_GetLastError
+ unless (err == eRROR_ENVVAR_NOT_FOUND) $ do
+ throwGetLastError "unsetEnv"
+#else
+unsetEnv key = withFilePath key (throwErrnoIf_ (/= 0) "unsetEnv" . c_unsetenv)
+#if __GLASGOW_HASKELL__ > 706
+foreign import ccall unsafe "__hsbase_unsetenv" c_unsetenv :: CString -> Prelude.IO CInt
+#else
+-- HACK: We hope very hard that !UNSETENV_RETURNS_VOID
+foreign import ccall unsafe "unsetenv" c_unsetenv :: CString -> Prelude.IO CInt
+#endif
+#endif
+
+#endif
diff --git a/cabal/Cabal/Distribution/Compat/Exception.hs b/cabal/Cabal/Distribution/Compat/Exception.hs
index 453d8b0..c7a4ccd 100644
--- a/cabal/Cabal/Distribution/Compat/Exception.hs
+++ b/cabal/Cabal/Distribution/Compat/Exception.hs
@@ -1,11 +1,16 @@
+{-# LANGUAGE CPP #-}
module Distribution.Compat.Exception (
catchIO,
catchExit,
tryIO,
+ displayException,
) where
import System.Exit
import qualified Control.Exception as Exception
+#if __GLASGOW_HASKELL__ >= 710
+import Control.Exception (displayException)
+#endif
tryIO :: IO a -> IO (Either Exception.IOException a)
tryIO = Exception.try
@@ -15,3 +20,8 @@ catchIO = Exception.catch
catchExit :: IO a -> (ExitCode -> IO a) -> IO a
catchExit = Exception.catch
+
+#if __GLASGOW_HASKELL__ < 710
+displayException :: Exception.Exception e => e -> String
+displayException = show
+#endif
diff --git a/cabal/Cabal/Distribution/Compat/GetShortPathName.hs b/cabal/Cabal/Distribution/Compat/GetShortPathName.hs
new file mode 100644
index 0000000..eebad98
--- /dev/null
+++ b/cabal/Cabal/Distribution/Compat/GetShortPathName.hs
@@ -0,0 +1,59 @@
+{-# LANGUAGE CPP #-}
+
+-----------------------------------------------------------------------------
+-- |
+-- Module : Distribution.Compat.GetShortPathName
+--
+-- Maintainer : cabal-devel@haskell.org
+-- Portability : Windows-only
+--
+-- Win32 API 'GetShortPathName' function.
+
+module Distribution.Compat.GetShortPathName ( getShortPathName )
+ where
+
+import Prelude ()
+import Distribution.Compat.Prelude
+
+#ifdef mingw32_HOST_OS
+
+import qualified Prelude
+import qualified System.Win32 as Win32
+import System.Win32 (LPCTSTR, LPTSTR, DWORD)
+import Foreign.Marshal.Array (allocaArray)
+
+#ifdef x86_64_HOST_ARCH
+#define WINAPI ccall
+#else
+#define WINAPI stdcall
+#endif
+
+foreign import WINAPI unsafe "windows.h GetShortPathNameW"
+ c_GetShortPathName :: LPCTSTR -> LPTSTR -> DWORD -> Prelude.IO DWORD
+
+-- | On Windows, retrieves the short path form of the specified path. On
+-- non-Windows, does nothing. See https://github.com/haskell/cabal/issues/3185.
+--
+-- From MS's GetShortPathName docs:
+--
+-- Passing NULL for [the second] parameter and zero for cchBuffer
+-- will always return the required buffer size for a
+-- specified lpszLongPath.
+--
+getShortPathName :: FilePath -> NoCallStackIO FilePath
+getShortPathName path =
+ Win32.withTString path $ \c_path -> do
+ c_len <- Win32.failIfZero "GetShortPathName #1 failed!" $
+ c_GetShortPathName c_path Win32.nullPtr 0
+ let arr_len = fromIntegral c_len
+ allocaArray arr_len $ \c_out -> do
+ void $ Win32.failIfZero "GetShortPathName #2 failed!" $
+ c_GetShortPathName c_path c_out c_len
+ Win32.peekTString c_out
+
+#else
+
+getShortPathName :: FilePath -> NoCallStackIO FilePath
+getShortPathName path = return path
+
+#endif
diff --git a/cabal/Cabal/Distribution/Compat/Graph.hs b/cabal/Cabal/Distribution/Compat/Graph.hs
new file mode 100644
index 0000000..88e62eb
--- /dev/null
+++ b/cabal/Cabal/Distribution/Compat/Graph.hs
@@ -0,0 +1,403 @@
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE BangPatterns #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module : Distribution.Compat.Graph
+-- Copyright : (c) Edward Z. Yang 2016
+-- License : BSD3
+--
+-- Maintainer : cabal-dev@haskell.org
+-- Stability : experimental
+-- Portability : portable
+--
+-- A data type representing directed graphs, backed by "Data.Graph".
+-- It is strict in the node type.
+--
+-- This is an alternative interface to "Data.Graph". In this interface,
+-- nodes (identified by the 'IsNode' type class) are associated with a
+-- key and record the keys of their neighbors. This interface is more
+-- convenient than 'Data.Graph.Graph', which requires vertices to be
+-- explicitly handled by integer indexes.
+--
+-- The current implementation has somewhat peculiar performance
+-- characteristics. The asymptotics of all map-like operations mirror
+-- their counterparts in "Data.Map". However, to perform a graph
+-- operation, we first must build the "Data.Graph" representation, an
+-- operation that takes /O(V + E log V)/. However, this operation can
+-- be amortized across all queries on that particular graph.
+--
+-- Some nodes may be broken, i.e., refer to neighbors which are not
+-- stored in the graph. In our graph algorithms, we transparently
+-- ignore such edges; however, you can easily query for the broken
+-- vertices of a graph using 'broken' (and should, e.g., to ensure that
+-- a closure of a graph is well-formed.) It's possible to take a closed
+-- subset of a broken graph and get a well-formed graph.
+--
+-----------------------------------------------------------------------------
+
+module Distribution.Compat.Graph (
+ -- * Graph type
+ Graph,
+ IsNode(..),
+ -- * Query
+ null,
+ size,
+ member,
+ lookup,
+ -- * Construction
+ empty,
+ insert,
+ deleteKey,
+ deleteLookup,
+ -- * Combine
+ unionLeft,
+ unionRight,
+ -- * Graph algorithms
+ stronglyConnComp,
+ SCC(..),
+ cycles,
+ broken,
+ neighbors,
+ revNeighbors,
+ closure,
+ revClosure,
+ topSort,
+ revTopSort,
+ -- * Conversions
+ -- ** Maps
+ toMap,
+ -- ** Lists
+ fromList,
+ toList,
+ keys,
+ -- ** Sets
+ keysSet,
+ -- ** Graphs
+ toGraph,
+ -- * Node type
+ Node(..),
+ nodeValue,
+) where
+
+import Prelude ()
+import qualified Distribution.Compat.Prelude as Prelude
+import Distribution.Compat.Prelude hiding (lookup, null, empty)
+
+import Data.Graph (SCC(..))
+import qualified Data.Graph as G
+import qualified Data.Map as Map
+import qualified Data.Set as Set
+import qualified Data.Array as Array
+import Data.Array ((!))
+import qualified Data.Tree as Tree
+import Data.Either (partitionEithers)
+import qualified Data.Foldable as Foldable
+
+-- | A graph of nodes @a@. The nodes are expected to have instance
+-- of class 'IsNode'.
+data Graph a
+ = Graph {
+ graphMap :: !(Map (Key a) a),
+ -- Lazily cached graph representation
+ graphForward :: G.Graph,
+ graphAdjoint :: G.Graph,
+ graphVertexToNode :: G.Vertex -> a,
+ graphKeyToVertex :: Key a -> Maybe G.Vertex,
+ graphBroken :: [(a, [Key a])]
+ }
+ deriving (Typeable)
+
+-- NB: Not a Functor! (or Traversable), because you need
+-- to restrict Key a ~ Key b. We provide our own mapping
+-- functions.
+
+-- General strategy is most operations are deferred to the
+-- Map representation.
+
+instance Show a => Show (Graph a) where
+ show = show . toList
+
+instance (IsNode a, Read a) => Read (Graph a) where
+ readsPrec d s = map (\(a,r) -> (fromList a, r)) (readsPrec d s)
+
+instance (IsNode a, Binary a) => Binary (Graph a) where
+ put x = put (toList x)
+ get = fmap fromList get
+
+instance (Eq (Key a), Eq a) => Eq (Graph a) where
+ g1 == g2 = graphMap g1 == graphMap g2
+
+instance Foldable.Foldable Graph where
+ fold = Foldable.fold . graphMap
+ 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
+#if MIN_VERSION_base(4,8,0)
+ length = Foldable.length . graphMap
+ null = Foldable.null . graphMap
+ toList = Foldable.toList . graphMap
+ elem x = Foldable.elem x . graphMap
+ maximum = Foldable.maximum . graphMap
+ minimum = Foldable.minimum . graphMap
+ sum = Foldable.sum . graphMap
+ product = Foldable.product . graphMap
+#endif
+#endif
+
+instance (NFData a, NFData (Key a)) => NFData (Graph a) where
+ rnf Graph {
+ graphMap = m,
+ graphForward = gf,
+ graphAdjoint = ga,
+ graphVertexToNode = vtn,
+ graphKeyToVertex = ktv,
+ graphBroken = b
+ } = gf `seq` ga `seq` vtn `seq` ktv `seq` b `seq` rnf m
+
+-- TODO: Data instance?
+
+-- | The 'IsNode' class is used for datatypes which represent directed
+-- graph nodes. A node of type @a@ is associated with some unique key of
+-- 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 :: *
+ nodeKey :: a -> Key a
+ nodeNeighbors :: a -> [Key a]
+
+instance (IsNode a, IsNode b, Key a ~ Key b) => IsNode (Either a b) where
+ type Key (Either a b) = Key a
+ nodeKey (Left x) = nodeKey x
+ nodeKey (Right x) = nodeKey x
+ nodeNeighbors (Left x) = nodeNeighbors x
+ nodeNeighbors (Right x) = nodeNeighbors x
+
+-- | A simple, trivial data type which admits an 'IsNode' instance.
+data Node k a = N a k [k]
+ deriving (Show, Eq)
+
+-- | Get the value from a 'Node'.
+nodeValue :: Node k a -> a
+nodeValue (N a _ _) = a
+
+instance Functor (Node k) where
+ fmap f (N a k ks) = N (f a) k ks
+
+instance Ord k => IsNode (Node k a) where
+ type Key (Node k a) = k
+ nodeKey (N _ k _) = k
+ nodeNeighbors (N _ _ ks) = ks
+
+-- TODO: Maybe introduce a typeclass for items which just
+-- keys (so, Key associated type, and nodeKey method). But
+-- I didn't need it here, so I didn't introduce it.
+
+-- Query
+
+-- | /O(1)/. Is the graph empty?
+null :: Graph a -> Bool
+null = Map.null . toMap
+
+-- | /O(1)/. The number of nodes in the graph.
+size :: Graph a -> Int
+size = Map.size . toMap
+
+-- | /O(log V)/. Check if the key is in the graph.
+member :: IsNode a => Key a -> Graph a -> Bool
+member k g = Map.member k (toMap g)
+
+-- | /O(log V)/. Lookup the node at a key in the graph.
+lookup :: IsNode a => Key a -> Graph a -> Maybe a
+lookup k g = Map.lookup k (toMap g)
+
+-- Construction
+
+-- | /O(1)/. The empty graph.
+empty :: IsNode a => Graph a
+empty = fromMap Map.empty
+
+-- | /O(log V)/. Insert a node into a graph.
+insert :: IsNode a => a -> Graph a -> Graph a
+insert !n g = fromMap (Map.insert (nodeKey n) n (toMap g))
+
+-- | /O(log V)/. Delete the node at a key from the graph.
+deleteKey :: IsNode a => Key a -> Graph a -> Graph a
+deleteKey k g = fromMap (Map.delete k (toMap g))
+
+-- | /O(log V)/. Lookup and delete. This function returns the deleted
+-- value if it existed.
+deleteLookup :: IsNode a => Key a -> Graph a -> (Maybe a, Graph a)
+deleteLookup k g =
+ let (r, m') = Map.updateLookupWithKey (\_ _ -> Nothing) k (toMap g)
+ in (r, fromMap m')
+
+-- Combining
+
+-- | /O(V + V')/. Right-biased union, preferring entries
+-- from the second map when conflicts occur.
+-- @'nodeKey' x = 'nodeKey' (f x)@.
+unionRight :: IsNode a => Graph a -> Graph a -> Graph a
+unionRight g g' = fromMap (Map.union (toMap g') (toMap g))
+
+-- | /O(V + V')/. Left-biased union, preferring entries from
+-- the first map when conflicts occur.
+unionLeft :: IsNode a => Graph a -> Graph a -> Graph a
+unionLeft = flip unionRight
+
+-- Graph-like operations
+
+-- | /Ω(V + E)/. Compute the strongly connected components of a graph.
+-- Requires amortized construction of graph.
+stronglyConnComp :: Graph a -> [SCC a]
+stronglyConnComp g = map decode forest
+ where
+ forest = G.scc (graphForward g)
+ decode (Tree.Node v [])
+ | mentions_itself v = CyclicSCC [graphVertexToNode g v]
+ | otherwise = AcyclicSCC (graphVertexToNode g v)
+ decode other = CyclicSCC (dec other [])
+ where dec (Tree.Node v ts) vs
+ = graphVertexToNode g v : foldr dec vs ts
+ mentions_itself v = v `elem` (graphForward g ! v)
+-- Implementation copied from 'stronglyConnCompR' in 'Data.Graph'.
+
+-- | /Ω(V + E)/. Compute the cycles of a graph.
+-- Requires amortized construction of graph.
+cycles :: Graph a -> [[a]]
+cycles g = [ vs | CyclicSCC vs <- stronglyConnComp g ]
+
+-- | /O(1)/. Return a list of nodes paired with their broken
+-- neighbors (i.e., neighbor keys which are not in the graph).
+-- Requires amortized construction of graph.
+broken :: Graph a -> [(a, [Key a])]
+broken g = graphBroken g
+
+-- | Lookup the immediate neighbors from a key in the graph.
+-- Requires amortized construction of graph.
+neighbors :: Graph a -> Key a -> Maybe [a]
+neighbors g k = do
+ v <- graphKeyToVertex g k
+ return (map (graphVertexToNode g) (graphForward g ! v))
+
+-- | Lookup the immediate reverse neighbors from a key in the graph.
+-- Requires amortized construction of graph.
+revNeighbors :: Graph a -> Key a -> Maybe [a]
+revNeighbors g k = do
+ v <- graphKeyToVertex g k
+ return (map (graphVertexToNode g) (graphAdjoint g ! v))
+
+-- | Compute the subgraph which is the closure of some set of keys.
+-- Returns @Nothing@ if one (or more) keys are not present in
+-- the graph.
+-- Requires amortized construction of graph.
+closure :: Graph a -> [Key a] -> Maybe [a]
+closure g ks = do
+ vs <- traverse (graphKeyToVertex g) ks
+ return (decodeVertexForest g (G.dfs (graphForward g) vs))
+
+-- | Compute the reverse closure of a graph from some set
+-- of keys. Returns @Nothing@ if one (or more) keys are not present in
+-- the graph.
+-- Requires amortized construction of graph.
+revClosure :: Graph a -> [Key a] -> Maybe [a]
+revClosure g ks = do
+ vs <- traverse (graphKeyToVertex g) ks
+ return (decodeVertexForest g (G.dfs (graphAdjoint g) vs))
+
+flattenForest :: Tree.Forest a -> [a]
+flattenForest = concatMap Tree.flatten
+
+decodeVertexForest :: Graph a -> Tree.Forest G.Vertex -> [a]
+decodeVertexForest g = map (graphVertexToNode g) . flattenForest
+
+-- | Topologically sort the nodes of a graph.
+-- Requires amortized construction of graph.
+topSort :: Graph a -> [a]
+topSort g = map (graphVertexToNode g) $ G.topSort (graphForward g)
+
+-- | Reverse topologically sort the nodes of a graph.
+-- Requires amortized construction of graph.
+revTopSort :: Graph a -> [a]
+revTopSort g = map (graphVertexToNode g) $ G.topSort (graphAdjoint g)
+
+-- Conversions
+
+-- | /O(1)/. Convert a map from keys to nodes into a graph.
+-- The map must satisfy the invariant that
+-- @'fromMap' m == 'fromList' ('Data.Map.elems' m)@;
+-- if you can't fulfill this invariant use @'fromList' ('Data.Map.elems' m)@
+-- instead. The values of the map are assumed to already
+-- be in WHNF.
+fromMap :: IsNode a => Map (Key a) a -> Graph a
+fromMap m
+ = Graph { graphMap = m
+ -- These are lazily computed!
+ , graphForward = g
+ , graphAdjoint = G.transposeG g
+ , graphVertexToNode = vertex_to_node
+ , graphKeyToVertex = key_to_vertex
+ , graphBroken = broke
+ }
+ where
+ try_key_to_vertex k = maybe (Left k) Right (key_to_vertex k)
+
+ (brokenEdges, edges)
+ = unzip
+ $ [ partitionEithers (map try_key_to_vertex (nodeNeighbors n))
+ | n <- ns ]
+ broke = filter (not . Prelude.null . snd) (zip ns brokenEdges)
+
+ g = Array.listArray bounds edges
+
+ ns = Map.elems m -- sorted ascending
+ vertices = zip (map nodeKey ns) [0..]
+ vertex_map = Map.fromAscList vertices
+ key_to_vertex k = Map.lookup k vertex_map
+
+ vertex_to_node vertex = nodeTable ! vertex
+
+ nodeTable = Array.listArray bounds ns
+ bounds = (0, Map.size m - 1)
+
+-- | /O(V log V)/. Convert a list of nodes into a graph.
+fromList :: IsNode a => [a] -> Graph a
+fromList ns = fromMap
+ . Map.fromList
+ . map (\n -> n `seq` (nodeKey n, n))
+ $ ns
+
+-- Map-like operations
+
+-- | /O(V)/. Convert a graph into a list of nodes.
+toList :: Graph a -> [a]
+toList g = Map.elems (toMap g)
+
+-- | /O(V)/. Convert a graph into a list of keys.
+keys :: Graph a -> [Key a]
+keys g = Map.keys (toMap g)
+
+-- | /O(V)/. Convert a graph into a set of keys.
+keysSet :: Graph a -> Set.Set (Key a)
+keysSet g = Map.keysSet (toMap g)
+
+-- | /O(1)/. Convert a graph into a map from keys to nodes.
+-- The resulting map @m@ is guaranteed to have the property that
+-- @'Prelude.all' (\(k,n) -> k == 'nodeKey' n) ('Data.Map.toList' m)@.
+toMap :: Graph a -> Map (Key a) a
+toMap = graphMap
+
+-- Graph-like operations
+
+-- | /O(1)/. Convert a graph into a 'Data.Graph.Graph'.
+-- Requires amortized construction of graph.
+toGraph :: Graph a -> (G.Graph, G.Vertex -> a, Key a -> Maybe G.Vertex)
+toGraph g = (graphForward g, graphVertexToNode g, graphKeyToVertex g)
diff --git a/cabal/Cabal/Distribution/Compat/MonadFail.hs b/cabal/Cabal/Distribution/Compat/MonadFail.hs
index a17e0d4..f535ccf 100644
--- a/cabal/Cabal/Distribution/Compat/MonadFail.hs
+++ b/cabal/Cabal/Distribution/Compat/MonadFail.hs
@@ -9,7 +9,7 @@ import Control.Monad.Fail (MonadFail(fail))
-- the following code corresponds to
-- http://hackage.haskell.org/package/fail-4.9.0.0
import qualified Prelude as P
-import Prelude hiding (fail)
+import Distribution.Compat.Prelude hiding (fail)
import Text.ParserCombinators.ReadP
import Text.ParserCombinators.ReadPrec
@@ -25,7 +25,7 @@ instance MonadFail Maybe where
instance MonadFail [] where
fail _ = []
-instance MonadFail IO where
+instance MonadFail P.IO where
fail = P.fail
instance MonadFail ReadPrec where
diff --git a/cabal/Cabal/Distribution/Compat/Parsec.hs b/cabal/Cabal/Distribution/Compat/Parsec.hs
new file mode 100644
index 0000000..1352936
--- /dev/null
+++ b/cabal/Cabal/Distribution/Compat/Parsec.hs
@@ -0,0 +1,73 @@
+{-# 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,
+
+ -- * Char
+ integral,
+ P.char,
+ P.anyChar,
+ P.satisfy,
+ P.space,
+ P.spaces,
+ 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
diff --git a/cabal/Cabal/Distribution/Compat/Prelude.hs b/cabal/Cabal/Distribution/Compat/Prelude.hs
new file mode 100644
index 0000000..21eec8d
--- /dev/null
+++ b/cabal/Cabal/Distribution/Compat/Prelude.hs
@@ -0,0 +1,203 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE FlexibleContexts #-}
+
+#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:
+--
+-- * Acts as a compatiblity layer, like @base-compat@.
+--
+-- * Provides commonly used imports.
+module Distribution.Compat.Prelude (
+ -- * Prelude
+ --
+ -- Prelude is re-exported, following is hidden:
+ module BasePrelude,
+
+#if !MINVER_base_48
+ -- * base 4.8 shim
+ Applicative(..), (<$), (<$>),
+ Monoid(..),
+#endif
+
+ -- * Common type-classes
+ Semigroup (..),
+ gmappend, gmempty,
+ Typeable,
+ Data,
+ Generic,
+ NFData (..), genericRnf,
+ Binary (..),
+ Alternative (..),
+ MonadPlus (..),
+
+ -- * Some types
+ IO, NoCallStackIO,
+ Map,
+
+ -- * Data.Maybe
+ catMaybes, mapMaybe,
+ fromMaybe,
+ maybeToList, listToMaybe,
+ isNothing, isJust,
+
+ -- * Data.List
+ unfoldr,
+ isPrefixOf, isSuffixOf,
+ intercalate, intersperse,
+ sort, sortBy,
+ nub, nubBy,
+
+ -- * Data.Foldable
+ Foldable, foldMap, foldr,
+ null, length,
+ find, foldl',
+ traverse_, for_,
+
+ -- * Data.Traversable
+ Traversable, traverse, sequenceA,
+ for,
+
+ -- * Control.Arrow
+ first,
+
+ -- * Control.Monad
+ liftM, liftM2,
+ unless, when,
+ ap, void,
+ foldM, filterM,
+
+ -- * Data.Char
+ isSpace, isDigit, isUpper, isAlpha, isAlphaNum,
+ chr, ord,
+ toLower, toUpper,
+
+ -- * Data.Word & Data.Int
+ Word,
+ Word8, Word16, Word32, Word64,
+ Int8, Int16, Int32, Int64,
+
+ -- * Text.PrettyPrint
+ (<<>>),
+ ) where
+
+-- We also could hide few partial function
+import Prelude as BasePrelude hiding
+ ( IO, mapM, mapM_, sequence, null, length, foldr
+#if MINVER_base_48
+ , Word
+ -- We hide them, as we import only some members
+ , Traversable, traverse, sequenceA
+ , Foldable, foldMap
+#endif
+ )
+
+#if !MINVER_base_48
+import Control.Applicative (Applicative (..), (<$), (<$>))
+import Distribution.Compat.Semigroup (Monoid (..))
+#else
+import Data.Foldable (length, null)
+#endif
+
+import Data.Foldable (Foldable (foldMap, foldr), find, foldl', for_, traverse_)
+import Data.Traversable (Traversable (traverse, sequenceA), for)
+
+import Control.Applicative (Alternative (..))
+import Control.DeepSeq (NFData (..))
+import Data.Data (Data)
+import Data.Typeable (Typeable)
+import Distribution.Compat.Binary (Binary (..))
+import Distribution.Compat.Semigroup (Semigroup (..), gmappend, gmempty)
+import GHC.Generics (Generic, Rep(..),
+ V1, U1(U1), K1(unK1), M1(unM1),
+ (:*:)((:*:)), (:+:)(L1,R1))
+
+import Data.Map (Map)
+
+import Control.Arrow (first)
+import Control.Monad hiding (mapM)
+import Data.Char
+import Data.List (intercalate, intersperse, isPrefixOf,
+ isSuffixOf, nub, nubBy, sort, sortBy,
+ unfoldr)
+import Data.Maybe
+import Data.Int
+import Data.Word
+
+import qualified Text.PrettyPrint as Disp
+
+import qualified Prelude as OrigPrelude
+import Distribution.Compat.Stack
+
+type IO a = WithCallStack (OrigPrelude.IO a)
+type NoCallStackIO a = OrigPrelude.IO a
+
+-- | New name for 'Text.PrettyPrint.<>'
+(<<>>) :: Disp.Doc -> Disp.Doc -> Disp.Doc
+(<<>>) = (Disp.<>)
+
+#if !MINVER_base_48
+-- | Test whether the structure is empty. The default implementation is
+-- optimized for structures that are similar to cons-lists, because there
+-- is no general way to do better.
+null :: Foldable t => t a -> Bool
+null = foldr (\_ _ -> False) True
+
+-- | Returns the size/length of a finite structure as an 'Int'. The
+-- default implementation is optimized for structures that are similar to
+-- cons-lists, because there is no general way to do better.
+length :: Foldable t => t a -> Int
+length = foldl' (\c _ -> c+1) 0
+#endif
+
+
+-- | "GHC.Generics"-based 'rnf' implementation
+--
+-- This is needed in order to support @deepseq < 1.4@ which didn't
+-- have a 'Generic'-based default 'rnf' implementation yet.
+--
+-- In order to define instances, use e.g.
+--
+-- > instance NFData MyType where rnf = genericRnf
+--
+-- The implementation has been taken from @deepseq-1.4.2@'s default
+-- 'rnf' implementation.
+genericRnf :: (Generic a, GNFData (Rep a)) => a -> ()
+genericRnf = grnf . from
+
+-- | Hidden internal type-class
+class GNFData f where
+ grnf :: f a -> ()
+
+instance GNFData V1 where
+ grnf = error "Control.DeepSeq.rnf: uninhabited type"
+
+instance GNFData U1 where
+ grnf U1 = ()
+
+instance NFData a => GNFData (K1 i a) where
+ grnf = rnf . unK1
+ {-# INLINEABLE grnf #-}
+
+instance GNFData a => GNFData (M1 i c a) where
+ grnf = grnf . unM1
+ {-# INLINEABLE grnf #-}
+
+instance (GNFData a, GNFData b) => GNFData (a :*: b) where
+ grnf (x :*: y) = grnf x `seq` grnf y
+ {-# INLINEABLE grnf #-}
+
+instance (GNFData a, GNFData b) => GNFData (a :+: b) where
+ grnf (L1 x) = grnf x
+ grnf (R1 x) = grnf x
+ {-# INLINEABLE grnf #-}
diff --git a/cabal/Cabal/Distribution/Compat/Prelude/Internal.hs b/cabal/Cabal/Distribution/Compat/Prelude/Internal.hs
new file mode 100644
index 0000000..b3f998d
--- /dev/null
+++ b/cabal/Cabal/Distribution/Compat/Prelude/Internal.hs
@@ -0,0 +1,14 @@
+-- | This module re-exports the non-exposed
+-- "Distribution.Compat.Prelude" module for
+-- reuse by @cabal-install@'s
+-- "Distribution.Client.Compat.Prelude" module.
+--
+-- It is highly discouraged to rely on this module
+-- for @Setup.hs@ scripts since its API is /not/
+-- stable.
+module Distribution.Compat.Prelude.Internal
+ {-# WARNING "This modules' API is not stable. Use at your own risk, or better yet, use @base-compat@!" #-}
+ ( module Distribution.Compat.Prelude
+ ) where
+
+import Distribution.Compat.Prelude
diff --git a/cabal/Cabal/Distribution/Compat/ReadP.hs b/cabal/Cabal/Distribution/Compat/ReadP.hs
index b4a3a09..44afb1c 100644
--- a/cabal/Cabal/Distribution/Compat/ReadP.hs
+++ b/cabal/Cabal/Distribution/Compat/ReadP.hs
@@ -37,6 +37,7 @@ module Distribution.Compat.ReadP
-- * Other operations
pfail, -- :: ReadP a
+ eof, -- :: ReadP ()
satisfy, -- :: (Char -> Bool) -> ReadP Char
char, -- :: Char -> ReadP Char
string, -- :: String -> ReadP String
@@ -69,11 +70,12 @@ module Distribution.Compat.ReadP
)
where
+import Prelude ()
+import Distribution.Compat.Prelude hiding (many, get)
+
import qualified Distribution.Compat.MonadFail as Fail
-import Control.Monad( MonadPlus(..), liftM, liftM2, replicateM, ap, (>=>) )
-import Data.Char (isSpace)
-import Control.Applicative as AP (Applicative(..), Alternative(empty, (<|>)))
+import Control.Monad( replicateM, (>=>) )
infixr 5 +++, <++
@@ -98,7 +100,7 @@ instance Applicative (P s) where
(<*>) = ap
instance Monad (P s) where
- return = AP.pure
+ return = pure
(Get f) >>= k = Get (f >=> k)
(Look f) >>= k = Look (f >=> k)
@@ -160,7 +162,7 @@ instance Applicative (Parser r s) where
(<*>) = ap
instance Monad (Parser r s) where
- return = AP.pure
+ return = pure
fail = Fail.fail
R m >>= f = R (\k -> m (\a -> let R m' = f a in m' k))
@@ -203,6 +205,12 @@ pfail :: ReadP r a
-- ^ Always fails.
pfail = R (const Fail)
+eof :: ReadP r ()
+-- ^ Succeeds iff we are at the end of input
+eof = do { s <- look
+ ; if null s then return ()
+ else pfail }
+
(+++) :: ReadP r a -> ReadP r a -> ReadP r a
-- ^ Symmetric choice.
R f1 +++ R f2 = R (\k -> f1 k `mplus` f2 k)
diff --git a/cabal/Cabal/Distribution/Compat/SnocList.hs b/cabal/Cabal/Distribution/Compat/SnocList.hs
new file mode 100644
index 0000000..c567916
--- /dev/null
+++ b/cabal/Cabal/Distribution/Compat/SnocList.hs
@@ -0,0 +1,33 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module : Distribution.Compat.SnocList
+-- License : BSD3
+--
+-- Maintainer : cabal-dev@haskell.org
+-- Stability : experimental
+-- Portability : portable
+--
+-- A very reversed list. Has efficient `snoc`
+module Distribution.Compat.SnocList (
+ SnocList,
+ runSnocList,
+ snoc,
+) where
+
+import Prelude ()
+import Distribution.Compat.Prelude
+
+newtype SnocList a = SnocList [a]
+
+snoc :: SnocList a -> a -> SnocList a
+snoc (SnocList xs) x = SnocList (x : xs)
+
+runSnocList :: SnocList a -> [a]
+runSnocList (SnocList xs) = reverse xs
+
+instance Semigroup (SnocList a) where
+ SnocList xs <> SnocList ys = SnocList (ys <> xs)
+
+instance Monoid (SnocList a) where
+ mempty = SnocList []
+ mappend = (<>)
diff --git a/cabal/Cabal/Distribution/Compat/Stack.hs b/cabal/Cabal/Distribution/Compat/Stack.hs
new file mode 100644
index 0000000..98e8159
--- /dev/null
+++ b/cabal/Cabal/Distribution/Compat/Stack.hs
@@ -0,0 +1,96 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ImplicitParams #-}
+module Distribution.Compat.Stack (
+ WithCallStack,
+ CallStack,
+ withFrozenCallStack,
+ withLexicalCallStack,
+ callStack,
+ prettyCallStack,
+ parentSrcLocPrefix
+) where
+
+#ifdef MIN_VERSION_base
+#if MIN_VERSION_base(4,8,1)
+#define GHC_STACK_SUPPORTED 1
+#endif
+#endif
+
+#ifdef GHC_STACK_SUPPORTED
+import GHC.Stack
+#endif
+
+#ifdef GHC_STACK_SUPPORTED
+
+#if MIN_VERSION_base(4,9,0)
+type WithCallStack a = HasCallStack => a
+#elif MIN_VERSION_base(4,8,1)
+type WithCallStack a = (?callStack :: CallStack) => a
+#endif
+
+#if !MIN_VERSION_base(4,9,0)
+-- NB: Can't say WithCallStack (WithCallStack a -> a);
+-- Haskell doesn't support this kind of implicit parameter!
+-- See https://mail.haskell.org/pipermail/ghc-devs/2016-January/011096.html
+-- Since this function doesn't do anything, it's OK to
+-- give it a less good type.
+withFrozenCallStack :: WithCallStack (a -> a)
+withFrozenCallStack x = x
+
+callStack :: (?callStack :: CallStack) => CallStack
+callStack = ?callStack
+
+prettyCallStack :: CallStack -> String
+prettyCallStack = showCallStack
+#endif
+
+-- | Give the *parent* of the person who invoked this;
+-- so it's most suitable for being called from a utility function.
+-- You probably want to call this using 'withFrozenCallStack'; otherwise
+-- it's not very useful. We didn't implement this for base-4.8.1
+-- because we cannot rely on freezing to have taken place.
+--
+parentSrcLocPrefix :: WithCallStack String
+#if MIN_VERSION_base(4,9,0)
+parentSrcLocPrefix =
+ case getCallStack callStack of
+ (_:(_, loc):_) -> showLoc loc
+ [(_, loc)] -> showLoc loc
+ [] -> error "parentSrcLocPrefix: empty call stack"
+ where
+ showLoc loc =
+ srcLocFile loc ++ ":" ++ show (srcLocStartLine loc) ++ ": "
+#else
+parentSrcLocPrefix = "Call sites not available with base < 4.9.0.0 (GHC 8.0): "
+#endif
+
+-- Yeah, this uses skivvy implementation details.
+withLexicalCallStack :: (a -> WithCallStack (IO b)) -> WithCallStack (a -> IO b)
+withLexicalCallStack f =
+ let stk = ?callStack
+ in \x -> let ?callStack = stk in f x
+
+#else
+
+data CallStack = CallStack
+ deriving (Eq, Show)
+
+type WithCallStack a = a
+
+withFrozenCallStack :: a -> a
+withFrozenCallStack x = x
+
+callStack :: CallStack
+callStack = CallStack
+
+prettyCallStack :: CallStack -> String
+prettyCallStack _ = "Call stacks not available with base < 4.8.1.0 (GHC 7.10)"
+
+parentSrcLocPrefix :: String
+parentSrcLocPrefix = "Call sites not available with base < 4.9.0.0 (GHC 8.0): "
+
+withLexicalCallStack :: (a -> IO b) -> a -> IO b
+withLexicalCallStack f = f
+
+#endif
diff --git a/cabal/cabal-install/Distribution/Client/Compat/Time.hs b/cabal/Cabal/Distribution/Compat/Time.hs
index 699431e..db359ac 100644
--- a/cabal/cabal-install/Distribution/Client/Compat/Time.hs
+++ b/cabal/Cabal/Distribution/Compat/Time.hs
@@ -1,21 +1,30 @@
-{-# LANGUAGE CPP, ForeignFunctionInterface, GeneralizedNewtypeDeriving #-}
-module Distribution.Client.Compat.Time
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Distribution.Compat.Time
( ModTime(..) -- Needed for testing
, getModTime, getFileAge, getCurTime
- , posixSecondsToModTime )
+ , posixSecondsToModTime
+ , calibrateMtimeChangeDelay )
where
-import Control.Arrow ( first )
-import Data.Int ( Int64 )
-import Data.Word ( Word64 )
+import Prelude ()
+import Distribution.Compat.Prelude
+
import System.Directory ( getModificationTime )
-import Distribution.Compat.Binary ( Binary )
+import Distribution.Simple.Utils ( withTempDirectory )
+import Distribution.Verbosity ( silent )
+
+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 )
-import Data.Time ( diffUTCTime, getCurrentTime )
#else
import System.Time ( getClockTime, diffClockTimes
, normalizeTimeDiff, tdDay, tdHour )
@@ -23,6 +32,7 @@ import System.Time ( getClockTime, diffClockTimes
#if defined mingw32_HOST_OS
+import qualified Prelude
import Data.Bits ((.|.), unsafeShiftL)
#if MIN_VERSION_base(4,7,0)
import Data.Bits (finiteBitSize)
@@ -30,7 +40,6 @@ import Data.Bits (finiteBitSize)
import Data.Bits (bitSize)
#endif
-import Data.Int ( Int32 )
import Foreign ( allocaBytes, peekByteOff )
import System.IO.Error ( mkIOError, doesNotExistErrorType )
import System.Win32.Types ( BOOL, DWORD, LPCTSTR, LPVOID, withTString )
@@ -63,7 +72,7 @@ instance Read ModTime where
--
-- This is a modified version of the code originally written for Shake by Neil
-- Mitchell. See module Development.Shake.FileInfo.
-getModTime :: FilePath -> IO ModTime
+getModTime :: FilePath -> NoCallStackIO ModTime
#if defined mingw32_HOST_OS
@@ -73,7 +82,7 @@ getModTime path = allocaBytes size_WIN32_FILE_ATTRIBUTE_DATA $ \info -> do
if not res
then do
let err = mkIOError doesNotExistErrorType
- "Distribution.Client.Compat.Time.getModTime"
+ "Distribution.Compat.Time.getModTime"
Nothing (Just path)
ioError err
else do
@@ -99,9 +108,9 @@ getModTime path = allocaBytes size_WIN32_FILE_ATTRIBUTE_DATA $ \info -> do
#endif
foreign import CALLCONV "windows.h GetFileAttributesExW"
- c_getFileAttributesEx :: LPCTSTR -> Int32 -> LPVOID -> IO BOOL
+ c_getFileAttributesEx :: LPCTSTR -> Int32 -> LPVOID -> Prelude.IO BOOL
-getFileAttributesEx :: String -> LPVOID -> IO BOOL
+getFileAttributesEx :: String -> LPVOID -> NoCallStackIO BOOL
getFileAttributesEx path lpFileInformation =
withTString path $ \c_path ->
c_getFileAttributesEx c_path getFileExInfoStandard lpFileInformation
@@ -150,7 +159,7 @@ posixTimeToModTime p = ModTime $ (ceiling $ p * 1e7) -- 100 ns precision
+ (secToUnixEpoch * windowsTick)
-- | Return age of given file in days.
-getFileAge :: FilePath -> IO Double
+getFileAge :: FilePath -> NoCallStackIO Double
getFileAge file = do
t0 <- getModificationTime file
#if MIN_VERSION_directory(1,2,0)
@@ -163,5 +172,34 @@ getFileAge file = do
#endif
-- | Return the current time as 'ModTime'.
-getCurTime :: IO ModTime
+getCurTime :: NoCallStackIO ModTime
getCurTime = posixTimeToModTime `fmap` getPOSIXTime -- Uses 'gettimeofday'.
+
+-- | Based on code written by Neil Mitchell for Shake. See
+-- 'sleepFileTimeCalibrate' in 'Test.Type'. Returns a pair
+-- of microsecond values: first, the maximum delay seen, and the
+-- recommended delay to use before testing for file modification change.
+-- The returned delay is never smaller
+-- than 10 ms, but never larger than 1 second.
+calibrateMtimeChangeDelay :: IO (Int, Int)
+calibrateMtimeChangeDelay =
+ withTempDirectory silent "." "calibration-" $ \dir -> do
+ let fileName = dir </> "probe"
+ mtimes <- for [1..25] $ \(i::Int) -> time $ do
+ writeFile fileName $ show i
+ t0 <- getModTime fileName
+ let spin j = do
+ writeFile fileName $ show (i,j)
+ t1 <- getModTime fileName
+ unless (t0 < t1) (spin $ j + 1)
+ spin (0::Int)
+ let mtimeChange = maximum mtimes
+ mtimeChange' = min 1000000 $ (max 10000 mtimeChange) * 2
+ return (mtimeChange, mtimeChange')
+ where
+ time :: IO () -> IO Int
+ time act = do
+ t0 <- getCurrentTime
+ act
+ t1 <- getCurrentTime
+ return . ceiling $! (t1 `diffUTCTime` t0) * 1e6 -- microseconds
diff --git a/cabal/Cabal/Distribution/Compiler.hs b/cabal/Cabal/Distribution/Compiler.hs
index 4e84d79..4b5dcb7 100644
--- a/cabal/Cabal/Distribution/Compiler.hs
+++ b/cabal/Cabal/Distribution/Compiler.hs
@@ -15,8 +15,8 @@
-- case analysis on this compiler flavour enumeration like:
--
-- > case compilerFlavor comp of
--- > GHC -> GHC.getInstalledPackages verbosity packageDb progconf
--- > JHC -> JHC.getInstalledPackages verbosity packageDb progconf
+-- > 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.
@@ -32,6 +32,7 @@ module Distribution.Compiler (
buildCompilerFlavor,
defaultCompilerFlavor,
parseCompilerFlavorCompat,
+ classifyCompilerFlavor,
-- * Compiler id
CompilerId(..),
@@ -42,27 +43,22 @@ module Distribution.Compiler (
AbiTag(..), abiTagString
) where
-import Distribution.Compat.Binary
+import Prelude ()
+import Distribution.Compat.Prelude
+
import Language.Haskell.Extension
-import Data.Data (Data)
-import Data.Typeable (Typeable)
-import Data.Maybe (fromMaybe)
-import Distribution.Version (Version(..))
-import GHC.Generics (Generic)
+import Distribution.Version (Version, mkVersion', nullVersion)
import qualified System.Info (compilerName, compilerVersion)
import Distribution.Text (Text(..), display)
import qualified Distribution.Compat.ReadP as Parse
import qualified Text.PrettyPrint as Disp
-import Text.PrettyPrint ((<>))
-
-import qualified Data.Char as Char (toLower, isDigit, isAlphaNum)
-import Control.Monad (when)
-data CompilerFlavor = GHC | GHCJS | NHC | YHC | Hugs | HBC | Helium | JHC | LHC | UHC
- | HaskellSuite String -- string is the id of the actual compiler
- | OtherCompiler String
+data CompilerFlavor =
+ GHC | GHCJS | NHC | YHC | Hugs | HBC | Helium | JHC | LHC | UHC
+ | HaskellSuite String -- string is the id of the actual compiler
+ | OtherCompiler String
deriving (Generic, Show, Read, Eq, Ord, Typeable, Data)
instance Binary CompilerFlavor
@@ -77,8 +73,8 @@ instance Text CompilerFlavor where
disp other = Disp.text (lowercase (show other))
parse = do
- comp <- Parse.munch1 Char.isAlphaNum
- when (all Char.isDigit comp) Parse.pfail
+ comp <- Parse.munch1 isAlphaNum
+ when (all isDigit comp) Parse.pfail
return (classifyCompilerFlavor comp)
classifyCompilerFlavor :: String -> CompilerFlavor
@@ -103,8 +99,8 @@ classifyCompilerFlavor s =
--
parseCompilerFlavorCompat :: Parse.ReadP r CompilerFlavor
parseCompilerFlavorCompat = do
- comp <- Parse.munch1 Char.isAlphaNum
- when (all Char.isDigit comp) Parse.pfail
+ comp <- Parse.munch1 isAlphaNum
+ when (all isDigit comp) Parse.pfail
case lookup comp compilerMap of
Just compiler -> return compiler
Nothing -> return (OtherCompiler comp)
@@ -117,7 +113,7 @@ buildCompilerFlavor :: CompilerFlavor
buildCompilerFlavor = classifyCompilerFlavor System.Info.compilerName
buildCompilerVersion :: Version
-buildCompilerVersion = System.Info.compilerVersion
+buildCompilerVersion = mkVersion' System.Info.compilerVersion
buildCompilerId :: CompilerId
buildCompilerId = CompilerId buildCompilerFlavor buildCompilerVersion
@@ -143,31 +139,35 @@ data CompilerId = CompilerId CompilerFlavor Version
instance Binary CompilerId
instance Text CompilerId where
- disp (CompilerId f (Version [] _)) = disp f
- disp (CompilerId f v) = disp f <> Disp.char '-' <> disp v
+ disp (CompilerId f v)
+ | v == nullVersion = disp f
+ | otherwise = disp f <<>> Disp.char '-' <<>> disp v
parse = do
flavour <- parse
- version <- (Parse.char '-' >> parse) Parse.<++ return (Version [] [])
+ version <- (Parse.char '-' >> parse) Parse.<++ return nullVersion
return (CompilerId flavour version)
lowercase :: String -> String
-lowercase = map Char.toLower
+lowercase = map toLower
-- ------------------------------------------------------------
-- * Compiler Info
-- ------------------------------------------------------------
--- | Compiler information used for resolving configurations. Some fields can be
--- set to Nothing to indicate that the information is unknown.
+-- | Compiler information used for resolving configurations. Some
+-- fields can be set to Nothing to indicate that the information is
+-- unknown.
data CompilerInfo = CompilerInfo {
compilerInfoId :: CompilerId,
-- ^ Compiler flavour and version.
compilerInfoAbiTag :: AbiTag,
- -- ^ Tag for distinguishing incompatible ABI's on the same architecture/os.
+ -- ^ Tag for distinguishing incompatible ABI's on the same
+ -- architecture/os.
compilerInfoCompat :: Maybe [CompilerId],
- -- ^ Other implementations that this compiler claims to be compatible with, if known.
+ -- ^ Other implementations that this compiler claims to be
+ -- compatible with, if known.
compilerInfoLanguages :: Maybe [Language],
-- ^ Supported language standards, if known.
compilerInfoExtensions :: Maybe [Extension]
@@ -189,7 +189,7 @@ instance Text AbiTag where
disp (AbiTag tag) = Disp.text tag
parse = do
- tag <- Parse.munch (\c -> Char.isAlphaNum c || c == '_')
+ tag <- Parse.munch (\c -> isAlphaNum c || c == '_')
if null tag then return NoAbiTag else return (AbiTag tag)
abiTagString :: AbiTag -> String
diff --git a/cabal/Cabal/Distribution/GetOpt.hs b/cabal/Cabal/Distribution/GetOpt.hs
index 6ba8076..248b414 100644
--- a/cabal/Cabal/Distribution/GetOpt.hs
+++ b/cabal/Cabal/Distribution/GetOpt.hs
@@ -7,36 +7,19 @@
-- Maintainer : libraries@haskell.org
-- Portability : portable
--
--- This library provides facilities for parsing the command-line options
--- in a standalone program. It is essentially a Haskell port of the GNU
--- @getopt@ library.
+-- This is a fork of "System.Console.GetOpt" with the following changes:
+--
+-- * Treat "cabal --flag command" as "cabal command --flag" e.g.
+-- "cabal -v configure" to mean "cabal configure -v" For flags that are
+-- not recognised as global flags, pass them on to the sub-command. See
+-- the difference in 'shortOpt'.
+--
+-- * Line wrapping in the 'usageInfo' output, plus a more compact
+-- rendering of short options, and slightly less padding.
+--
+-- If you want to take on the challenge of merging this with the GetOpt
+-- from the base package then go for it!
--
------------------------------------------------------------------------------
-
-{-
-Sven Panne <Sven.Panne@informatik.uni-muenchen.de> Oct. 1996 (small
-changes Dec. 1997)
-
-Two rather obscure features are missing: The Bash 2.0 non-option hack
-(if you don't already know it, you probably don't want to hear about
-it...) and the recognition of long options with a single dash
-(e.g. '-help' is recognised as '--help', as long as there is no short
-option 'h').
-
-Other differences between GNU's getopt and this implementation:
-
-* To enforce a coherent description of options and arguments, there
- are explanation fields in the option/argument descriptor.
-
-* Error messages are now more informative, but no longer POSIX
- compliant... :-(
-
-And a final Haskell advertisement: The GNU C implementation uses well
-over 1100 lines, we need only 195 here, including a 46 line example!
-:-)
--}
-
-{-# OPTIONS_HADDOCK hide #-}
module Distribution.GetOpt (
-- * GetOpt
getOpt, getOpt',
@@ -46,44 +29,13 @@ module Distribution.GetOpt (
ArgDescr(..),
-- * Example
-
- -- $example
+ -- | See "System.Console.GetOpt" for examples
) where
-import Data.List ( isPrefixOf, intercalate, find )
-import Data.Maybe ( isJust )
-
--- |What to do with options following non-options
-data ArgOrder a
- = RequireOrder -- ^ no option processing after first non-option
- | Permute -- ^ freely intersperse options and non-options
- | ReturnInOrder (String -> a) -- ^ wrap non-options into options
-
-{-|
-Each 'OptDescr' describes a single option.
-
-The arguments to 'Option' are:
-
-* list of short option characters
-
-* list of long option strings (without \"--\")
-
-* argument descriptor
-
-* explanation of option for user
--}
-data OptDescr a = -- description of a single options:
- Option [Char] -- list of short option characters
- [String] -- list of long option strings (without "--")
- (ArgDescr a) -- argument descriptor
- String -- explanation of option for user
-
--- |Describes whether an option takes an argument or not, and if so
--- how the argument is injected into a value of type @a@.
-data ArgDescr a
- = NoArg a -- ^ no argument expected
- | ReqArg (String -> a) String -- ^ option requires argument
- | OptArg (Maybe String -> a) String -- ^ optional argument
+import Prelude ()
+import Distribution.Compat.Prelude
+import System.Console.GetOpt
+ ( ArgOrder(..), OptDescr(..), ArgDescr(..) )
data OptKind a -- kind of cmd line arg (internal use only):
= Opt a -- an option
@@ -123,6 +75,7 @@ fmtShort :: ArgDescr a -> Char -> String
fmtShort (NoArg _ ) so = "-" ++ [so]
fmtShort (ReqArg _ _) so = "-" ++ [so]
fmtShort (OptArg _ _) so = "-" ++ [so]
+ -- unlike upstream GetOpt we omit the arg name for short options
fmtLong :: ArgDescr a -> String -> String
fmtLong (NoArg _ ) lo = "--" ++ lo
@@ -234,6 +187,11 @@ shortOpt y ys rs optDescr = short ads ys rs
short (OptArg f _:_) xs rest = (Opt (f (Just xs)),rest)
short [] [] rest = (UnreqOpt optStr,rest)
short [] xs rest = (UnreqOpt (optStr++xs),rest)
+ -- This is different vs upstream = (UnreqOpt optStr,('-':xs):rest)
+ -- Apparently this was part of the change so that flags that are
+ -- not recognised as global flags are passed on to the sub-command.
+ -- But why was no equivalent change required for longOpt? So could
+ -- this change go upstream?
-- miscellaneous error formatting
@@ -249,87 +207,3 @@ errUnrec optStr = "unrecognized option `" ++ optStr ++ "'\n"
errNoArg :: String -> OptKind a
errNoArg optStr = OptErr ("option `" ++ optStr ++ "' doesn't allow an argument\n")
-
-{-
------------------------------------------------------------------------------------------
--- and here a small and hopefully enlightening example:
-
-data Flag = Verbose | Version | Name String | Output String | Arg String deriving Show
-
-options :: [OptDescr Flag]
-options =
- [Option ['v'] ["verbose"] (NoArg Verbose) "verbosely list files",
- Option ['V','?'] ["version","release"] (NoArg Version) "show version info",
- Option ['o'] ["output"] (OptArg out "FILE") "use FILE for dump",
- Option ['n'] ["name"] (ReqArg Name "USER") "only dump USER's files"]
-
-out :: Maybe String -> Flag
-out Nothing = Output "stdout"
-out (Just o) = Output o
-
-test :: ArgOrder Flag -> [String] -> String
-test order cmdline = case getOpt order options cmdline of
- (o,n,[] ) -> "options=" ++ show o ++ " args=" ++ show n ++ "\n"
- (_,_,errs) -> concat errs ++ usageInfo header options
- where header = "Usage: foobar [OPTION...] files..."
-
--- example runs:
--- putStr (test RequireOrder ["foo","-v"])
--- ==> options=[] args=["foo", "-v"]
--- putStr (test Permute ["foo","-v"])
--- ==> options=[Verbose] args=["foo"]
--- putStr (test (ReturnInOrder Arg) ["foo","-v"])
--- ==> options=[Arg "foo", Verbose] args=[]
--- putStr (test Permute ["foo","--","-v"])
--- ==> options=[] args=["foo", "-v"]
--- putStr (test Permute ["-?o","--name","bar","--na=baz"])
--- ==> options=[Version, Output "stdout", Name "bar", Name "baz"] args=[]
--- putStr (test Permute ["--ver","foo"])
--- ==> option `--ver' is ambiguous; could be one of:
--- -v --verbose verbosely list files
--- -V, -? --version, --release show version info
--- Usage: foobar [OPTION...] files...
--- -v --verbose verbosely list files
--- -V, -? --version, --release show version info
--- -o[FILE] --output[=FILE] use FILE for dump
--- -n USER --name=USER only dump USER's files
------------------------------------------------------------------------------------------
--}
-
-{- $example
-
-To hopefully illuminate the role of the different data
-structures, here\'s the command-line options for a (very simple)
-compiler:
-
-> module Opts where
->
-> import Distribution.GetOpt
-> import Data.Maybe ( fromMaybe )
->
-> data Flag
-> = Verbose | Version
-> | Input String | Output String | LibDir String
-> deriving Show
->
-> options :: [OptDescr Flag]
-> options =
-> [ Option ['v'] ["verbose"] (NoArg Verbose) "chatty output on stderr"
-> , Option ['V','?'] ["version"] (NoArg Version) "show version number"
-> , Option ['o'] ["output"] (OptArg outp "FILE") "output FILE"
-> , Option ['c'] [] (OptArg inp "FILE") "input FILE"
-> , Option ['L'] ["libdir"] (ReqArg LibDir "DIR") "library directory"
-> ]
->
-> inp,outp :: Maybe String -> Flag
-> outp = Output . fromMaybe "stdout"
-> inp = Input . fromMaybe "stdin"
->
-> compilerOpts :: [String] -> IO ([Flag], [String])
-> compilerOpts argv =
-> case getOpt Permute options argv of
-> (o,n,[] ) -> return (o,n)
-> (_,_,errs) -> ioError (userError (concat errs ++ usageInfo header options))
-> where header = "Usage: ic [OPTION...] files..."
-
--}
diff --git a/cabal/Cabal/Distribution/InstalledPackageInfo.hs b/cabal/Cabal/Distribution/InstalledPackageInfo.hs
index 08e197b..ec5ef28 100644
--- a/cabal/Cabal/Distribution/InstalledPackageInfo.hs
+++ b/cabal/Cabal/Distribution/InstalledPackageInfo.hs
@@ -1,4 +1,6 @@
{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE TypeFamilies #-}
-----------------------------------------------------------------------------
-- |
@@ -28,8 +30,10 @@
module Distribution.InstalledPackageInfo (
InstalledPackageInfo(..),
- installedComponentId,
installedPackageId,
+ installedComponentId,
+ requiredSignatures,
+ installedOpenUnitId,
ExposedModule(..),
ParseResult(..), PError(..), PWarning,
emptyInstalledPackageInfo,
@@ -40,19 +44,25 @@ module Distribution.InstalledPackageInfo (
fieldsInstalledPackageInfo,
) where
+import Prelude ()
+import Distribution.Compat.Prelude
+
import Distribution.ParseUtils
import Distribution.License
import Distribution.Package hiding (installedUnitId, installedPackageId)
+import Distribution.Package.TextClass ()
+import Distribution.Backpack
import qualified Distribution.Package as Package
import Distribution.ModuleName
import Distribution.Version
import Distribution.Text
import qualified Distribution.Compat.ReadP as Parse
-import Distribution.Compat.Binary
+import Distribution.Compat.Graph
import Text.PrettyPrint as Disp
-import Data.Maybe (fromMaybe)
-import GHC.Generics (Generic)
+import qualified Data.Char as Char
+import qualified Data.Map as Map
+import Data.Set (Set)
-- -----------------------------------------------------------------------------
-- The InstalledPackageInfo type
@@ -64,6 +74,12 @@ data 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)],
compatPackageKey :: String,
license :: License,
copyright :: String,
@@ -77,18 +93,24 @@ data InstalledPackageInfo
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],
ccOptions :: [String],
ldOptions :: [String],
@@ -98,14 +120,33 @@ data InstalledPackageInfo
haddockHTMLs :: [FilePath],
pkgRoot :: Maybe FilePath
}
- deriving (Eq, Generic, Read, Show)
+ deriving (Eq, Generic, Typeable, Read, Show)
installedComponentId :: InstalledPackageInfo -> ComponentId
-installedComponentId ipi = case installedUnitId ipi of
- SimpleUnitId cid -> cid
+installedComponentId ipi =
+ case unComponentId (installedComponentId_ ipi) of
+ "" -> mkComponentId (unUnitId (installedUnitId ipi))
+ _ -> installedComponentId_ ipi
+
+-- | Get the indefinite unit identity representing this package.
+-- This IS NOT guaranteed to give you a substitution; for
+-- instantiated packages you will get @DefiniteUnitId (installedUnitId ipi)@.
+-- For indefinite libraries, however, you will correctly get
+-- an @OpenUnitId@ with the appropriate 'OpenModuleSubst'.
+installedOpenUnitId :: InstalledPackageInfo -> OpenUnitId
+installedOpenUnitId ipi
+ = mkOpenUnitId (installedUnitId ipi) (installedComponentId ipi) (Map.fromList (instantiatedWith ipi))
+
+-- | Returns the set of module names which need to be filled for
+-- an indefinite package, or the empty set if the package is definite.
+requiredSignatures :: InstalledPackageInfo -> Set ModuleName
+requiredSignatures ipi = openModuleSubstFreeHoles (Map.fromList (instantiatedWith ipi))
{-# DEPRECATED installedPackageId "Use installedUnitId instead" #-}
-- | Backwards compatibility with Cabal pre-1.24.
+-- This type synonym is slightly awful because in cabal-install
+-- we define an 'InstalledPackageId' but it's a ComponentId,
+-- not a UnitId!
installedPackageId :: InstalledPackageInfo -> UnitId
installedPackageId = installedUnitId
@@ -120,11 +161,18 @@ instance Package.HasUnitId InstalledPackageInfo where
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 (PackageName "") (Version [] []),
+ sourcePackageId = PackageIdentifier (mkPackageName "") nullVersion,
installedUnitId = mkUnitId "",
+ installedComponentId_ = mkComponentId "",
+ instantiatedWith = [],
compatPackageKey = "",
license = UnspecifiedLicense,
copyright = "",
@@ -136,13 +184,15 @@ emptyInstalledPackageInfo
synopsis = "",
description = "",
category = "",
- abiHash = AbiHash "",
+ abiHash = mkAbiHash "",
+ indefinite = False,
exposed = False,
exposedModules = [],
hiddenModules = [],
trusted = False,
importDirs = [],
libraryDirs = [],
+ libraryDynDirs = [],
dataDir = "",
hsLibraries = [],
extraLibraries = [],
@@ -165,17 +215,17 @@ emptyInstalledPackageInfo
data ExposedModule
= ExposedModule {
exposedName :: ModuleName,
- exposedReexport :: Maybe Module
+ exposedReexport :: Maybe OpenModule
}
deriving (Eq, Generic, Read, Show)
instance Text ExposedModule where
disp (ExposedModule m reexport) =
- Disp.sep [ disp m
- , case reexport of
- Just m' -> Disp.sep [Disp.text "from", disp m']
- Nothing -> Disp.empty
- ]
+ 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
@@ -185,7 +235,6 @@ instance Text ExposedModule where
fmap Just parse
return (ExposedModule m reexport)
-
instance Binary ExposedModule
-- To maintain backwards-compatibility, we accept both comma/non-comma
@@ -223,6 +272,13 @@ showInstalledPackageInfoField = showSingleNamedField fieldsInstalledPackageInfo
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
@@ -240,9 +296,11 @@ basicFieldDescrs =
, simpleField "id"
disp parse
installedUnitId (\pk pkg -> pkg{installedUnitId=pk})
- -- NB: parse these as component IDs
+ , simpleField "instantiated-with"
+ (dispOpenModuleSubst . Map.fromList) (fmap Map.toList parseOpenModuleSubst)
+ instantiatedWith (\iw pkg -> pkg{instantiatedWith=iw})
, simpleField "key"
- (disp . ComponentId) (fmap (\(ComponentId s) -> s) parse)
+ dispCompatPackageKey parseCompatPackageKey
compatPackageKey (\pk pkg -> pkg{compatPackageKey=pk})
, simpleField "license"
disp parseLicenseQ
@@ -280,6 +338,8 @@ 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})
@@ -297,6 +357,9 @@ installedFieldDescrs = [
, 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})
diff --git a/cabal/Cabal/Distribution/Lex.hs b/cabal/Cabal/Distribution/Lex.hs
index bfecf47..4dbab59 100644
--- a/cabal/Cabal/Distribution/Lex.hs
+++ b/cabal/Cabal/Distribution/Lex.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE PatternGuards #-}
-----------------------------------------------------------------------------
-- |
-- Module : Distribution.Lex
@@ -13,23 +12,9 @@ module Distribution.Lex (
tokenizeQuotedWords
) where
-import Data.Char (isSpace)
-import Distribution.Compat.Semigroup as Semi
-
-newtype DList a = DList ([a] -> [a])
-
-runDList :: DList a -> [a]
-runDList (DList run) = run []
-
-singleton :: a -> DList a
-singleton a = DList (a:)
-
-instance Monoid (DList a) where
- mempty = DList id
- mappend = (Semi.<>)
-
-instance Semigroup (DList a) where
- DList a <> DList b = DList (a . b)
+import Prelude ()
+import Distribution.Compat.Prelude
+import Distribution.Compat.DList
tokenizeQuotedWords :: String -> [String]
tokenizeQuotedWords = filter (not . null) . go False mempty
diff --git a/cabal/Cabal/Distribution/License.hs b/cabal/Cabal/Distribution/License.hs
index dc3515c..ece7718 100644
--- a/cabal/Cabal/Distribution/License.hs
+++ b/cabal/Cabal/Distribution/License.hs
@@ -47,17 +47,13 @@ module Distribution.License (
knownLicenses,
) where
+import Prelude ()
+import Distribution.Compat.Prelude
+
import Distribution.Version
import Distribution.Text
import qualified Distribution.Compat.ReadP as Parse
-import Distribution.Compat.Binary
-
import qualified Text.PrettyPrint as Disp
-import Text.PrettyPrint ((<>))
-import qualified Data.Char as Char (isAlphaNum)
-import Data.Data (Data)
-import Data.Typeable (Typeable)
-import GHC.Generics (Generic)
-- | 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
@@ -133,24 +129,24 @@ knownLicenses = [ GPL unversioned, GPL (version [2]), GPL (version [3])
, LGPL unversioned, LGPL (version [2, 1]), LGPL (version [3])
, AGPL unversioned, AGPL (version [3])
, BSD2, BSD3, MIT, ISC
- , MPL (Version [2, 0] [])
+ , MPL (mkVersion [2, 0])
, Apache unversioned, Apache (version [2, 0])
, PublicDomain, AllRightsReserved, OtherLicense]
where
unversioned = Nothing
- version v = Just (Version v [])
+ version = Just . mkVersion
instance Text License where
- disp (GPL version) = Disp.text "GPL" <> dispOptVersion version
- disp (LGPL version) = Disp.text "LGPL" <> dispOptVersion version
- disp (AGPL version) = Disp.text "AGPL" <> dispOptVersion version
- disp (MPL version) = Disp.text "MPL" <> dispVersion version
- disp (Apache version) = Disp.text "Apache" <> dispOptVersion version
+ disp (GPL version) = Disp.text "GPL" <<>> dispOptVersion version
+ disp (LGPL version) = Disp.text "LGPL" <<>> dispOptVersion version
+ disp (AGPL version) = Disp.text "AGPL" <<>> dispOptVersion version
+ disp (MPL version) = Disp.text "MPL" <<>> dispVersion version
+ disp (Apache version) = Disp.text "Apache" <<>> dispOptVersion version
disp (UnknownLicense other) = Disp.text other
disp other = Disp.text (show other)
parse = do
- name <- Parse.munch1 (\c -> Char.isAlphaNum c && c /= '-')
+ name <- Parse.munch1 (\c -> isAlphaNum c && c /= '-')
version <- Parse.option Nothing (Parse.char '-' >> fmap Just parse)
return $! case (name, version :: Maybe Version) of
("GPL", _ ) -> GPL version
@@ -174,4 +170,4 @@ dispOptVersion Nothing = Disp.empty
dispOptVersion (Just v) = dispVersion v
dispVersion :: Version -> Disp.Doc
-dispVersion v = Disp.char '-' <> disp v
+dispVersion v = Disp.char '-' <<>> disp v
diff --git a/cabal/Cabal/Distribution/Make.hs b/cabal/Cabal/Distribution/Make.hs
index c29a073..63467c0 100644
--- a/cabal/Cabal/Distribution/Make.hs
+++ b/cabal/Cabal/Distribution/Make.hs
@@ -1,3 +1,6 @@
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE RankNTypes #-}
+
-----------------------------------------------------------------------------
-- |
-- Module : Distribution.Make
@@ -56,10 +59,13 @@
module Distribution.Make (
module Distribution.Package,
- License(..), Version(..),
+ License(..), Version,
defaultMain, defaultMainArgs, defaultMainNoRead
) where
+import Prelude ()
+import Distribution.Compat.Prelude
+
-- local
import Distribution.Compat.Exception
import Distribution.Package
@@ -112,7 +118,7 @@ defaultMainHelper args =
printVersion = putStrLn $ "Cabal library version "
++ display cabalVersion
- progs = defaultProgramConfiguration
+ progs = defaultProgramDb
commands =
[configureCommand progs `commandAddAction` configureAction
,buildCommand progs `commandAddAction` buildAction
diff --git a/cabal/Cabal/Distribution/ModuleName.hs b/cabal/Cabal/Distribution/ModuleName.hs
index c2e1b62..1fa1435 100644
--- a/cabal/Cabal/Distribution/ModuleName.hs
+++ b/cabal/Cabal/Distribution/ModuleName.hs
@@ -13,33 +13,30 @@
-- Data type for Haskell module names.
module Distribution.ModuleName (
- ModuleName,
+ ModuleName (..), -- TODO: move Parsec instance here, don't export constructor
fromString,
+ fromComponents,
components,
toFilePath,
main,
simple,
+ -- * Internal
+ validModuleComponent,
) where
+import Prelude ()
+import Distribution.Compat.Prelude
+
+import Distribution.Utils.ShortText
import Distribution.Text
-import Distribution.Compat.Binary
import qualified Distribution.Compat.ReadP as Parse
-import qualified Data.Char as Char
- ( isAlphaNum, isUpper )
-import Control.DeepSeq
-import Data.Data (Data)
-import Data.Typeable (Typeable)
import qualified Text.PrettyPrint as Disp
-import Data.List
- ( intercalate, intersperse )
-import GHC.Generics (Generic)
-import System.FilePath
- ( pathSeparator )
+import System.FilePath ( pathSeparator )
-- | A valid Haskell module name.
--
-newtype ModuleName = ModuleName [String]
+newtype ModuleName = ModuleName ShortTextLst
deriving (Eq, Generic, Ord, Read, Show, Typeable, Data)
instance Binary ModuleName
@@ -49,29 +46,29 @@ instance NFData ModuleName where
instance Text ModuleName where
disp (ModuleName ms) =
- Disp.hcat (intersperse (Disp.char '.') (map Disp.text ms))
+ Disp.hcat (intersperse (Disp.char '.') (map Disp.text $ stlToStrings ms))
parse = do
ms <- Parse.sepBy1 component (Parse.char '.')
- return (ModuleName ms)
+ return (ModuleName $ stlFromStrings ms)
where
component = do
- c <- Parse.satisfy Char.isUpper
+ c <- Parse.satisfy isUpper
cs <- Parse.munch validModuleChar
return (c:cs)
validModuleChar :: Char -> Bool
-validModuleChar c = Char.isAlphaNum c || c == '_' || c == '\''
+validModuleChar c = isAlphaNum c || c == '_' || c == '\''
validModuleComponent :: String -> Bool
validModuleComponent [] = False
-validModuleComponent (c:cs) = Char.isUpper c
+validModuleComponent (c:cs) = isUpper c
&& all validModuleChar cs
{-# DEPRECATED simple "use ModuleName.fromString instead" #-}
simple :: String -> ModuleName
-simple str = ModuleName [str]
+simple str = ModuleName (stlFromStrings [str])
-- | Construct a 'ModuleName' from a valid module name 'String'.
--
@@ -80,29 +77,34 @@ simple str = ModuleName [str]
-- are parsing user input then use 'Distribution.Text.simpleParse' instead.
--
fromString :: String -> ModuleName
-fromString string
- | all validModuleComponent components' = ModuleName components'
- | otherwise = error badName
-
+fromString string = fromComponents (split string)
where
- components' = split string
- badName = "ModuleName.fromString: invalid module name " ++ show string
-
split cs = case break (=='.') cs of
(chunk,[]) -> chunk : []
(chunk,_:rest) -> chunk : split rest
+-- | Construct a 'ModuleName' from valid module components, i.e. parts
+-- separated by dots.
+fromComponents :: [String] -> ModuleName
+fromComponents components'
+ | null components' = error zeroComponents
+ | all validModuleComponent components' = ModuleName (stlFromStrings components')
+ | otherwise = error badName
+ where
+ zeroComponents = "ModuleName.fromComponents: zero components"
+ badName = "ModuleName.fromComponents: invalid components " ++ show components'
+
-- | The module name @Main@.
--
main :: ModuleName
-main = ModuleName ["Main"]
+main = ModuleName (stlFromStrings ["Main"])
-- | The individual components of a hierarchical module name. For example
--
-- > components (fromString "A.B.C") = ["A", "B", "C"]
--
components :: ModuleName -> [String]
-components (ModuleName ms) = ms
+components (ModuleName ms) = stlToStrings ms
-- | Convert a module name to a file path, but without any file extension.
-- For example:
@@ -111,3 +113,39 @@ components (ModuleName ms) = ms
--
toFilePath :: ModuleName -> FilePath
toFilePath = intercalate [pathSeparator] . components
+
+----------------------------------------------------------------------------
+-- internal helper
+
+-- | Strict/unpacked representation of @[ShortText]@
+data ShortTextLst = STLNil
+ | STLCons !ShortText !ShortTextLst
+ deriving (Eq, Generic, Ord, Typeable, Data)
+
+instance NFData ShortTextLst where
+ rnf = flip seq ()
+
+instance Show ShortTextLst where
+ showsPrec p = showsPrec p . stlToList
+
+
+instance Read ShortTextLst where
+ readsPrec p = map (first stlFromList) . readsPrec p
+
+instance Binary ShortTextLst where
+ put = put . stlToList
+ get = stlFromList <$> get
+
+stlToList :: ShortTextLst -> [ShortText]
+stlToList STLNil = []
+stlToList (STLCons st next) = st : stlToList next
+
+stlToStrings :: ShortTextLst -> [String]
+stlToStrings = map fromShortText . stlToList
+
+stlFromList :: [ShortText] -> ShortTextLst
+stlFromList [] = STLNil
+stlFromList (x:xs) = STLCons x (stlFromList xs)
+
+stlFromStrings :: [String] -> ShortTextLst
+stlFromStrings = stlFromList . map toShortText
diff --git a/cabal/Cabal/Distribution/Package.hs b/cabal/Cabal/Distribution/Package.hs
index 1fec1c8..45c37e5 100644
--- a/cabal/Cabal/Distribution/Package.hs
+++ b/cabal/Cabal/Distribution/Package.hs
@@ -18,14 +18,20 @@
module Distribution.Package (
-- * Package ids
- PackageName(..),
+ UnqualComponentName, unUnqualComponentName, mkUnqualComponentName,
+ PackageName, unPackageName, mkPackageName,
+ packageNameToUnqualComponentName, unqualComponentNameToPackageName,
PackageIdentifier(..),
PackageId,
+ PkgconfigName, unPkgconfigName, mkPkgconfigName,
-- * Package keys/installed package IDs (used for linker symbols)
- ComponentId(..),
- UnitId(..),
- mkUnitId,
+ ComponentId, unComponentId, mkComponentId,
+ UnitId, unUnitId, mkUnitId,
+ DefUnitId,
+ unsafeMkDefUnitId,
+ unDefUnitId,
+ newSimpleUnitId,
mkLegacyUnitId,
getHSLibraryName,
InstalledPackageId, -- backwards compat
@@ -34,10 +40,12 @@ module Distribution.Package (
Module(..),
-- * ABI hash
- AbiHash(..),
+ AbiHash, unAbiHash, mkAbiHash,
-- * Package source dependencies
Dependency(..),
+ LegacyExeDependency(..),
+ PkgconfigDependency(..),
thisPackageVersion,
notThisPackageVersion,
simplifyDependency,
@@ -49,46 +57,165 @@ module Distribution.Package (
PackageInstalled(..),
) where
+import Prelude ()
+import Distribution.Compat.Prelude
+import Distribution.Utils.ShortText
+
import Distribution.Version
- ( Version(..), VersionRange, anyVersion, thisVersion
- , notThisVersion, simplifyVersionRange )
+ ( Version, VersionRange, thisVersion
+ , notThisVersion, simplifyVersionRange
+ , nullVersion )
import qualified Distribution.Compat.ReadP as Parse
import qualified Text.PrettyPrint as Disp
import Distribution.Compat.ReadP
-import Distribution.Compat.Binary
import Distribution.Text
import Distribution.ModuleName
-import Control.DeepSeq (NFData(..))
-import qualified Data.Char as Char
- ( isDigit, isAlphaNum, )
-import Data.Data ( Data )
-import Data.List ( intercalate )
-import Data.Typeable ( Typeable )
-import GHC.Generics (Generic)
-import Text.PrettyPrint ((<>), (<+>), text)
+import Text.PrettyPrint (text)
+
+-- | An unqualified component name, for any kind of component.
+--
+-- This is distinguished from a 'ComponentName' and 'ComponentId'. The former
+-- also states which of a library, executable, etc the name refers too. The
+-- later uniquely identifiers a component and its closure.
+--
+-- @since 2.0
+newtype UnqualComponentName = UnqualComponentName ShortText
+ deriving (Generic, Read, Show, Eq, Ord, Typeable, Data,
+ Semigroup, Monoid) -- TODO: bad enabler of bad monoids
+
+-- | Convert 'UnqualComponentName' to 'String'
+--
+-- @since 2.0
+unUnqualComponentName :: UnqualComponentName -> String
+unUnqualComponentName (UnqualComponentName s) = fromShortText s
-newtype PackageName = PackageName { unPackageName :: String }
+-- | Construct a 'UnqualComponentName' from a 'String'
+--
+-- 'mkUnqualComponentName' is the inverse to 'unUnqualComponentName'
+--
+-- Note: No validations are performed to ensure that the resulting
+-- 'UnqualComponentName' is valid
+--
+-- @since 2.0
+mkUnqualComponentName :: String -> UnqualComponentName
+mkUnqualComponentName = UnqualComponentName . toShortText
+
+instance Binary UnqualComponentName
+
+parsePackageName :: Parse.ReadP r String
+parsePackageName = do
+ ns <- Parse.sepBy1 component (Parse.char '-')
+ return $ intercalate "-" ns
+ where
+ component = do
+ cs <- Parse.munch1 isAlphaNum
+ if all isDigit cs then Parse.pfail else return cs
+ -- each component must contain an alphabetic character, to avoid
+ -- ambiguity in identifiers like foo-1 (the 1 is the version number).
+
+instance Text UnqualComponentName where
+ disp = Disp.text . unUnqualComponentName
+ parse = mkUnqualComponentName <$> parsePackageName
+
+instance NFData UnqualComponentName where
+ rnf (UnqualComponentName pkg) = rnf pkg
+
+-- | A package name.
+--
+-- Use 'mkPackageName' and 'unPackageName' to convert from/to a
+-- 'String'.
+--
+-- This type is opaque since @Cabal-2.0@
+--
+-- @since 2.0
+newtype PackageName = PackageName ShortText
deriving (Generic, Read, Show, Eq, Ord, Typeable, Data)
+-- | Convert 'PackageName' to 'String'
+unPackageName :: PackageName -> String
+unPackageName (PackageName s) = fromShortText s
+
+-- | Construct a 'PackageName' from a 'String'
+--
+-- 'mkPackageName' is the inverse to 'unPackageName'
+--
+-- Note: No validations are performed to ensure that the resulting
+-- 'PackageName' is valid
+--
+-- @since 2.0
+mkPackageName :: String -> PackageName
+mkPackageName = PackageName . toShortText
+
+-- | Converts a package name to an unqualified component name
+--
+-- Useful in legacy situations where a package name may refer to an internal
+-- component, if one is defined with that name.
+--
+-- @since 2.0
+packageNameToUnqualComponentName :: PackageName -> UnqualComponentName
+packageNameToUnqualComponentName (PackageName s) = UnqualComponentName s
+
+-- | Converts an unqualified component name to a package name
+--
+-- `packageNameToUnqualComponentName` is the inverse of
+-- `unqualComponentNameToPackageName`.
+--
+-- Useful in legacy situations where a package name may refer to an internal
+-- component, if one is defined with that name.
+--
+-- @since 2.0
+unqualComponentNameToPackageName :: UnqualComponentName -> PackageName
+unqualComponentNameToPackageName (UnqualComponentName s) = PackageName s
+
instance Binary PackageName
instance Text PackageName where
- disp (PackageName n) = Disp.text n
- parse = do
- ns <- Parse.sepBy1 component (Parse.char '-')
- return (PackageName (intercalate "-" ns))
- where
- component = do
- cs <- Parse.munch1 Char.isAlphaNum
- if all Char.isDigit cs then Parse.pfail else return cs
- -- each component must contain an alphabetic character, to avoid
- -- ambiguity in identifiers like foo-1 (the 1 is the version number).
+ disp = Disp.text . unPackageName
+ parse = mkPackageName <$> parsePackageName
instance NFData PackageName where
rnf (PackageName pkg) = rnf pkg
+-- | A pkg-config library name
+--
+-- This is parsed as any valid argument to the pkg-config utility.
+--
+-- @since 2.0
+newtype PkgconfigName = PkgconfigName ShortText
+ deriving (Generic, Read, Show, Eq, Ord, Typeable, Data)
+
+-- | Convert 'PkgconfigName' to 'String'
+--
+-- @since 2.0
+unPkgconfigName :: PkgconfigName -> String
+unPkgconfigName (PkgconfigName s) = fromShortText s
+
+-- | Construct a 'PkgconfigName' from a 'String'
+--
+-- 'mkPkgconfigName' is the inverse to 'unPkgconfigName'
+--
+-- Note: No validations are performed to ensure that the resulting
+-- 'PkgconfigName' is valid
+--
+-- @since 2.0
+mkPkgconfigName :: String -> PkgconfigName
+mkPkgconfigName = PkgconfigName . toShortText
+
+instance Binary PkgconfigName
+
+-- pkg-config allows versions and other letters in package names, eg
+-- "gtk+-2.0" is a valid pkg-config package _name_. It then has a package
+-- version number like 2.10.13
+instance Text PkgconfigName where
+ disp = Disp.text . unPkgconfigName
+ parse = mkPkgconfigName
+ <$> munch1 (\c -> isAlphaNum c || c `elem` "+-._")
+
+instance NFData PkgconfigName where
+ rnf (PkgconfigName pkg) = rnf pkg
+
-- | Type alias so we can use the shorter name PackageId.
type PackageId = PackageIdentifier
@@ -103,13 +230,13 @@ data PackageIdentifier
instance Binary PackageIdentifier
instance Text PackageIdentifier where
- disp (PackageIdentifier n v) = case v of
- Version [] _ -> disp n -- if no version, don't show version.
- _ -> disp n <> Disp.char '-' <> disp v
+ disp (PackageIdentifier n v)
+ | v == nullVersion = disp n -- if no version, don't show version.
+ | otherwise = disp n <<>> Disp.char '-' <<>> disp v
parse = do
n <- parse
- v <- (Parse.char '-' >> parse) <++ return (Version [] [])
+ v <- (Parse.char '-' >> parse) <++ return nullVersion
return (PackageIdentifier n v)
instance NFData PackageIdentifier where
@@ -124,15 +251,14 @@ instance NFData PackageIdentifier where
-- module identities, e.g., when writing out reexported modules in
-- the 'InstalledPackageInfo'.
data Module =
- Module { moduleUnitId :: UnitId,
- moduleName :: ModuleName }
+ Module DefUnitId ModuleName
deriving (Generic, Read, Show, Eq, Ord, Typeable, Data)
instance Binary Module
instance Text Module where
disp (Module uid mod_name) =
- disp uid <> Disp.text ":" <> disp mod_name
+ disp uid <<>> Disp.text ":" <<>> disp mod_name
parse = do
uid <- parse
_ <- Parse.char ':'
@@ -143,43 +269,122 @@ instance NFData Module where
rnf (Module uid mod_name) = rnf uid `seq` rnf mod_name
-- | A 'ComponentId' uniquely identifies the transitive source
--- code closure of a component. For non-Backpack components, it also
--- serves as the basis for install paths, symbols, etc.
+-- code closure of a component (i.e. libraries, executables).
--
-data ComponentId
- = ComponentId String
+-- For non-Backpack components, this corresponds one to one with
+-- the 'UnitId', which serves as the basis for install paths,
+-- linker symbols, etc.
+--
+-- Use 'mkComponentId' and 'unComponentId' to convert from/to a
+-- 'String'.
+--
+-- This type is opaque since @Cabal-2.0@
+--
+-- @since 2.0
+newtype ComponentId = ComponentId ShortText
deriving (Generic, Read, Show, Eq, Ord, Typeable, Data)
+-- | Construct a 'ComponentId' from a 'String'
+--
+-- 'mkComponentId' is the inverse to 'unComponentId'
+--
+-- Note: No validations are performed to ensure that the resulting
+-- 'ComponentId' is valid
+--
+-- @since 2.0
+mkComponentId :: String -> ComponentId
+mkComponentId = ComponentId . toShortText
+
+-- | Convert 'ComponentId' to 'String'
+--
+-- @since 2.0
+unComponentId :: ComponentId -> String
+unComponentId (ComponentId s) = fromShortText s
+
{-# DEPRECATED InstalledPackageId "Use UnitId instead" #-}
type InstalledPackageId = UnitId
instance Binary ComponentId
instance Text ComponentId where
- disp (ComponentId str) = text str
+ disp = text . unComponentId
- parse = ComponentId `fmap` Parse.munch1 abi_char
- where abi_char c = Char.isAlphaNum c || c `elem` "-_."
+ parse = mkComponentId `fmap` Parse.munch1 abi_char
+ where abi_char c = isAlphaNum c || c `elem` "-_."
instance NFData ComponentId where
- rnf (ComponentId pk) = rnf pk
+ rnf = rnf . unComponentId
-- | Returns library name prefixed with HS, suitable for filenames
getHSLibraryName :: UnitId -> String
-getHSLibraryName (SimpleUnitId (ComponentId s)) = "HS" ++ s
+getHSLibraryName uid = "HS" ++ display uid
--- | For now, there is no distinction between component IDs
--- and unit IDs in Cabal.
-newtype UnitId = SimpleUnitId ComponentId
- deriving (Generic, Read, Show, Eq, Ord, Typeable, Data, Binary, Text, NFData)
+-- | A unit identifier identifies a (possibly instantiated)
+-- package/component that can be installed the installed package
+-- database. There are several types of components that can be
+-- installed:
+--
+-- * A traditional library with no holes, so that 'unitIdHash'
+-- is @Nothing@. In the absence of Backpack, 'UnitId'
+-- is the same as a 'ComponentId'.
+--
+-- * An indefinite, Backpack library with holes. In this case,
+-- 'unitIdHash' is still @Nothing@, but in the install,
+-- there are only interfaces, no compiled objects.
+--
+-- * An instantiated Backpack library with all the holes
+-- filled in. 'unitIdHash' is a @Just@ a hash of the
+-- instantiating mapping.
+--
+-- A unit is a component plus the additional information on how the
+-- holes are filled in. Thus there is a one to many relationship: for a
+-- particular component there are many different ways of filling in the
+-- holes, and each different combination is a unit (and has a separate
+-- 'UnitId').
+--
+-- 'UnitId' is distinct from 'OpenUnitId', in that it is always
+-- installed, whereas 'OpenUnitId' are intermediate unit identities
+-- that arise during mixin linking, and don't necessarily correspond
+-- to any actually installed unit. Since the mapping is not actually
+-- recorded in a 'UnitId', you can't actually substitute over them
+-- (but you can substitute over 'OpenUnitId'). See also
+-- "Distribution.Backpack.FullUnitId" for a mechanism for expanding an
+-- instantiated 'UnitId' to retrieve its mapping.
+--
+newtype UnitId = UnitId ShortText
+ deriving (Generic, Read, Show, Eq, Ord, Typeable, Data, NFData)
+
+instance Binary UnitId
+
+instance Text UnitId where
+ disp = text . unUnitId
+ parse = mkUnitId <$> Parse.munch1 (\c -> isAlphaNum c || c `elem` "-_.+")
+
+unUnitId :: UnitId -> String
+unUnitId (UnitId s) = fromShortText s
--- | Makes a simple-style UnitId from a string.
mkUnitId :: String -> UnitId
-mkUnitId = SimpleUnitId . ComponentId
+mkUnitId = UnitId . toShortText
+
+-- | A 'UnitId' for a definite package. The 'DefUnitId' invariant says
+-- that a 'UnitId' identified this way is definite; i.e., it has no
+-- unfilled holes.
+newtype DefUnitId = DefUnitId { unDefUnitId :: UnitId }
+ deriving (Generic, Read, Show, Eq, Ord, Typeable, Data, Binary, NFData, Text)
+
+-- | Unsafely create a 'DefUnitId' from a 'UnitId'. Your responsibility
+-- is to ensure that the 'DefUnitId' invariant holds.
+unsafeMkDefUnitId :: UnitId -> DefUnitId
+unsafeMkDefUnitId = DefUnitId
+
+-- | Create a unit identity with no associated hash directly
+-- from a 'ComponentId'.
+newSimpleUnitId :: ComponentId -> UnitId
+newSimpleUnitId (ComponentId s) = UnitId s
-- | Make an old-style UnitId from a package identifier
mkLegacyUnitId :: PackageId -> UnitId
-mkLegacyUnitId = SimpleUnitId . ComponentId . display
+mkLegacyUnitId = newSimpleUnitId . mkComponentId . display
-- ------------------------------------------------------------
-- * Package source dependencies
@@ -190,17 +395,33 @@ mkLegacyUnitId = SimpleUnitId . ComponentId . display
data Dependency = Dependency PackageName VersionRange
deriving (Generic, Read, Show, Eq, Typeable, Data)
-instance Binary Dependency
+-- | Describes a legacy `build-tools`-style dependency on an executable
+--
+-- It is "legacy" because we do not know what the build-tool referred to. It
+-- could refer to a pkg-config executable (PkgconfigName), or an internal
+-- executable (UnqualComponentName). Thus the name is stringly typed.
+--
+-- @since 2.0
+data LegacyExeDependency = LegacyExeDependency
+ String
+ VersionRange
+ deriving (Generic, Read, Show, Eq, Typeable, Data)
-instance Text Dependency where
- disp (Dependency name ver) =
- disp name <+> disp ver
+-- | Describes a dependency on a pkg-config library
+--
+-- @since 2.0
+data PkgconfigDependency = PkgconfigDependency
+ PkgconfigName
+ VersionRange
+ deriving (Generic, Read, Show, Eq, Typeable, Data)
+
+instance Binary Dependency
+instance Binary LegacyExeDependency
+instance Binary PkgconfigDependency
- parse = do name <- parse
- Parse.skipSpaces
- ver <- parse <++ return anyVersion
- Parse.skipSpaces
- return (Dependency name ver)
+instance NFData Dependency where rnf = genericRnf
+instance NFData LegacyExeDependency where rnf = genericRnf
+instance NFData PkgconfigDependency where rnf = genericRnf
thisPackageVersion :: PackageIdentifier -> Dependency
thisPackageVersion (PackageIdentifier n v) =
@@ -239,7 +460,7 @@ packageVersion = pkgVersion . packageId
instance Package PackageIdentifier where
packageId = id
--- | Packages that have an installed package ID
+-- | Packages that have an installed unit ID
class Package pkg => HasUnitId pkg where
installedUnitId :: pkg -> UnitId
@@ -260,10 +481,36 @@ class (HasUnitId pkg) => PackageInstalled pkg where
-- -----------------------------------------------------------------------------
-- ABI hash
-newtype AbiHash = AbiHash String
+-- | ABI Hashes
+--
+-- Use 'mkAbiHash' and 'unAbiHash' to convert from/to a
+-- 'String'.
+--
+-- This type is opaque since @Cabal-2.0@
+--
+-- @since 2.0
+newtype AbiHash = AbiHash ShortText
deriving (Eq, Show, Read, Generic)
+
+-- | Construct a 'AbiHash' from a 'String'
+--
+-- 'mkAbiHash' is the inverse to 'unAbiHash'
+--
+-- Note: No validations are performed to ensure that the resulting
+-- 'AbiHash' is valid
+--
+-- @since 2.0
+unAbiHash :: AbiHash -> String
+unAbiHash (AbiHash h) = fromShortText h
+
+-- | Convert 'AbiHash' to 'String'
+--
+-- @since 2.0
+mkAbiHash :: String -> AbiHash
+mkAbiHash = AbiHash . toShortText
+
instance Binary AbiHash
instance Text AbiHash where
- disp (AbiHash abi) = Disp.text abi
- parse = fmap AbiHash (Parse.munch Char.isAlphaNum)
+ disp = Disp.text . unAbiHash
+ parse = fmap mkAbiHash (Parse.munch isAlphaNum)
diff --git a/cabal/Cabal/Distribution/Package/TextClass.hs b/cabal/Cabal/Distribution/Package/TextClass.hs
new file mode 100644
index 0000000..f24ebe7
--- /dev/null
+++ b/cabal/Cabal/Distribution/Package/TextClass.hs
@@ -0,0 +1,56 @@
+-- | *Dependency Text instances moved from Distribution.Package
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+module Distribution.Package.TextClass () where
+
+import Prelude ()
+import Distribution.Compat.Prelude
+
+import Distribution.Package
+import Distribution.ParseUtils
+import Distribution.Version (anyVersion)
+
+import qualified Distribution.Compat.ReadP as Parse
+import qualified Text.PrettyPrint as Disp
+import Distribution.Compat.ReadP
+import Distribution.Text
+
+import Text.PrettyPrint ((<+>))
+
+
+instance Text Dependency where
+ disp (Dependency name ver) =
+ disp name <+> disp ver
+
+ parse = do name <- parse
+ Parse.skipSpaces
+ ver <- parse <++ return anyVersion
+ Parse.skipSpaces
+ return (Dependency name ver)
+
+instance Text LegacyExeDependency where
+ disp (LegacyExeDependency name ver) =
+ Disp.text name <+> disp ver
+
+ parse = do name <- parseMaybeQuoted parseBuildToolName
+ Parse.skipSpaces
+ ver <- parse <++ return anyVersion
+ Parse.skipSpaces
+ return $ LegacyExeDependency name ver
+ where
+ -- like parsePackageName but accepts symbols in components
+ parseBuildToolName :: Parse.ReadP r String
+ parseBuildToolName = do ns <- sepBy1 component (Parse.char '-')
+ return (intercalate "-" ns)
+ where component = do
+ cs <- munch1 (\c -> isAlphaNum c || c == '+' || c == '_')
+ if all isDigit cs then pfail else return cs
+
+instance Text PkgconfigDependency where
+ disp (PkgconfigDependency name ver) =
+ disp name <+> disp ver
+
+ parse = do name <- parse
+ Parse.skipSpaces
+ ver <- parse <++ return anyVersion
+ Parse.skipSpaces
+ return $ PkgconfigDependency name ver
diff --git a/cabal/Cabal/Distribution/PackageDescription.hs b/cabal/Cabal/Distribution/PackageDescription.hs
index 72fb378..e59a25a 100644
--- a/cabal/Cabal/Distribution/PackageDescription.hs
+++ b/cabal/Cabal/Distribution/PackageDescription.hs
@@ -11,19 +11,8 @@
-- Maintainer : cabal-devel@haskell.org
-- Portability : portable
--
--- This defines the data structure for the @.cabal@ file format. There are
--- several parts to this structure. It has top level info and then 'Library',
--- 'Executable', 'TestSuite', and 'Benchmark' sections each of which have
--- associated 'BuildInfo' data that's used to build the library, exe, test, or
--- benchmark. To further complicate things there is both a 'PackageDescription'
--- and a 'GenericPackageDescription'. This distinction relates to cabal
--- configurations. When we initially read a @.cabal@ file we get a
--- 'GenericPackageDescription' which has all the conditional sections.
--- Before actually building a package we have to decide
--- on each conditional. Once we've done that we get a 'PackageDescription'.
--- It was done this way initially to avoid breaking too much stuff when the
--- feature was introduced. It could probably do with being rationalised at some
--- point to make it simpler.
+-- Backwards compatibility reexport of everything you need to know
+-- about @.cabal@ files.
module Distribution.PackageDescription (
-- * Package descriptions
@@ -33,11 +22,11 @@ module Distribution.PackageDescription (
descCabalVersion,
BuildType(..),
knownBuildTypes,
+ allLibraries,
- -- ** Renaming
+ -- ** Renaming (syntactic)
ModuleRenaming(..),
defaultRenaming,
- lookupRenaming,
-- ** Libraries
Library(..),
@@ -46,6 +35,8 @@ module Distribution.PackageDescription (
withLib,
hasPublicLib,
hasLibs,
+ explicitLibModules,
+ libModulesAutogen,
libModules,
-- ** Executables
@@ -54,6 +45,7 @@ module Distribution.PackageDescription (
withExe,
hasExes,
exeModules,
+ exeModulesAutogen,
-- * Tests
TestSuite(..),
@@ -65,7 +57,7 @@ module Distribution.PackageDescription (
hasTests,
withTest,
testModules,
- enabledTests,
+ testModulesAutogen,
-- * Benchmarks
Benchmark(..),
@@ -77,7 +69,7 @@ module Distribution.PackageDescription (
hasBenchmarks,
withBenchmark,
benchmarkModules,
- enabledBenchmarks,
+ benchmarkModulesAutogen,
-- * Build information
BuildInfo(..),
@@ -99,1197 +91,41 @@ module Distribution.PackageDescription (
-- * package configuration
GenericPackageDescription(..),
- Flag(..), FlagName(..), FlagAssignment,
+ Flag(..), emptyFlag,
+ FlagName, mkFlagName, unFlagName,
+ FlagAssignment,
CondTree(..), ConfVar(..), Condition(..),
- cNot,
+ cNot, cAnd, cOr,
-- * Source repositories
SourceRepo(..),
RepoKind(..),
RepoType(..),
knownRepoTypes,
+ emptySourceRepo,
-- * Custom setup build information
SetupBuildInfo(..),
) where
-import Distribution.Compat.Binary
-import qualified Distribution.Compat.Semigroup as Semi ((<>))
-import Distribution.Compat.Semigroup as Semi (Monoid(..), Semigroup, gmempty, gmappend)
-import qualified Distribution.Compat.ReadP as Parse
-import Distribution.Compat.ReadP ((<++))
-import Distribution.Package
-import Distribution.ModuleName
-import Distribution.Version
-import Distribution.License
-import Distribution.Compiler
-import Distribution.System
-import Distribution.Text
-import Language.Haskell.Extension
-
-import Data.Data (Data)
-import Data.List (nub, intercalate)
-import Data.Maybe (fromMaybe, maybeToList)
-import Data.Foldable as Fold (Foldable(foldMap))
-import Data.Traversable as Trav (Traversable(traverse))
-import Data.Typeable ( Typeable )
-import Control.Applicative as AP (Alternative(..), Applicative(..))
-import Control.Monad (MonadPlus(mplus,mzero), ap)
-import GHC.Generics (Generic)
-import Text.PrettyPrint as Disp
-import qualified Data.Char as Char (isAlphaNum, isDigit, toLower)
-import qualified Data.Map as Map
-import Data.Map (Map)
-
--- -----------------------------------------------------------------------------
--- The PackageDescription type
-
--- | This data type is the internal representation of the file @pkg.cabal@.
--- It contains two kinds of information about the package: information
--- which is needed for all packages, such as the package name and version, and
--- information which is needed for the simple build system only, such as
--- the compiler options and library name.
---
-data PackageDescription
- = PackageDescription {
- -- the following are required by all packages:
- package :: PackageIdentifier,
- license :: License,
- licenseFiles :: [FilePath],
- copyright :: String,
- maintainer :: String,
- author :: String,
- stability :: String,
- testedWith :: [(CompilerFlavor,VersionRange)],
- homepage :: String,
- pkgUrl :: String,
- bugReports :: String,
- sourceRepos :: [SourceRepo],
- synopsis :: String, -- ^A one-line summary of this package
- description :: String, -- ^A more verbose description of this package
- category :: String,
- customFieldsPD :: [(String,String)], -- ^Custom fields starting
- -- with x-, stored in a
- -- simple assoc-list.
-
- -- | YOU PROBABLY DON'T WANT TO USE THIS FIELD. This field is
- -- special! Depending on how far along processing the
- -- PackageDescription we are, the contents of this field are
- -- either nonsense, or the collected dependencies of *all* the
- -- components in this package. buildDepends is initialized by
- -- 'finalizePackageDescription' and 'flattenPackageDescription';
- -- prior to that, dependency info is stored in the 'CondTree'
- -- built around a 'GenericPackageDescription'. When this
- -- resolution is done, dependency info is written to the inner
- -- 'BuildInfo' and this field. This is all horrible, and #2066
- -- tracks progress to get rid of this field.
- buildDepends :: [Dependency],
- -- | The version of the Cabal spec that this package description uses.
- -- For historical reasons this is specified with a version range but
- -- only ranges of the form @>= v@ make sense. We are in the process of
- -- transitioning to specifying just a single version, not a range.
- specVersionRaw :: Either Version VersionRange,
- buildType :: Maybe BuildType,
- setupBuildInfo :: Maybe SetupBuildInfo,
- -- components
- libraries :: [Library],
- executables :: [Executable],
- testSuites :: [TestSuite],
- benchmarks :: [Benchmark],
- dataFiles :: [FilePath],
- dataDir :: FilePath,
- extraSrcFiles :: [FilePath],
- extraTmpFiles :: [FilePath],
- extraDocFiles :: [FilePath]
- }
- deriving (Generic, Show, Read, Eq, Typeable, Data)
-
-instance Binary PackageDescription
-
-instance Package PackageDescription where
- packageId = package
-
--- | The version of the Cabal spec that this package should be interpreted
--- against.
---
--- Historically we used a version range but we are switching to using a single
--- version. Currently we accept either. This function converts into a single
--- version by ignoring upper bounds in the version range.
---
-specVersion :: PackageDescription -> Version
-specVersion pkg = case specVersionRaw pkg of
- Left version -> version
- Right versionRange -> case asVersionIntervals versionRange of
- [] -> Version [0] []
- ((LowerBound version _, _):_) -> version
-
--- | The range of versions of the Cabal tools that this package is intended to
--- work with.
---
--- This function is deprecated and should not be used for new purposes, only to
--- support old packages that rely on the old interpretation.
---
-descCabalVersion :: PackageDescription -> VersionRange
-descCabalVersion pkg = case specVersionRaw pkg of
- Left version -> orLaterVersion version
- Right versionRange -> versionRange
-{-# DEPRECATED descCabalVersion "Use specVersion instead" #-}
-
-emptyPackageDescription :: PackageDescription
-emptyPackageDescription
- = PackageDescription {
- package = PackageIdentifier (PackageName "")
- (Version [] []),
- license = UnspecifiedLicense,
- licenseFiles = [],
- specVersionRaw = Right anyVersion,
- buildType = Nothing,
- copyright = "",
- maintainer = "",
- author = "",
- stability = "",
- testedWith = [],
- buildDepends = [],
- homepage = "",
- pkgUrl = "",
- bugReports = "",
- sourceRepos = [],
- synopsis = "",
- description = "",
- category = "",
- customFieldsPD = [],
- setupBuildInfo = Nothing,
- libraries = [],
- executables = [],
- testSuites = [],
- benchmarks = [],
- dataFiles = [],
- dataDir = "",
- extraSrcFiles = [],
- extraTmpFiles = [],
- extraDocFiles = []
- }
-
--- | The type of build system used by this package.
-data BuildType
- = Simple -- ^ calls @Distribution.Simple.defaultMain@
- | Configure -- ^ calls @Distribution.Simple.defaultMainWithHooks defaultUserHooks@,
- -- which invokes @configure@ to generate additional build
- -- information used by later phases.
- | Make -- ^ calls @Distribution.Make.defaultMain@
- | Custom -- ^ uses user-supplied @Setup.hs@ or @Setup.lhs@ (default)
- | UnknownBuildType String
- -- ^ a package that uses an unknown build type cannot actually
- -- be built. Doing it this way rather than just giving a
- -- parse error means we get better error messages and allows
- -- you to inspect the rest of the package description.
- deriving (Generic, Show, Read, Eq, Typeable, Data)
-
-instance Binary BuildType
-
-knownBuildTypes :: [BuildType]
-knownBuildTypes = [Simple, Configure, Make, Custom]
-
-instance Text BuildType where
- disp (UnknownBuildType other) = Disp.text other
- disp other = Disp.text (show other)
-
- parse = do
- name <- Parse.munch1 Char.isAlphaNum
- return $ case name of
- "Simple" -> Simple
- "Configure" -> Configure
- "Custom" -> Custom
- "Make" -> Make
- _ -> UnknownBuildType name
-
--- ---------------------------------------------------------------------------
--- The SetupBuildInfo type
-
--- One can see this as a very cut-down version of BuildInfo below.
--- To keep things simple for tools that compile Setup.hs we limit the
--- options authors can specify to just Haskell package dependencies.
-
-data SetupBuildInfo = SetupBuildInfo {
- setupDepends :: [Dependency]
- }
- deriving (Generic, Show, Eq, Read, Typeable, Data)
-
-instance Binary SetupBuildInfo
-
-instance Semi.Monoid SetupBuildInfo where
- mempty = gmempty
- mappend = (Semi.<>)
-
-instance Semigroup SetupBuildInfo where
- (<>) = gmappend
-
--- ---------------------------------------------------------------------------
--- Module renaming
-
--- | Renaming applied to the modules provided by a package.
--- The boolean indicates whether or not to also include all of the
--- original names of modules. Thus, @ModuleRenaming False []@ is
--- "don't expose any modules, and @ModuleRenaming True [("Data.Bool", "Bool")]@
--- is, "expose all modules, but also expose @Data.Bool@ as @Bool@".
---
-data ModuleRenaming = ModuleRenaming Bool [(ModuleName, ModuleName)]
- deriving (Show, Read, Eq, Ord, Typeable, Data, Generic)
-
-defaultRenaming :: ModuleRenaming
-defaultRenaming = ModuleRenaming True []
-
-lookupRenaming :: Package pkg => pkg -> Map PackageName ModuleRenaming -> ModuleRenaming
-lookupRenaming = Map.findWithDefault defaultRenaming . packageName
-
-instance Binary ModuleRenaming where
-
-instance Monoid ModuleRenaming where
- mempty = ModuleRenaming False []
- mappend = (Semi.<>)
-
-instance Semigroup ModuleRenaming where
- ModuleRenaming b rns <> ModuleRenaming b' rns'
- = ModuleRenaming (b || b') (rns ++ rns') -- TODO: dedupe?
-
--- NB: parentheses are mandatory, because later we may extend this syntax
--- to allow "hiding (A, B)" or other modifier words.
-instance Text ModuleRenaming where
- disp (ModuleRenaming True []) = Disp.empty
- disp (ModuleRenaming b vs) = (if b then text "with" else Disp.empty) <+> dispRns
- where dispRns = Disp.parens
- (Disp.hsep
- (Disp.punctuate Disp.comma (map dispEntry vs)))
- dispEntry (orig, new)
- | orig == new = disp orig
- | otherwise = disp orig <+> text "as" <+> disp new
-
- parse = do Parse.string "with" >> Parse.skipSpaces
- fmap (ModuleRenaming True) parseRns
- <++ fmap (ModuleRenaming False) parseRns
- <++ return (ModuleRenaming True [])
- where parseRns = do
- rns <- Parse.between (Parse.char '(') (Parse.char ')') parseList
- Parse.skipSpaces
- return rns
- parseList =
- Parse.sepBy parseEntry (Parse.char ',' >> Parse.skipSpaces)
- parseEntry :: Parse.ReadP r (ModuleName, ModuleName)
- parseEntry = do
- orig <- parse
- Parse.skipSpaces
- (do _ <- Parse.string "as"
- Parse.skipSpaces
- new <- parse
- Parse.skipSpaces
- return (orig, new)
- <++
- return (orig, orig))
-
--- ---------------------------------------------------------------------------
--- The Library type
-
-data Library = Library {
- libName :: String,
- exposedModules :: [ModuleName],
- reexportedModules :: [ModuleReexport],
- requiredSignatures:: [ModuleName], -- ^ What sigs need implementations?
- exposedSignatures:: [ModuleName], -- ^ What sigs are visible to users?
- libExposed :: Bool, -- ^ Is the lib to be exposed by default?
- libBuildInfo :: BuildInfo
- }
- deriving (Generic, Show, Eq, Read, Typeable, Data)
-
-instance Binary Library
-
-instance Monoid Library where
- mempty = Library {
- libName = mempty,
- exposedModules = mempty,
- reexportedModules = mempty,
- requiredSignatures = mempty,
- exposedSignatures = mempty,
- libExposed = True,
- libBuildInfo = mempty
- }
- mappend = (Semi.<>)
-
-instance Semigroup Library where
- a <> b = Library {
- libName = combine' libName,
- exposedModules = combine exposedModules,
- reexportedModules = combine reexportedModules,
- requiredSignatures = combine requiredSignatures,
- exposedSignatures = combine exposedSignatures,
- libExposed = libExposed a && libExposed b, -- so False propagates
- libBuildInfo = combine libBuildInfo
- }
- where combine field = field a `mappend` field b
- combine' field = case (field a, field b) of
- ("","") -> ""
- ("", x) -> x
- (x, "") -> x
- (x, y) -> error $ "Ambiguous values for library field: '"
- ++ x ++ "' and '" ++ y ++ "'"
-
-emptyLibrary :: Library
-emptyLibrary = mempty
-
--- | Does this package have a PUBLIC library?
-hasPublicLib :: PackageDescription -> Bool
-hasPublicLib p = any f (libraries p)
- where f lib = buildable (libBuildInfo lib) &&
- libName lib == display (packageName (package p))
-
--- | Does this package have any libraries?
-hasLibs :: PackageDescription -> Bool
-hasLibs p = any (buildable . libBuildInfo) (libraries p)
-
--- |If the package description has a library section, call the given
--- function with the library build info as argument.
-withLib :: PackageDescription -> (Library -> IO ()) -> IO ()
-withLib pkg_descr f =
- sequence_ [f lib | lib <- libraries pkg_descr, buildable (libBuildInfo lib)]
-
--- | Get all the module names from the library (exposed and internal modules)
--- which need to be compiled. (This does not include reexports, which
--- do not need to be compiled.)
-libModules :: Library -> [ModuleName]
-libModules lib = exposedModules lib
- ++ otherModules (libBuildInfo lib)
- ++ exposedSignatures lib
- ++ requiredSignatures lib
-
--- -----------------------------------------------------------------------------
--- Module re-exports
-
-data ModuleReexport = ModuleReexport {
- moduleReexportOriginalPackage :: Maybe PackageName,
- moduleReexportOriginalName :: ModuleName,
- moduleReexportName :: ModuleName
- }
- deriving (Eq, Generic, Read, Show, Typeable, Data)
-
-instance Binary ModuleReexport
-
-instance Text ModuleReexport where
- disp (ModuleReexport mpkgname origname newname) =
- maybe Disp.empty (\pkgname -> disp pkgname <> Disp.char ':') mpkgname
- <> disp origname
- <+> if newname == origname
- then Disp.empty
- else Disp.text "as" <+> disp newname
-
- parse = do
- mpkgname <- Parse.option Nothing $ do
- pkgname <- parse
- _ <- Parse.char ':'
- return (Just pkgname)
- origname <- parse
- newname <- Parse.option origname $ do
- Parse.skipSpaces
- _ <- Parse.string "as"
- Parse.skipSpaces
- parse
- return (ModuleReexport mpkgname origname newname)
-
--- ---------------------------------------------------------------------------
--- The Executable type
-
-data Executable = Executable {
- exeName :: String,
- modulePath :: FilePath,
- buildInfo :: BuildInfo
- }
- deriving (Generic, Show, Read, Eq, Typeable, Data)
-
-instance Binary Executable
-
-instance Monoid Executable where
- mempty = gmempty
- mappend = (Semi.<>)
-
-instance Semigroup Executable where
- a <> b = Executable{
- exeName = combine' exeName,
- modulePath = combine modulePath,
- buildInfo = combine buildInfo
- }
- where combine field = field a `mappend` field b
- combine' field = case (field a, field b) of
- ("","") -> ""
- ("", x) -> x
- (x, "") -> x
- (x, y) -> error $ "Ambiguous values for executable field: '"
- ++ x ++ "' and '" ++ y ++ "'"
-
-emptyExecutable :: Executable
-emptyExecutable = mempty
-
--- |does this package have any executables?
-hasExes :: PackageDescription -> Bool
-hasExes p = any (buildable . buildInfo) (executables p)
-
--- | Perform the action on each buildable 'Executable' in the package
--- description.
-withExe :: PackageDescription -> (Executable -> IO ()) -> IO ()
-withExe pkg_descr f =
- sequence_ [f exe | exe <- executables pkg_descr, buildable (buildInfo exe)]
-
--- | Get all the module names from an exe
-exeModules :: Executable -> [ModuleName]
-exeModules exe = otherModules (buildInfo exe)
-
--- ---------------------------------------------------------------------------
--- The TestSuite type
-
--- | A \"test-suite\" stanza in a cabal file.
---
-data TestSuite = TestSuite {
- testName :: String,
- testInterface :: TestSuiteInterface,
- testBuildInfo :: BuildInfo,
- testEnabled :: Bool
- -- TODO: By having a 'testEnabled' field in the PackageDescription, we
- -- are mixing build status information (i.e., arguments to 'configure')
- -- with static package description information. This is undesirable, but
- -- a better solution is waiting on the next overhaul to the
- -- GenericPackageDescription -> PackageDescription resolution process.
- }
- deriving (Generic, Show, Read, Eq, Typeable, Data)
-
-instance Binary TestSuite
-
--- | The test suite interfaces that are currently defined. Each test suite must
--- specify which interface it supports.
---
--- More interfaces may be defined in future, either new revisions or totally
--- new interfaces.
---
-data TestSuiteInterface =
-
- -- | Test interface \"exitcode-stdio-1.0\". The test-suite takes the form
- -- of an executable. It returns a zero exit code for success, non-zero for
- -- failure. The stdout and stderr channels may be logged. It takes no
- -- command line parameters and nothing on stdin.
- --
- TestSuiteExeV10 Version FilePath
-
- -- | Test interface \"detailed-0.9\". The test-suite takes the form of a
- -- library containing a designated module that exports \"tests :: [Test]\".
- --
- | TestSuiteLibV09 Version ModuleName
-
- -- | A test suite that does not conform to one of the above interfaces for
- -- the given reason (e.g. unknown test type).
- --
- | TestSuiteUnsupported TestType
- deriving (Eq, Generic, Read, Show, Typeable, Data)
-
-instance Binary TestSuiteInterface
-
-instance Monoid TestSuite where
- mempty = TestSuite {
- testName = mempty,
- testInterface = mempty,
- testBuildInfo = mempty,
- testEnabled = False
- }
- mappend = (Semi.<>)
-
-instance Semigroup TestSuite where
- a <> b = TestSuite {
- testName = combine' testName,
- testInterface = combine testInterface,
- testBuildInfo = combine testBuildInfo,
- testEnabled = testEnabled a || testEnabled b
- }
- where combine field = field a `mappend` field b
- combine' f = case (f a, f b) of
- ("", x) -> x
- (x, "") -> x
- (x, y) -> error "Ambiguous values for test field: '"
- ++ x ++ "' and '" ++ y ++ "'"
-
-instance Monoid TestSuiteInterface where
- mempty = TestSuiteUnsupported (TestTypeUnknown mempty (Version [] []))
- mappend = (Semi.<>)
-
-instance Semigroup TestSuiteInterface where
- a <> (TestSuiteUnsupported _) = a
- _ <> b = b
-
-emptyTestSuite :: TestSuite
-emptyTestSuite = mempty
-
--- | Does this package have any test suites?
-hasTests :: PackageDescription -> Bool
-hasTests = any (buildable . testBuildInfo) . testSuites
-
--- | Get all the enabled test suites from a package.
-enabledTests :: PackageDescription -> [TestSuite]
-enabledTests = filter testEnabled . testSuites
-
--- | Perform an action on each buildable 'TestSuite' in a package.
-withTest :: PackageDescription -> (TestSuite -> IO ()) -> IO ()
-withTest pkg_descr f =
- mapM_ f $ filter (buildable . testBuildInfo) $ enabledTests pkg_descr
-
--- | Get all the module names from a test suite.
-testModules :: TestSuite -> [ModuleName]
-testModules test = (case testInterface test of
- TestSuiteLibV09 _ m -> [m]
- _ -> [])
- ++ otherModules (testBuildInfo test)
-
--- | The \"test-type\" field in the test suite stanza.
---
-data TestType = TestTypeExe Version -- ^ \"type: exitcode-stdio-x.y\"
- | TestTypeLib Version -- ^ \"type: detailed-x.y\"
- | TestTypeUnknown String Version -- ^ Some unknown test type e.g. \"type: foo\"
- deriving (Generic, Show, Read, Eq, Typeable, Data)
-
-instance Binary TestType
-
-knownTestTypes :: [TestType]
-knownTestTypes = [ TestTypeExe (Version [1,0] [])
- , TestTypeLib (Version [0,9] []) ]
-
-stdParse :: Text ver => (ver -> String -> res) -> Parse.ReadP r res
-stdParse f = do
- cs <- Parse.sepBy1 component (Parse.char '-')
- _ <- Parse.char '-'
- ver <- parse
- let name = intercalate "-" cs
- return $! f ver (lowercase name)
- where
- component = do
- cs <- Parse.munch1 Char.isAlphaNum
- if all Char.isDigit cs then Parse.pfail else return cs
- -- each component must contain an alphabetic character, to avoid
- -- ambiguity in identifiers like foo-1 (the 1 is the version number).
-
-instance Text TestType where
- disp (TestTypeExe ver) = text "exitcode-stdio-" <> disp ver
- disp (TestTypeLib ver) = text "detailed-" <> disp ver
- disp (TestTypeUnknown name ver) = text name <> char '-' <> disp ver
-
- parse = stdParse $ \ver name -> case name of
- "exitcode-stdio" -> TestTypeExe ver
- "detailed" -> TestTypeLib ver
- _ -> TestTypeUnknown name ver
-
-
-testType :: TestSuite -> TestType
-testType test = case testInterface test of
- TestSuiteExeV10 ver _ -> TestTypeExe ver
- TestSuiteLibV09 ver _ -> TestTypeLib ver
- TestSuiteUnsupported testtype -> testtype
-
--- ---------------------------------------------------------------------------
--- The Benchmark type
-
--- | A \"benchmark\" stanza in a cabal file.
---
-data Benchmark = Benchmark {
- benchmarkName :: String,
- benchmarkInterface :: BenchmarkInterface,
- benchmarkBuildInfo :: BuildInfo,
- benchmarkEnabled :: Bool
- -- TODO: See TODO for 'testEnabled'.
- }
- deriving (Generic, Show, Read, Eq, Typeable, Data)
-
-instance Binary Benchmark
-
--- | The benchmark interfaces that are currently defined. Each
--- benchmark must specify which interface it supports.
---
--- More interfaces may be defined in future, either new revisions or
--- totally new interfaces.
---
-data BenchmarkInterface =
-
- -- | Benchmark interface \"exitcode-stdio-1.0\". The benchmark
- -- takes the form of an executable. It returns a zero exit code
- -- for success, non-zero for failure. The stdout and stderr
- -- channels may be logged. It takes no command line parameters
- -- and nothing on stdin.
- --
- BenchmarkExeV10 Version FilePath
-
- -- | A benchmark that does not conform to one of the above
- -- interfaces for the given reason (e.g. unknown benchmark type).
- --
- | BenchmarkUnsupported BenchmarkType
- deriving (Eq, Generic, Read, Show, Typeable, Data)
-
-instance Binary BenchmarkInterface
-
-instance Monoid Benchmark where
- mempty = Benchmark {
- benchmarkName = mempty,
- benchmarkInterface = mempty,
- benchmarkBuildInfo = mempty,
- benchmarkEnabled = False
- }
- mappend = (Semi.<>)
-
-instance Semigroup Benchmark where
- a <> b = Benchmark {
- benchmarkName = combine' benchmarkName,
- benchmarkInterface = combine benchmarkInterface,
- benchmarkBuildInfo = combine benchmarkBuildInfo,
- benchmarkEnabled = benchmarkEnabled a || benchmarkEnabled b
- }
- where combine field = field a `mappend` field b
- combine' f = case (f a, f b) of
- ("", x) -> x
- (x, "") -> x
- (x, y) -> error "Ambiguous values for benchmark field: '"
- ++ x ++ "' and '" ++ y ++ "'"
-
-instance Monoid BenchmarkInterface where
- mempty = BenchmarkUnsupported (BenchmarkTypeUnknown mempty (Version [] []))
- mappend = (Semi.<>)
-
-instance Semigroup BenchmarkInterface where
- a <> (BenchmarkUnsupported _) = a
- _ <> b = b
-
-emptyBenchmark :: Benchmark
-emptyBenchmark = mempty
-
--- | Does this package have any benchmarks?
-hasBenchmarks :: PackageDescription -> Bool
-hasBenchmarks = any (buildable . benchmarkBuildInfo) . benchmarks
-
--- | Get all the enabled benchmarks from a package.
-enabledBenchmarks :: PackageDescription -> [Benchmark]
-enabledBenchmarks = filter benchmarkEnabled . benchmarks
-
--- | Perform an action on each buildable 'Benchmark' in a package.
-withBenchmark :: PackageDescription -> (Benchmark -> IO ()) -> IO ()
-withBenchmark pkg_descr f =
- mapM_ f $ filter (buildable . benchmarkBuildInfo) $ enabledBenchmarks pkg_descr
-
--- | Get all the module names from a benchmark.
-benchmarkModules :: Benchmark -> [ModuleName]
-benchmarkModules benchmark = otherModules (benchmarkBuildInfo benchmark)
-
--- | The \"benchmark-type\" field in the benchmark stanza.
---
-data BenchmarkType = BenchmarkTypeExe Version
- -- ^ \"type: exitcode-stdio-x.y\"
- | BenchmarkTypeUnknown String Version
- -- ^ Some unknown benchmark type e.g. \"type: foo\"
- deriving (Generic, Show, Read, Eq, Typeable, Data)
-
-instance Binary BenchmarkType
-
-knownBenchmarkTypes :: [BenchmarkType]
-knownBenchmarkTypes = [ BenchmarkTypeExe (Version [1,0] []) ]
-
-instance Text BenchmarkType where
- disp (BenchmarkTypeExe ver) = text "exitcode-stdio-" <> disp ver
- disp (BenchmarkTypeUnknown name ver) = text name <> char '-' <> disp ver
-
- parse = stdParse $ \ver name -> case name of
- "exitcode-stdio" -> BenchmarkTypeExe ver
- _ -> BenchmarkTypeUnknown name ver
-
-
-benchmarkType :: Benchmark -> BenchmarkType
-benchmarkType benchmark = case benchmarkInterface benchmark of
- BenchmarkExeV10 ver _ -> BenchmarkTypeExe ver
- BenchmarkUnsupported benchmarktype -> benchmarktype
-
--- ---------------------------------------------------------------------------
--- The BuildInfo type
-
--- Consider refactoring into executable and library versions.
-data BuildInfo = BuildInfo {
- buildable :: Bool, -- ^ component is buildable here
- buildTools :: [Dependency], -- ^ tools needed to build this bit
- cppOptions :: [String], -- ^ options for pre-processing Haskell code
- ccOptions :: [String], -- ^ options for C compiler
- ldOptions :: [String], -- ^ options for linker
- pkgconfigDepends :: [Dependency], -- ^ pkg-config packages that are used
- frameworks :: [String], -- ^support frameworks for Mac OS X
- extraFrameworkDirs:: [String], -- ^ extra locations to find frameworks.
- cSources :: [FilePath],
- jsSources :: [FilePath],
- hsSourceDirs :: [FilePath], -- ^ where to look for the Haskell module hierarchy
- otherModules :: [ModuleName], -- ^ non-exposed or non-main modules
-
- defaultLanguage :: Maybe Language,-- ^ language used when not explicitly specified
- otherLanguages :: [Language], -- ^ other languages used within the package
- defaultExtensions :: [Extension], -- ^ language extensions used by all modules
- otherExtensions :: [Extension], -- ^ other language extensions used within the package
- oldExtensions :: [Extension], -- ^ the old extensions field, treated same as 'defaultExtensions'
-
- extraLibs :: [String], -- ^ what libraries to link with when compiling a program that uses your package
- extraGHCiLibs :: [String], -- ^ if present, overrides extraLibs when package is loaded with GHCi.
- extraLibDirs :: [String],
- includeDirs :: [FilePath], -- ^directories to find .h files
- includes :: [FilePath], -- ^ The .h files to be found in includeDirs
- installIncludes :: [FilePath], -- ^ .h files to install with the package
- options :: [(CompilerFlavor,[String])],
- profOptions :: [(CompilerFlavor,[String])],
- sharedOptions :: [(CompilerFlavor,[String])],
- customFieldsBI :: [(String,String)], -- ^Custom fields starting
- -- with x-, stored in a
- -- simple assoc-list.
- targetBuildDepends :: [Dependency], -- ^ Dependencies specific to a library or executable target
- targetBuildRenaming :: Map PackageName ModuleRenaming
- }
- deriving (Generic, Show, Read, Eq, Typeable, Data)
-
-instance Binary BuildInfo
-
-instance Monoid BuildInfo where
- mempty = BuildInfo {
- buildable = True,
- buildTools = [],
- cppOptions = [],
- ccOptions = [],
- ldOptions = [],
- pkgconfigDepends = [],
- frameworks = [],
- extraFrameworkDirs = [],
- cSources = [],
- jsSources = [],
- hsSourceDirs = [],
- otherModules = [],
- defaultLanguage = Nothing,
- otherLanguages = [],
- defaultExtensions = [],
- otherExtensions = [],
- oldExtensions = [],
- extraLibs = [],
- extraGHCiLibs = [],
- extraLibDirs = [],
- includeDirs = [],
- includes = [],
- installIncludes = [],
- options = [],
- profOptions = [],
- sharedOptions = [],
- customFieldsBI = [],
- targetBuildDepends = [],
- targetBuildRenaming = Map.empty
- }
- mappend = (Semi.<>)
-
-instance Semigroup BuildInfo where
- a <> b = BuildInfo {
- buildable = buildable a && buildable b,
- buildTools = combine buildTools,
- cppOptions = combine cppOptions,
- ccOptions = combine ccOptions,
- ldOptions = combine ldOptions,
- pkgconfigDepends = combine pkgconfigDepends,
- frameworks = combineNub frameworks,
- extraFrameworkDirs = combineNub extraFrameworkDirs,
- cSources = combineNub cSources,
- jsSources = combineNub jsSources,
- hsSourceDirs = combineNub hsSourceDirs,
- otherModules = combineNub otherModules,
- defaultLanguage = combineMby defaultLanguage,
- otherLanguages = combineNub otherLanguages,
- defaultExtensions = combineNub defaultExtensions,
- otherExtensions = combineNub otherExtensions,
- oldExtensions = combineNub oldExtensions,
- extraLibs = combine extraLibs,
- extraGHCiLibs = combine extraGHCiLibs,
- extraLibDirs = combineNub extraLibDirs,
- includeDirs = combineNub includeDirs,
- includes = combineNub includes,
- installIncludes = combineNub installIncludes,
- options = combine options,
- profOptions = combine profOptions,
- sharedOptions = combine sharedOptions,
- customFieldsBI = combine customFieldsBI,
- targetBuildDepends = combineNub targetBuildDepends,
- targetBuildRenaming = combineMap targetBuildRenaming
- }
- where
- combine field = field a `mappend` field b
- combineNub field = nub (combine field)
- combineMby field = field b `mplus` field a
- combineMap field = Map.unionWith mappend (field a) (field b)
-
-emptyBuildInfo :: BuildInfo
-emptyBuildInfo = mempty
-
--- | The 'BuildInfo' for the library (if there is one and it's buildable), and
--- all buildable executables, test suites and benchmarks. Useful for gathering
--- dependencies.
-allBuildInfo :: PackageDescription -> [BuildInfo]
-allBuildInfo pkg_descr = [ bi | lib <- libraries pkg_descr
- , let bi = libBuildInfo lib
- , buildable bi ]
- ++ [ bi | exe <- executables pkg_descr
- , let bi = buildInfo exe
- , buildable bi ]
- ++ [ bi | tst <- testSuites pkg_descr
- , let bi = testBuildInfo tst
- , buildable bi
- , testEnabled tst ]
- ++ [ bi | tst <- benchmarks pkg_descr
- , let bi = benchmarkBuildInfo tst
- , buildable bi
- , benchmarkEnabled tst ]
- --FIXME: many of the places where this is used, we actually want to look at
- -- unbuildable bits too, probably need separate functions
-
--- | The 'Language's used by this component
---
-allLanguages :: BuildInfo -> [Language]
-allLanguages bi = maybeToList (defaultLanguage bi)
- ++ otherLanguages bi
-
--- | The 'Extension's that are used somewhere by this component
---
-allExtensions :: BuildInfo -> [Extension]
-allExtensions bi = usedExtensions bi
- ++ otherExtensions bi
-
--- | The 'Extensions' that are used by all modules in this component
---
-usedExtensions :: BuildInfo -> [Extension]
-usedExtensions bi = oldExtensions bi
- ++ defaultExtensions bi
-
--- Libraries live in a separate namespace, so must distinguish
-data ComponentName = CLibName String
- | CExeName String
- | CTestName String
- | CBenchName String
- deriving (Eq, Generic, Ord, Read, Show)
-
-instance Binary ComponentName
-
-defaultLibName :: PackageIdentifier -> ComponentName
-defaultLibName pid = CLibName (display (pkgName pid))
-
-type HookedBuildInfo = [(ComponentName, BuildInfo)]
-
-emptyHookedBuildInfo :: HookedBuildInfo
-emptyHookedBuildInfo = []
-
--- |Select options for a particular Haskell compiler.
-hcOptions :: CompilerFlavor -> BuildInfo -> [String]
-hcOptions = lookupHcOptions options
-
-hcProfOptions :: CompilerFlavor -> BuildInfo -> [String]
-hcProfOptions = lookupHcOptions profOptions
-
-hcSharedOptions :: CompilerFlavor -> BuildInfo -> [String]
-hcSharedOptions = lookupHcOptions sharedOptions
-
-lookupHcOptions :: (BuildInfo -> [(CompilerFlavor,[String])])
- -> CompilerFlavor -> BuildInfo -> [String]
-lookupHcOptions f hc bi = [ opt | (hc',opts) <- f bi
- , hc' == hc
- , opt <- opts ]
-
--- ------------------------------------------------------------
--- * Source repos
--- ------------------------------------------------------------
-
--- | Information about the source revision control system for a package.
---
--- When specifying a repo it is useful to know the meaning or intention of the
--- information as doing so enables automation. There are two obvious common
--- purposes: one is to find the repo for the latest development version, the
--- other is to find the repo for this specific release. The 'ReopKind'
--- specifies which one we mean (or another custom one).
---
--- A package can specify one or the other kind or both. Most will specify just
--- a head repo but some may want to specify a repo to reconstruct the sources
--- for this package release.
---
--- The required information is the 'RepoType' which tells us if it's using
--- 'Darcs', 'Git' for example. The 'repoLocation' and other details are
--- interpreted according to the repo type.
---
-data SourceRepo = SourceRepo {
- -- | The kind of repo. This field is required.
- repoKind :: RepoKind,
-
- -- | The type of the source repository system for this repo, eg 'Darcs' or
- -- 'Git'. This field is required.
- repoType :: Maybe RepoType,
-
- -- | The location of the repository. For most 'RepoType's this is a URL.
- -- This field is required.
- repoLocation :: Maybe String,
-
- -- | 'CVS' can put multiple \"modules\" on one server and requires a
- -- module name in addition to the location to identify a particular repo.
- -- Logically this is part of the location but unfortunately has to be
- -- specified separately. This field is required for the 'CVS' 'RepoType' and
- -- should not be given otherwise.
- repoModule :: Maybe String,
-
- -- | The name or identifier of the branch, if any. Many source control
- -- systems have the notion of multiple branches in a repo that exist in the
- -- same location. For example 'Git' and 'CVS' use this while systems like
- -- 'Darcs' use different locations for different branches. This field is
- -- optional but should be used if necessary to identify the sources,
- -- especially for the 'RepoThis' repo kind.
- repoBranch :: Maybe String,
-
- -- | The tag identify a particular state of the repository. This should be
- -- given for the 'RepoThis' repo kind and not for 'RepoHead' kind.
- --
- repoTag :: Maybe String,
-
- -- | Some repositories contain multiple projects in different subdirectories
- -- This field specifies the subdirectory where this packages sources can be
- -- found, eg the subdirectory containing the @.cabal@ file. It is interpreted
- -- relative to the root of the repository. This field is optional. If not
- -- given the default is \".\" ie no subdirectory.
- repoSubdir :: Maybe FilePath
-}
- deriving (Eq, Generic, Read, Show, Typeable, Data)
-
-instance Binary SourceRepo
-
--- | What this repo info is for, what it represents.
---
-data RepoKind =
- -- | The repository for the \"head\" or development version of the project.
- -- This repo is where we should track the latest development activity or
- -- the usual repo people should get to contribute patches.
- RepoHead
-
- -- | The repository containing the sources for this exact package version
- -- or release. For this kind of repo a tag should be given to give enough
- -- information to re-create the exact sources.
- | RepoThis
-
- | RepoKindUnknown String
- deriving (Eq, Generic, Ord, Read, Show, Typeable, Data)
-
-instance Binary RepoKind
-
--- | An enumeration of common source control systems. The fields used in the
--- 'SourceRepo' depend on the type of repo. The tools and methods used to
--- obtain and track the repo depend on the repo type.
---
-data RepoType = Darcs | Git | SVN | CVS
- | Mercurial | GnuArch | Bazaar | Monotone
- | OtherRepoType String
- deriving (Eq, Generic, Ord, Read, Show, Typeable, Data)
-
-instance Binary RepoType
-
-knownRepoTypes :: [RepoType]
-knownRepoTypes = [Darcs, Git, SVN, CVS
- ,Mercurial, GnuArch, Bazaar, Monotone]
-
-repoTypeAliases :: RepoType -> [String]
-repoTypeAliases Bazaar = ["bzr"]
-repoTypeAliases Mercurial = ["hg"]
-repoTypeAliases GnuArch = ["arch"]
-repoTypeAliases _ = []
-
-instance Text RepoKind where
- disp RepoHead = Disp.text "head"
- disp RepoThis = Disp.text "this"
- disp (RepoKindUnknown other) = Disp.text other
-
- parse = do
- name <- ident
- return $ case lowercase name of
- "head" -> RepoHead
- "this" -> RepoThis
- _ -> RepoKindUnknown name
-
-instance Text RepoType where
- disp (OtherRepoType other) = Disp.text other
- disp other = Disp.text (lowercase (show other))
- parse = fmap classifyRepoType ident
-
-classifyRepoType :: String -> RepoType
-classifyRepoType s =
- fromMaybe (OtherRepoType s) $ lookup (lowercase s) repoTypeMap
- where
- repoTypeMap = [ (name, repoType')
- | repoType' <- knownRepoTypes
- , name <- display repoType' : repoTypeAliases repoType' ]
-
-ident :: Parse.ReadP r String
-ident = Parse.munch1 (\c -> Char.isAlphaNum c || c == '_' || c == '-')
-
-lowercase :: String -> String
-lowercase = map Char.toLower
-
--- ------------------------------------------------------------
--- * Utils
--- ------------------------------------------------------------
-
-updatePackageDescription :: HookedBuildInfo -> PackageDescription -> PackageDescription
-updatePackageDescription hooked_bis p
- = p{ executables = updateMany (CExeName . exeName) updateExecutable (executables p)
- , libraries = updateMany (CLibName . libName) updateLibrary (libraries p)
- , benchmarks = updateMany (CBenchName . benchmarkName) updateBenchmark (benchmarks p)
- , testSuites = updateMany (CTestName . testName) updateTestSuite (testSuites p)
- }
- where
- updateMany :: (a -> ComponentName) -- ^ get 'ComponentName' from @a@
- -> (BuildInfo -> a -> a) -- ^ @updateExecutable@, @updateLibrary@, etc
- -> [a] -- ^list of components to update
- -> [a] -- ^list with updated components
- updateMany name update cs' = foldr (updateOne name update) cs' hooked_bis
-
- updateOne :: (a -> ComponentName) -- ^ get 'ComponentName' from @a@
- -> (BuildInfo -> a -> a) -- ^ @updateExecutable@, @updateLibrary@, etc
- -> (ComponentName, BuildInfo) -- ^(name, new buildinfo)
- -> [a] -- ^list of components to update
- -> [a] -- ^list with name component updated
- updateOne _ _ _ [] = []
- updateOne name_sel update hooked_bi'@(name,bi) (c:cs)
- | name_sel c == name ||
- -- Special case: an empty name means "please update the BuildInfo for
- -- the public library, i.e. the one with the same name as the
- -- package." See 'parseHookedBuildInfo'.
- name == CLibName "" && name_sel c == defaultLibName (package p)
- = update bi c : cs
- | otherwise = c : updateOne name_sel update hooked_bi' cs
-
- updateExecutable bi exe = exe{buildInfo = bi `mappend` buildInfo exe}
- updateLibrary bi lib = lib{libBuildInfo = bi `mappend` libBuildInfo lib}
- updateBenchmark bi ben = ben{benchmarkBuildInfo = bi `mappend` benchmarkBuildInfo ben}
- updateTestSuite bi test = test{testBuildInfo = bi `mappend` testBuildInfo test}
-
--- ---------------------------------------------------------------------------
--- The GenericPackageDescription type
-
-data GenericPackageDescription =
- GenericPackageDescription {
- packageDescription :: PackageDescription,
- genPackageFlags :: [Flag],
- condLibraries :: [(String, CondTree ConfVar [Dependency] Library)],
- condExecutables :: [(String, CondTree ConfVar [Dependency] Executable)],
- condTestSuites :: [(String, CondTree ConfVar [Dependency] TestSuite)],
- condBenchmarks :: [(String, CondTree ConfVar [Dependency] Benchmark)]
- }
- deriving (Show, Eq, Typeable, Data, Generic)
-
-instance Package GenericPackageDescription where
- packageId = packageId . packageDescription
-
-instance Binary GenericPackageDescription
-
--- | A flag can represent a feature to be included, or a way of linking
--- a target against its dependencies, or in fact whatever you can think of.
-data Flag = MkFlag
- { flagName :: FlagName
- , flagDescription :: String
- , flagDefault :: Bool
- , flagManual :: Bool
- }
- deriving (Show, Eq, Typeable, Data, Generic)
-
-instance Binary Flag
-
--- | A 'FlagName' is the name of a user-defined configuration flag
-newtype FlagName = FlagName String
- deriving (Eq, Generic, Ord, Show, Read, Typeable, Data)
-
-instance Binary FlagName
-
--- | A 'FlagAssignment' is a total or partial mapping of 'FlagName's to
--- 'Bool' flag values. It represents the flags chosen by the user or
--- discovered during configuration. For example @--flags=foo --flags=-bar@
--- becomes @[("foo", True), ("bar", False)]@
---
-type FlagAssignment = [(FlagName, Bool)]
-
--- | A @ConfVar@ represents the variable type used.
-data ConfVar = OS OS
- | Arch Arch
- | Flag FlagName
- | Impl CompilerFlavor VersionRange
- deriving (Eq, Show, Typeable, Data, Generic)
-
-instance Binary ConfVar
-
--- | A boolean expression parameterized over the variable type used.
-data Condition c = Var c
- | Lit Bool
- | CNot (Condition c)
- | COr (Condition c) (Condition c)
- | CAnd (Condition c) (Condition c)
- deriving (Show, Eq, Typeable, Data, Generic)
-
-cNot :: Condition a -> Condition a
-cNot (Lit b) = Lit (not b)
-cNot (CNot c) = c
-cNot c = CNot c
-
-instance Functor Condition where
- f `fmap` Var c = Var (f c)
- _ `fmap` Lit c = Lit c
- f `fmap` CNot c = CNot (fmap f c)
- f `fmap` COr c d = COr (fmap f c) (fmap f d)
- f `fmap` CAnd c d = CAnd (fmap f c) (fmap f d)
-
-instance Foldable Condition where
- f `foldMap` Var c = f c
- _ `foldMap` Lit _ = mempty
- f `foldMap` CNot c = Fold.foldMap f c
- f `foldMap` COr c d = foldMap f c `mappend` foldMap f d
- f `foldMap` CAnd c d = foldMap f c `mappend` foldMap f d
-
-instance Traversable Condition where
- f `traverse` Var c = Var `fmap` f c
- _ `traverse` Lit c = pure $ Lit c
- f `traverse` CNot c = CNot `fmap` Trav.traverse f c
- f `traverse` COr c d = COr `fmap` traverse f c <*> traverse f d
- f `traverse` CAnd c d = CAnd `fmap` traverse f c <*> traverse f d
-
-instance Applicative Condition where
- pure = Var
- (<*>) = ap
-
-instance Monad Condition where
- return = AP.pure
- -- Terminating cases
- (>>=) (Lit x) _ = Lit x
- (>>=) (Var x) f = f x
- -- Recursing cases
- (>>=) (CNot x ) f = CNot (x >>= f)
- (>>=) (COr x y) f = COr (x >>= f) (y >>= f)
- (>>=) (CAnd x y) f = CAnd (x >>= f) (y >>= f)
-
-instance Monoid (Condition a) where
- mempty = Lit False
- mappend = (Semi.<>)
-
-instance Semigroup (Condition a) where
- (<>) = COr
-
-instance Alternative Condition where
- empty = mempty
- (<|>) = mappend
-
-instance MonadPlus Condition where
- mzero = mempty
- mplus = mappend
-
-instance Binary c => Binary (Condition c)
-
-data CondTree v c a = CondNode
- { condTreeData :: a
- , condTreeConstraints :: c
- , condTreeComponents :: [( Condition v
- , CondTree v c a
- , Maybe (CondTree v c a))]
- }
- deriving (Show, Eq, Typeable, Data, Generic)
-
-instance (Binary v, Binary c, Binary a) => Binary (CondTree v c a)
+import Prelude ()
+--import Distribution.Compat.Prelude
+
+import Distribution.Types.Library
+import Distribution.Types.TestSuite
+import Distribution.Types.Executable
+import Distribution.Types.Benchmark
+import Distribution.Types.TestType
+import Distribution.Types.TestSuiteInterface
+import Distribution.Types.BenchmarkType
+import Distribution.Types.BenchmarkInterface
+import Distribution.Types.ModuleRenaming
+import Distribution.Types.ModuleReexport
+import Distribution.Types.BuildInfo
+import Distribution.Types.SetupBuildInfo
+import Distribution.Types.BuildType
+import Distribution.Types.GenericPackageDescription
+import Distribution.Types.PackageDescription
+import Distribution.Types.ComponentName
+import Distribution.Types.HookedBuildInfo
+import Distribution.Types.SourceRepo
diff --git a/cabal/Cabal/Distribution/PackageDescription/Check.hs b/cabal/Cabal/Distribution/PackageDescription/Check.hs
index add824c..3eb30ad 100644
--- a/cabal/Cabal/Distribution/PackageDescription/Check.hs
+++ b/cabal/Cabal/Distribution/PackageDescription/Check.hs
@@ -34,38 +34,40 @@ module Distribution.PackageDescription.Check (
checkPackageFileNames,
) where
+import Prelude ()
+import Distribution.Compat.Prelude
+
import Distribution.PackageDescription
import Distribution.PackageDescription.Configuration
import Distribution.Compiler
import Distribution.System
import Distribution.License
+import Distribution.Simple.BuildPaths (autogenPathsModuleName)
import Distribution.Simple.CCompiler
+import Distribution.Types.ComponentRequestedSpec
import Distribution.Simple.Utils hiding (findPackageDesc, notice)
import Distribution.Version
import Distribution.Package
import Distribution.Text
import Language.Haskell.Extension
-import Data.Maybe
- ( isNothing, isJust, catMaybes, mapMaybe, fromMaybe )
-import Data.List (sort, group, isPrefixOf, nub, find)
-import Control.Monad
- ( filterM, liftM )
+import Control.Monad (mapM)
+import Data.List (group)
import qualified System.Directory as System
( doesFileExist, doesDirectoryExist )
import qualified Data.Map as Map
import qualified Text.PrettyPrint as Disp
-import Text.PrettyPrint ((<>), (<+>))
+import Text.PrettyPrint ((<+>))
import qualified System.Directory (getDirectoryContents)
import System.IO (openBinaryFile, IOMode(ReadMode), hGetContents)
import System.FilePath
- ( (</>), takeExtension, isRelative, isAbsolute
- , splitDirectories, splitPath, splitExtension )
+ ( (</>), takeExtension, splitDirectories, splitPath, splitExtension )
import System.FilePath.Windows as FilePath.Windows
( isValid )
+
-- | Results of some kind of failed package check.
--
-- There are a range of severities, from merely dubious to totally insane.
@@ -112,7 +114,7 @@ check True pc = Just pc
checkSpecVersion :: PackageDescription -> [Int] -> Bool -> PackageCheck
-> Maybe PackageCheck
checkSpecVersion pkg specver cond pc
- | specVersion pkg >= Version specver [] = Nothing
+ | specVersion pkg >= mkVersion specver = Nothing
| otherwise = check cond pc
-- ------------------------------------------------------------
@@ -165,28 +167,45 @@ checkSanity :: PackageDescription -> [PackageCheck]
checkSanity pkg =
catMaybes [
- check (null . (\(PackageName n) -> n) . packageName $ pkg) $
+ check (null . unPackageName . packageName $ pkg) $
PackageBuildImpossible "No 'name' field."
- , check (null . versionBranch . packageVersion $ pkg) $
+ , check (nullVersion == packageVersion pkg) $
PackageBuildImpossible "No 'version' field."
, check (all ($ pkg) [ null . executables
, null . testSuites
, null . benchmarks
- , null . libraries ]) $
+ , null . allLibraries
+ , null . foreignLibs ]) $
PackageBuildImpossible
"No executables, libraries, tests, or benchmarks found. Nothing to do."
+ , check (any isNothing (map libName $ subLibraries pkg)) $
+ PackageBuildImpossible $ "Found one or more unnamed internal libraries. "
+ ++ "Only the non-internal library can have the same name as the package."
+
, check (not (null duplicateNames)) $
- PackageBuildImpossible $ "Duplicate sections: " ++ commaSep duplicateNames
- ++ ". The name of every library, executable, test suite, and benchmark section in"
+ PackageBuildImpossible $ "Duplicate sections: "
+ ++ commaSep (map unUnqualComponentName duplicateNames)
+ ++ ". The name of every library, executable, test suite,"
+ ++ " and benchmark section in"
++ " the package must be unique."
+
+ -- NB: but it's OK for executables to have the same name!
+ -- TODO shouldn't need to compare on the string level
+ , check (any (== display (packageName pkg)) (display <$> subLibNames)) $
+ PackageBuildImpossible $ "Illegal internal library name "
+ ++ display (packageName pkg)
+ ++ ". Internal libraries cannot have the same name as the package."
+ ++ " Maybe you wanted a non-internal library?"
+ ++ " If so, rewrite the section stanza"
+ ++ " from 'library: '" ++ display (packageName pkg) ++ "' to 'library'."
]
--TODO: check for name clashes case insensitively: windows file systems cannot
--cope.
- ++ concatMap (checkLibrary pkg) (libraries pkg)
+ ++ concatMap (checkLibrary pkg) (allLibraries pkg)
++ concatMap (checkExecutable pkg) (executables pkg)
++ concatMap (checkTestSuite pkg) (testSuites pkg)
++ concatMap (checkBenchmark pkg) (benchmarks pkg)
@@ -200,15 +219,14 @@ checkSanity pkg =
++ "tool only supports up to version " ++ display cabalVersion ++ "."
]
where
- -- The public library gets special dispensation, because it
+ -- The public 'library' gets special dispensation, because it
-- is common practice to export a library and name the executable
- -- the same as the package. We always put the public library
- -- in the top-level directory in dist, so no conflicts either.
- libNames = filter (/= unPackageName (packageName pkg)) . map libName $ libraries pkg
+ -- the same as the package.
+ subLibNames = catMaybes . map libName $ subLibraries pkg
exeNames = map exeName $ executables pkg
testNames = map testName $ testSuites pkg
bmNames = map benchmarkName $ benchmarks pkg
- duplicateNames = dups $ libNames ++ exeNames ++ testNames ++ bmNames
+ duplicateNames = dups $ subLibNames ++ exeNames ++ testNames ++ bmNames
checkLibrary :: PackageDescription -> Library -> [PackageCheck]
checkLibrary pkg lib =
@@ -219,25 +237,37 @@ checkLibrary pkg lib =
"Duplicate modules in library: "
++ commaSep (map display moduleDuplicates)
- -- check use of required-signatures/exposed-signatures sections
- , checkVersion [1,21] (not (null (requiredSignatures lib))) $
- PackageDistInexcusable $
- "To use the 'required-signatures' field the package needs to specify "
- ++ "at least 'cabal-version: >= 1.21'."
+ -- TODO: This check is bogus if a required-signature was passed through
+ , check (null (explicitLibModules lib) && null (reexportedModules lib)) $
+ PackageDistSuspiciousWarn $
+ "Library " ++ (case libName lib of
+ Nothing -> ""
+ Just n -> display n
+ ) ++ "does not expose any modules"
- , checkVersion [1,21] (not (null (exposedSignatures lib))) $
+ -- check use of signatures sections
+ , checkVersion [1,25] (not (null (signatures lib))) $
PackageDistInexcusable $
- "To use the 'exposed-signatures' field the package needs to specify "
- ++ "at least 'cabal-version: >= 1.21'."
+ "To use the 'signatures' field the package needs to specify "
+ ++ "at least 'cabal-version: >= 1.25'."
+
+ -- check that all autogen-modules appear on other-modules or exposed-modules
+ , check
+ (not $ and $ map (flip elem (explicitLibModules lib)) (libModulesAutogen lib)) $
+ PackageBuildImpossible $
+ "An 'autogen-module' is neither on 'exposed-modules' or "
+ ++ "'other-modules'."
+
]
where
checkVersion :: [Int] -> Bool -> PackageCheck -> Maybe PackageCheck
checkVersion ver cond pc
- | specVersion pkg >= Version ver [] = Nothing
+ | specVersion pkg >= mkVersion ver = Nothing
| otherwise = check cond pc
- moduleDuplicates = dups (libModules lib ++
+ -- TODO: not sure if this check is always right in Backpack
+ moduleDuplicates = dups (explicitLibModules lib ++
map moduleReexportName (reexportedModules lib))
checkExecutable :: PackageDescription -> Executable -> [PackageCheck]
@@ -246,7 +276,7 @@ checkExecutable pkg exe =
check (null (modulePath exe)) $
PackageBuildImpossible $
- "No 'main-is' field found for executable " ++ exeName exe
+ "No 'main-is' field found for executable " ++ display (exeName exe)
, check (not (null (modulePath exe))
&& (not $ fileExtensionSupportedLanguage $ modulePath exe)) $
@@ -264,8 +294,16 @@ checkExecutable pkg exe =
, check (not (null moduleDuplicates)) $
PackageBuildImpossible $
- "Duplicate modules in executable '" ++ exeName exe ++ "': "
+ "Duplicate modules in executable '" ++ display (exeName exe) ++ "': "
++ commaSep (map display moduleDuplicates)
+
+ -- check that all autogen-modules appear on other-modules
+ , check
+ (not $ and $ map (flip elem (exeModules exe)) (exeModulesAutogen exe)) $
+ PackageBuildImpossible $
+ "On executable '" ++ display (exeName exe) ++ "' an 'autogen-module' is not "
+ ++ "on 'other-modules'"
+
]
where
moduleDuplicates = dups (exeModules exe)
@@ -290,7 +328,7 @@ checkTestSuite pkg test =
, check (not $ null moduleDuplicates) $
PackageBuildImpossible $
- "Duplicate modules in test suite '" ++ testName test ++ "': "
+ "Duplicate modules in test suite '" ++ display (testName test) ++ "': "
++ commaSep (map display moduleDuplicates)
, check mainIsWrongExt $
@@ -303,6 +341,16 @@ checkTestSuite pkg test =
PackageDistInexcusable $
"The package uses a C/C++/obj-C source file for the 'main-is' field. "
++ "To use this feature you must specify 'cabal-version: >= 1.18'."
+
+ -- check that all autogen-modules appear on other-modules
+ , check
+ (not $ and $ map
+ (flip elem (testModules test))
+ (testModulesAutogen test)
+ ) $
+ PackageBuildImpossible $
+ "On test suite '" ++ display (testName test) ++ "' an 'autogen-module' is not "
+ ++ "on 'other-modules'"
]
where
moduleDuplicates = dups $ testModules test
@@ -335,13 +383,23 @@ checkBenchmark _pkg bm =
, check (not $ null moduleDuplicates) $
PackageBuildImpossible $
- "Duplicate modules in benchmark '" ++ benchmarkName bm ++ "': "
+ "Duplicate modules in benchmark '" ++ display (benchmarkName bm) ++ "': "
++ commaSep (map display moduleDuplicates)
, check mainIsWrongExt $
PackageBuildImpossible $
"The 'main-is' field must specify a '.hs' or '.lhs' file "
++ "(even if it is generated by a preprocessor)."
+
+ -- check that all autogen-modules appear on other-modules
+ , check
+ (not $ and $ map
+ (flip elem (benchmarkModules bm))
+ (benchmarkModulesAutogen bm)
+ ) $
+ PackageBuildImpossible $
+ "On benchmark '" ++ display (benchmarkName bm) ++ "' an 'autogen-module' is "
+ ++ "not on 'other-modules'"
]
where
moduleDuplicates = dups $ benchmarkModules bm
@@ -441,6 +499,22 @@ checkFields pkg =
PackageDistSuspicious
"The 'synopsis' field is rather long (max 80 chars is recommended)."
+ -- See also https://github.com/haskell/cabal/pull/3479
+ , check (not (null (description pkg))
+ && length (description pkg) <= length (synopsis pkg)) $
+ PackageDistSuspicious $
+ "The 'description' field should be longer than the 'synopsis' "
+ ++ "field. "
+ ++ "It's useful to provide an informative 'description' to allow "
+ ++ "Haskell programmers who have never heard about your package to "
+ ++ "understand the purpose of your package. "
+ ++ "The 'description' field content is typically shown by tooling "
+ ++ "(e.g. 'cabal info', Haddock, Hackage) below the 'synopsis' which "
+ ++ "serves as a headline. "
+ ++ "Please refer to <https://www.haskell.org/"
+ ++ "cabal/users-guide/developing-packages.html#package-properties>"
+ ++ " for more details."
+
-- check use of impossible constraints "tested-with: GHC== 6.10 && ==6.12"
, check (not (null testedWithImpossibleRanges)) $
PackageDistInexcusable $
@@ -450,6 +524,14 @@ checkFields pkg =
++ "different versions of the same compiler use multiple entries, "
++ "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 buildDependsRangeOnInternalLibrary)) $
+ PackageBuildWarning $
+ "The package has a version range for a dependency on an "
+ ++ "internal library: "
+ ++ commaSep (map display buildDependsRangeOnInternalLibrary)
+ ++ ". This version range has no semantic meaning and can be "
+ ++ "removed."
]
where
unknownCompilers = [ name | (OtherCompiler name, _) <- testedWith pkg ]
@@ -468,10 +550,21 @@ checkFields pkg =
, name `elem` map display knownLanguages ]
testedWithImpossibleRanges =
- [ Dependency (PackageName (display compiler)) vr
+ [ Dependency (mkPackageName (display compiler)) vr
| (compiler, vr) <- testedWith pkg
, isNoVersion vr ]
+ internalLibraries =
+ map (maybe (packageName pkg) (unqualComponentNameToPackageName) . libName)
+ (allLibraries pkg)
+ buildDependsRangeOnInternalLibrary =
+ [ dep
+ | bi <- allBuildInfo pkg
+ , dep@(Dependency name versionRange) <- targetBuildDepends bi
+ , not (isAnyVersion versionRange)
+ , name `elem` internalLibraries
+ ]
+
checkLicense :: PackageDescription -> [PackageCheck]
checkLicense pkg =
@@ -558,7 +651,7 @@ checkSourceRepos pkg =
++ "field. It should specify the tag corresponding to this version "
++ "or release of the package."
- , check (maybe False System.FilePath.isAbsolute (repoSubdir repo)) $
+ , check (maybe False isAbsoluteOnAnyPlatform (repoSubdir repo)) $
PackageDistInexcusable
"The 'subdir' field of a source-repository must be a relative path."
]
@@ -692,7 +785,8 @@ checkGhcOptions pkg =
where
all_ghc_options = concatMap get_ghc_options (allBuildInfo pkg)
- lib_ghc_options = concatMap (get_ghc_options . libBuildInfo) (libraries pkg)
+ lib_ghc_options = concatMap (get_ghc_options . libBuildInfo)
+ (allLibraries pkg)
get_ghc_options bi = hcOptions GHC bi ++ hcProfOptions GHC bi
++ hcSharedOptions GHC bi
@@ -781,7 +875,8 @@ checkCPPOptions pkg =
where all_cppOptions = [ opts | bi <- allBuildInfo pkg
, opts <- cppOptions bi ]
-checkAlternatives :: String -> String -> [(String, String)] -> Maybe PackageCheck
+checkAlternatives :: String -> String -> [(String, String)]
+ -> Maybe PackageCheck
checkAlternatives badField goodField flags =
check (not (null badFlags)) $
PackageBuildWarning $
@@ -802,7 +897,7 @@ checkPaths pkg =
[ PackageDistInexcusable $
quote (kind ++ ": " ++ path) ++ " is an absolute path."
| (path, kind) <- relPaths
- , isAbsolute path ]
+ , isAbsoluteOnAnyPlatform path ]
++
[ PackageDistInexcusable $
quote (kind ++ ": " ++ path) ++ " points inside the 'dist' "
@@ -867,7 +962,7 @@ checkCabalVersion pkg =
catMaybes [
-- check syntax of cabal-version field
- check (specVersion pkg >= Version [1,10] []
+ check (specVersion pkg >= mkVersion [1,10]
&& not simpleSpecVersionRangeSyntax) $
PackageBuildWarning $
"Packages relying on Cabal 1.10 or later must only specify a "
@@ -875,7 +970,7 @@ checkCabalVersion pkg =
++ "'cabal-version: >= " ++ display (specVersion pkg) ++ "'."
-- check syntax of cabal-version field
- , check (specVersion pkg < Version [1,9] []
+ , check (specVersion pkg < mkVersion [1,9]
&& not simpleSpecVersionRangeSyntax) $
PackageDistSuspicious $
"It is recommended that the 'cabal-version' field only specify a "
@@ -906,7 +1001,7 @@ checkCabalVersion pkg =
"To use the 'default-language' field the package needs to specify "
++ "at least 'cabal-version: >= 1.10'."
- , check (specVersion pkg >= Version [1,10] []
+ , check (specVersion pkg >= mkVersion [1,10]
&& (any isNothing (buildInfoField defaultLanguage))) $
PackageBuildWarning $
"Packages using 'cabal-version: >= 1.10' must spec