From ab07653c6637b596b4d228bb29fbd3105ee1ba1d Mon Sep 17 00:00:00 2001 From: Bodigrim Date: Thu, 2 Jul 2026 20:42:42 +0100 Subject: [PATCH] There is a better way to parse record fields (ApplicativeDo + RecordWildCards) --- .../PackageDescription/FieldGrammar.hs | 314 ++++++++------- .../InstalledPackageInfo/FieldGrammar.hs | 34 +- Cabal/src/Distribution/Simple/InstallDirs.hs | 40 +- cabal-dev-scripts/src/GenSPDX.hs | 15 +- .../Client/BuildReports/Anonymous.hs | 26 +- .../Client/CmdInstall/ClientInstallFlags.hs | 20 +- .../src/Distribution/Client/DistDirLayout.hs | 2 +- .../Client/Init/Interactive/Command.hs | 87 ++-- .../Client/Init/NonInteractive/Command.hs | 86 ++-- .../Client/ProjectConfig/FieldGrammar.hs | 378 +++++++----------- .../Distribution/Client/Types/SourceRepo.hs | 18 +- .../src/Distribution/Client/Utils/Parsec.hs | 19 +- cabal-testsuite/src/Test/Cabal/Monad.hs | 34 +- cabal-validate/src/Cli.hs | 147 +++---- solver-benchmarks/HackageBenchmark.hs | 28 +- 15 files changed, 618 insertions(+), 630 deletions(-) diff --git a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs index 08064d27f29..1f8d47a4faf 100644 --- a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs +++ b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs @@ -1,5 +1,7 @@ +{-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RecordWildCards #-} -- | 'GenericPackageDescription' Field descriptions module Distribution.PackageDescription.FieldGrammar @@ -104,48 +106,50 @@ packageDescriptionFieldGrammar , c CompatDataDir ) => g PackageDescription PackageDescription -packageDescriptionFieldGrammar = - PackageDescription - <$> optionalFieldDefAla "cabal-version" SpecVersion L.specVersion CabalSpecV1_0 - <*> blurFieldGrammar L.package packageIdentifierGrammar - <*> optionalFieldDefAla "license" SpecLicense L.licenseRaw (Left SPDX.NONE) - <*> licenseFilesGrammar - <*> freeTextFieldDefST "copyright" L.copyright - <*> freeTextFieldDefST "maintainer" L.maintainer - <*> freeTextFieldDefST "author" L.author - <*> freeTextFieldDefST "stability" L.stability - <*> monoidalFieldAla "tested-with" (alaList' FSep TestedWith) L.testedWith - <*> freeTextFieldDefST "homepage" L.homepage - <*> freeTextFieldDefST "package-url" L.pkgUrl - <*> freeTextFieldDefST "bug-reports" L.bugReports - <*> pure [] -- source-repos are stanza - <*> freeTextFieldDefST "synopsis" L.synopsis - <*> freeTextFieldDefST "description" L.description - <*> freeTextFieldDefST "category" L.category - <*> prefixedFields "x-" L.customFieldsPD - <*> optionalField "build-type" L.buildTypeRaw - <*> pure Nothing -- custom-setup - -- components - <*> pure Nothing -- lib - <*> pure [] -- sub libs - <*> pure [] -- executables - <*> pure [] -- foreign libs - <*> pure [] -- test suites - <*> pure [] -- benchmarks - -- * Files - <*> monoidalFieldAla "data-files" (alaList' VCat RelativePathNT) L.dataFiles - <*> optionalFieldDefAla "data-dir" CompatDataDir L.dataDir sameDirectory +packageDescriptionFieldGrammar = do + specVersion <- optionalFieldDefAla "cabal-version" SpecVersion L.specVersion CabalSpecV1_0 + package <- blurFieldGrammar L.package packageIdentifierGrammar + licenseRaw <- optionalFieldDefAla "license" SpecLicense L.licenseRaw (Left SPDX.NONE) + licenseFiles <- licenseFilesGrammar + copyright <- freeTextFieldDefST "copyright" L.copyright + maintainer <- freeTextFieldDefST "maintainer" L.maintainer + author <- freeTextFieldDefST "author" L.author + stability <- freeTextFieldDefST "stability" L.stability + testedWith <- monoidalFieldAla "tested-with" (alaList' FSep TestedWith) L.testedWith + homepage <- freeTextFieldDefST "homepage" L.homepage + pkgUrl <- freeTextFieldDefST "package-url" L.pkgUrl + bugReports <- freeTextFieldDefST "bug-reports" L.bugReports + let sourceRepos = [] + synopsis <- freeTextFieldDefST "synopsis" L.synopsis + description <- freeTextFieldDefST "description" L.description + category <- freeTextFieldDefST "category" L.category + customFieldsPD <- prefixedFields "x-" L.customFieldsPD + buildTypeRaw <- optionalField "build-type" L.buildTypeRaw + let setupBuildInfo = Nothing + -- components + library = Nothing + subLibraries = [] + executables = [] + foreignLibs = [] + testSuites = [] + benchmarks = [] + -- * Files + dataFiles <- monoidalFieldAla "data-files" (alaList' VCat RelativePathNT) L.dataFiles + dataDir <- + optionalFieldDefAla "data-dir" CompatDataDir L.dataDir sameDirectory ^^^ fmap (\x -> if null (getSymbolicPath x) then sameDirectory else x) -- map empty directories to "." - <*> monoidalFieldAla "extra-source-files" formatExtraSourceFiles L.extraSrcFiles - <*> monoidalFieldAla "extra-tmp-files" (alaList' VCat RelativePathNT) L.extraTmpFiles - <*> monoidalFieldAla "extra-doc-files" formatExtraSourceFiles L.extraDocFiles - <*> monoidalFieldAla "extra-files" formatExtraSourceFiles L.extraFiles + extraSrcFiles <- monoidalFieldAla "extra-source-files" formatExtraSourceFiles L.extraSrcFiles + extraTmpFiles <- monoidalFieldAla "extra-tmp-files" (alaList' VCat RelativePathNT) L.extraTmpFiles + extraDocFiles <- monoidalFieldAla "extra-doc-files" formatExtraSourceFiles L.extraDocFiles + extraFiles <- + monoidalFieldAla "extra-files" formatExtraSourceFiles L.extraFiles ^^^ availableSince CabalSpecV3_14 [] + pure PackageDescription{..} where - packageIdentifierGrammar = - PackageIdentifier - <$> uniqueField "name" L.pkgName - <*> uniqueField "version" L.pkgVersion + packageIdentifierGrammar = do + pkgName <- uniqueField "name" L.pkgName + pkgVersion <- uniqueField "version" L.pkgVersion + pure PackageIdentifier{..} licenseFilesGrammar = (++) @@ -186,17 +190,18 @@ libraryFieldGrammar ) => LibraryName -> g Library Library -libraryFieldGrammar n = - Library n - <$> monoidalFieldAla "exposed-modules" formatExposedModules L.exposedModules - <*> monoidalFieldAla "reexported-modules" (alaList CommaVCat) L.reexportedModules - <*> monoidalFieldAla "signatures" (alaList' VCat MQuoted) L.signatures +libraryFieldGrammar libName = do + exposedModules <- monoidalFieldAla "exposed-modules" formatExposedModules L.exposedModules + reexportedModules <- monoidalFieldAla "reexported-modules" (alaList CommaVCat) L.reexportedModules + signatures <- + monoidalFieldAla "signatures" (alaList' VCat MQuoted) L.signatures ^^^ availableSince CabalSpecV2_0 [] - <*> booleanFieldDef "exposed" L.libExposed True - <*> visibilityField - <*> blurFieldGrammar L.libBuildInfo buildInfoFieldGrammar + libExposed <- booleanFieldDef "exposed" L.libExposed True + libVisibility <- visibilityField + libBuildInfo <- blurFieldGrammar L.libBuildInfo buildInfoFieldGrammar + pure Library{..} where - visibilityField = case n of + visibilityField = case libName of -- nameless/"main" libraries are public LMainLibName -> pure LibraryVisibilityPublic -- named libraries have the field @@ -239,14 +244,14 @@ foreignLibFieldGrammar ) => UnqualComponentName -> g ForeignLib ForeignLib -foreignLibFieldGrammar n = - ForeignLib n - <$> optionalFieldDef "type" L.foreignLibType ForeignLibTypeUnknown - <*> monoidalFieldAla "options" (alaList FSep) L.foreignLibOptions - <*> blurFieldGrammar L.foreignLibBuildInfo buildInfoFieldGrammar - <*> optionalField "lib-version-info" L.foreignLibVersionInfo - <*> optionalField "lib-version-linux" L.foreignLibVersionLinux - <*> monoidalFieldAla "mod-def-file" (alaList' FSep RelativePathNT) L.foreignLibModDefFile +foreignLibFieldGrammar foreignLibName = do + foreignLibType <- optionalFieldDef "type" L.foreignLibType ForeignLibTypeUnknown + foreignLibOptions <- monoidalFieldAla "options" (alaList FSep) L.foreignLibOptions + foreignLibBuildInfo <- blurFieldGrammar L.foreignLibBuildInfo buildInfoFieldGrammar + foreignLibVersionInfo <- optionalField "lib-version-info" L.foreignLibVersionInfo + foreignLibVersionLinux <- optionalField "lib-version-linux" L.foreignLibVersionLinux + foreignLibModDefFile <- monoidalFieldAla "mod-def-file" (alaList' FSep RelativePathNT) L.foreignLibModDefFile + pure ForeignLib{..} {-# SPECIALIZE foreignLibFieldGrammar :: UnqualComponentName -> ParsecFieldGrammar' ForeignLib #-} {-# SPECIALIZE foreignLibFieldGrammar :: UnqualComponentName -> PrettyFieldGrammar' ForeignLib #-} @@ -280,13 +285,14 @@ executableFieldGrammar ) => UnqualComponentName -> g Executable Executable -executableFieldGrammar n = - Executable n - -- main-is is optional as conditional blocks don't have it - <$> optionalFieldDefAla "main-is" RelativePathNT L.modulePath (modulePath mempty) - <*> optionalFieldDef "scope" L.exeScope ExecutablePublic +executableFieldGrammar exeName = do + -- main-is is optional as conditional blocks don't have it + modulePath <- optionalFieldDefAla "main-is" RelativePathNT L.modulePath (modulePath mempty) + exeScope <- + optionalFieldDef "scope" L.exeScope ExecutablePublic ^^^ availableSince CabalSpecV2_0 ExecutablePublic - <*> blurFieldGrammar L.buildInfo buildInfoFieldGrammar + buildInfo <- blurFieldGrammar L.buildInfo buildInfoFieldGrammar + pure Executable{..} {-# SPECIALIZE executableFieldGrammar :: UnqualComponentName -> ParsecFieldGrammar' Executable #-} {-# SPECIALIZE executableFieldGrammar :: UnqualComponentName -> PrettyFieldGrammar' Executable #-} @@ -354,14 +360,15 @@ testSuiteFieldGrammar , c (MQuoted Language) ) => g TestSuiteStanza TestSuiteStanza -testSuiteFieldGrammar = - TestSuiteStanza - <$> optionalField "type" testStanzaTestType - <*> optionalFieldAla "main-is" RelativePathNT testStanzaMainIs - <*> optionalField "test-module" testStanzaTestModule - <*> blurFieldGrammar testStanzaBuildInfo buildInfoFieldGrammar - <*> monoidalFieldAla "code-generators" (alaList' CommaFSep Token) testStanzaCodeGenerators +testSuiteFieldGrammar = do + _testStanzaTestType <- optionalField "type" testStanzaTestType + _testStanzaMainIs <- optionalFieldAla "main-is" RelativePathNT testStanzaMainIs + _testStanzaTestModule <- optionalField "test-module" testStanzaTestModule + _testStanzaBuildInfo <- blurFieldGrammar testStanzaBuildInfo buildInfoFieldGrammar + _testStanzaCodeGenerators <- + monoidalFieldAla "code-generators" (alaList' CommaFSep Token) testStanzaCodeGenerators ^^^ availableSince CabalSpecV3_8 [] + pure TestSuiteStanza{..} validateTestSuite :: CabalSpecVersion -> Position -> TestSuiteStanza -> ParseResult src TestSuite validateTestSuite cabalSpecVersion pos stanza = case testSuiteType of @@ -500,12 +507,12 @@ benchmarkFieldGrammar , c (MQuoted Language) ) => g BenchmarkStanza BenchmarkStanza -benchmarkFieldGrammar = - BenchmarkStanza - <$> optionalField "type" benchmarkStanzaBenchmarkType - <*> optionalFieldAla "main-is" RelativePathNT benchmarkStanzaMainIs - <*> optionalField "benchmark-module" benchmarkStanzaBenchmarkModule - <*> blurFieldGrammar benchmarkStanzaBuildInfo buildInfoFieldGrammar +benchmarkFieldGrammar = do + _benchmarkStanzaBenchmarkType <- optionalField "type" benchmarkStanzaBenchmarkType + _benchmarkStanzaMainIs <- optionalFieldAla "main-is" RelativePathNT benchmarkStanzaMainIs + _benchmarkStanzaBenchmarkModule <- optionalField "benchmark-module" benchmarkStanzaBenchmarkModule + _benchmarkStanzaBuildInfo <- blurFieldGrammar benchmarkStanzaBuildInfo buildInfoFieldGrammar + pure BenchmarkStanza{..} validateBenchmark :: CabalSpecVersion -> Position -> BenchmarkStanza -> ParseResult src Benchmark validateBenchmark cabalSpecVersion pos stanza = case benchmarkStanzaType of @@ -604,92 +611,113 @@ buildInfoFieldGrammar , c (MQuoted Language) ) => g BuildInfo BuildInfo -buildInfoFieldGrammar = - BuildInfo - <$> booleanFieldDef "buildable" L.buildable True - <*> monoidalFieldAla "build-tools" (alaList CommaFSep) L.buildTools +buildInfoFieldGrammar = do + buildable <- booleanFieldDef "buildable" L.buildable True + buildTools <- + monoidalFieldAla "build-tools" (alaList CommaFSep) L.buildTools ^^^ deprecatedSince CabalSpecV2_0 "Please use 'build-tool-depends' field" ^^^ removedIn CabalSpecV3_0 "Please use 'build-tool-depends' field." - <*> monoidalFieldAla "build-tool-depends" (alaList CommaFSep) L.buildToolDepends - -- {- ^^^ availableSince [2,0] [] -} - -- here, we explicitly want to recognise build-tool-depends for all Cabal files - -- as otherwise cabal new-build cannot really work. - -- - -- I.e. we don't want trigger unknown field warning - <*> monoidalFieldAla "cpp-options" (alaList' NoCommaFSep Token') L.cppOptions - <*> monoidalFieldAla "asm-options" (alaList' NoCommaFSep Token') L.asmOptions + buildToolDepends <- monoidalFieldAla "build-tool-depends" (alaList CommaFSep) L.buildToolDepends + -- {- ^^^ availableSince [2,0] [] -} + -- here, we explicitly want to recognise build-tool-depends for all Cabal files + -- as otherwise cabal new-build cannot really work. + -- + -- I.e. we don't want trigger unknown field warning + cppOptions <- monoidalFieldAla "cpp-options" (alaList' NoCommaFSep Token') L.cppOptions + asmOptions <- + monoidalFieldAla "asm-options" (alaList' NoCommaFSep Token') L.asmOptions ^^^ availableSince CabalSpecV3_0 [] - <*> monoidalFieldAla "cmm-options" (alaList' NoCommaFSep Token') L.cmmOptions + cmmOptions <- + monoidalFieldAla "cmm-options" (alaList' NoCommaFSep Token') L.cmmOptions ^^^ availableSince CabalSpecV3_0 [] - <*> monoidalFieldAla "cc-options" (alaList' NoCommaFSep Token') L.ccOptions - <*> monoidalFieldAla "cxx-options" (alaList' NoCommaFSep Token') L.cxxOptions + ccOptions <- monoidalFieldAla "cc-options" (alaList' NoCommaFSep Token') L.ccOptions + cxxOptions <- + monoidalFieldAla "cxx-options" (alaList' NoCommaFSep Token') L.cxxOptions ^^^ availableSince CabalSpecV2_2 [] - <*> monoidalFieldAla "jspp-options" (alaList' NoCommaFSep Token') L.jsppOptions + jsppOptions <- + monoidalFieldAla "jspp-options" (alaList' NoCommaFSep Token') L.jsppOptions ^^^ availableSince CabalSpecV3_16 [] - <*> monoidalFieldAla "ld-options" (alaList' NoCommaFSep Token') L.ldOptions - <*> monoidalFieldAla "hsc2hs-options" (alaList' NoCommaFSep Token') L.hsc2hsOptions + ldOptions <- monoidalFieldAla "ld-options" (alaList' NoCommaFSep Token') L.ldOptions + hsc2hsOptions <- + monoidalFieldAla "hsc2hs-options" (alaList' NoCommaFSep Token') L.hsc2hsOptions ^^^ availableSince CabalSpecV3_6 [] - <*> monoidalFieldAla "pkgconfig-depends" (alaList CommaFSep) L.pkgconfigDepends - <*> monoidalFieldAla "frameworks" (alaList' FSep RelativePathNT) L.frameworks - <*> monoidalFieldAla "extra-framework-dirs" (alaList' FSep SymbolicPathNT) L.extraFrameworkDirs - <*> monoidalFieldAla "asm-sources" (alaList' VCat SymbolicPathNT) L.asmSources + pkgconfigDepends <- monoidalFieldAla "pkgconfig-depends" (alaList CommaFSep) L.pkgconfigDepends + frameworks <- monoidalFieldAla "frameworks" (alaList' FSep RelativePathNT) L.frameworks + extraFrameworkDirs <- monoidalFieldAla "extra-framework-dirs" (alaList' FSep SymbolicPathNT) L.extraFrameworkDirs + asmSources <- + monoidalFieldAla "asm-sources" (alaList' VCat SymbolicPathNT) L.asmSources ^^^ availableSince CabalSpecV3_0 [] - <*> monoidalFieldAla "cmm-sources" (alaList' VCat SymbolicPathNT) L.cmmSources + cmmSources <- + monoidalFieldAla "cmm-sources" (alaList' VCat SymbolicPathNT) L.cmmSources ^^^ availableSince CabalSpecV3_0 [] - <*> monoidalFieldAla "c-sources" (alaList' VCat SymbolicPathNT) L.cSources - <*> monoidalFieldAla "cxx-sources" (alaList' VCat SymbolicPathNT) L.cxxSources + cSources <- monoidalFieldAla "c-sources" (alaList' VCat SymbolicPathNT) L.cSources + cxxSources <- + monoidalFieldAla "cxx-sources" (alaList' VCat SymbolicPathNT) L.cxxSources ^^^ availableSince CabalSpecV2_2 [] - <*> monoidalFieldAla "js-sources" (alaList' VCat SymbolicPathNT) L.jsSources - <*> hsSourceDirsGrammar - <*> monoidalFieldAla "other-modules" formatOtherModules L.otherModules - <*> monoidalFieldAla "virtual-modules" (alaList' VCat MQuoted) L.virtualModules + jsSources <- monoidalFieldAla "js-sources" (alaList' VCat SymbolicPathNT) L.jsSources + hsSourceDirs <- hsSourceDirsGrammar + otherModules <- monoidalFieldAla "other-modules" formatOtherModules L.otherModules + virtualModules <- + monoidalFieldAla "virtual-modules" (alaList' VCat MQuoted) L.virtualModules ^^^ availableSince CabalSpecV2_2 [] - <*> monoidalFieldAla "autogen-modules" (alaList' VCat MQuoted) L.autogenModules + autogenModules <- + monoidalFieldAla "autogen-modules" (alaList' VCat MQuoted) L.autogenModules ^^^ availableSince CabalSpecV2_0 [] - <*> optionalFieldAla "default-language" MQuoted L.defaultLanguage + defaultLanguage <- + optionalFieldAla "default-language" MQuoted L.defaultLanguage ^^^ availableSince CabalSpecV1_10 Nothing - <*> monoidalFieldAla "other-languages" (alaList' FSep MQuoted) L.otherLanguages + otherLanguages <- + monoidalFieldAla "other-languages" (alaList' FSep MQuoted) L.otherLanguages ^^^ availableSince CabalSpecV1_10 [] - <*> monoidalFieldAla "default-extensions" (alaList' FSep MQuoted) L.defaultExtensions + defaultExtensions <- + monoidalFieldAla "default-extensions" (alaList' FSep MQuoted) L.defaultExtensions ^^^ availableSince CabalSpecV1_10 [] - <*> monoidalFieldAla "other-extensions" formatOtherExtensions L.otherExtensions + otherExtensions <- + monoidalFieldAla "other-extensions" formatOtherExtensions L.otherExtensions ^^^ availableSinceWarn CabalSpecV1_10 - <*> monoidalFieldAla "extensions" (alaList' FSep MQuoted) L.oldExtensions + oldExtensions <- + monoidalFieldAla "extensions" (alaList' FSep MQuoted) L.oldExtensions ^^^ deprecatedSince CabalSpecV1_12 "Please use 'default-extensions' or 'other-extensions' fields." ^^^ removedIn CabalSpecV3_0 "Please use 'default-extensions' or 'other-extensions' fields." - <*> monoidalFieldAla "extra-libraries" (alaList' VCat Token) L.extraLibs - <*> monoidalFieldAla "extra-libraries-static" (alaList' VCat Token) L.extraLibsStatic + extraLibs <- monoidalFieldAla "extra-libraries" (alaList' VCat Token) L.extraLibs + extraLibsStatic <- + monoidalFieldAla "extra-libraries-static" (alaList' VCat Token) L.extraLibsStatic ^^^ availableSince CabalSpecV3_8 [] - <*> monoidalFieldAla "extra-ghci-libraries" (alaList' VCat Token) L.extraGHCiLibs - <*> monoidalFieldAla "extra-bundled-libraries" (alaList' VCat Token) L.extraBundledLibs - <*> monoidalFieldAla "extra-library-flavours" (alaList' VCat Token) L.extraLibFlavours - <*> monoidalFieldAla "extra-dynamic-library-flavours" (alaList' VCat Token) L.extraDynLibFlavours + extraGHCiLibs <- monoidalFieldAla "extra-ghci-libraries" (alaList' VCat Token) L.extraGHCiLibs + extraBundledLibs <- monoidalFieldAla "extra-bundled-libraries" (alaList' VCat Token) L.extraBundledLibs + extraLibFlavours <- monoidalFieldAla "extra-library-flavours" (alaList' VCat Token) L.extraLibFlavours + extraDynLibFlavours <- + monoidalFieldAla "extra-dynamic-library-flavours" (alaList' VCat Token) L.extraDynLibFlavours ^^^ availableSince CabalSpecV3_0 [] - <*> monoidalFieldAla "extra-lib-dirs" (alaList' FSep SymbolicPathNT) L.extraLibDirs - <*> monoidalFieldAla "extra-lib-dirs-static" (alaList' FSep SymbolicPathNT) L.extraLibDirsStatic + extraLibDirs <- monoidalFieldAla "extra-lib-dirs" (alaList' FSep SymbolicPathNT) L.extraLibDirs + extraLibDirsStatic <- + monoidalFieldAla "extra-lib-dirs-static" (alaList' FSep SymbolicPathNT) L.extraLibDirsStatic ^^^ availableSince CabalSpecV3_8 [] - <*> monoidalFieldAla "include-dirs" (alaList' FSep SymbolicPathNT) L.includeDirs - <*> monoidalFieldAla "includes" (alaList' FSep SymbolicPathNT) L.includes - <*> monoidalFieldAla "autogen-includes" (alaList' FSep RelativePathNT) L.autogenIncludes + includeDirs <- monoidalFieldAla "include-dirs" (alaList' FSep SymbolicPathNT) L.includeDirs + includes <- monoidalFieldAla "includes" (alaList' FSep SymbolicPathNT) L.includes + autogenIncludes <- + monoidalFieldAla "autogen-includes" (alaList' FSep RelativePathNT) L.autogenIncludes ^^^ availableSince CabalSpecV3_0 [] - <*> monoidalFieldAla "install-includes" (alaList' FSep RelativePathNT) L.installIncludes - <*> optionsFieldGrammar - <*> profOptionsFieldGrammar - <*> sharedOptionsFieldGrammar - <*> profSharedOptionsFieldGrammar - <*> pure mempty -- static-options ??? - <*> prefixedFields "x-" L.customFieldsBI - <*> monoidalFieldAla "build-depends" formatDependencyList L.targetBuildDepends - <*> monoidalFieldAla "mixins" formatMixinList L.mixins + installIncludes <- monoidalFieldAla "install-includes" (alaList' FSep RelativePathNT) L.installIncludes + options <- optionsFieldGrammar + profOptions <- profOptionsFieldGrammar + sharedOptions <- sharedOptionsFieldGrammar + profSharedOptions <- profSharedOptionsFieldGrammar + let staticOptions = mempty + customFieldsBI <- prefixedFields "x-" L.customFieldsBI + targetBuildDepends <- monoidalFieldAla "build-depends" formatDependencyList L.targetBuildDepends + mixins <- + monoidalFieldAla "mixins" formatMixinList L.mixins ^^^ availableSince CabalSpecV2_0 [] + pure BuildInfo{..} {-# SPECIALIZE buildInfoFieldGrammar :: ParsecFieldGrammar' BuildInfo #-} {-# SPECIALIZE buildInfoFieldGrammar :: PrettyFieldGrammar' BuildInfo #-} @@ -778,11 +806,11 @@ flagFieldGrammar :: FieldGrammar c g => FlagName -> g PackageFlag PackageFlag -flagFieldGrammar name = - MkPackageFlag name - <$> freeTextFieldDef "description" L.flagDescription - <*> booleanFieldDef "default" L.flagDefault True - <*> booleanFieldDef "manual" L.flagManual False +flagFieldGrammar flagName = do + flagDescription <- freeTextFieldDef "description" L.flagDescription + flagDefault <- booleanFieldDef "default" L.flagDefault True + flagManual <- booleanFieldDef "manual" L.flagManual False + pure MkPackageFlag{..} {-# SPECIALIZE flagFieldGrammar :: FlagName -> ParsecFieldGrammar' PackageFlag #-} {-# SPECIALIZE flagFieldGrammar :: FlagName -> PrettyFieldGrammar' PackageFlag #-} @@ -794,14 +822,14 @@ sourceRepoFieldGrammar :: (FieldGrammar c g, c (Identity RepoType)) => RepoKind -> g SourceRepo SourceRepo -sourceRepoFieldGrammar kind = - SourceRepo kind - <$> optionalField "type" L.repoType - <*> freeTextField "location" L.repoLocation - <*> optionalFieldAla "module" Token L.repoModule - <*> optionalFieldAla "branch" Token L.repoBranch - <*> optionalFieldAla "tag" Token L.repoTag - <*> optionalFieldAla "subdir" FilePathNT L.repoSubdir +sourceRepoFieldGrammar repoKind = do + repoType <- optionalField "type" L.repoType + repoLocation <- freeTextField "location" L.repoLocation + repoModule <- optionalFieldAla "module" Token L.repoModule + repoBranch <- optionalFieldAla "branch" Token L.repoBranch + repoTag <- optionalFieldAla "tag" Token L.repoTag + repoSubdir <- optionalFieldAla "subdir" FilePathNT L.repoSubdir + pure SourceRepo{..} {-# SPECIALIZE sourceRepoFieldGrammar :: RepoKind -> ParsecFieldGrammar' SourceRepo #-} {-# SPECIALIZE sourceRepoFieldGrammar :: RepoKind -> PrettyFieldGrammar' SourceRepo #-} diff --git a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs index 4037024a3f5..ebb4672607d 100644 --- a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs +++ b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} @@ -303,27 +304,26 @@ basicFieldGrammar , c (MQuoted Version) ) => g Basic Basic -basicFieldGrammar = - mkBasic - <$> optionalFieldDefAla "name" MQuoted basicName (mungedPackageName emptyInstalledPackageInfo) - <*> optionalFieldDefAla "version" MQuoted basicVersion nullVersion - <*> optionalField "package-name" basicPkgName - <*> optionalField "lib-name" basicLibName - <*> optionalFieldDef "visibility" basicLibVisibility LibraryVisibilityPrivate - where - mkBasic n v pn ln lv = Basic n v pn ln' lv' - where - ln' = maybe LMainLibName LSubLibName ln - -- Older GHCs (<8.8) always report installed libraries as private +basicFieldGrammar = do + _basicName <- optionalFieldDefAla "name" MQuoted basicName (mungedPackageName emptyInstalledPackageInfo) + _basicVersion <- optionalFieldDefAla "version" MQuoted basicVersion nullVersion + _basicPkgName <- optionalField "package-name" basicPkgName + _basicLibName <- maybe LMainLibName LSubLibName <$> optionalField "lib-name" basicLibName + _basicLibVisibility' <- optionalFieldDef "visibility" basicLibVisibility LibraryVisibilityPrivate + pure + Basic + { -- Older GHCs (<8.8) always report installed libraries as private -- because their ghc-pkg builds with an older Cabal. -- So we always set LibraryVisibilityPublic for main (unnamed) libs. -- This can be removed once we stop supporting GHC<8.8, at the -- condition that we keep marking main libraries as public when -- registering them. - lv' = - if let MungedPackageName _ mln = n - in -- We need to check both because on ghc<8.2 ln' will always + _basicLibVisibility = + if let MungedPackageName _ mln = _basicName + in -- We need to check both because on ghc<8.2 _basicLibName will always -- be LMainLibName - ln' == LMainLibName && mln == LMainLibName + _basicLibName == LMainLibName && mln == LMainLibName then LibraryVisibilityPublic - else lv + else _basicLibVisibility' + , .. + } diff --git a/Cabal/src/Distribution/Simple/InstallDirs.hs b/Cabal/src/Distribution/Simple/InstallDirs.hs index 0ccd1ef6e3a..8fb68b24270 100644 --- a/Cabal/src/Distribution/Simple/InstallDirs.hs +++ b/Cabal/src/Distribution/Simple/InstallDirs.hs @@ -1,7 +1,9 @@ +{-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE CApiFFI #-} {-# LANGUAGE CPP #-} {-# LANGUAGE DerivingVia #-} {-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RecordWildCards #-} -- | -- Module : Distribution.Simple.InstallDirs @@ -559,25 +561,25 @@ foreign import capi unsafe "shlobj.h SHGetFolderPathW" -- FieldGrammar installDirsGrammar :: ParsecFieldGrammar' (InstallDirs (Flag PathTemplate)) -installDirsGrammar = - InstallDirs - <$> optionalFieldDef "prefix" installDirsPrefixLens mempty - <*> optionalFieldDef "bindir" installDirsBindirLens mempty - <*> optionalFieldDef "libdir" installDirsLibdirLens mempty - <*> optionalFieldDef "libsubdir" installDirsLibsubdirLens mempty - <*> optionalFieldDef "dynlibdir" installDirsDynlibdirLens mempty - <*> optionalFieldDef "bytecodelibdir" installDirsBytecodelibdirLens mempty - <*> pure NoFlag -- flibdir - <*> optionalFieldDef "libexecdir" installDirsLibexecdirLens mempty - <*> optionalFieldDef "libexecsubdir" installDirsLibexecsubdirLens mempty - <*> pure NoFlag -- includedir - <*> optionalFieldDef "datadir" installDirsDatadirLens mempty - <*> optionalFieldDef "datasubdir" installDirsDatasubdirLens mempty - <*> optionalFieldDef "docdir" installDirsDocdirLens mempty - <*> pure NoFlag -- mandir - <*> optionalFieldDef "htmldir" installDirsHtmldirLens mempty - <*> optionalFieldDef "haddockdir" installDirsHaddockdirLens mempty - <*> optionalFieldDef "sysconfdir" installDirsSysconfdirLens mempty +installDirsGrammar = do + prefix <- optionalFieldDef "prefix" installDirsPrefixLens mempty + bindir <- optionalFieldDef "bindir" installDirsBindirLens mempty + libdir <- optionalFieldDef "libdir" installDirsLibdirLens mempty + libsubdir <- optionalFieldDef "libsubdir" installDirsLibsubdirLens mempty + dynlibdir <- optionalFieldDef "dynlibdir" installDirsDynlibdirLens mempty + bytecodelibdir <- optionalFieldDef "bytecodelibdir" installDirsBytecodelibdirLens mempty + let flibdir = NoFlag + libexecdir <- optionalFieldDef "libexecdir" installDirsLibexecdirLens mempty + libexecsubdir <- optionalFieldDef "libexecsubdir" installDirsLibexecsubdirLens mempty + let includedir = NoFlag + datadir <- optionalFieldDef "datadir" installDirsDatadirLens mempty + datasubdir <- optionalFieldDef "datasubdir" installDirsDatasubdirLens mempty + docdir <- optionalFieldDef "docdir" installDirsDocdirLens mempty + let mandir = NoFlag + htmldir <- optionalFieldDef "htmldir" installDirsHtmldirLens mempty + haddockdir <- optionalFieldDef "haddockdir" installDirsHaddockdirLens mempty + sysconfdir <- optionalFieldDef "sysconfdir" installDirsSysconfdirLens mempty + pure InstallDirs{..} -- --------------------------------------------------------------------------- -- Lenses diff --git a/cabal-dev-scripts/src/GenSPDX.hs b/cabal-dev-scripts/src/GenSPDX.hs index a8466b31f6e..e72dc508562 100644 --- a/cabal-dev-scripts/src/GenSPDX.hs +++ b/cabal-dev-scripts/src/GenSPDX.hs @@ -1,4 +1,6 @@ +{-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RecordWildCards #-} module Main (main) where import Control.Lens (imap) @@ -119,12 +121,13 @@ newtype LicenseList = LL { unLL :: [License] } deriving (Show) instance FromJSON License where - parseJSON = withObject "License" $ \obj -> License - <$> obj .: "licenseId" - <*> obj .: "name" - <*> obj .: "isOsiApproved" - <*> obj .:? "isFsfLibre" .!= False - <*> obj .: "isDeprecatedLicenseId" + parseJSON = withObject "License" $ \obj -> do + licenseId <- obj .: "licenseId" + licenseName <- obj .: "name" + licenseOsiApproved <- obj .: "isOsiApproved" + licenseFsfLibre <- obj .:? "isFsfLibre" .!= False + licenseDeprecated <- obj .: "isDeprecatedLicenseId" + pure License{..} instance FromJSON LicenseList where parseJSON = withObject "License list" $ \obj -> diff --git a/cabal-install/src/Distribution/Client/BuildReports/Anonymous.hs b/cabal-install/src/Distribution/Client/BuildReports/Anonymous.hs index 59dfdda0211..9291790c28e 100644 --- a/cabal-install/src/Distribution/Client/BuildReports/Anonymous.hs +++ b/cabal-install/src/Distribution/Client/BuildReports/Anonymous.hs @@ -1,4 +1,6 @@ +{-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RecordWildCards #-} -- | -- Module : Distribution.Client.Reporting @@ -117,18 +119,18 @@ fieldDescrs , c (List VCat (Identity PackageIdentifier) PackageIdentifier) ) => g BuildReport BuildReport -fieldDescrs = - BuildReport - <$> uniqueField "package" L.package - <*> uniqueField "os" L.os - <*> uniqueField "arch" L.arch - <*> uniqueField "compiler" L.compiler - <*> uniqueField "client" L.client - <*> monoidalField "flags" L.flagAssignment - <*> monoidalFieldAla "dependencies" (alaList VCat) L.dependencies - <*> uniqueField "install-outcome" L.installOutcome - <*> uniqueField "docs-outcome" L.docsOutcome - <*> uniqueField "tests-outcome" L.testsOutcome +fieldDescrs = do + package <- uniqueField "package" L.package + os <- uniqueField "os" L.os + arch <- uniqueField "arch" L.arch + compiler <- uniqueField "compiler" L.compiler + client <- uniqueField "client" L.client + flagAssignment <- monoidalField "flags" L.flagAssignment + dependencies <- monoidalFieldAla "dependencies" (alaList VCat) L.dependencies + installOutcome <- uniqueField "install-outcome" L.installOutcome + docsOutcome <- uniqueField "docs-outcome" L.docsOutcome + testsOutcome <- uniqueField "tests-outcome" L.testsOutcome + pure BuildReport{..} -- ----------------------------------------------------------------------------- -- Parsing diff --git a/cabal-install/src/Distribution/Client/CmdInstall/ClientInstallFlags.hs b/cabal-install/src/Distribution/Client/CmdInstall/ClientInstallFlags.hs index c90d6a5cf13..2bd77736733 100644 --- a/cabal-install/src/Distribution/Client/CmdInstall/ClientInstallFlags.hs +++ b/cabal-install/src/Distribution/Client/CmdInstall/ClientInstallFlags.hs @@ -1,6 +1,8 @@ +{-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE DerivingVia #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE RecordWildCards #-} module Distribution.Client.CmdInstall.ClientInstallFlags ( InstallMethod (..) @@ -122,15 +124,15 @@ clientInstallFlagsGrammar , c (Identity (Flag InstallMethod)) ) => g ClientInstallFlags ClientInstallFlags -clientInstallFlagsGrammar = - ClientInstallFlags - <$> optionalFieldDef "lib" cinstInstallLibsLens mempty - <*> ( optionalFieldDefAla "package-env" (alaFlag FilePathNT) cinstEnvironmentPathLens mempty - <* optionalFieldDefAla "env" (alaFlag FilePathNT) cinstEnvironmentPathLens mempty - ) - <*> optionalFieldDef "overwrite-policy" cinstOverwritePolicyLens mempty - <*> optionalFieldDef "install-method" cinstInstallMethodLens mempty - <*> optionalFieldDefAla "installdir" (alaFlag FilePathNT) cinstInstalldirLens mempty +clientInstallFlagsGrammar = do + cinstInstallLibs <- optionalFieldDef "lib" cinstInstallLibsLens mempty + cinstEnvironmentPath <- + optionalFieldDefAla "package-env" (alaFlag FilePathNT) cinstEnvironmentPathLens mempty + <* optionalFieldDefAla "env" (alaFlag FilePathNT) cinstEnvironmentPathLens mempty + cinstOverwritePolicy <- optionalFieldDef "overwrite-policy" cinstOverwritePolicyLens mempty + cinstInstallMethod <- optionalFieldDef "install-method" cinstInstallMethodLens mempty + cinstInstalldir <- optionalFieldDefAla "installdir" (alaFlag FilePathNT) cinstInstalldirLens mempty + pure ClientInstallFlags{..} {-# SPECIALIZE clientInstallFlagsGrammar :: ParsecFieldGrammar' ClientInstallFlags #-} parsecInstallMethod :: CabalParsing m => m InstallMethod diff --git a/cabal-install/src/Distribution/Client/DistDirLayout.hs b/cabal-install/src/Distribution/Client/DistDirLayout.hs index 0e8fd2026a5..ca32684dd98 100644 --- a/cabal-install/src/Distribution/Client/DistDirLayout.hs +++ b/cabal-install/src/Distribution/Client/DistDirLayout.hs @@ -336,4 +336,4 @@ mkCabalDirLayout mstoreDir mlogDir = do defaultStoreDirLayout <$> maybe defaultStoreDir pure mstoreDir cabalLogsDirectory <- maybe defaultLogsDir pure mlogDir - pure $ CabalDirLayout{..} + pure CabalDirLayout{..} diff --git a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs index 2645f1129fe..6b9f93273c4 100644 --- a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs @@ -1,9 +1,7 @@ +{-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE PatternSynonyms #-} - ------------------------------------------------------------------------------ - ------------------------------------------------------------------------------ +{-# LANGUAGE RecordWildCards #-} -- | -- Module : Distribution.Client.Init.Command @@ -192,19 +190,19 @@ genPkgDescription -> SourcePackageDb -> m PkgDescription genPkgDescription flags' srcDb = do - csv <- cabalVersionPrompt flags' - let flags = flags'{cabalVersion = Flag csv} - PkgDescription csv - <$> packageNamePrompt srcDb flags - <*> versionPrompt flags - <*> licensePrompt flags - <*> authorPrompt flags - <*> emailPrompt flags - <*> homepagePrompt flags - <*> synopsisPrompt flags - <*> categoryPrompt flags - <*> getExtraSrcFiles flags - <*> getExtraDocFiles flags + _pkgCabalVersion <- cabalVersionPrompt flags' + let flags = flags'{cabalVersion = Flag _pkgCabalVersion} + _pkgName <- packageNamePrompt srcDb flags + _pkgVersion <- versionPrompt flags + _pkgLicense <- licensePrompt flags + _pkgAuthor <- authorPrompt flags + _pkgEmail <- emailPrompt flags + _pkgHomePage <- homepagePrompt flags + _pkgSynopsis <- synopsisPrompt flags + _pkgCategory <- categoryPrompt flags + _pkgExtraSrcFiles <- getExtraSrcFiles flags + _pkgExtraDocFiles <- getExtraDocFiles flags + pure PkgDescription{..} -- | Extract flags relevant to a library target and interactively -- generate a 'LibTarget' object for creation. If the user specifies @@ -215,15 +213,15 @@ genLibTarget => InitFlags -> InstalledPackageIndex -> m LibTarget -genLibTarget flags pkgs = - LibTarget - <$> srcDirsPrompt flags - <*> languagePrompt flags "library" - <*> getExposedModules flags - <*> getOtherModules flags - <*> getOtherExts flags - <*> dependenciesPrompt pkgs flags - <*> getBuildTools flags +genLibTarget flags pkgs = do + _libSourceDirs <- srcDirsPrompt flags + _libLanguage <- languagePrompt flags "library" + _libExposedModules <- getExposedModules flags + _libOtherModules <- getOtherModules flags + _libOtherExts <- getOtherExts flags + _libDependencies <- dependenciesPrompt pkgs flags + _libBuildTools <- getBuildTools flags + pure LibTarget{..} -- | Extract flags relevant to a executable target and interactively -- generate a 'ExeTarget' object for creation. If the user specifies @@ -234,15 +232,15 @@ genExeTarget => InitFlags -> InstalledPackageIndex -> m ExeTarget -genExeTarget flags pkgs = - ExeTarget - <$> mainFilePrompt flags - <*> appDirsPrompt flags - <*> languagePrompt flags "executable" - <*> getOtherModules flags - <*> getOtherExts flags - <*> dependenciesPrompt pkgs flags - <*> getBuildTools flags +genExeTarget flags pkgs = do + _exeMainIs <- mainFilePrompt flags + _exeApplicationDirs <- appDirsPrompt flags + _exeLanguage <- languagePrompt flags "executable" + _exeOtherModules <- getOtherModules flags + _exeOtherExts <- getOtherExts flags + _exeDependencies <- dependenciesPrompt pkgs flags + _exeBuildTools <- getBuildTools flags + pure ExeTarget{..} -- | Extract flags relevant to a test target and interactively -- generate a 'TestTarget' object for creation. If the user specifies @@ -261,16 +259,15 @@ genTestTarget flags pkgs = initializeTestSuitePrompt flags >>= go where go initialized | not initialized = return Nothing - | otherwise = - fmap Just $ - TestTarget - <$> testMainPrompt - <*> testDirsPrompt flags - <*> languagePrompt flags "test suite" - <*> getOtherModules flags - <*> getOtherExts flags - <*> dependenciesPrompt pkgs flags - <*> getBuildTools flags + | otherwise = do + _testMainIs <- testMainPrompt + _testDirs <- testDirsPrompt flags + _testLanguage <- languagePrompt flags "test suite" + _testOtherModules <- getOtherModules flags + _testOtherExts <- getOtherExts flags + _testDependencies <- dependenciesPrompt pkgs flags + _testBuildTools <- getBuildTools flags + pure $ Just TestTarget{..} -- -------------------------------------------------------------------- -- -- Prompts diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs index 8c0027b1a38..e25d5293149 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs @@ -1,4 +1,5 @@ {-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE RecordWildCards #-} module Distribution.Client.Init.NonInteractive.Command ( genPkgDescription @@ -171,19 +172,19 @@ genPkgDescription => InitFlags -> SourcePackageDb -> m PkgDescription -genPkgDescription flags srcDb = - PkgDescription - <$> cabalVersionHeuristics flags - <*> packageNameHeuristics srcDb flags - <*> versionHeuristics flags - <*> licenseHeuristics flags - <*> authorHeuristics flags - <*> emailHeuristics flags - <*> homepageHeuristics flags - <*> synopsisHeuristics flags - <*> categoryHeuristics flags - <*> getExtraSrcFiles flags - <*> extraDocFileHeuristics flags +genPkgDescription flags srcDb = do + _pkgCabalVersion <- cabalVersionHeuristics flags + _pkgName <- packageNameHeuristics srcDb flags + _pkgVersion <- versionHeuristics flags + _pkgLicense <- licenseHeuristics flags + _pkgAuthor <- authorHeuristics flags + _pkgEmail <- emailHeuristics flags + _pkgHomePage <- homepageHeuristics flags + _pkgSynopsis <- synopsisHeuristics flags + _pkgCategory <- categoryHeuristics flags + _pkgExtraSrcFiles <- getExtraSrcFiles flags + _pkgExtraDocFiles <- extraDocFileHeuristics flags + pure PkgDescription{..} genLibTarget :: Interactive m @@ -192,15 +193,15 @@ genLibTarget -> CabalSpecVersion -> m LibTarget genLibTarget flags pkgs v = do - srcDirs <- srcDirsHeuristics flags - let srcDir = fromMaybe defaultSourceDir $ safeHead srcDirs - LibTarget srcDirs - <$> languageHeuristics flags - <*> exposedModulesHeuristics flags - <*> libOtherModulesHeuristics flags - <*> otherExtsHeuristics flags srcDir - <*> dependenciesHeuristics flags srcDir pkgs - <*> buildToolsHeuristics flags srcDir v + _libSourceDirs <- srcDirsHeuristics flags + let srcDir = fromMaybe defaultSourceDir $ safeHead _libSourceDirs + _libLanguage <- languageHeuristics flags + _libExposedModules <- exposedModulesHeuristics flags + _libOtherModules <- libOtherModulesHeuristics flags + _libOtherExts <- otherExtsHeuristics flags srcDir + _libDependencies <- dependenciesHeuristics flags srcDir pkgs + _libBuildTools <- buildToolsHeuristics flags srcDir v + pure LibTarget{..} genExeTarget :: Interactive m @@ -209,16 +210,15 @@ genExeTarget -> CabalSpecVersion -> m ExeTarget genExeTarget flags pkgs v = do - appDirs <- appDirsHeuristics flags - let appDir = fromMaybe defaultApplicationDir $ safeHead appDirs - ExeTarget - <$> mainFileHeuristics flags - <*> pure appDirs - <*> languageHeuristics flags - <*> exeOtherModulesHeuristics flags - <*> otherExtsHeuristics flags appDir - <*> dependenciesHeuristics flags appDir pkgs - <*> buildToolsHeuristics flags appDir v + _exeApplicationDirs <- appDirsHeuristics flags + let appDir = fromMaybe defaultApplicationDir $ safeHead _exeApplicationDirs + _exeMainIs <- mainFileHeuristics flags + _exeLanguage <- languageHeuristics flags + _exeOtherModules <- exeOtherModulesHeuristics flags + _exeOtherExts <- otherExtsHeuristics flags appDir + _exeDependencies <- dependenciesHeuristics flags appDir pkgs + _exeBuildTools <- buildToolsHeuristics flags appDir v + pure ExeTarget{..} genTestTarget :: Interactive m @@ -228,20 +228,18 @@ genTestTarget -> m (Maybe TestTarget) genTestTarget flags pkgs v = do initialized <- initializeTestSuiteHeuristics flags - testDirs' <- testDirsHeuristics flags - let testDir = fromMaybe defaultTestDir $ safeHead testDirs' + _testDirs <- testDirsHeuristics flags + let testDir = fromMaybe defaultTestDir $ safeHead _testDirs if not initialized then return Nothing - else - fmap Just $ - TestTarget - <$> testMainHeuristics flags - <*> pure testDirs' - <*> languageHeuristics flags - <*> testOtherModulesHeuristics flags - <*> otherExtsHeuristics flags testDir - <*> dependenciesHeuristics flags testDir pkgs - <*> buildToolsHeuristics flags testDir v + else do + _testMainIs <- testMainHeuristics flags + _testLanguage <- languageHeuristics flags + _testOtherModules <- testOtherModulesHeuristics flags + _testOtherExts <- otherExtsHeuristics flags testDir + _testDependencies <- dependenciesHeuristics flags testDir pkgs + _testBuildTools <- buildToolsHeuristics flags testDir v + pure $ Just TestTarget{..} -- -------------------------------------------------------------------- -- -- Get flags from init config diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/FieldGrammar.hs b/cabal-install/src/Distribution/Client/ProjectConfig/FieldGrammar.hs index f5672a3ccf8..b8c858682aa 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/FieldGrammar.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/FieldGrammar.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} @@ -23,242 +24,173 @@ import Distribution.Solver.Types.ProjectConfigPath import Distribution.Types.PackageVersionConstraint (PackageVersionConstraint (..)) projectConfigFieldGrammar :: ProjectConfigPath -> [String] -> ParsecFieldGrammar' ProjectConfig -projectConfigFieldGrammar source knownPrograms = - ProjectConfig - <$> monoidalFieldAla "packages" (alaList' FSep Token) L.projectPackages - <*> monoidalFieldAla "optional-packages" (alaList' FSep Token) L.projectPackagesOptional - <*> pure mempty -- source-repository-package stanza - <*> monoidalFieldAla "extra-packages" formatPackageVersionConstraints L.projectPackagesNamed - <*> blurFieldGrammar L.projectConfigBuildOnly projectConfigBuildOnlyFieldGrammar - <*> blurFieldGrammar L.projectConfigShared (projectConfigSharedFieldGrammar source) - <*> pure provenance - <*> pure mempty - -- \^ PackageConfig to be applied to all packages, specified inside 'package *' stanza - <*> blurFieldGrammar L.projectConfigLocalPackages (packageConfigFieldGrammar knownPrograms) - -- \^ PackageConfig to be applied to locally built packages, specified not inside a stanza - <*> pure mempty - where - -- \^ PackageConfig applied to explicitly named packages - provenance = Set.singleton (Explicit source) +projectConfigFieldGrammar source knownPrograms = do + projectPackages <- monoidalFieldAla "packages" (alaList' FSep Token) L.projectPackages + projectPackagesOptional <- monoidalFieldAla "optional-packages" (alaList' FSep Token) L.projectPackagesOptional + let projectPackagesRepo = mempty + projectPackagesNamed <- monoidalFieldAla "extra-packages" formatPackageVersionConstraints L.projectPackagesNamed + projectConfigBuildOnly <- blurFieldGrammar L.projectConfigBuildOnly projectConfigBuildOnlyFieldGrammar + projectConfigShared <- blurFieldGrammar L.projectConfigShared (projectConfigSharedFieldGrammar source) + let projectConfigProvenance = Set.singleton (Explicit source) + projectConfigAllPackages = mempty + projectConfigSpecificPackage = mempty + projectConfigLocalPackages <- blurFieldGrammar L.projectConfigLocalPackages (packageConfigFieldGrammar knownPrograms) + pure ProjectConfig{..} formatPackageVersionConstraints :: [PackageVersionConstraint] -> List CommaVCat (Identity PackageVersionConstraint) PackageVersionConstraint formatPackageVersionConstraints = alaList CommaVCat projectConfigBuildOnlyFieldGrammar :: ParsecFieldGrammar' ProjectConfigBuildOnly -projectConfigBuildOnlyFieldGrammar = - ProjectConfigBuildOnly - <$> optionalFieldDef "verbose" L.projectConfigVerbosity mempty - <*> pure mempty -- cli flag: projectConfigDryRun - <*> pure mempty -- cli flag: projectConfigOnlyDeps - <*> pure mempty -- cli flag: projectConfigOnlyDownload - <*> monoidalFieldAla "build-summary" (alaNubList VCat) L.projectConfigSummaryFile - <*> optionalFieldDef "build-log" L.projectConfigLogFile mempty - <*> optionalFieldDef "remote-build-reporting" L.projectConfigBuildReports mempty - <*> optionalFieldDef "report-planning-failure" L.projectConfigReportPlanningFailure mempty - <*> optionalFieldDefAla "symlink-bindir" (alaFlag FilePathNT) L.projectConfigSymlinkBinDir mempty - <*> optionalFieldDefAla "jobs" (alaFlag NumJobs) L.projectConfigNumJobs mempty - <*> optionalFieldDef "semaphore" L.projectConfigUseSemaphore mempty - <*> optionalFieldDef "keep-going" L.projectConfigKeepGoing mempty - <*> optionalFieldDef "offline" L.projectConfigOfflineMode mempty - <*> optionalFieldDef "haddock-keep-temp-files" L.projectConfigKeepTempFiles mempty - <*> optionalFieldDefAla "http-transport" (alaFlag Token) L.projectConfigHttpTransport mempty - <*> optionalFieldDef "ignore-expiry" L.projectConfigIgnoreExpiry mempty - <*> optionalFieldDefAla "remote-repo-cache" (alaFlag FilePathNT) L.projectConfigCacheDir mempty - <*> optionalFieldDefAla "logs-dir" (alaFlag FilePathNT) L.projectConfigLogsDir mempty - <*> blurFieldGrammar L.projectConfigClientInstallFlags clientInstallFlagsGrammar - <*> optionalFieldDef "build-timings" L.projectConfigBuildTimings mempty +projectConfigBuildOnlyFieldGrammar = do + projectConfigVerbosity <- optionalFieldDef "verbose" L.projectConfigVerbosity mempty + let projectConfigDryRun = mempty + projectConfigOnlyDeps = mempty + projectConfigOnlyDownload = mempty + projectConfigSummaryFile <- monoidalFieldAla "build-summary" (alaNubList VCat) L.projectConfigSummaryFile + projectConfigLogFile <- optionalFieldDef "build-log" L.projectConfigLogFile mempty + projectConfigBuildReports <- optionalFieldDef "remote-build-reporting" L.projectConfigBuildReports mempty + projectConfigReportPlanningFailure <- optionalFieldDef "report-planning-failure" L.projectConfigReportPlanningFailure mempty + projectConfigSymlinkBinDir <- optionalFieldDefAla "symlink-bindir" (alaFlag FilePathNT) L.projectConfigSymlinkBinDir mempty + projectConfigNumJobs <- optionalFieldDefAla "jobs" (alaFlag NumJobs) L.projectConfigNumJobs mempty + projectConfigUseSemaphore <- optionalFieldDef "semaphore" L.projectConfigUseSemaphore mempty + projectConfigKeepGoing <- optionalFieldDef "keep-going" L.projectConfigKeepGoing mempty + projectConfigOfflineMode <- optionalFieldDef "offline" L.projectConfigOfflineMode mempty + projectConfigKeepTempFiles <- optionalFieldDef "haddock-keep-temp-files" L.projectConfigKeepTempFiles mempty + projectConfigHttpTransport <- optionalFieldDefAla "http-transport" (alaFlag Token) L.projectConfigHttpTransport mempty + projectConfigIgnoreExpiry <- optionalFieldDef "ignore-expiry" L.projectConfigIgnoreExpiry mempty + projectConfigCacheDir <- optionalFieldDefAla "remote-repo-cache" (alaFlag FilePathNT) L.projectConfigCacheDir mempty + projectConfigLogsDir <- optionalFieldDefAla "logs-dir" (alaFlag FilePathNT) L.projectConfigLogsDir mempty + projectConfigClientInstallFlags <- blurFieldGrammar L.projectConfigClientInstallFlags clientInstallFlagsGrammar + projectConfigBuildTimings <- optionalFieldDef "build-timings" L.projectConfigBuildTimings mempty + pure ProjectConfigBuildOnly{..} projectConfigSharedFieldGrammar :: ProjectConfigPath -> ParsecFieldGrammar' ProjectConfigShared -projectConfigSharedFieldGrammar source = - ProjectConfigShared - <$> optionalFieldDefAla "builddir" (alaFlag FilePathNT) L.projectConfigDistDir mempty - <*> pure mempty -- cli flag: projectConfigConfigFile - <*> optionalFieldDefAla "project-dir" (alaFlag FilePathNT) L.projectConfigProjectDir mempty - <*> optionalFieldDefAla "project-file" (alaFlag FilePathNT) L.projectConfigProjectFile mempty - <*> pure mempty -- You can't set the parser type in the project file. - <*> optionalFieldDef "ignore-project" L.projectConfigIgnoreProject mempty - <*> optionalFieldDef "compiler" L.projectConfigHcFlavor mempty - <*> optionalFieldDefAla "with-compiler" (alaFlag FilePathNT) L.projectConfigHcPath mempty - <*> optionalFieldDefAla "with-hc-pkg" (alaFlag FilePathNT) L.projectConfigHcPkg mempty - <*> optionalFieldDef "doc-index-file" L.projectConfigHaddockIndex mempty - <*> blurFieldGrammar L.projectConfigInstallDirs installDirsGrammar - <*> monoidalFieldAla "package-dbs" (alaList' CommaFSep PackageDBNT) L.projectConfigPackageDBs - <*> pure mempty -- repository stanza for projectConfigRemoteRepos - <*> pure mempty -- repository stanza for projectConfigLocalNoIndexRepos - <*> monoidalField "active-repositories" L.projectConfigActiveRepos - <*> monoidalField "index-state" L.projectConfigIndexState - <*> optionalFieldDefAla "store-dir" (alaFlag FilePathNT) L.projectConfigStoreDir mempty - <*> monoidalFieldAla "constraints" (alaList' FSep ProjectConstraints) L.projectConfigConstraints +projectConfigSharedFieldGrammar source = do + projectConfigDistDir <- optionalFieldDefAla "builddir" (alaFlag FilePathNT) L.projectConfigDistDir mempty + let projectConfigConfigFile = mempty + projectConfigProjectDir <- optionalFieldDefAla "project-dir" (alaFlag FilePathNT) L.projectConfigProjectDir mempty + projectConfigProjectFile <- optionalFieldDefAla "project-file" (alaFlag FilePathNT) L.projectConfigProjectFile mempty + let projectConfigProjectFileParser = mempty -- You can't set the parser type in the project file. + projectConfigIgnoreProject <- optionalFieldDef "ignore-project" L.projectConfigIgnoreProject mempty + projectConfigHcFlavor <- optionalFieldDef "compiler" L.projectConfigHcFlavor mempty + projectConfigHcPath <- optionalFieldDefAla "with-compiler" (alaFlag FilePathNT) L.projectConfigHcPath mempty + projectConfigHcPkg <- optionalFieldDefAla "with-hc-pkg" (alaFlag FilePathNT) L.projectConfigHcPkg mempty + projectConfigHaddockIndex <- optionalFieldDef "doc-index-file" L.projectConfigHaddockIndex mempty + projectConfigInstallDirs <- blurFieldGrammar L.projectConfigInstallDirs installDirsGrammar + projectConfigPackageDBs <- monoidalFieldAla "package-dbs" (alaList' CommaFSep PackageDBNT) L.projectConfigPackageDBs + let projectConfigRemoteRepos = mempty + projectConfigLocalNoIndexRepos = mempty + projectConfigActiveRepos <- monoidalField "active-repositories" L.projectConfigActiveRepos + projectConfigIndexState <- monoidalField "index-state" L.projectConfigIndexState + projectConfigStoreDir <- optionalFieldDefAla "store-dir" (alaFlag FilePathNT) L.projectConfigStoreDir mempty + projectConfigConstraints <- + monoidalFieldAla "constraints" (alaList' FSep ProjectConstraints) L.projectConfigConstraints ^^^ (fmap . fmap) (\(userConstraint, _) -> (userConstraint, ConstraintSourceProjectConfig source)) - <*> monoidalFieldAla "preferences" formatPackageVersionConstraints L.projectConfigPreferences - <*> optionalFieldDef "cabal-lib-version" L.projectConfigCabalVersion mempty - <*> optionalFieldDef "solver" L.projectConfigSolver mempty - <*> monoidalFieldAla "allow-older" AllowOlderNT L.projectConfigAllowOlder - <*> monoidalFieldAla "allow-newer" AllowNewerNT L.projectConfigAllowNewer - <*> optionalFieldDef "write-ghc-environment-files" L.projectConfigWriteGhcEnvironmentFilesPolicy mempty - <*> optionalFieldDefAla "max-backjumps" (alaFlag MaxBackjumps) L.projectConfigMaxBackjumps mempty - <*> optionalFieldDef "reorder-goals" L.projectConfigReorderGoals mempty - <*> optionalFieldDef "count-conflicts" L.projectConfigCountConflicts mempty - <*> optionalFieldDef "fine-grained-conflicts" L.projectConfigFineGrainedConflicts mempty - <*> optionalFieldDef "minimize-conflict-set" L.projectConfigMinimizeConflictSet mempty - <*> optionalFieldDef "strong-flags" L.projectConfigStrongFlags mempty - <*> optionalFieldDef "allow-boot-library-installs" L.projectConfigAllowBootLibInstalls mempty - <*> optionalFieldDef "reject-unconstrained-dependencies" L.projectConfigOnlyConstrained mempty - <*> optionalFieldDef "per-component" L.projectConfigPerComponent mempty - <*> optionalFieldDef "independent-goals" L.projectConfigIndependentGoals mempty - <*> optionalFieldDef "prefer-oldest" L.projectConfigPreferOldest mempty - <*> monoidalFieldAla "extra-prog-path-shared-only" (alaNubList' FSep FilePathNT) L.projectConfigProgPathExtra - <*> optionalFieldDef "multi-repl" L.projectConfigMultiRepl mempty + projectConfigPreferences <- monoidalFieldAla "preferences" formatPackageVersionConstraints L.projectConfigPreferences + projectConfigCabalVersion <- optionalFieldDef "cabal-lib-version" L.projectConfigCabalVersion mempty + projectConfigSolver <- optionalFieldDef "solver" L.projectConfigSolver mempty + projectConfigAllowOlder <- monoidalFieldAla "allow-older" AllowOlderNT L.projectConfigAllowOlder + projectConfigAllowNewer <- monoidalFieldAla "allow-newer" AllowNewerNT L.projectConfigAllowNewer + projectConfigWriteGhcEnvironmentFilesPolicy <- optionalFieldDef "write-ghc-environment-files" L.projectConfigWriteGhcEnvironmentFilesPolicy mempty + projectConfigMaxBackjumps <- optionalFieldDefAla "max-backjumps" (alaFlag MaxBackjumps) L.projectConfigMaxBackjumps mempty + projectConfigReorderGoals <- optionalFieldDef "reorder-goals" L.projectConfigReorderGoals mempty + projectConfigCountConflicts <- optionalFieldDef "count-conflicts" L.projectConfigCountConflicts mempty + projectConfigFineGrainedConflicts <- optionalFieldDef "fine-grained-conflicts" L.projectConfigFineGrainedConflicts mempty + projectConfigMinimizeConflictSet <- optionalFieldDef "minimize-conflict-set" L.projectConfigMinimizeConflictSet mempty + projectConfigStrongFlags <- optionalFieldDef "strong-flags" L.projectConfigStrongFlags mempty + projectConfigAllowBootLibInstalls <- optionalFieldDef "allow-boot-library-installs" L.projectConfigAllowBootLibInstalls mempty + projectConfigOnlyConstrained <- optionalFieldDef "reject-unconstrained-dependencies" L.projectConfigOnlyConstrained mempty + projectConfigPerComponent <- optionalFieldDef "per-component" L.projectConfigPerComponent mempty + projectConfigIndependentGoals <- optionalFieldDef "independent-goals" L.projectConfigIndependentGoals mempty + projectConfigPreferOldest <- optionalFieldDef "prefer-oldest" L.projectConfigPreferOldest mempty + projectConfigProgPathExtra <- monoidalFieldAla "extra-prog-path-shared-only" (alaNubList' FSep FilePathNT) L.projectConfigProgPathExtra + projectConfigMultiRepl <- optionalFieldDef "multi-repl" L.projectConfigMultiRepl mempty + pure ProjectConfigShared{..} packageConfigFieldGrammar :: [String] -> ParsecFieldGrammar' PackageConfig -packageConfigFieldGrammar knownPrograms = - mkPackageConfig - <$> optionalFieldDef "haddock-all" noopLens mempty +packageConfigFieldGrammar knownPrograms = do + haddockAll <- + optionalFieldDef "haddock-all" noopLens mempty ^^^ hiddenField - <*> pure mempty -- program-options stanza - <*> pure mempty -- program-locations stanza - <*> monoidalFieldAla "extra-prog-path" (alaNubList' FSep FilePathNT) L.packageConfigProgramPathExtra - <*> monoidalField "flags" L.packageConfigFlagAssignment - <*> optionalFieldDef "library-vanilla" L.packageConfigVanillaLib mempty - <*> optionalFieldDef "shared" L.packageConfigSharedLib mempty - <*> optionalFieldDef "static" L.packageConfigStaticLib mempty - <*> optionalFieldDef "library-bytecode" L.packageConfigBytecodeLib mempty - <*> optionalFieldDef "executable-dynamic" L.packageConfigDynExe mempty - <*> optionalFieldDef "executable-static" L.packageConfigFullyStaticExe mempty - <*> optionalFieldDef "profiling" L.packageConfigProf mempty - <*> optionalFieldDef "library-profiling" L.packageConfigProfLib mempty - <*> optionalFieldDef "profiling-shared" L.packageConfigProfShared mempty - <*> optionalFieldDef "executable-profiling" L.packageConfigProfExe mempty - <*> optionalFieldDef "profiling-detail" L.packageConfigProfDetail mempty - <*> optionalFieldDef "library-profiling-detail" L.packageConfigProfLibDetail mempty - <*> monoidalFieldAla "configure-options" (alaList' NoCommaFSep Token) L.packageConfigConfigureArgs - <*> optionalFieldDef "optimization" L.packageConfigOptimization mempty - <*> optionalFieldDef "program-prefix" L.packageConfigProgPrefix mempty - <*> optionalFieldDef "program-suffix" L.packageConfigProgSuffix mempty - <*> monoidalFieldAla "extra-lib-dirs" (alaList' FSep FilePathNT) L.packageConfigExtraLibDirs - <*> monoidalFieldAla "extra-lib-dirs-static" (alaList' FSep FilePathNT) L.packageConfigExtraLibDirsStatic - <*> monoidalFieldAla "extra-framework-dirs" (alaList' FSep FilePathNT) L.packageConfigExtraFrameworkDirs - <*> monoidalFieldAla "extra-include-dirs" (alaList' FSep FilePathNT) L.packageConfigExtraIncludeDirs - <*> optionalFieldDef "library-for-ghci" L.packageConfigGHCiLib mempty - <*> optionalFieldDef "split-sections" L.packageConfigSplitSections mempty - <*> optionalFieldDef "split-objs" L.packageConfigSplitObjs mempty - <*> optionalFieldDef "executable-stripping" L.packageConfigStripExes mempty - <*> optionalFieldDef "library-stripping" L.packageConfigStripLibs mempty - <*> optionalFieldDef "tests" L.packageConfigTests mempty - <*> optionalFieldDef "benchmarks" L.packageConfigBenchmarks mempty - <*> packageConfigCoverageGrammar - <*> optionalFieldDef "relocatable" L.packageConfigRelocatable mempty - <*> optionalFieldDef "debug-info" L.packageConfigDebugInfo mempty - <*> optionalFieldDef "build-info" L.packageConfigDumpBuildInfo mempty - <*> optionalFieldDef "run-tests" L.packageConfigRunTests mempty - <*> optionalFieldDef "documentation" L.packageConfigDocumentation mempty - <*> optionalFieldDef "haddock-hoogle" L.packageConfigHaddockHoogle mempty - <*> optionalFieldDef "haddock-html" L.packageConfigHaddockHtml mempty - <*> optionalFieldDefAla "haddock-html-location" (alaFlag Token) L.packageConfigHaddockHtmlLocation mempty - <*> optionalFieldDef "haddock-foreign-libraries" L.packageConfigHaddockForeignLibs mempty - <*> optionalFieldDef "haddock-executables" L.packageConfigHaddockExecutables mempty - <*> optionalFieldDef "haddock-tests" L.packageConfigHaddockTestSuites mempty - <*> optionalFieldDef "haddock-benchmarks" L.packageConfigHaddockBenchmarks mempty - <*> optionalFieldDef "haddock-internal" L.packageConfigHaddockInternal mempty - <*> optionalFieldDefAla "haddock-css" (alaFlag FilePathNT) L.packageConfigHaddockCss mempty - <*> optionalFieldDef "haddock-hyperlink-source" L.packageConfigHaddockLinkedSource mempty - <*> optionalFieldDef "haddock-quickjump" L.packageConfigHaddockQuickJump mempty - <*> optionalFieldDefAla "haddock-hscolour-css" (alaFlag FilePathNT) L.packageConfigHaddockHscolourCss mempty - <*> optionalFieldDef "haddock-contents-location" L.packageConfigHaddockContents mempty - <*> optionalFieldDef "haddock-index-location" L.packageConfigHaddockIndex mempty - <*> optionalFieldDefAla "haddock-base-url" (alaFlag Token) L.packageConfigHaddockBaseUrl mempty - <*> optionalFieldDefAla "haddock-resources-dir" (alaFlag Token) L.packageConfigHaddockResourcesDir mempty - <*> optionalFieldDefAla "haddock-output-dir" (alaFlag FilePathNT) L.packageConfigHaddockOutputDir mempty - <*> optionalFieldDef "haddock-use-unicode" L.packageConfigHaddockUseUnicode mempty - <*> optionalFieldDef "haddock-for-hackage" L.packageConfigHaddockForHackage mempty - <*> optionalFieldDef "test-log" L.packageConfigTestHumanLog mempty - <*> optionalFieldDef "test-machine-log" L.packageConfigTestMachineLog mempty - <*> optionalFieldDef "test-show-details" L.packageConfigTestShowDetails mempty - <*> optionalFieldDef "test-keep-tix-files" L.packageConfigTestKeepTix mempty - <*> optionalFieldDefAla "test-wrapper" (alaFlag FilePathNT) L.packageConfigTestWrapper mempty - <*> optionalFieldDef "test-fail-when-no-test-suites" L.packageConfigTestFailWhenNoTestSuites mempty - <*> monoidalFieldAla "test-options" (alaList NoCommaFSep) L.packageConfigTestTestOptions - <*> monoidalFieldAla "benchmark-options" (alaList NoCommaFSep) L.packageConfigBenchmarkOptions - -- A PackageConfig may contain -options and -location fields inside a package * (projectConfigAllPackages) or package stanza (packageConfigSpecificPackage). - -- When declared at top level (packageConfigLocalPackages), the PackageConfig must contain a program-options stanza/program-locations for these fields. - <* traverse_ (knownField . BS.pack . (<> "-options")) knownPrograms - <* traverse_ (knownField . BS.pack . (<> "-location")) knownPrograms + let packageConfigProgramPaths = mempty + packageConfigProgramArgs = mempty + packageConfigProgramPathExtra <- monoidalFieldAla "extra-prog-path" (alaNubList' FSep FilePathNT) L.packageConfigProgramPathExtra + packageConfigFlagAssignment <- monoidalField "flags" L.packageConfigFlagAssignment + packageConfigVanillaLib <- optionalFieldDef "library-vanilla" L.packageConfigVanillaLib mempty + packageConfigSharedLib <- optionalFieldDef "shared" L.packageConfigSharedLib mempty + packageConfigStaticLib <- optionalFieldDef "static" L.packageConfigStaticLib mempty + packageConfigBytecodeLib <- optionalFieldDef "library-bytecode" L.packageConfigBytecodeLib mempty + packageConfigDynExe <- optionalFieldDef "executable-dynamic" L.packageConfigDynExe mempty + packageConfigFullyStaticExe <- optionalFieldDef "executable-static" L.packageConfigFullyStaticExe mempty + packageConfigProf <- optionalFieldDef "profiling" L.packageConfigProf mempty + packageConfigProfLib <- optionalFieldDef "library-profiling" L.packageConfigProfLib mempty + packageConfigProfShared <- optionalFieldDef "profiling-shared" L.packageConfigProfShared mempty + packageConfigProfExe <- optionalFieldDef "executable-profiling" L.packageConfigProfExe mempty + packageConfigProfDetail <- optionalFieldDef "profiling-detail" L.packageConfigProfDetail mempty + packageConfigProfLibDetail <- optionalFieldDef "library-profiling-detail" L.packageConfigProfLibDetail mempty + packageConfigConfigureArgs <- monoidalFieldAla "configure-options" (alaList' NoCommaFSep Token) L.packageConfigConfigureArgs + packageConfigOptimization <- optionalFieldDef "optimization" L.packageConfigOptimization mempty + packageConfigProgPrefix <- optionalFieldDef "program-prefix" L.packageConfigProgPrefix mempty + packageConfigProgSuffix <- optionalFieldDef "program-suffix" L.packageConfigProgSuffix mempty + packageConfigExtraLibDirs <- monoidalFieldAla "extra-lib-dirs" (alaList' FSep FilePathNT) L.packageConfigExtraLibDirs + packageConfigExtraLibDirsStatic <- monoidalFieldAla "extra-lib-dirs-static" (alaList' FSep FilePathNT) L.packageConfigExtraLibDirsStatic + packageConfigExtraFrameworkDirs <- monoidalFieldAla "extra-framework-dirs" (alaList' FSep FilePathNT) L.packageConfigExtraFrameworkDirs + packageConfigExtraIncludeDirs <- monoidalFieldAla "extra-include-dirs" (alaList' FSep FilePathNT) L.packageConfigExtraIncludeDirs + packageConfigGHCiLib <- optionalFieldDef "library-for-ghci" L.packageConfigGHCiLib mempty + packageConfigSplitSections <- optionalFieldDef "split-sections" L.packageConfigSplitSections mempty + packageConfigSplitObjs <- optionalFieldDef "split-objs" L.packageConfigSplitObjs mempty + packageConfigStripExes <- optionalFieldDef "executable-stripping" L.packageConfigStripExes mempty + packageConfigStripLibs <- optionalFieldDef "library-stripping" L.packageConfigStripLibs mempty + packageConfigTests <- optionalFieldDef "tests" L.packageConfigTests mempty + packageConfigBenchmarks <- optionalFieldDef "benchmarks" L.packageConfigBenchmarks mempty + packageConfigCoverage <- packageConfigCoverageGrammar + packageConfigRelocatable <- optionalFieldDef "relocatable" L.packageConfigRelocatable mempty + packageConfigDebugInfo <- optionalFieldDef "debug-info" L.packageConfigDebugInfo mempty + packageConfigDumpBuildInfo <- optionalFieldDef "build-info" L.packageConfigDumpBuildInfo mempty + packageConfigRunTests <- optionalFieldDef "run-tests" L.packageConfigRunTests mempty + packageConfigDocumentation <- optionalFieldDef "documentation" L.packageConfigDocumentation mempty + packageConfigHaddockHoogle <- optionalFieldDef "haddock-hoogle" L.packageConfigHaddockHoogle mempty + packageConfigHaddockHtml <- optionalFieldDef "haddock-html" L.packageConfigHaddockHtml mempty + packageConfigHaddockHtmlLocation <- optionalFieldDefAla "haddock-html-location" (alaFlag Token) L.packageConfigHaddockHtmlLocation mempty + packageConfigHaddockForeignLibs' <- optionalFieldDef "haddock-foreign-libraries" L.packageConfigHaddockForeignLibs mempty + packageConfigHaddockExecutables' <- optionalFieldDef "haddock-executables" L.packageConfigHaddockExecutables mempty + packageConfigHaddockTestSuites' <- optionalFieldDef "haddock-tests" L.packageConfigHaddockTestSuites mempty + packageConfigHaddockBenchmarks' <- optionalFieldDef "haddock-benchmarks" L.packageConfigHaddockBenchmarks mempty + packageConfigHaddockInternal <- optionalFieldDef "haddock-internal" L.packageConfigHaddockInternal mempty + packageConfigHaddockCss <- optionalFieldDefAla "haddock-css" (alaFlag FilePathNT) L.packageConfigHaddockCss mempty + packageConfigHaddockLinkedSource <- optionalFieldDef "haddock-hyperlink-source" L.packageConfigHaddockLinkedSource mempty + packageConfigHaddockQuickJump <- optionalFieldDef "haddock-quickjump" L.packageConfigHaddockQuickJump mempty + packageConfigHaddockHscolourCss <- optionalFieldDefAla "haddock-hscolour-css" (alaFlag FilePathNT) L.packageConfigHaddockHscolourCss mempty + packageConfigHaddockContents <- optionalFieldDef "haddock-contents-location" L.packageConfigHaddockContents mempty + packageConfigHaddockIndex <- optionalFieldDef "haddock-index-location" L.packageConfigHaddockIndex mempty + packageConfigHaddockBaseUrl <- optionalFieldDefAla "haddock-base-url" (alaFlag Token) L.packageConfigHaddockBaseUrl mempty + packageConfigHaddockResourcesDir <- optionalFieldDefAla "haddock-resources-dir" (alaFlag Token) L.packageConfigHaddockResourcesDir mempty + packageConfigHaddockOutputDir <- optionalFieldDefAla "haddock-output-dir" (alaFlag FilePathNT) L.packageConfigHaddockOutputDir mempty + packageConfigHaddockUseUnicode <- optionalFieldDef "haddock-use-unicode" L.packageConfigHaddockUseUnicode mempty + packageConfigHaddockForHackage <- optionalFieldDef "haddock-for-hackage" L.packageConfigHaddockForHackage mempty + packageConfigTestHumanLog <- optionalFieldDef "test-log" L.packageConfigTestHumanLog mempty + packageConfigTestMachineLog <- optionalFieldDef "test-machine-log" L.packageConfigTestMachineLog mempty + packageConfigTestShowDetails <- optionalFieldDef "test-show-details" L.packageConfigTestShowDetails mempty + packageConfigTestKeepTix <- optionalFieldDef "test-keep-tix-files" L.packageConfigTestKeepTix mempty + packageConfigTestWrapper <- optionalFieldDefAla "test-wrapper" (alaFlag FilePathNT) L.packageConfigTestWrapper mempty + packageConfigTestFailWhenNoTestSuites <- optionalFieldDef "test-fail-when-no-test-suites" L.packageConfigTestFailWhenNoTestSuites mempty + packageConfigTestTestOptions <- monoidalFieldAla "test-options" (alaList NoCommaFSep) L.packageConfigTestTestOptions + packageConfigBenchmarkOptions <- monoidalFieldAla "benchmark-options" (alaList NoCommaFSep) L.packageConfigBenchmarkOptions + -- A PackageConfig may contain -options and -location fields inside a package * (projectConfigAllPackages) or package stanza (packageConfigSpecificPackage). + -- When declared at top level (packageConfigLocalPackages), the PackageConfig must contain a program-options stanza/program-locations for these fields. + traverse_ (knownField . BS.pack . (<> "-options")) knownPrograms + traverse_ (knownField . BS.pack . (<> "-location")) knownPrograms + pure + PackageConfig + { -- The haddock-all field provides a default value, but explicit declarations can override it + packageConfigHaddockForeignLibs = haddockAll <> packageConfigHaddockForeignLibs' + , packageConfigHaddockExecutables = haddockAll <> packageConfigHaddockExecutables' + , packageConfigHaddockTestSuites = haddockAll <> packageConfigHaddockTestSuites' + , packageConfigHaddockBenchmarks = haddockAll <> packageConfigHaddockBenchmarks' + , .. + } where noopLens f s = s <$ f mempty - mkPackageConfig - haddockAll - packageConfigProgramPaths - packageConfigProgramArgs - packageConfigProgramPathExtra - packageConfigFlagAssignment - packageConfigVanillaLib - packageConfigSharedLib - packageConfigStaticLib - packageConfigBytecodeLib - packageConfigDynExe - packageConfigFullyStaticExe - packageConfigProf - packageConfigProfLib - packageConfigProfShared - packageConfigProfExe - packageConfigProfDetail - packageConfigProfLibDetail - packageConfigConfigureArgs - packageConfigOptimization - packageConfigProgPrefix - packageConfigProgSuffix - packageConfigExtraLibDirs - packageConfigExtraLibDirsStatic - packageConfigExtraFrameworkDirs - packageConfigExtraIncludeDirs - packageConfigGHCiLib - packageConfigSplitSections - packageConfigSplitObjs - packageConfigStripExes - packageConfigStripLibs - packageConfigTests - packageConfigBenchmarks - packageConfigCoverage - packageConfigRelocatable - packageConfigDebugInfo - packageConfigDumpBuildInfo - packageConfigRunTests - packageConfigDocumentation - packageConfigHaddockHoogle - packageConfigHaddockHtml - packageConfigHaddockHtmlLocation - packageConfigHaddockForeignLibs' - packageConfigHaddockExecutables' - packageConfigHaddockTestSuites' - packageConfigHaddockBenchmarks' - packageConfigHaddockInternal - packageConfigHaddockCss - packageConfigHaddockLinkedSource - packageConfigHaddockQuickJump - packageConfigHaddockHscolourCss - packageConfigHaddockContents - packageConfigHaddockIndex - packageConfigHaddockBaseUrl - packageConfigHaddockResourcesDir - packageConfigHaddockOutputDir - packageConfigHaddockUseUnicode - packageConfigHaddockForHackage - packageConfigTestHumanLog - packageConfigTestMachineLog - packageConfigTestShowDetails - packageConfigTestKeepTix - packageConfigTestWrapper - packageConfigTestFailWhenNoTestSuites - packageConfigTestTestOptions - packageConfigBenchmarkOptions = - PackageConfig - { -- The haddock-al` field provides a default value, but explicit declarations can override it - packageConfigHaddockForeignLibs = haddockAll <> packageConfigHaddockForeignLibs' - , packageConfigHaddockExecutables = haddockAll <> packageConfigHaddockExecutables' - , packageConfigHaddockTestSuites = haddockAll <> packageConfigHaddockTestSuites' - , packageConfigHaddockBenchmarks = haddockAll <> packageConfigHaddockBenchmarks' - , .. - } packageConfigCoverageGrammar :: ParsecFieldGrammar PackageConfig (Distribution.Simple.Flag.Flag Bool) packageConfigCoverageGrammar = diff --git a/cabal-install/src/Distribution/Client/Types/SourceRepo.hs b/cabal-install/src/Distribution/Client/Types/SourceRepo.hs index 991e7b78714..18fc23cf2a4 100644 --- a/cabal-install/src/Distribution/Client/Types/SourceRepo.hs +++ b/cabal-install/src/Distribution/Client/Types/SourceRepo.hs @@ -1,5 +1,7 @@ +{-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE UndecidableInstances #-} module Distribution.Client.Types.SourceRepo @@ -102,14 +104,14 @@ sourceRepositoryPackageGrammar , c (NonEmpty' NoCommaFSep Token String) ) => g SourceRepoList SourceRepoList -sourceRepositoryPackageGrammar = - SourceRepositoryPackage - <$> uniqueField "type" srpTypeLens - <*> uniqueFieldAla "location" Token srpLocationLens - <*> optionalFieldAla "tag" Token srpTagLens - <*> optionalFieldAla "branch" Token srpBranchLens - <*> monoidalFieldAla "subdir" (alaList' NoCommaFSep FilePathNT) srpSubdirLens -- note: NoCommaFSep is somewhat important for roundtrip, as "." is there... - <*> fmap (maybe [] toList) pcc +sourceRepositoryPackageGrammar = do + srpType <- uniqueField "type" srpTypeLens + srpLocation <- uniqueFieldAla "location" Token srpLocationLens + srpTag <- optionalFieldAla "tag" Token srpTagLens + srpBranch <- optionalFieldAla "branch" Token srpBranchLens + srpSubdir <- monoidalFieldAla "subdir" (alaList' NoCommaFSep FilePathNT) srpSubdirLens -- note: NoCommaFSep is somewhat important for roundtrip, as "." is there... + srpCommand <- fmap (maybe [] toList) pcc + pure SourceRepositoryPackage{..} where pcc = optionalFieldAla "post-checkout-command" (alaNonEmpty' NoCommaFSep Token) srpCommandLensNE {-# SPECIALIZE sourceRepositoryPackageGrammar :: ParsecFieldGrammar' SourceRepoList #-} diff --git a/cabal-install/src/Distribution/Client/Utils/Parsec.hs b/cabal-install/src/Distribution/Client/Utils/Parsec.hs index 684a9d42fa2..1a06b6573c9 100644 --- a/cabal-install/src/Distribution/Client/Utils/Parsec.hs +++ b/cabal-install/src/Distribution/Client/Utils/Parsec.hs @@ -1,4 +1,6 @@ +{-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RecordWildCards #-} module Distribution.Client.Utils.Parsec ( remoteRepoGrammar @@ -77,10 +79,13 @@ instance (Newtype a b, Sep sep, Pretty b) => Pretty (NubList' sep b a) where pretty = prettySep (Proxy :: Proxy sep) . map (pretty . (pack :: a -> b)) . NubList.fromNubList . unpack remoteRepoGrammar :: RepoName -> ParsecFieldGrammar RemoteRepo RemoteRepo -remoteRepoGrammar name = - pure (RemoteRepo name) - <*> uniqueFieldAla "url" URI_NT remoteRepoURILens - <*> optionalField "secure" remoteRepoSecureLens - <*> monoidalFieldAla "root-keys" (alaList' FSep Token) remoteRepoRootKeysLens - <*> optionalFieldDefAla "key-threshold" KeyThreshold remoteRepoKeyThresholdLens 0 - <*> pure False -- we don't parse remoteRepoShouldTryHttps +remoteRepoGrammar remoteRepoName = do + remoteRepoURI <- uniqueFieldAla "url" URI_NT remoteRepoURILens + remoteRepoSecure <- optionalField "secure" remoteRepoSecureLens + remoteRepoRootKeys <- monoidalFieldAla "root-keys" (alaList' FSep Token) remoteRepoRootKeysLens + remoteRepoKeyThreshold <- optionalFieldDefAla "key-threshold" KeyThreshold remoteRepoKeyThresholdLens 0 + pure + RemoteRepo + { remoteRepoShouldTryHttps = False -- we don't parse remoteRepoShouldTryHttps + , .. + } diff --git a/cabal-testsuite/src/Test/Cabal/Monad.hs b/cabal-testsuite/src/Test/Cabal/Monad.hs index c8f1bd31ae1..cc4b428c901 100644 --- a/cabal-testsuite/src/Test/Cabal/Monad.hs +++ b/cabal-testsuite/src/Test/Cabal/Monad.hs @@ -1,4 +1,8 @@ -- | The test monad + +{-# LANGUAGE ApplicativeDo #-} +{-# LANGUAGE RecordWildCards #-} + module Test.Cabal.Monad ( -- * High-level runners setupAndCabalTest @@ -134,9 +138,8 @@ data CommonArgs = CommonArgs } commonArgParser :: Parser CommonArgs -commonArgParser = - CommonArgs - <$> optional +commonArgParser = do + argCabalInstallPath <- optional ( option str ( help "Path to cabal-install executable to test. If omitted, tests involving cabal-install are skipped!" @@ -144,7 +147,7 @@ commonArgParser = <> metavar "PATH" ) ) - <*> optional + argGhcPath <- optional ( option str ( help "GHC to ask Cabal to use via --with-ghc flag" @@ -153,7 +156,7 @@ commonArgParser = <> metavar "PATH" ) ) - <*> optional + argHackageRepoToolPath <- optional ( option str ( help "Path to hackage-repo-tool to use for repository manipulation" @@ -161,7 +164,7 @@ commonArgParser = <> metavar "PATH" ) ) - <*> optional + argHaddockPath <- optional ( option str ( help "Path to haddock to use for --with-haddock flag" @@ -169,15 +172,16 @@ commonArgParser = <> metavar "PATH" ) ) - <*> switch + argKeepTmpFiles <- switch ( long "keep-tmp-files" <> help "Keep temporary files" ) - <*> switch + argAccept <- switch ( long "accept" <> help "Accept output" ) - <*> switch (long "skip-setup-tests" <> help "Skip setup tests") + argSkipSetupTests <- switch (long "skip-setup-tests" <> help "Skip setup tests") + pure CommonArgs{..} renderCommonArgs :: CommonArgs -> [String] renderCommonArgs args = @@ -197,15 +201,14 @@ data TestArgs = TestArgs } testArgParser :: Parser TestArgs -testArgParser = - TestArgs - <$> option +testArgParser = do + testArgDistDir <- option str ( help "Build directory of cabal-testsuite" <> long "builddir" <> metavar "DIR" ) - <*> many + testArgPackageDb <- many ( option str ( help "Package DB which contains Cabal and Cabal-syntax" @@ -213,8 +216,9 @@ testArgParser = <> metavar "DIR" ) ) - <*> argument str (metavar "FILE") - <*> commonArgParser + testArgScriptPath <- argument str (metavar "FILE") + testCommonArgs <- commonArgParser + pure TestArgs{..} -- * skip tests diff --git a/cabal-validate/src/Cli.hs b/cabal-validate/src/Cli.hs index 87425a7575d..d806e077943 100644 --- a/cabal-validate/src/Cli.hs +++ b/cabal-validate/src/Cli.hs @@ -1,3 +1,6 @@ +{-# LANGUAGE ApplicativeDo #-} +{-# LANGUAGE RecordWildCards #-} + -- | Parse CLI arguments and resolve defaults from the environment. module Cli ( Opts (..) @@ -315,69 +318,75 @@ data RawOpts = RawOpts -- -- See: `fullRawOptsParser` rawOptsParser :: Parser RawOpts -rawOptsParser = - RawOpts - <$> ( flag' - Verbose - ( short 'v' - <> long "verbose" - <> help "Always display build and test output" - ) - <|> flag - Info - Quiet - ( short 'q' - <> long "quiet" - <> help "Silence build and test output" - ) +rawOptsParser = do + rawVerbosity <- + flag' + Verbose + ( short 'v' + <> long "verbose" + <> help "Always display build and test output" + ) + <|> flag + Info + Quiet + ( short 'q' + <> long "quiet" + <> help "Silence build and test output" ) - <*> option + rawJobs <- + option (Just <$> auto) ( short 'j' <> long "jobs" <> help "Passed to `cabal build --jobs`" <> value Nothing ) - <*> strOption + rawCompiler <- + strOption ( short 'w' <> long "with-compiler" <> help "Build Cabal with the given compiler instead of `ghc`" <> value "ghc" ) - <*> strOption + rawCabal <- + strOption ( long "with-cabal" <> help "Test the given `cabal-install` (the `cabal` on your `$PATH` is used for builds)" <> value "cabal" ) - <*> many + rawExtraCompilers <- + many ( strOption ( long "extra-hc" <> help "Extra compilers to run the test suites against" ) ) - <*> option + rawTastyPattern <- + option (Just <$> Opt.str) ( short 'p' <> long "pattern" <> help "Pattern to filter tests by" <> value Nothing ) - <*> many + rawTastyArgs <- + many ( strOption ( long "tasty-arg" <> help "Extra arguments to pass to Tasty test suites" ) ) - <*> maybeBoolOption + rawTastyHideSuccesses <- + maybeBoolOption "hide-successes" - ( help "Do not print tests that passed successfully" - ) - <*> boolOption + (help "Do not print tests that passed successfully") + rawDoctest <- + boolOption False "doctest" - ( help "Run doctest on the `Cabal` library" - ) - <*> many + (help "Run doctest on the `Cabal` library") + rawSteps <- + many ( option (maybeReader parseStep) ( short 's' @@ -385,64 +394,66 @@ rawOptsParser = <> help "Run only a specific step (can be specified multiple times)" ) ) - <*> switch + rawListSteps <- + switch ( long "list-steps" <> help "List the available steps and exit" ) - <*> ( flag' - True - ( long "lib-only" - <> help "Test only `Cabal` (the library)" - ) - <|> flag - False - False - ( long "cli" - <> help "Test `cabal-install` (the executable) in addition to `Cabal` (the library)" - ) + rawLibOnly <- + flag' + True + ( long "lib-only" + <> help "Test only `Cabal` (the library)" + ) + <|> flag + False + False + ( long "cli" + <> help "Test `cabal-install` (the executable) in addition to `Cabal` (the library)" ) - <*> boolOption + rawRunLibTests <- + boolOption True "run-lib-tests" - ( help "Run tests for the `Cabal` library" - ) - <*> boolOption + (help "Run tests for the `Cabal` library") + rawRunCliTests <- + boolOption True "run-cli-tests" - ( help "Run client tests for the `cabal-install` executable" - ) - <*> boolOption + (help "Run client tests for the `cabal-install` executable") + rawRunLibSuite <- + boolOption False "run-lib-suite" - ( help "Run `cabal-testsuite` with the `Cabal` library" - ) - <*> boolOption + (help "Run `cabal-testsuite` with the `Cabal` library") + rawRunCliSuite <- + boolOption False "run-cli-suite" - ( help "Run `cabal-testsuite` with the `cabal-install` executable" - ) - <*> boolOption + (help "Run `cabal-testsuite` with the `cabal-install` executable") + rawRunSolverTests <- + boolOption True "run-solver-tests" - ( help "Run `cabal-install-solver` tests" - ) - <*> boolOption + (help "Run `cabal-install-solver` tests") + rawSolverBenchmarks <- + boolOption False "solver-benchmarks" - ( help "Build and trial run `solver-benchmarks`" + (help "Build and trial run `solver-benchmarks`") + rawHackageTests <- + flag' + CompleteHackageTests + ( long "complete-hackage-tests" + <> help "Run `hackage-tests` on complete Hackage data" ) - <*> ( flag' - CompleteHackageTests - ( long "complete-hackage-tests" - <> help "Run `hackage-tests` on complete Hackage data" - ) - <|> flag - NoHackageTests - PartialHackageTests - ( long "partial-hackage-tests" - <> help "Run `hackage-tests` on parts of Hackage data" - ) + <|> flag + NoHackageTests + PartialHackageTests + ( long "partial-hackage-tests" + <> help "Run `hackage-tests` on parts of Hackage data" ) + pure RawOpts{..} -- | Parse a boolean switch with separate names for the true and false options. boolOption' :: Bool -> String -> String -> Mod FlagFields Bool -> Parser Bool diff --git a/solver-benchmarks/HackageBenchmark.hs b/solver-benchmarks/HackageBenchmark.hs index 02a59921c90..12025b5246f 100644 --- a/solver-benchmarks/HackageBenchmark.hs +++ b/solver-benchmarks/HackageBenchmark.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE RecordWildCards #-} module HackageBenchmark ( @@ -371,32 +372,32 @@ parserInfo = info (argParser <**> helper) <> header "hackage-benchmark" ) argParser :: Parser Args -argParser = Args - <$> strOption +argParser = do + argCabal1 <- strOption ( long "cabal1" <> metavar "PATH" <> help "First cabal executable") - <*> strOption + argCabal2 <- strOption ( long "cabal2" <> metavar "PATH" <> help "Second cabal executable") - <*> option (words <$> str) + argCabal1Flags <- option (words <$> str) ( long "cabal1-flags" <> value [] <> metavar "FLAGS" <> help "Extra flags for the first cabal executable") - <*> option (words <$> str) + argCabal2Flags <- option (words <$> str) ( long "cabal2-flags" <> value [] <> metavar "FLAGS" <> help "Extra flags for the second cabal executable") - <*> option (map mkPackageName . words <$> str) + argPackages <- option (map mkPackageName . words <$> str) ( long "packages" <> value [] <> metavar "PACKAGES" <> help ("Space separated list of packages to test, or all of Hackage" ++ " if unspecified")) - <*> option auto + argMinRunTimeDifferenceToRerun <- option auto ( long "min-run-time-percentage-difference-to-rerun" <> showDefault <> value 0.0 @@ -404,31 +405,32 @@ argParser = Args <> help ("Stop testing a package when the difference in run times in" ++ " the first trial are within this percentage, in order to" ++ " save time")) - <*> option (mkPValue <$> auto) + argPValue <- option (mkPValue <$> auto) ( long "pvalue" <> showDefault <> value (mkPValue 0.05) <> metavar "DOUBLE" <> help ("p-value used to determine whether to print the results for" ++ " each package")) - <*> option auto + argTrials <- option auto ( long "trials" <> showDefault <> value 10 <> metavar "N" <> help "Number of trials for each package") - <*> switch + argConcurrently <- switch ( long "concurrently" <> help "Run cabals concurrently") - <*> switch + argPrintTrials <- switch ( long "print-trials" <> help "Whether to include the results from individual trials in the output") - <*> switch + argPrintSkippedPackages <- switch ( long "print-skipped-packages" <> help "Whether to include skipped packages in the output") - <*> option auto + argTimeoutSeconds <- option auto ( long "timeout" <> showDefault <> value 90 <> metavar "SECONDS" <> help "Maximum time to run a cabal command, in seconds") + pure Args{..}