blob: f5f96b47c09a47d5d2d231620b75fba9c5ea3105 [file] [log] [blame]
// 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