summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2025-05-18 10:35:24 +0200
committerRoman Smrž <roman.smrz@seznam.cz>2025-05-20 22:03:55 +0200
commitaa9926074264d63aa6ceb2f3dd81e1fb9f9d0d29 (patch)
treee4d2b06e65fb11081fbc61787d05572cc904bc71
parent4ac26772681d74be2cbbf9376a02ebc395257c86 (diff)
Reflect dependencies in job id
-rw-r--r--src/Eval.hs25
-rw-r--r--test/asset/run/external.yaml42
-rw-r--r--test/script/run.et64
3 files changed, 123 insertions, 8 deletions
diff --git a/src/Eval.hs b/src/Eval.hs
index 013c074..05381dd 100644
--- a/src/Eval.hs
+++ b/src/Eval.hs
@@ -58,22 +58,30 @@ isDefaultRepoMissingInId djob
matches (JobIdCommit rname _) = isNothing rname
matches (JobIdTree rname _ _) = isNothing rname
-collectOtherRepos :: DeclaredJob -> Eval [ (( Maybe RepoName, Maybe Text ), FilePath ) ]
-collectOtherRepos decl = do
+collectOtherRepos :: DeclaredJobSet -> DeclaredJob -> Eval [ (( Maybe RepoName, Maybe Text ), FilePath ) ]
+collectOtherRepos dset decl = do
+ let dependencies = map fst $ jobUses decl
+ dependencyRepos <- forM dependencies $ \name -> do
+ jobs <- either (throwError . OtherEvalError . T.pack) return $ jobsetJobsEither dset
+ job <- maybe (throwError $ OtherEvalError $ "job ‘" <> textJobName name <> "’ not found") return . find ((name ==) . jobName) $ jobs
+ return $ jobOtherCheckout job
+
missingDefault <- isDefaultRepoMissingInId decl
+
let checkouts = concat
[ if missingDefault then map (( Nothing, Nothing ), ) $ jobContainingCheckout decl else []
, map (first (first Just)) $ jobOtherCheckout decl
+ , map (first (first Just)) $ concat dependencyRepos
]
let commonSubdir reporev = joinPath $ foldr1 commonPrefix $
map (maybe [] splitDirectories . jcSubtree . snd) . filter ((reporev ==) . fst) $ checkouts
return $ map (\r -> ( r, commonSubdir r )) . nub . map fst $ checkouts
-evalJob :: [ ( Maybe RepoName, Tree ) ] -> DeclaredJob -> Eval Job
-evalJob revisionOverrides decl = do
+evalJob :: [ ( Maybe RepoName, Tree ) ] -> DeclaredJobSet -> DeclaredJob -> Eval Job
+evalJob revisionOverrides dset decl = do
EvalInput {..} <- ask
- otherRepos <- collectOtherRepos decl
+ otherRepos <- collectOtherRepos dset decl
otherRepoTrees <- forM otherRepos $ \(( mbname, mbrev ), commonPath ) -> do
( mbname, ) . ( commonPath, ) <$> case lookup mbname revisionOverrides of
Just tree -> return tree
@@ -101,7 +109,7 @@ evalJob revisionOverrides decl = do
evalJobSet :: [ ( Maybe RepoName, Tree ) ] -> DeclaredJobSet -> Eval JobSet
evalJobSet revisionOverrides decl = do
- jobs <- either (return . Left) (handleToEither . mapM (evalJob revisionOverrides)) $ jobsetJobsEither decl
+ jobs <- either (return . Left) (handleToEither . mapM (evalJob revisionOverrides decl)) $ jobsetJobsEither decl
return JobSet
{ jobsetCommit = jobsetCommit decl
, jobsetJobsEither = jobs
@@ -121,9 +129,10 @@ evalRepo (Just name) = asks (lookup name . eiOtherRepos) >>= \case
canonicalJobName :: [ Text ] -> Config -> Eval JobId
canonicalJobName (r : rs) config = do
let name = JobName r
+ dset = JobSet Nothing $ Right $ configJobs config
case find ((name ==) . jobName) (configJobs config) of
Just djob -> do
- otherRepos <- collectOtherRepos djob
+ otherRepos <- collectOtherRepos dset djob
( overrides, rs' ) <- (\f -> foldM f ( [], rs ) otherRepos) $
\( overrides, crs ) (( mbname, _ ), path ) -> do
( tree, crs' ) <- readTreeFromIdRef crs path =<< evalRepo mbname
@@ -131,7 +140,7 @@ canonicalJobName (r : rs) config = do
case rs' of
(r' : _) -> throwError $ OtherEvalError $ "unexpected job ref part ‘" <> r' <> "’"
_ -> return ()
- jobId <$> evalJob overrides djob
+ jobId <$> evalJob overrides dset djob
Nothing -> throwError $ OtherEvalError $ "job ‘" <> r <> "’ not found"
canonicalJobName [] _ = throwError $ OtherEvalError "expected job name"
diff --git a/test/asset/run/external.yaml b/test/asset/run/external.yaml
new file mode 100644
index 0000000..f1d2b2c
--- /dev/null
+++ b/test/asset/run/external.yaml
@@ -0,0 +1,42 @@
+repo first:
+ path: ../first
+
+repo second:
+ path: ../second
+
+
+job single:
+ checkout:
+ repo: first
+ dest: first
+
+ shell:
+ - tar czf first.tar.gz first
+
+ artifact tarball:
+ path: ./first.tar.gz
+
+job multiple:
+ checkout:
+ - repo: first
+ dest: first-subdir
+ subtree: subdir
+ - repo: second
+ dest: second-subdir
+ subtree: sub
+
+ shell:
+ - tar czf pack.tar.gz first-subdir second-subdir
+
+ artifact tarball:
+ path: ./pack.tar.gz
+
+job combine:
+ checkout: null
+
+ shell:
+ - ls
+
+ uses:
+ - single.tarball
+ - multiple.tarball
diff --git a/test/script/run.et b/test/script/run.et
index 4f4e016..9efc0e7 100644
--- a/test/script/run.et
+++ b/test/script/run.et
@@ -10,6 +10,9 @@ def expect_result from p of job result result:
/job-finish $job ([a-z]+)/ capture done
guard (done == result)
+def expect_success from p of job:
+ expect_result from p of job result "done"
+
test RunWithouRepo:
node n
@@ -71,3 +74,64 @@ test RunWithRepo:
expect /(.*)/ from p capture done
guard (done == "run-finish")
+
+
+test RunExternalRepo:
+ node n
+ shell on n as git_init:
+ mkdir -p first/subdir
+ git -C first -c init.defaultBranch=master init -q
+ git -C first -c user.name=test -c user.email=test commit -q --allow-empty -m 'initial commit'
+ touch first/subdir/file
+ git -C first add subdir
+ git -C first -c user.name=test -c user.email=test commit -q -m 'commit'
+ git -C first rev-parse HEAD^{tree}
+ git -C first rev-parse HEAD:subdir
+
+ mkdir -p second/sub
+ git -C second -c init.defaultBranch=master init -q
+ git -C second -c user.name=test -c user.email=test commit -q --allow-empty -m 'initial commit'
+ touch second/sub/other
+ git -C second add sub
+ git -C second -c user.name=test -c user.email=test commit -q -m 'commit'
+ git -C second rev-parse HEAD^{tree}
+ git -C second rev-parse HEAD:sub
+
+ mkdir -p main
+ git -C main -c init.defaultBranch=master init -q
+ git -C main -c user.name=test -c user.email=test commit -q --allow-empty -m 'initial commit'
+ cp "${scripts.path}/external.yaml" main/minici.yaml
+ git -C main add minici.yaml
+ git -C main -c user.name=test -c user.email=test commit -q -m 'commit'
+ git -C main rev-parse HEAD^{tree}
+
+ expect /([0-9a-f]+)/ from git_init capture first_root
+ expect /([0-9a-f]+)/ from git_init capture first_subtree
+ expect /([0-9a-f]+)/ from git_init capture second_root
+ expect /([0-9a-f]+)/ from git_init capture second_subtree
+ expect /([0-9a-f]+)/ from git_init capture main_root
+
+ # Explicit jobfile outside of any git repo
+ local:
+ spawn on n as p args [ "--repo=first:./first", "--repo=second:./second", "${scripts.path}/external.yaml", "run", "single", "multiple", "combine" ]
+ for job in [ "single.$first_root", "multiple.$first_subtree.$second_subtree", "combine.$first_root.$second_subtree" ]:
+ expect_success from p of job
+
+ expect /(.*)/ from p capture done
+ guard (done == "run-finish")
+
+ # Explicit jobfile within a git repo
+ local:
+ spawn on n as p args [ "--repo=first:./first", "--repo=second:./second", "${scripts.path}/external.yaml", "run", "single" ]
+ expect_success from p of "single.$first_root"
+ expect /(.*)/ from p capture done
+ guard (done == "run-finish")
+
+ # Implicit jobfile within a git repo
+ local:
+ spawn on n as p args [ "--repo=first:./first", "--repo=second:./second", "./main", "run", "HEAD^..HEAD" ]
+ for job in [ "single.$first_root", "multiple.$first_subtree.$second_subtree", "combine.$first_root.$second_subtree" ]:
+ expect_success from p of "$main_root.$job"
+
+ expect /(.*)/ from p capture done
+ guard (done == "run-finish")