From 6beba62d56ab31927ef1ad7671ab52800ba51103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Wed, 10 Dec 2025 21:45:45 +0100 Subject: =?UTF-8?q?Accept=20literal=20text=20block=20for=20the=20=E2=80=98?= =?UTF-8?q?shell=E2=80=99=20section?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changelog: Accept literal text block for the `shell` section --- README.md | 11 ++++++----- src/Config.hs | 17 +++++++++++------ src/Job.hs | 12 ++++++++++-- src/Job/Types.hs | 2 +- test/asset/run/norepo-basic.yaml | 11 +++++++++++ test/script/run.et | 20 ++++++++++++++------ 6 files changed, 53 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 0829ed6..ceb8255 100644 --- a/README.md +++ b/README.md @@ -17,22 +17,23 @@ Example: ``` job build: - shell: - - make + shell: | + ./configure + make artifact bin: path: build/example job test: uses: - build.bin - shell: - - ./build/example test + shell: | + ./build/example test ``` Each job is a map with the following attributes: `shell` -: List of shell commands to perform the job +: Shell script to perform the job. `artifact ` (optional) : Defines artifact `` produced by this job. Is itself defined as a dictionary. diff --git a/src/Config.hs b/src/Config.hs index fb3a828..40eb1e5 100644 --- a/src/Config.hs +++ b/src/Config.hs @@ -117,18 +117,23 @@ parseSingleCheckout = withMap "checkout definition" $ \m -> do parseMultipleCheckouts :: Node Pos -> Parser [ JobCheckout Declared ] parseMultipleCheckouts = withSeq "checkout definitions" $ fmap concat . mapM parseSingleCheckout -cabalJob :: Node Pos -> Parser [CreateProcess] +cabalJob :: Node Pos -> Parser [ Either CreateProcess Text ] cabalJob = withMap "cabal job" $ \m -> do ghcOptions <- m .:? "ghc-options" >>= \case Nothing -> return [] Just s -> withSeq "GHC option list" (mapM (withStr "GHC option" return)) s return - [ proc "cabal" $ concat [ ["build"], ("--ghc-option="++) . T.unpack <$> ghcOptions ] ] - -shellJob :: Node Pos -> Parser [CreateProcess] -shellJob = withSeq "shell commands" $ \xs -> do - fmap (map shell) $ forM xs $ withStr "shell command" $ return . T.unpack + [ Left $ proc "cabal" $ concat [ ["build"], ("--ghc-option="++) . T.unpack <$> ghcOptions ] ] + +shellJob :: Node Pos -> Parser [ Either CreateProcess Text ] +shellJob node = do + commands <- choice + [ withStr "shell commands" return node + , withSeq "shell commands" (\xs -> do + fmap T.unlines $ forM xs $ withStr "shell command" $ return) node + ] + return [ Right commands ] parseArtifacts :: Mapping Pos -> Parser [ ( ArtifactName, Pattern ) ] parseArtifacts m = do diff --git a/src/Job.hs b/src/Job.hs index 5a22d63..3fe75e6 100644 --- a/src/Job.hs +++ b/src/Job.hs @@ -38,6 +38,7 @@ import Data.Text qualified as T import Data.Text.IO qualified as T import System.Directory +import System.Environment import System.Exit import System.FilePath import System.FilePath.Glob @@ -424,14 +425,21 @@ runJob job uses checkoutPath jdir = do copyRecursive (aoutStorePath aout) target bracket (liftIO $ openFile (jdir "log") WriteMode) (liftIO . hClose) $ \logs -> do - forM_ (fromMaybe [] $ jobRecipe job) $ \p -> do + forM_ (fromMaybe [] $ jobRecipe job) $ \ep -> do + ( p, input ) <- case ep of + Left p -> return ( p, "" ) + Right script -> do + sh <- fromMaybe "/bin/sh" <$> liftIO (lookupEnv "SHELL") + return ( proc sh [], script ) (Just hin, _, _, hp) <- liftIO $ createProcess_ "" p { cwd = Just checkoutPath , std_in = CreatePipe , std_out = UseHandle logs , std_err = UseHandle logs } - liftIO $ hClose hin + liftIO $ void $ forkIO $ do + T.hPutStr hin input + hClose hin liftIO (waitForProcess hp) >>= \case ExitSuccess -> return () ExitFailure n diff --git a/src/Job/Types.hs b/src/Job/Types.hs index 5d3f0f3..262a267 100644 --- a/src/Job/Types.hs +++ b/src/Job/Types.hs @@ -20,7 +20,7 @@ data Job' d = Job { jobId :: JobId' d , jobName :: JobName , jobCheckout :: [ JobCheckout d ] - , jobRecipe :: Maybe [ CreateProcess ] + , jobRecipe :: Maybe [ Either CreateProcess Text ] , jobArtifacts :: [ ( ArtifactName, Pattern ) ] , jobUses :: [ ArtifactSpec ] , jobPublish :: [ JobPublish d ] diff --git a/test/asset/run/norepo-basic.yaml b/test/asset/run/norepo-basic.yaml index 2000858..ecd3a97 100644 --- a/test/asset/run/norepo-basic.yaml +++ b/test/asset/run/norepo-basic.yaml @@ -7,3 +7,14 @@ job failure: checkout: null shell: - "false" + +job block_recipe: + checkout: null + shell: | + mkdir dir + cd dir + export VAR='abc' + echo $VAR > var + + artifact out: + path: dir/var diff --git a/test/script/run.et b/test/script/run.et index f00a4a7..3e13ca1 100644 --- a/test/script/run.et +++ b/test/script/run.et @@ -8,12 +8,20 @@ asset scripts: test RunWithoutRepo: node n - spawn on n as p args [ "--storage=.minici", "${scripts.path}/norepo-basic.yaml", "run", "success", "failure" ] - expect_result from p: - of "success" result "done" - of "failure" result "failed" - expect /(.*)/ from p capture done - guard (done == "run-finish") + local: + spawn on n as p args [ "--storage=.minici", "${scripts.path}/norepo-basic.yaml", "run", "success", "failure", "block_recipe" ] + expect_result from p: + of "success" result "done" + of "failure" result "failed" + of "block_recipe" result "done" + expect /(.*)/ from p capture done + guard (done == "run-finish") + local: + spawn on n as p args [ "--storage=.minici", "${scripts.path}/norepo-basic.yaml", "extract", "block_recipe.out", "." ] + local: + shell on n as s: + cat var + expect /abc/ from s test RunWithRepo: -- cgit v1.2.3