summaryrefslogtreecommitdiff
path: root/hadrian/src/CommandLine.hs
diff options
context:
space:
mode:
authorAlp Mestanogullari <alpmestan@gmail.com>2019-06-24 20:43:49 +0200
committerMarge Bot <ben+marge-bot@smart-cactus.org>2019-07-09 22:57:31 -0400
commit18ac9ad404f490bd7ea0639a1b85a88ed4502613 (patch)
treeb623b43f77709e148a83cef6f5b3be192ce15640 /hadrian/src/CommandLine.hs
parent42ff8653bd5ce7f00af5783f2973393ebfcd7cc7 (diff)
downloadhaskell-18ac9ad404f490bd7ea0639a1b85a88ed4502613.tar.gz
Hadrian: implement key-value settings for builder options
They take the general form `foo.bar.baz [+]= some values`, where `=` completely overrides the arguments for a builder and `+=` extends them. We currenly only support settings for updating the GHC and C compiler options, of the form: ``` {stage0, ..., stage3 or *}.{package name or *} .ghc.{c, hs, link, deps, toolargs or *}.opts {stage0, ..., stage3 or *}.{package name or *} .cc.{c, deps or *}.opts ``` The supported settings and their use is covered in the new section of `hadrian/doc/user-settings.md`, while the implementation is explained in a new Note [Hadrian settings]. Most of the logic is implemented in a new module, `Settings.Parser`, which contains key-value assignment/extension parsers as well as utilities for specifying allowed settings at a high-level, generating a `Predicate` from such a description or generating the list of possible completions for a given string. The additions to the `Settings` module make use of this to describe the settings that Hadrian currently supports, and apply all such key-value settings (from the command line and `<root>/hadrian.settings`) to the flavour that Hadrian is going to proceed with. This new setting system comes with support for generating Bash completions, implemented in `hadrian/completion.sh` and Hadrian's `autocomplete` target: > source hadrian/completion.sh > hadrian/build.sh stage1.base.ghc.<TAB> stage1.base.ghc.c.opts stage1.base.ghc.hs.opts stage1.base.ghc.*.opts stage1.base.ghc.deps.opts stage1.base.ghc.link.opts stage1.base.ghc.toolargs.opts
Diffstat (limited to 'hadrian/src/CommandLine.hs')
-rw-r--r--hadrian/src/CommandLine.hs52
1 files changed, 46 insertions, 6 deletions
diff --git a/hadrian/src/CommandLine.hs b/hadrian/src/CommandLine.hs
index 461898cdfd..aad616f40a 100644
--- a/hadrian/src/CommandLine.hs
+++ b/hadrian/src/CommandLine.hs
@@ -1,6 +1,6 @@
module CommandLine (
optDescrs, cmdLineArgsMap, cmdFlavour, lookupFreeze1, cmdIntegerSimple,
- cmdProgressColour, cmdProgressInfo, cmdConfigure,
+ cmdProgressColour, cmdProgressInfo, cmdConfigure, cmdCompleteSetting,
cmdDocsArgs, lookupBuildRoot, TestArgs(..), TestSpeed(..), defaultTestArgs
) where
@@ -10,8 +10,10 @@ import Data.List.Extra
import Development.Shake hiding (Normal)
import Flavour (DocTargets, DocTarget(..))
import Hadrian.Utilities hiding (buildRoot)
+import Settings.Parser
import System.Console.GetOpt
import System.Environment
+import qualified System.Directory as Directory
import qualified Data.Set as Set
@@ -27,7 +29,8 @@ data CommandLineArgs = CommandLineArgs
, progressInfo :: ProgressInfo
, buildRoot :: BuildRoot
, testArgs :: TestArgs
- , docTargets :: DocTargets }
+ , docTargets :: DocTargets
+ , completeStg :: Maybe String }
deriving (Eq, Show)
-- | Default values for 'CommandLineArgs'.
@@ -41,7 +44,8 @@ defaultCommandLineArgs = CommandLineArgs
, progressInfo = Brief
, buildRoot = BuildRoot "_build"
, testArgs = defaultTestArgs
- , docTargets = Set.fromList [minBound..maxBound] }
+ , docTargets = Set.fromList [minBound..maxBound]
+ , completeStg = Nothing }
-- | These arguments are used by the `test` target.
data TestArgs = TestArgs
@@ -199,6 +203,9 @@ readTestWay way =
let newWays = way : testWays (testArgs flags)
in flags { testArgs = (testArgs flags) {testWays = newWays} }
+readCompleteStg :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs)
+readCompleteStg ms = Right $ \flags -> flags { completeStg = ms }
+
readDocsArg :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs)
readDocsArg ms = maybe (Left "Cannot parse docs argument") (Right . set) (go =<< ms)
@@ -263,18 +270,48 @@ optDescrs =
"A verbosity value between 0 and 5. 0 is silent, 4 and higher activates extra output."
, Option [] ["test-way"] (OptArg readTestWay "TEST_WAY")
"only run these ways"
- , Option ['a'] ["test-accept"] (NoArg readTestAccept) "Accept new output of tests" ]
+ , Option ['a'] ["test-accept"] (NoArg readTestAccept) "Accept new output of tests"
+ , Option [] ["complete-setting"] (OptArg readCompleteStg "SETTING")
+ "Setting key to autocomplete, for the 'autocomplete' target."
+ ]
-- | A type-indexed map containing Hadrian command line arguments to be passed
-- to Shake via 'shakeExtra'.
cmdLineArgsMap :: IO (Map.HashMap TypeRep Dynamic)
cmdLineArgsMap = do
- (opts, _, _) <- getOpt Permute optDescrs <$> getArgs
- let args = foldl (flip id) defaultCommandLineArgs (rights opts)
+ xs <- getArgs
+ let -- We split the arguments between the ones that look like
+ -- "k = v" or "k += v", in cliSettings, and the rest in
+ -- optArgs.
+ (optsArgs, cliSettings) = partitionKVs xs
+
+ -- We only use the arguments that don't look like setting
+ -- updates for parsing Hadrian and Shake flags/options.
+ (opts, _, _) = getOpt Permute optDescrs optsArgs
+ args = foldl (flip id) defaultCommandLineArgs (rights opts)
+
+ BuildRoot root = buildRoot args
+ settingsFile = root -/- "hadrian.settings"
+
+ -- We try to look at <root>/hadrian.settings, and if it exists
+ -- we read as many settings as we can from it, combining
+ -- them with the ones we got on the command line, in allSettings.
+ -- We then insert all those settings in the dynamic map, so that
+ -- the 'Settings.flavour' action can look them up and apply
+ -- all the relevant updates to the flavour that Hadrian is set
+ -- to run with.
+ settingsFileExists <- Directory.doesFileExist settingsFile
+ fileSettings <-
+ if settingsFileExists
+ then parseJustKVs . lines <$> readFile settingsFile
+ else return []
+ let allSettings = cliSettings ++ fileSettings
+
return $ insertExtra (progressColour args) -- Accessed by Hadrian.Utilities
$ insertExtra (progressInfo args) -- Accessed by Hadrian.Utilities
$ insertExtra (buildRoot args) -- Accessed by Hadrian.Utilities
$ insertExtra (testArgs args) -- Accessed by Settings.Builders.RunTest
+ $ insertExtra allSettings -- Accessed by Settings
$ insertExtra args Map.empty
cmdLineArgs :: Action CommandLineArgs
@@ -286,6 +323,9 @@ cmdConfigure = configure <$> cmdLineArgs
cmdFlavour :: Action (Maybe String)
cmdFlavour = flavour <$> cmdLineArgs
+cmdCompleteSetting :: Action (Maybe String)
+cmdCompleteSetting = completeStg <$> cmdLineArgs
+
lookupBuildRoot :: Map.HashMap TypeRep Dynamic -> BuildRoot
lookupBuildRoot = buildRoot . lookupExtra defaultCommandLineArgs