mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-20 01:07:18 +03:00
Refactor daml start options, add true/false to yes/no/auto flags. (#12169)
* Refactor daml start & add true/false to yesNoAuto. - Refactor the way we pass arguments to daml start. We were relying on positional arguments with newtypes, but this is super cumbersome. I changed it to a RecordWildCards-style approach, where we don't need quite so many newtypes, and no more positional arguments. - "--start-navigator" flag had some custom logic to accept "true" and "false". I don't see why we can't just accept "true" and "false" anywhere we use the "yes/no/auto" flags, so I just changed that and got rid of the custom logic. - The way "auto" was handled for this flag was incorrect, since "auto" is supposed to be equivalent the default, i.e. not passing any flag. I changed it so auto is equivalent to not passing an argument. (I.e. it looks in daml.yaml for the start-navigator option). changelog_begin changelog_end * dont pass in shutdownStdinClose to runStart
This commit is contained in:
parent
1ed02369eb
commit
8b05a533ce
@ -61,20 +61,9 @@ data Command
|
|||||||
| Init { targetFolderM :: Maybe FilePath }
|
| Init { targetFolderM :: Maybe FilePath }
|
||||||
| ListTemplates
|
| ListTemplates
|
||||||
| Start
|
| Start
|
||||||
{ sandboxPortM :: Maybe SandboxPortSpec
|
{ startOptions :: StartOptions
|
||||||
, openBrowser :: OpenBrowser
|
, shutdownStdinClose :: Bool
|
||||||
, startNavigator :: Maybe StartNavigator
|
}
|
||||||
, navigatorPort :: NavigatorPort
|
|
||||||
, jsonApiCfg :: JsonApiConfig
|
|
||||||
, onStartM :: Maybe String
|
|
||||||
, waitForSignal :: WaitForSignal
|
|
||||||
, sandboxOptions :: SandboxOptions
|
|
||||||
, navigatorOptions :: NavigatorOptions
|
|
||||||
, jsonApiOptions :: JsonApiOptions
|
|
||||||
, scriptOptions :: ScriptOptions
|
|
||||||
, shutdownStdinClose :: Bool
|
|
||||||
, sandboxClassic :: SandboxClassic
|
|
||||||
}
|
|
||||||
| Deploy { flags :: LedgerFlags }
|
| Deploy { flags :: LedgerFlags }
|
||||||
| LedgerListParties { flags :: LedgerFlags, json :: JsonFlag }
|
| LedgerListParties { flags :: LedgerFlags, json :: JsonFlag }
|
||||||
| LedgerAllocateParties { flags :: LedgerFlags, parties :: [String] }
|
| LedgerAllocateParties { flags :: LedgerFlags, parties :: [String] }
|
||||||
@ -166,37 +155,21 @@ commandParser = subparser $ fold
|
|||||||
initCmd = Init
|
initCmd = Init
|
||||||
<$> optional (argument str (metavar "TARGET_PATH" <> help "Project folder to initialize."))
|
<$> optional (argument str (metavar "TARGET_PATH" <> help "Project folder to initialize."))
|
||||||
|
|
||||||
startCmd = Start
|
startCmd = do
|
||||||
<$> optional (option (maybeReader (toSandboxPortSpec <=< readMaybe)) (long "sandbox-port" <> metavar "PORT_NUM" <> help "Port number for the sandbox"))
|
sandboxPortM <- optional (option (maybeReader (toSandboxPortSpec <=< readMaybe)) (long "sandbox-port" <> metavar "PORT_NUM" <> help "Port number for the sandbox"))
|
||||||
<*> (OpenBrowser <$> flagYesNoAuto "open-browser" True "Open the browser after navigator" idm)
|
shouldOpenBrowser <- flagYesNoAuto "open-browser" True "Open the browser after navigator" idm
|
||||||
<*> optional navigatorFlag
|
shouldStartNavigator <- flagYesNoAuto' "start-navigator" "Start navigator as part of daml start. Can be set to true or false. Defaults to true." idm
|
||||||
<*> navigatorPortOption
|
navigatorPort <- navigatorPortOption
|
||||||
<*> jsonApiCfg
|
jsonApiConfig <- jsonApiCfg
|
||||||
<*> optional (option str (long "on-start" <> metavar "COMMAND" <> help "Command to run once sandbox and navigator are running."))
|
onStartM <- optional (option str (long "on-start" <> metavar "COMMAND" <> help "Command to run once sandbox and navigator are running."))
|
||||||
<*> (WaitForSignal <$> flagYesNoAuto "wait-for-signal" True "Wait for Ctrl+C or interrupt after starting servers." idm)
|
shouldWaitForSignal <- flagYesNoAuto "wait-for-signal" True "Wait for Ctrl+C or interrupt after starting servers." idm
|
||||||
<*> (SandboxOptions <$> many (strOption (long "sandbox-option" <> metavar "SANDBOX_OPTION" <> help "Pass option to sandbox")))
|
sandboxOptions <- many (strOption (long "sandbox-option" <> metavar "SANDBOX_OPTION" <> help "Pass option to sandbox"))
|
||||||
<*> (NavigatorOptions <$> many (strOption (long "navigator-option" <> metavar "NAVIGATOR_OPTION" <> help "Pass option to navigator")))
|
navigatorOptions <- many (strOption (long "navigator-option" <> metavar "NAVIGATOR_OPTION" <> help "Pass option to navigator"))
|
||||||
<*> (JsonApiOptions <$> many (strOption (long "json-api-option" <> metavar "JSON_API_OPTION" <> help "Pass option to HTTP JSON API")))
|
jsonApiOptions <- many (strOption (long "json-api-option" <> metavar "JSON_API_OPTION" <> help "Pass option to HTTP JSON API"))
|
||||||
<*> (ScriptOptions <$> many (strOption (long "script-option" <> metavar "SCRIPT_OPTION" <> help "Pass option to Daml script interpreter")))
|
scriptOptions <- many (strOption (long "script-option" <> metavar "SCRIPT_OPTION" <> help "Pass option to Daml script interpreter"))
|
||||||
<*> stdinCloseOpt
|
shutdownStdinClose <- stdinCloseOpt
|
||||||
<*> (SandboxClassic <$> switch (long "sandbox-classic" <> help "Deprecated. Run with Sandbox Classic."))
|
sandboxClassic <- SandboxClassic <$> switch (long "sandbox-classic" <> help "Deprecated. Run with Sandbox Classic.")
|
||||||
|
pure $ Start StartOptions{..} shutdownStdinClose
|
||||||
navigatorFlag =
|
|
||||||
-- We do not use flagYesNoAuto here since that doesn’t allow us to differentiate
|
|
||||||
-- if the flag was passed explicitly or not.
|
|
||||||
StartNavigator <$>
|
|
||||||
option reader (long "start-navigator" <> help helpText <> completeWith ["true", "false"] <> idm)
|
|
||||||
where
|
|
||||||
reader = eitherReader $ \case
|
|
||||||
-- We allow for both yes and true since we want a boolean in daml.yaml
|
|
||||||
"true" -> Right True
|
|
||||||
"yes" -> Right True
|
|
||||||
"false" -> Right False
|
|
||||||
"no" -> Right False
|
|
||||||
"auto" -> Right True
|
|
||||||
s -> Left ("Expected \"yes\", \"true\", \"no\", \"false\" or \"auto\" but got " <> show s)
|
|
||||||
-- To make things less confusing, we do not mention yes, no and auto here.
|
|
||||||
helpText = "Start navigator as part of daml start. Can be set to true or false. Defaults to true."
|
|
||||||
|
|
||||||
navigatorPortOption = NavigatorPort <$> option auto
|
navigatorPortOption = NavigatorPort <$> option auto
|
||||||
(long "navigator-port"
|
(long "navigator-port"
|
||||||
@ -475,19 +448,7 @@ runCommand = \case
|
|||||||
ListTemplates -> runListTemplates
|
ListTemplates -> runListTemplates
|
||||||
Start {..} ->
|
Start {..} ->
|
||||||
(if shutdownStdinClose then withCloseOnStdin else id) $
|
(if shutdownStdinClose then withCloseOnStdin else id) $
|
||||||
runStart
|
runStart startOptions
|
||||||
sandboxPortM
|
|
||||||
startNavigator
|
|
||||||
navigatorPort
|
|
||||||
jsonApiCfg
|
|
||||||
openBrowser
|
|
||||||
onStartM
|
|
||||||
waitForSignal
|
|
||||||
sandboxOptions
|
|
||||||
navigatorOptions
|
|
||||||
jsonApiOptions
|
|
||||||
scriptOptions
|
|
||||||
sandboxClassic
|
|
||||||
Deploy {..} -> runDeploy flags
|
Deploy {..} -> runDeploy flags
|
||||||
LedgerListParties {..} -> runLedgerListParties flags json
|
LedgerListParties {..} -> runLedgerListParties flags json
|
||||||
PackagesList {..} -> runLedgerListPackages0 flags
|
PackagesList {..} -> runLedgerListPackages0 flags
|
||||||
|
@ -8,19 +8,13 @@ module DA.Daml.Helper.Start
|
|||||||
, withSandbox
|
, withSandbox
|
||||||
, withNavigator
|
, withNavigator
|
||||||
|
|
||||||
|
, StartOptions(..)
|
||||||
, NavigatorPort(..)
|
, NavigatorPort(..)
|
||||||
, SandboxPort(..)
|
, SandboxPort(..)
|
||||||
, SandboxPortSpec(..)
|
, SandboxPortSpec(..)
|
||||||
, toSandboxPortSpec
|
, toSandboxPortSpec
|
||||||
, JsonApiPort(..)
|
, JsonApiPort(..)
|
||||||
, JsonApiConfig(..)
|
, JsonApiConfig(..)
|
||||||
, OpenBrowser(..)
|
|
||||||
, StartNavigator(..)
|
|
||||||
, WaitForSignal(..)
|
|
||||||
, SandboxOptions(..)
|
|
||||||
, NavigatorOptions(..)
|
|
||||||
, JsonApiOptions(..)
|
|
||||||
, ScriptOptions(..)
|
|
||||||
, SandboxClassic(..)
|
, SandboxClassic(..)
|
||||||
) where
|
) where
|
||||||
|
|
||||||
@ -46,6 +40,8 @@ import Web.Browser
|
|||||||
import qualified Web.JWT as JWT
|
import qualified Web.JWT as JWT
|
||||||
import Data.Aeson
|
import Data.Aeson
|
||||||
|
|
||||||
|
import Options.Applicative.Extended (YesNoAuto, determineAutoM)
|
||||||
|
|
||||||
import DA.Daml.Helper.Codegen
|
import DA.Daml.Helper.Codegen
|
||||||
import DA.Daml.Helper.Ledger
|
import DA.Daml.Helper.Ledger
|
||||||
import DA.Daml.Helper.Util
|
import DA.Daml.Helper.Util
|
||||||
@ -153,23 +149,10 @@ withJsonApi (SandboxPort sandboxPort) (JsonApiPort jsonApiPort) extraArgs a = do
|
|||||||
waitForHttpServer (putStr "." *> threadDelay 500000) ("http://localhost:" <> show jsonApiPort <> "/v1/query") headers
|
waitForHttpServer (putStr "." *> threadDelay 500000) ("http://localhost:" <> show jsonApiPort <> "/v1/query") headers
|
||||||
a ph
|
a ph
|
||||||
|
|
||||||
-- | Whether `daml start` should open a browser automatically.
|
|
||||||
newtype OpenBrowser = OpenBrowser Bool
|
|
||||||
|
|
||||||
-- | Whether `daml start` should start the navigator automatically.
|
|
||||||
newtype StartNavigator = StartNavigator Bool
|
|
||||||
|
|
||||||
data JsonApiConfig = JsonApiConfig
|
data JsonApiConfig = JsonApiConfig
|
||||||
{ mbJsonApiPort :: Maybe JsonApiPort -- If Nothing, don’t start the JSON API
|
{ mbJsonApiPort :: Maybe JsonApiPort -- If Nothing, don’t start the JSON API
|
||||||
}
|
}
|
||||||
|
|
||||||
-- | Whether `daml start` should wait for Ctrl+C or interrupt after starting servers.
|
|
||||||
newtype WaitForSignal = WaitForSignal Bool
|
|
||||||
|
|
||||||
newtype SandboxOptions = SandboxOptions [String]
|
|
||||||
newtype NavigatorOptions = NavigatorOptions [String]
|
|
||||||
newtype JsonApiOptions = JsonApiOptions [String]
|
|
||||||
newtype ScriptOptions = ScriptOptions [String]
|
|
||||||
newtype SandboxClassic = SandboxClassic { unSandboxClassic :: Bool }
|
newtype SandboxClassic = SandboxClassic { unSandboxClassic :: Bool }
|
||||||
|
|
||||||
withOptsFromProjectConfig :: T.Text -> [String] -> ProjectConfig -> IO [String]
|
withOptsFromProjectConfig :: T.Text -> [String] -> ProjectConfig -> IO [String]
|
||||||
@ -180,35 +163,24 @@ withOptsFromProjectConfig fieldName cliOpts projectConfig = do
|
|||||||
queryProjectConfig [fieldName] projectConfig
|
queryProjectConfig [fieldName] projectConfig
|
||||||
pure (optsYaml ++ cliOpts)
|
pure (optsYaml ++ cliOpts)
|
||||||
|
|
||||||
|
data StartOptions = StartOptions
|
||||||
|
{ sandboxPortM :: Maybe SandboxPortSpec
|
||||||
|
, shouldOpenBrowser :: Bool
|
||||||
|
, shouldStartNavigator :: YesNoAuto
|
||||||
|
, navigatorPort :: NavigatorPort
|
||||||
|
, jsonApiConfig :: JsonApiConfig
|
||||||
|
, onStartM :: Maybe String
|
||||||
|
, shouldWaitForSignal :: Bool
|
||||||
|
, sandboxOptions :: [String]
|
||||||
|
, navigatorOptions :: [String]
|
||||||
|
, jsonApiOptions :: [String]
|
||||||
|
, scriptOptions :: [String]
|
||||||
|
, sandboxClassic :: SandboxClassic
|
||||||
|
}
|
||||||
|
|
||||||
runStart
|
runStart :: StartOptions -> IO ()
|
||||||
:: Maybe SandboxPortSpec
|
runStart StartOptions{..} =
|
||||||
-> Maybe StartNavigator
|
withProjectRoot Nothing (ProjectCheck "daml start" True) $ \_ _ -> do
|
||||||
-> NavigatorPort
|
|
||||||
-> JsonApiConfig
|
|
||||||
-> OpenBrowser
|
|
||||||
-> Maybe String
|
|
||||||
-> WaitForSignal
|
|
||||||
-> SandboxOptions
|
|
||||||
-> NavigatorOptions
|
|
||||||
-> JsonApiOptions
|
|
||||||
-> ScriptOptions
|
|
||||||
-> SandboxClassic
|
|
||||||
-> IO ()
|
|
||||||
runStart
|
|
||||||
sandboxPortM
|
|
||||||
mbStartNavigator
|
|
||||||
navigatorPort
|
|
||||||
(JsonApiConfig mbJsonApiPort)
|
|
||||||
(OpenBrowser shouldOpenBrowser)
|
|
||||||
onStartM
|
|
||||||
(WaitForSignal shouldWaitForSignal)
|
|
||||||
(SandboxOptions sandboxOpts)
|
|
||||||
(NavigatorOptions navigatorOpts)
|
|
||||||
(JsonApiOptions jsonApiOpts)
|
|
||||||
(ScriptOptions scriptOpts)
|
|
||||||
sandboxClassic
|
|
||||||
= withProjectRoot Nothing (ProjectCheck "daml start" True) $ \_ _ -> do
|
|
||||||
projectConfig <- getProjectConfig Nothing
|
projectConfig <- getProjectConfig Nothing
|
||||||
darPath <- getDarPath
|
darPath <- getDarPath
|
||||||
mbScenario :: Maybe String <-
|
mbScenario :: Maybe String <-
|
||||||
@ -217,17 +189,15 @@ runStart
|
|||||||
mbInitScript :: Maybe String <-
|
mbInitScript :: Maybe String <-
|
||||||
requiredE "Failed to parse init-script" $
|
requiredE "Failed to parse init-script" $
|
||||||
queryProjectConfig ["init-script"] projectConfig
|
queryProjectConfig ["init-script"] projectConfig
|
||||||
shouldStartNavigator :: Bool <- case mbStartNavigator of
|
shouldStartNavigator :: Bool <-
|
||||||
-- If an option is passed explicitly, we use it, otherwise we read daml.yaml.
|
determineAutoM (fmap (fromMaybe True) $
|
||||||
Nothing ->
|
requiredE "Failed to parse start-navigator" $
|
||||||
fmap (fromMaybe True) $
|
queryProjectConfig ["start-navigator"] projectConfig)
|
||||||
requiredE "Failed to parse start-navigator" $
|
shouldStartNavigator
|
||||||
queryProjectConfig ["start-navigator"] projectConfig
|
sandboxOpts <- withOptsFromProjectConfig "sandbox-options" sandboxOptions projectConfig
|
||||||
Just (StartNavigator explicit) -> pure explicit
|
navigatorOpts <- withOptsFromProjectConfig "navigator-options" navigatorOptions projectConfig
|
||||||
sandboxOpts <- withOptsFromProjectConfig "sandbox-options" sandboxOpts projectConfig
|
jsonApiOpts <- withOptsFromProjectConfig "json-api-options" jsonApiOptions projectConfig
|
||||||
navigatorOpts <- withOptsFromProjectConfig "navigator-options" navigatorOpts projectConfig
|
scriptOpts <- withOptsFromProjectConfig "script-options" scriptOptions projectConfig
|
||||||
jsonApiOpts <- withOptsFromProjectConfig "json-api-options" jsonApiOpts projectConfig
|
|
||||||
scriptOpts <- withOptsFromProjectConfig "script-options" scriptOpts projectConfig
|
|
||||||
doBuild
|
doBuild
|
||||||
doCodegen projectConfig
|
doCodegen projectConfig
|
||||||
let scenarioArgs = maybe [] (\scenario -> ["--scenario", scenario]) mbScenario
|
let scenarioArgs = maybe [] (\scenario -> ["--scenario", scenario]) mbScenario
|
||||||
@ -266,7 +236,7 @@ runStart
|
|||||||
then withNavigator
|
then withNavigator
|
||||||
else (\_ _ _ f -> f sandboxPh)
|
else (\_ _ _ f -> f sandboxPh)
|
||||||
withJsonApi' sandboxPh sandboxPort args f =
|
withJsonApi' sandboxPh sandboxPort args f =
|
||||||
case mbJsonApiPort of
|
case mbJsonApiPort jsonApiConfig of
|
||||||
Nothing -> f sandboxPh
|
Nothing -> f sandboxPh
|
||||||
Just jsonApiPort -> withJsonApi sandboxPort jsonApiPort args f
|
Just jsonApiPort -> withJsonApi sandboxPort jsonApiPort args f
|
||||||
doCodegen projectConfig =
|
doCodegen projectConfig =
|
||||||
|
@ -7,6 +7,7 @@ module Options.Applicative.Extended
|
|||||||
, flagYesNoAuto
|
, flagYesNoAuto
|
||||||
, flagYesNoAuto'
|
, flagYesNoAuto'
|
||||||
, determineAuto
|
, determineAuto
|
||||||
|
, determineAutoM
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Options.Applicative
|
import Options.Applicative
|
||||||
@ -25,16 +26,25 @@ determineAuto b = \case
|
|||||||
Auto -> b
|
Auto -> b
|
||||||
Yes -> True
|
Yes -> True
|
||||||
|
|
||||||
|
-- | Convert YesNoAuto value to Bool by specifying how default value for Auto should be determined, in a monad.
|
||||||
|
determineAutoM :: Monad m => m Bool -> YesNoAuto -> m Bool
|
||||||
|
determineAutoM m = \case
|
||||||
|
No -> pure False
|
||||||
|
Auto -> m
|
||||||
|
Yes -> pure True
|
||||||
|
|
||||||
-- | This constructs flags that can be set to yes, no, or auto, with auto being the default.
|
-- | This constructs flags that can be set to yes, no, or auto, with auto being the default.
|
||||||
-- This maps yes to "Just true", no to "Just False" and auto to "Nothing"
|
-- This maps yes to "Just true", no to "Just False" and auto to "Nothing"
|
||||||
flagYesNoAuto' :: String -> String -> Mod OptionFields YesNoAuto -> Parser YesNoAuto
|
flagYesNoAuto' :: String -> String -> Mod OptionFields YesNoAuto -> Parser YesNoAuto
|
||||||
flagYesNoAuto' flagName helpText mods =
|
flagYesNoAuto' flagName helpText mods =
|
||||||
option reader (long flagName <> value Auto <> help helpText <> completeWith ["yes", "no", "auto"] <> mods)
|
option reader (long flagName <> value Auto <> help helpText <> completeWith ["true", "false", "yes", "no", "auto"] <> mods)
|
||||||
where reader = eitherReader $ \case
|
where reader = eitherReader $ \case
|
||||||
"yes" -> Right Yes
|
"yes" -> Right Yes
|
||||||
|
"true" -> Right Yes
|
||||||
"no" -> Right No
|
"no" -> Right No
|
||||||
|
"false" -> Right No
|
||||||
"auto" -> Right Auto
|
"auto" -> Right Auto
|
||||||
s -> Left ("Expected \"yes\", \"no\" or \"auto\" but got " <> show s)
|
s -> Left ("Expected \"yes\", \"true\", \"no\", \"false\", or \"auto\" but got " <> show s)
|
||||||
|
|
||||||
-- | This constructs flags that can be set to yes, no, or auto to control a boolean value
|
-- | This constructs flags that can be set to yes, no, or auto to control a boolean value
|
||||||
-- with auto using the default.
|
-- with auto using the default.
|
||||||
|
Loading…
Reference in New Issue
Block a user