diff options
author | Oliver Reiche <oliver.reiche@huawei.com> | 2022-07-22 11:43:45 +0200 |
---|---|---|
committer | Oliver Reiche <oliver.reiche@huawei.com> | 2022-07-27 18:01:04 +0200 |
commit | 6f1225fa7a94caa4ed5fcd3cfd7b8be93cc85072 (patch) | |
tree | 98c04c3ab93eebca5794785405e442f287e06043 /src | |
parent | b45653fac48af05a03a09271959b7f51fdeb5b83 (diff) | |
download | justbuild-6f1225fa7a94caa4ed5fcd3cfd7b8be93cc85072.tar.gz |
describe: Support describing by rule name
Diffstat (limited to 'src')
-rw-r--r-- | src/buildtool/common/cli.hpp | 13 | ||||
-rw-r--r-- | src/buildtool/main/main.cpp | 189 |
2 files changed, 119 insertions, 83 deletions
diff --git a/src/buildtool/common/cli.hpp b/src/buildtool/common/cli.hpp index a95cac5f..7bc0317a 100644 --- a/src/buildtool/common/cli.hpp +++ b/src/buildtool/common/cli.hpp @@ -49,6 +49,11 @@ struct AnalysisArguments { std::optional<std::filesystem::path> artifacts_to_build_file{}; }; +/// \brief Arguments required for describing targets/rules. +struct DescribeArguments { + bool describe_rule{}; +}; + /// \brief Arguments required for running diagnostics. struct DiagnosticArguments { std::optional<std::string> dump_actions{std::nullopt}; @@ -217,6 +222,14 @@ static inline auto SetupAnalysisArguments( } } +static inline auto SetupDescribeArguments( + gsl::not_null<CLI::App*> const& app, + gsl::not_null<DescribeArguments*> const& clargs) { + app->add_flag("--rule", + clargs->describe_rule, + "Positional arguments refer to rule instead of target."); +} + static inline auto SetupDiagnosticArguments( gsl::not_null<CLI::App*> const& app, gsl::not_null<DiagnosticArguments*> const& clargs) { diff --git a/src/buildtool/main/main.cpp b/src/buildtool/main/main.cpp index e9f2d72c..997fcd2f 100644 --- a/src/buildtool/main/main.cpp +++ b/src/buildtool/main/main.cpp @@ -58,6 +58,7 @@ struct CommandLineArguments { CommonArguments common; LogArguments log; AnalysisArguments analysis; + DescribeArguments describe; DiagnosticArguments diagnose; EndpointArguments endpoint; BuildArguments build; @@ -74,6 +75,7 @@ auto SetupDescribeCommandArguments( SetupCommonArguments(app, &clargs->common); SetupAnalysisArguments(app, &clargs->analysis, false); SetupLogArguments(app, &clargs->log); + SetupDescribeArguments(app, &clargs->describe); } /// \brief Setup arguments for sub command "just analyse". @@ -1221,89 +1223,34 @@ void PrintFields(nlohmann::json const& fields, } } -auto DescribeTarget(std::string const& main_repo, - std::optional<std::filesystem::path> const& main_ws_root, - std::size_t jobs, - AnalysisArguments const& clargs) -> int { +auto DetermineNonExplicitTarget( + std::string const& main_repo, + std::optional<std::filesystem::path> const& main_ws_root, + AnalysisArguments const& clargs) + -> std::optional<BuildMaps::Target::ConfiguredTarget> { auto id = ReadConfiguredTarget(clargs, main_repo, main_ws_root); - if (id.target.GetNamedTarget().reference_t == Base::ReferenceType::kFile) { - std::cout << id.ToString() << " is a source file." << std::endl; - return kExitSuccess; - } - auto targets_file_map = Base::CreateTargetsFileMap(jobs); - nlohmann::json targets_file{}; - bool failed{false}; - { - TaskSystem ts{jobs}; - targets_file_map.ConsumeAfterKeysReady( - &ts, - {id.target.ToModule()}, - [&targets_file](auto values) { targets_file = *values[0]; }, - [&failed](auto const& msg, bool fatal) { - Logger::Log(fatal ? LogLevel::Error : LogLevel::Warning, - "While searching for target description:\n{}", - msg); - failed = failed or fatal; - }); - } - if (failed) { - return kExitFailure; - } - auto desc_it = targets_file.find(id.target.GetNamedTarget().name); - if (desc_it == targets_file.end()) { - std::cout << id.ToString() << " is implicitly a source file." - << std::endl; - return kExitSuccess; - } - nlohmann::json desc = *desc_it; - auto rule_it = desc.find("type"); - if (rule_it == desc.end()) { - Logger::Log(LogLevel::Error, - "{} is a target without specified type.", - id.ToString()); - return kExitFailure; - } - if (BuildMaps::Target::IsBuiltInRule(*rule_it)) { - std::cout << id.ToString() << " is defined by built-in rule " - << rule_it->dump() << "." << std::endl; - if (*rule_it == "export") { - // export targets may have doc fields of their own. - auto doc = desc.find("doc"); - if (doc != desc.end()) { - PrintDoc(*doc, " | "); - } - auto config_doc = nlohmann::json::object(); - auto config_doc_it = desc.find("config_doc"); - if (config_doc_it != desc.end() and config_doc_it->is_object()) { - config_doc = *config_doc_it; - } - auto flexible_config = desc.find("flexible_config"); - if (flexible_config != desc.end() and - (not flexible_config->empty())) { - std::cout << " Flexible configuration variables\n"; - PrintFields(*flexible_config, config_doc, " - ", " | "); - } - } - return kExitSuccess; - } - auto rule_name = BuildMaps::Base::ParseEntityNameFromJson( - *rule_it, id.target, [&rule_it, &id](std::string const& parse_err) { - Logger::Log(LogLevel::Error, - "Parsing rule name {} for target {} failed with:\n{}.", - rule_it->dump(), - id.ToString(), - parse_err); - }); - if (not rule_name) { - return kExitFailure; + switch (id.target.GetNamedTarget().reference_t) { + case Base::ReferenceType::kFile: + std::cout << id.ToString() << " is a source file." << std::endl; + return std::nullopt; + case Base::ReferenceType::kTree: + std::cout << id.ToString() << " is a tree." << std::endl; + return std::nullopt; + case Base::ReferenceType::kTarget: + return id; } +} + +auto DescribeUserDefinedRule(BuildMaps::Base::EntityName const& rule_name, + std::size_t jobs) -> int { + bool failed{}; auto rule_file_map = Base::CreateRuleFileMap(jobs); nlohmann::json rules_file; { TaskSystem ts{jobs}; rule_file_map.ConsumeAfterKeysReady( &ts, - {rule_name->ToModule()}, + {rule_name.ToModule()}, [&rules_file](auto values) { rules_file = *values[0]; }, [&failed](auto const& msg, bool fatal) { Logger::Log(fatal ? LogLevel::Error : LogLevel::Warning, @@ -1315,15 +1262,13 @@ auto DescribeTarget(std::string const& main_repo, if (failed) { return kExitFailure; } - auto ruledesc_it = rules_file.find(rule_name->GetNamedTarget().name); + auto ruledesc_it = rules_file.find(rule_name.GetNamedTarget().name); if (ruledesc_it == rules_file.end()) { Logger::Log(LogLevel::Error, "Rule definition of {} is missing", - rule_name->ToString()); + rule_name.ToString()); return kExitFailure; } - std::cout << id.ToString() << " is defined by user-defined rule " - << rule_name->ToString() << ".\n\n"; auto const& rdesc = *ruledesc_it; auto doc = rdesc.find("doc"); if (doc != rdesc.end()) { @@ -1383,6 +1328,80 @@ auto DescribeTarget(std::string const& main_repo, return kExitSuccess; } +auto DescribeTarget(BuildMaps::Target::ConfiguredTarget const& id, + std::size_t jobs) -> int { + auto targets_file_map = Base::CreateTargetsFileMap(jobs); + nlohmann::json targets_file{}; + bool failed{false}; + { + TaskSystem ts{jobs}; + targets_file_map.ConsumeAfterKeysReady( + &ts, + {id.target.ToModule()}, + [&targets_file](auto values) { targets_file = *values[0]; }, + [&failed](auto const& msg, bool fatal) { + Logger::Log(fatal ? LogLevel::Error : LogLevel::Warning, + "While searching for target description:\n{}", + msg); + failed = failed or fatal; + }); + } + if (failed) { + return kExitFailure; + } + auto desc_it = targets_file.find(id.target.GetNamedTarget().name); + if (desc_it == targets_file.end()) { + std::cout << id.ToString() << " is implicitly a source file." + << std::endl; + return kExitSuccess; + } + nlohmann::json desc = *desc_it; + auto rule_it = desc.find("type"); + if (rule_it == desc.end()) { + Logger::Log(LogLevel::Error, + "{} is a target without specified type.", + id.ToString()); + return kExitFailure; + } + if (BuildMaps::Target::IsBuiltInRule(*rule_it)) { + std::cout << id.ToString() << " is defined by built-in rule " + << rule_it->dump() << "." << std::endl; + if (*rule_it == "export") { + // export targets may have doc fields of their own. + auto doc = desc.find("doc"); + if (doc != desc.end()) { + PrintDoc(*doc, " | "); + } + auto config_doc = nlohmann::json::object(); + auto config_doc_it = desc.find("config_doc"); + if (config_doc_it != desc.end() and config_doc_it->is_object()) { + config_doc = *config_doc_it; + } + auto flexible_config = desc.find("flexible_config"); + if (flexible_config != desc.end() and + (not flexible_config->empty())) { + std::cout << " Flexible configuration variables\n"; + PrintFields(*flexible_config, config_doc, " - ", " | "); + } + } + return kExitSuccess; + } + auto rule_name = BuildMaps::Base::ParseEntityNameFromJson( + *rule_it, id.target, [&rule_it, &id](std::string const& parse_err) { + Logger::Log(LogLevel::Error, + "Parsing rule name {} for target {} failed with:\n{}.", + rule_it->dump(), + id.ToString(), + parse_err); + }); + if (not rule_name) { + return kExitFailure; + } + std::cout << id.ToString() << " is defined by user-defined rule " + << rule_name->ToString() << ".\n\n"; + return DescribeUserDefinedRule(*rule_name, jobs); +} + void DumpArtifactsToBuild( std::map<std::string, ArtifactDescription> const& artifacts, std::map<std::string, ArtifactDescription> const& runfiles, @@ -1517,10 +1536,14 @@ auto main(int argc, char* argv[]) -> int { } } else if (arguments.cmd == SubCommand::kDescribe) { - return DescribeTarget(main_repo, - main_ws_root, - arguments.common.jobs, - arguments.analysis); + if (auto id = DetermineNonExplicitTarget( + main_repo, main_ws_root, arguments.analysis)) { + return arguments.describe.describe_rule + ? DescribeUserDefinedRule(id->target, + arguments.common.jobs) + : DescribeTarget(*id, arguments.common.jobs); + } + return kExitFailure; } else { |