diff options
author | Klaus Aehlig <klaus.aehlig@huawei.com> | 2025-01-08 18:05:48 +0100 |
---|---|---|
committer | Klaus Aehlig <klaus.aehlig@huawei.com> | 2025-01-09 13:59:16 +0100 |
commit | 3c2877dd63698f6ef424538ed91ffa66144bf115 (patch) | |
tree | 60b9a40c708ff3e870dc915e01a974d1cbf78b91 /src | |
parent | 16d3b50a4f8d8f3de21297759467f47b6ff374f9 (diff) | |
download | justbuild-3c2877dd63698f6ef424538ed91ffa66144bf115.tar.gz |
just build: add new option -p
... allowing to print the unique artifact built (if any). This
allows convenient inspection of the build result of targets that
define precisely one artifact.
Diffstat (limited to 'src')
-rw-r--r-- | src/buildtool/common/cli.hpp | 5 | ||||
-rw-r--r-- | src/buildtool/computed_roots/evaluate.cpp | 1 | ||||
-rw-r--r-- | src/buildtool/graph_traverser/graph_traverser.hpp | 52 |
3 files changed, 54 insertions, 4 deletions
diff --git a/src/buildtool/common/cli.hpp b/src/buildtool/common/cli.hpp index 3c7ac45e..c6771cb3 100644 --- a/src/buildtool/common/cli.hpp +++ b/src/buildtool/common/cli.hpp @@ -114,6 +114,7 @@ struct BuildArguments { std::size_t build_jobs{}; std::optional<std::string> dump_artifacts{std::nullopt}; std::optional<std::string> print_to_stdout{std::nullopt}; + bool print_unique{false}; bool show_runfiles{false}; }; @@ -533,6 +534,10 @@ static inline auto SetupExtendedBuildArguments( clargs->print_to_stdout, "After building, print the specified artifact to stdout.") ->type_name("LOGICAL_PATH"); + + app->add_flag("-p,--print-unique-artifact", + clargs->print_unique, + "Print the unique artifact, if any, to stdout."); } static inline auto SetupTCArguments(gsl::not_null<CLI::App*> const& app, diff --git a/src/buildtool/computed_roots/evaluate.cpp b/src/buildtool/computed_roots/evaluate.cpp index 6c05aadb..ed1df8de 100644 --- a/src/buildtool/computed_roots/evaluate.cpp +++ b/src/buildtool/computed_roots/evaluate.cpp @@ -317,6 +317,7 @@ void ComputeAndFill( StageArguments{.output_dir = root_dir, .remember = true}; root_build_args.rebuild = std::nullopt; root_build_args.build.print_to_stdout = std::nullopt; + root_build_args.build.print_unique = false; root_build_args.build.dump_artifacts = std::nullopt; root_build_args.build.show_runfiles = false; auto root_exec_context = ExecutionContext{context->repo_config, diff --git a/src/buildtool/graph_traverser/graph_traverser.hpp b/src/buildtool/graph_traverser/graph_traverser.hpp index 51069c0b..3203f9c7 100644 --- a/src/buildtool/graph_traverser/graph_traverser.hpp +++ b/src/buildtool/graph_traverser/graph_traverser.hpp @@ -158,7 +158,13 @@ class GraphTraverser { rel_paths, artifact_nodes, runfile_descriptions); - MaybePrintToStdout(rel_paths, artifact_nodes); + MaybePrintToStdout( + rel_paths, + artifact_nodes, + artifact_descriptions.size() == 1 + ? std::optional<std::string>{artifact_descriptions.begin() + ->first} + : std::nullopt); return BuildResult{.output_paths = std::move(rel_paths), .extra_infos = std::move(infos), .failed_artifacts = failed_artifacts}; @@ -182,7 +188,13 @@ class GraphTraverser { artifact_nodes, runfile_descriptions); - MaybePrintToStdout(rel_paths, artifact_nodes); + MaybePrintToStdout( + rel_paths, + artifact_nodes, + artifact_descriptions.size() == 1 + ? std::optional<std::string>{artifact_descriptions.begin() + ->first} + : std::nullopt); return BuildResult{.output_paths = *output_paths, .extra_infos = std::move(infos), @@ -671,8 +683,8 @@ class GraphTraverser { void MaybePrintToStdout( std::vector<std::filesystem::path> const& paths, - std::vector<DependencyGraph::ArtifactNode const*> const& artifacts) - const { + std::vector<DependencyGraph::ArtifactNode const*> const& artifacts, + std::optional<std::string> const& unique_artifact) const { if (clargs_.build.print_to_stdout) { auto const& remote = *context_.apis->remote; for (std::size_t i = 0; i < paths.size(); i++) { @@ -751,6 +763,38 @@ class GraphTraverser { "{} not a logical path of the specified target", *(clargs_.build.print_to_stdout)); } + else if (clargs_.build.print_unique) { + if (unique_artifact) { + auto const& remote = *context_.apis->remote; + std::optional<Artifact::ObjectInfo> info = std::nullopt; + for (std::size_t i = 0; i < paths.size(); i++) { + if (paths[i] == unique_artifact) { + info = artifacts[i]->Content().Info(); + } + } + if (info) { + if (not remote.RetrieveToFds({*info}, + {dup(fileno(stdout))}, + /*raw_tree=*/false, + &*context_.apis->local)) { + Logger::Log(logger_, + LogLevel::Error, + "Failed to retrieve {}", + *unique_artifact); + } + } + else { + Logger::Log(logger_, + LogLevel::Error, + "Failed to obtain object information for {}", + *unique_artifact); + } + return; + } + Logger::Log(logger_, + LogLevel::Info, + "Target does not have precisely one artifact."); + } } }; |