diff options
author | Alp Mestanogullari <alpmestan@gmail.com> | 2019-06-24 20:43:49 +0200 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2019-07-09 22:57:31 -0400 |
commit | 18ac9ad404f490bd7ea0639a1b85a88ed4502613 (patch) | |
tree | b623b43f77709e148a83cef6f5b3be192ce15640 /hadrian/src/CommandLine.hs | |
parent | 42ff8653bd5ce7f00af5783f2973393ebfcd7cc7 (diff) | |
download | haskell-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.hs | 52 |
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 |