hotel-california 0.0.1.0 → 0.0.2.0
raw patch · 5 files changed
+64/−20 lines, 5 filesdep +posix-escapePVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: posix-escape
API changes (from Hackage documentation)
- HotelCalifornia.Exec: [execArgsScript] :: ExecArgs -> NonEmpty String
+ HotelCalifornia.Exec: Proc :: NonEmpty String -> Subprocess
+ HotelCalifornia.Exec: Shell :: String -> Subprocess
+ HotelCalifornia.Exec: [execArgsSubprocess] :: ExecArgs -> Subprocess
+ HotelCalifornia.Exec: commandToProcessConfig :: Subprocess -> ProcessConfig () () ()
+ HotelCalifornia.Exec: commandToString :: Subprocess -> String
+ HotelCalifornia.Exec: data Subprocess
+ HotelCalifornia.Exec: parseProc :: Parser (NonEmpty String)
+ HotelCalifornia.Exec: parseShell :: Parser String
+ HotelCalifornia.Exec: parseSubprocess :: Parser Subprocess
- HotelCalifornia.Exec: ExecArgs :: NonEmpty String -> Maybe Text -> ExecArgs
+ HotelCalifornia.Exec: ExecArgs :: Subprocess -> Maybe Text -> ExecArgs
Files
- CHANGELOG.md +17/−1
- README.md +4/−4
- app/Main.hs +3/−2
- hotel-california.cabal +4/−1
- src/HotelCalifornia/Exec.hs +36/−12
CHANGELOG.md view
@@ -8,8 +8,24 @@ ## Unreleased +## 0.0.2.0 - 2023-09-15++- [#7](https://github.com/parsonsmatt/hotel-california/pull/7)+ - Fixed escaping of shell commands. Previously, single quotes would not be+ passed correctly, so a command like this:+ ```+ hotel exec -- cabal build --ghc-options='-Werror -ferror-spans'+ ```+ would get passed like `cabal ["build", "--ghc-options='-Werror'", "-ferror-spans'"]`.+ This is now fixed, and it will be properly passed as `cabal ["build", "--ghc-options='-Werror -ferrorspans'"]`.+ - CLI interface changed subtly - now, `hotel exec command [args]` will do a+ process lookup for `command`. If you want to pass a shell script, instead+ do:+ ```+ hotel exec --shell 'echo a && echo b || true'+ ```+ ## 0.0.1.0 - 2023-09-12 - Initial Release - Introduce `exec` functionality-
README.md view
@@ -10,7 +10,8 @@ ```sh $ hotel exec --help-Usage: hotel exec [-s|--span-name SPAN_NAME] SCRIPT [SCRIPT...]+Usage: hotel exec [-s|--span-name SPAN_NAME]+ (COMMAND [ARGUMENT]... | --shell SCRIPT) Execute the given command with tracing enabled @@ -18,9 +19,8 @@ -h,--help Show this help text -s,--span-name SPAN_NAME The name of the span that the program reports. By default, this is the script you pass in.- SCRIPT The command to run, along with any arguments. Best to- use -- before providing the script, otherwise it may- pass arguments to `hotel` instead of to your script+ --shell SCRIPT Run an arbitrary shell script instead of running an+ executable command ``` Currently, the program only looks in environment variables for configuration.
app/Main.hs view
@@ -24,7 +24,7 @@ info' :: Parser a -> String -> ParserInfo a info' p desc = info (helper <*> p)- (fullDesc <> progDesc desc)+ (fullDesc <> progDesc desc <> noIntersperse) parser' :: Parser Command parser' =@@ -48,7 +48,8 @@ main :: IO () main = do withGlobalTracing do- Command {..} <- execParser optionsParser+ let parserPrefs = defaultPrefs{ prefMultiSuffix = "..." }+ Command {..} <- customExecParser parserPrefs optionsParser case commandSubCommand of Exec execArgs -> runExecArgs execArgs
hotel-california.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: hotel-california-version: 0.0.1.0+version: 0.0.2.0 description: Please see the README on GitHub at <https://github.com/parsonsmatt/hotel-california#readme> homepage: https://github.com/parsonsmatt/hotel-california#readme bug-reports: https://github.com/parsonsmatt/hotel-california/issues@@ -82,6 +82,7 @@ , hs-opentelemetry-vendor-honeycomb , http-types , optparse-applicative+ , posix-escape , text , time , typed-process@@ -144,6 +145,7 @@ , hs-opentelemetry-vendor-honeycomb , http-types , optparse-applicative+ , posix-escape , text , time , typed-process@@ -207,6 +209,7 @@ , hs-opentelemetry-vendor-honeycomb , http-types , optparse-applicative+ , posix-escape , text , time , typed-process
src/HotelCalifornia/Exec.hs view
@@ -10,15 +10,43 @@ import HotelCalifornia.Tracing import HotelCalifornia.Tracing.TraceParent import System.Environment (getEnvironment)-import Options.Applicative+import qualified System.Posix.Escape.Unicode as Escape+import Options.Applicative hiding (command) import System.Exit import System.Process.Typed +data Subprocess = Proc (NonEmpty String) | Shell String++commandToString :: Subprocess -> String+commandToString (Proc tokens) = Escape.escapeMany (NEL.toList tokens)+commandToString (Shell line) = line++commandToProcessConfig :: Subprocess -> ProcessConfig () () ()+commandToProcessConfig (Proc (command :| args)) = proc command args+commandToProcessConfig (Shell line) = shell line+ data ExecArgs = ExecArgs- { execArgsScript :: NonEmpty String+ { execArgsSubprocess :: Subprocess , execArgsSpanName :: Maybe Text } +parseProc :: Parser (NonEmpty String)+parseProc = do+ command <- argument str (metavar "COMMAND")+ arguments <- many (argument str (metavar "ARGUMENT"))+ return (command :| arguments)++parseShell :: Parser String+parseShell =+ option str+ ( metavar "SCRIPT"+ <> long "shell"+ <> help "Run an arbitrary shell script instead of running an executable command"+ )++parseSubprocess :: Parser Subprocess+parseSubprocess = fmap Proc parseProc <|> fmap Shell parseShell+ parseExecArgs :: Parser ExecArgs parseExecArgs = do execArgsSpanName <- optional do@@ -28,17 +56,12 @@ , short 's' , help "The name of the span that the program reports. By default, this is the script you pass in." ]- execArgsScript1 <- argument str (metavar "SCRIPT" <> help "The command to run, along with any arguments. Best to use -- before providing the script, otherwise it may pass arguments to `hotel` instead of to your script")- execArgsScriptRest <- many $ argument str (metavar "SCRIPT...")- pure ExecArgs- { execArgsScript = execArgsScript1 :| execArgsScriptRest- , ..- }+ execArgsSubprocess <- parseSubprocess+ pure ExecArgs{..} runExecArgs :: ExecArgs -> IO () runExecArgs ExecArgs {..} = do- let script =- unwords $ NEL.toList execArgsScript+ let script = commandToString execArgsSubprocess spanName = fromMaybe (Text.pack script) execArgsSpanName @@ -46,8 +69,9 @@ newEnv <- spanContextToEnvironment span_ fullEnv <- mappend newEnv <$> getEnvironment - let processConfig = shell $ unwords $ NEL.toList execArgsScript- exitCode <- runProcess $ setEnv fullEnv $ processConfig+ let processConfig = commandToProcessConfig execArgsSubprocess++ exitCode <- runProcess $ setEnv fullEnv processConfig case exitCode of ExitSuccess -> pure ()