diff options
| -rw-r--r-- | src/Eval.hs | 25 | ||||
| -rw-r--r-- | test/asset/run/external.yaml | 42 | ||||
| -rw-r--r-- | test/script/run.et | 64 | 
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") |