packages feed

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 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 ()