[metadata] Adding `meta` command Change-Id: Ib2d436b647936cca989e0d14f387c1383ad5df57 Reviewed-on: https://gn-review.googlesource.com/c/3361 Commit-Queue: Julie Hockett <juliehockett@google.com> Reviewed-by: Brett Wilson <brettw@chromium.org>
diff --git a/build/gen.py b/build/gen.py index 82c15d1..b5c2fbe 100755 --- a/build/gen.py +++ b/build/gen.py
@@ -421,6 +421,7 @@ 'tools/gn/command_format.cc', 'tools/gn/command_gen.cc', 'tools/gn/command_help.cc', + 'tools/gn/command_meta.cc', 'tools/gn/command_ls.cc', 'tools/gn/command_path.cc', 'tools/gn/command_refs.cc',
diff --git a/tools/gn/command_meta.cc b/tools/gn/command_meta.cc new file mode 100644 index 0000000..f5f96b4 --- /dev/null +++ b/tools/gn/command_meta.cc
@@ -0,0 +1,134 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <algorithm> +#include <set> + +#include "base/command_line.h" +#include "base/strings/string_split.h" +#include "tools/gn/commands.h" +#include "tools/gn/metadata_walk.h" +#include "tools/gn/setup.h" +#include "tools/gn/standard_out.h" +#include "tools/gn/switches.h" +#include "tools/gn/target.h" + +namespace commands { + +const char kMeta[] = "meta"; +const char kMeta_HelpShort[] = "meta: List target metadata collection results."; +const char kMeta_Help[] = + R"(gn meta <out_dir> <target>* --data=<key>[,<key>*]* [--walk=<key>[,<key>*]*] + [--rebase] + + Lists collected metaresults of all given targets for the given data key(s), + collecting metadata dependencies as specified by the given walk key(s). + +Examples + + gn meta out/Debug "//base/foo" --data=files + Lists collected metaresults for the `files` key in the //base/foo:foo + target and all of its dependency tree. + + gn meta out/Debug "//base/foo" --data=files --data=other + Lists collected metaresults for the `files` and `other` keys in the + //base/foo:foo target and all of its dependency tree. + + gn meta out/Debug "//base/foo" --data=files --walk=stop + Lists collected metaresults for the `files` key in the //base/foo:foo + target and all of the dependencies listed in the `stop` key (and so on). + + gn meta out/Debug "//base/foo" --data=files --rebase-files + Lists collected metaresults for the `files` key in the //base/foo:foo + target and all of its dependency tree, rebasing the strings in the `files` + key onto the source directory of the target's declaration. +)"; + +int RunMeta(const std::vector<std::string>& args) { + if (args.size() == 0) { + Err(Location(), "You're holding it wrong.", + "Usage: \"gn meta <out_dir> <target>* --data=<key>[,<key>*] " + "[--walk=<key>[,<key>*]*] [--rebase-files]\"") + .PrintToStdout(); + return 1; + } + + Setup* setup = new Setup; + if (!setup->DoSetup(args[0], false) || !setup->Run()) + return 1; + + const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); + bool rebase_files = cmdline->HasSwitch(switches::kMetaRebaseFiles); + std::string data_keys_str = + cmdline->GetSwitchValueASCII(switches::kMetaDataKeys); + std::string walk_keys_str = + cmdline->GetSwitchValueASCII(switches::kMetaWalkKeys); + + std::vector<std::string> inputs(args.begin() + 1, args.end()); + + UniqueVector<const Target*> targets; + for (const auto& input : inputs) { + const Target* target = ResolveTargetFromCommandLineString(setup, input); + if (!target) { + Err(Location(), "Unknown target " + input).PrintToStdout(); + return 1; + } + targets.push_back(target); + } + + std::vector<std::string> data_keys = base::SplitString( + data_keys_str, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + if (data_keys.empty()) { + return 1; + } + std::vector<std::string> walk_keys = base::SplitString( + walk_keys_str, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + Err err; + std::set<const Target*> targets_walked; + std::vector<Value> result = WalkMetadata(targets, data_keys, walk_keys, + rebase_files, &targets_walked, &err); + if (err.has_error()) { + err.PrintToStdout(); + return 1; + } + + OutputString("Metadata values\n", DECORATION_DIM); + for (const auto& value : result) + OutputString("\n" + value.ToString(false) + "\n"); + + // TODO(juliehockett): We should have better dep tracing and error support for + // this. Also possibly data about where different values came from. + OutputString("\nExtracted from:\n", DECORATION_DIM); + bool first = true; + for (const auto* target : targets_walked) { + if (!first) { + first = false; + OutputString(", ", DECORATION_DIM); + } + OutputString(target->label().GetUserVisibleName(true) + "\n"); + } + OutputString("\nusing data keys:\n", DECORATION_DIM); + first = true; + for (const auto& key : data_keys) { + if (!first) { + first = false; + OutputString(", "); + } + OutputString(key + "\n"); + } + if (!walk_keys.empty()) { + OutputString("\nand using walk keys:\n", DECORATION_DIM); + first = true; + for (const auto& key : walk_keys) { + if (!first) { + first = false; + OutputString(", "); + } + OutputString(key + "\n"); + } + } + return 0; +} + +} // namespace commands
diff --git a/tools/gn/commands.cc b/tools/gn/commands.cc index 7fb496d..b7cd871 100644 --- a/tools/gn/commands.cc +++ b/tools/gn/commands.cc
@@ -386,6 +386,7 @@ INSERT_COMMAND(Gen) INSERT_COMMAND(Format) INSERT_COMMAND(Help) + INSERT_COMMAND(Meta) INSERT_COMMAND(Ls) INSERT_COMMAND(Path) INSERT_COMMAND(Refs)
diff --git a/tools/gn/commands.h b/tools/gn/commands.h index 7d6017e..71950e6 100644 --- a/tools/gn/commands.h +++ b/tools/gn/commands.h
@@ -69,6 +69,11 @@ extern const char kHelp_Help[]; int RunHelp(const std::vector<std::string>& args); +extern const char kMeta[]; +extern const char kMeta_HelpShort[]; +extern const char kMeta_Help[]; +int RunMeta(const std::vector<std::string>& args); + extern const char kLs[]; extern const char kLs_HelpShort[]; extern const char kLs_Help[];
diff --git a/tools/gn/switches.cc b/tools/gn/switches.cc index 1e0082c..f6a4704 100644 --- a/tools/gn/switches.cc +++ b/tools/gn/switches.cc
@@ -111,6 +111,39 @@ interpreter. )"; +const char kMetaDataKeys[] = "data"; +const char kMetaDataKeys_HelpShort[] = + "--data: list of data keys to concatenate when collecting metadata."; +const char kMetaDataKeys_Help[] = + R"(--data: list of data keys to concatenate when collecting metadata. + + Data keys identify which variables in the given targets' `metadata` + scopes should be collected. At least one data key must be specified. +)"; + +const char kMetaWalkKeys[] = "walk"; +const char kMetaWalkKeys_HelpShort[] = + "--walk: list of walk keys to traverse when collecting metadata."; +const char kMetaWalkKeys_Help[] = + R"(--walk: list of walk keys to traverse when collecting metadata. + + Walk keys identify which variables in the given targets' `metadata` + scopes contain the list of dependencies to walk next. Absence of any + walk keys indicates that all deps and data_deps should be walked. +)"; + +const char kMetaRebaseFiles[] = "rebase-files"; +const char kMetaRebaseFiles_HelpShort[] = + "--rebase-files (boolean): whether to rebase the paths of the collected " + "metadata."; +const char kMetaRebaseFiles_Help[] = + R"(--rebase-files: whether to rebase the paths of the collected metadata. + + This flag indicates whether or not to rebase the collected results onto their + declaring source directory path. Note that this requires the data key(s) to + contain only lists of strings, which will be interpreted as file names. +)"; + const char kQuiet[] = "q"; const char kQuiet_HelpShort[] = "-q: Quiet mode. Don't print output on success.";
diff --git a/tools/gn/switches.h b/tools/gn/switches.h index 1dc9828..d1abb1f 100644 --- a/tools/gn/switches.h +++ b/tools/gn/switches.h
@@ -47,6 +47,18 @@ extern const char kMarkdown_HelpShort[]; extern const char kMarkdown_Help[]; +extern const char kMetaDataKeys[]; +extern const char kMetaDataKeys_HelpShort[]; +extern const char kMetaDataKeys_Help[]; + +extern const char kMetaWalkKeys[]; +extern const char kMetaWalkKeys_HelpShort[]; +extern const char kMetaWalkKeys_Help[]; + +extern const char kMetaRebaseFiles[]; +extern const char kMetaRebaseFiles_HelpShort[]; +extern const char kMetaRebaseFiles_Help[]; + extern const char kNoColor[]; extern const char kNoColor_HelpShort[]; extern const char kNoColor_Help[];