diff options
-rw-r--r-- | src/Config.hs | 7 | ||||
-rw-r--r-- | src/Job.hs | 38 | ||||
-rw-r--r-- | src/Job/Types.hs | 3 |
3 files changed, 29 insertions, 19 deletions
diff --git a/src/Config.hs b/src/Config.hs index 13be619..08bc3f2 100644 --- a/src/Config.hs +++ b/src/Config.hs @@ -23,6 +23,7 @@ import Data.YAML import System.Directory import System.FilePath +import System.FilePath.Glob import System.Process import Job.Types @@ -112,7 +113,7 @@ shellJob :: Node Pos -> Parser [CreateProcess] shellJob = withSeq "shell commands" $ \xs -> do fmap (map shell) $ forM xs $ withStr "shell command" $ return . T.unpack -parseArtifacts :: Mapping Pos -> Parser [(ArtifactName, CreateProcess)] +parseArtifacts :: Mapping Pos -> Parser [ ( ArtifactName, Pattern ) ] parseArtifacts m = do fmap catMaybes $ forM (M.assocs m) $ \case (Scalar _ (SStr tag), node) | ["artifact", name] <- T.words tag -> do @@ -120,8 +121,8 @@ parseArtifacts m = do _ -> return Nothing where parseArtifact name = withMap "Artifact" $ \am -> do - path <- am .: "path" - return (ArtifactName name, proc "echo" [ T.unpack path ]) + pat <- compile . T.unpack <$> am .: "path" + return ( ArtifactName name, pat ) parseUses :: Node Pos -> Parser [(JobName, ArtifactName)] parseUses = withSeq "Uses list" $ mapM $ @@ -31,6 +31,7 @@ import Data.Text.IO qualified as T import System.Directory import System.Exit import System.FilePath +import System.FilePath.Glob import System.IO import System.IO.Temp import System.Posix.Signals @@ -330,19 +331,26 @@ runJob job uses checkoutPath jdir = do | fromIntegral n == -sigINT -> throwError JobCancelled | otherwise -> throwError JobFailed - let adir = jdir </> "artifacts" - artifacts <- forM (jobArtifacts job) $ \(name@(ArtifactName tname), pathCmd) -> liftIO $ do - [path] <- lines <$> readCreateProcess pathCmd { cwd = Just checkoutPath } "" - let target = adir </> T.unpack tname - createDirectoryIfMissing True adir - copyFile (checkoutPath </> path) target - return $ ArtifactOutput - { aoutName = name - , aoutWorkPath = path - , aoutStorePath = target - } + let adir = jdir </> "artifacts" + artifacts <- forM (jobArtifacts job) $ \( name@(ArtifactName tname), pathPattern ) -> do + path <- liftIO (globDir1 pathPattern checkoutPath) >>= \case + [ path ] -> return path + found -> do + liftIO $ hPutStrLn logs $ + (if null found then "no file" else "multiple files") <> " found matching pattern `" <> + decompile pathPattern <> "' for artifact `" <> T.unpack tname <> "'" + throwError JobFailed + let target = adir </> T.unpack tname </> takeFileName path + liftIO $ do + createDirectoryIfMissing True $ takeDirectory target + copyFile (checkoutPath </> path) target + return $ ArtifactOutput + { aoutName = name + , aoutWorkPath = path + , aoutStorePath = target + } - return JobOutput - { outName = jobName job - , outArtifacts = artifacts - } + return JobOutput + { outName = jobName job + , outArtifacts = artifacts + } diff --git a/src/Job/Types.hs b/src/Job/Types.hs index 4de9ef9..0f91b94 100644 --- a/src/Job/Types.hs +++ b/src/Job/Types.hs @@ -3,6 +3,7 @@ module Job.Types where import Data.Text (Text) import Data.Text qualified as T +import System.FilePath.Glob import System.Process import Repo @@ -16,7 +17,7 @@ data Job' d = Job , jobContainingCheckout :: [ JobCheckout ] , jobOtherCheckout :: [ ( JobRepo d, Maybe Text, JobCheckout ) ] , jobRecipe :: [ CreateProcess ] - , jobArtifacts :: [ ( ArtifactName, CreateProcess ) ] + , jobArtifacts :: [ ( ArtifactName, Pattern ) ] , jobUses :: [ ( JobName, ArtifactName ) ] } |