Skip to content

Commit

Permalink
Fix inputs tool implementation.
Browse files Browse the repository at this point in the history
This uses the InputsCollector class introduced in the
previous patch to implement the tool properly. Results
are still shell-escaped and sorted alphabetically.

Fixed #2482
  • Loading branch information
digit-google committed Sep 2, 2024
1 parent 7e03348 commit 5b94d34
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 87 deletions.
21 changes: 21 additions & 0 deletions misc/output_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,27 @@ def test_tool_inputs(self) -> None:
out2
''')

# Verify that results are shell-escaped by default.
# Also verify that phony outputs are never part of the results.
quote = '"' if platform.system() == "Windows" else "'"

plan = '''
rule cat
command = cat $in $out
build out1 : cat in1
build out$ 2 : cat out1
build out$ 3 : phony out$ 2
build all: phony out$ 3
'''

self.assertEqual(run(plan, flags='-t inputs all'),
f'''{quote}out 2{quote}
in1
out1
''')



def test_explain_output(self):
b = BuildDir('''\
build .FORCE: phony
Expand Down
22 changes: 0 additions & 22 deletions src/graph.cc
Original file line number Diff line number Diff line change
Expand Up @@ -496,28 +496,6 @@ std::string EdgeEnv::MakePathList(const Node* const* const span,
return result;
}

void Edge::CollectInputs(bool shell_escape,
std::vector<std::string>* out) const {
for (std::vector<Node*>::const_iterator it = inputs_.begin();
it != inputs_.end(); ++it) {
std::string path = (*it)->PathDecanonicalized();
if (shell_escape) {
std::string unescaped;
unescaped.swap(path);
#ifdef _WIN32
GetWin32EscapedString(unescaped, &path);
#else
GetShellEscapedString(unescaped, &path);
#endif
}
#if __cplusplus >= 201103L
out->push_back(std::move(path));
#else
out->push_back(path);
#endif
}
}

std::string Edge::EvaluateCommand(const bool incl_rsp_file) const {
string command = GetBinding("command");
if (incl_rsp_file) {
Expand Down
3 changes: 0 additions & 3 deletions src/graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,6 @@ struct Edge {

void Dump(const char* prefix="") const;

// Append all edge explicit inputs to |*out|. Possibly with shell escaping.
void CollectInputs(bool shell_escape, std::vector<std::string>* out) const;

// critical_path_weight is the priority during build scheduling. The
// "critical path" between this edge's inputs and any target node is
// the path which maximises the sum oof weights along that path.
Expand Down
33 changes: 0 additions & 33 deletions src/graph_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -215,39 +215,6 @@ TEST_F(GraphTest, RootNodes) {
}
}

TEST_F(GraphTest, CollectInputs) {
ASSERT_NO_FATAL_FAILURE(AssertParse(
&state_,
"build out$ 1: cat in1 in2 in$ with$ space | implicit || order_only\n"));

std::vector<std::string> inputs;
Edge* edge = GetNode("out 1")->in_edge();

// Test without shell escaping.
inputs.clear();
edge->CollectInputs(false, &inputs);
EXPECT_EQ(5u, inputs.size());
EXPECT_EQ("in1", inputs[0]);
EXPECT_EQ("in2", inputs[1]);
EXPECT_EQ("in with space", inputs[2]);
EXPECT_EQ("implicit", inputs[3]);
EXPECT_EQ("order_only", inputs[4]);

// Test with shell escaping.
inputs.clear();
edge->CollectInputs(true, &inputs);
EXPECT_EQ(5u, inputs.size());
EXPECT_EQ("in1", inputs[0]);
EXPECT_EQ("in2", inputs[1]);
#ifdef _WIN32
EXPECT_EQ("\"in with space\"", inputs[2]);
#else
EXPECT_EQ("'in with space'", inputs[2]);
#endif
EXPECT_EQ("implicit", inputs[3]);
EXPECT_EQ("order_only", inputs[4]);
}

TEST_F(GraphTest, InputsCollector) {
// Build plan for the following graph:
//
Expand Down
42 changes: 13 additions & 29 deletions src/ninja.cc
Original file line number Diff line number Diff line change
Expand Up @@ -761,27 +761,12 @@ int NinjaMain::ToolCommands(const Options* options, int argc, char* argv[]) {
return 0;
}

void CollectInputs(Edge* edge, std::set<Edge*>* seen,
std::vector<std::string>* result) {
if (!edge)
return;
if (!seen->insert(edge).second)
return;

for (vector<Node*>::iterator in = edge->inputs_.begin();
in != edge->inputs_.end(); ++in)
CollectInputs((*in)->in_edge(), seen, result);

if (!edge->is_phony()) {
edge->CollectInputs(true, result);
}
}

int NinjaMain::ToolInputs(const Options* options, int argc, char* argv[]) {
// The inputs tool uses getopt, and expects argv[0] to contain the name of
// the tool, i.e. "inputs".
argc++;
argv--;

optind = 1;
int opt;
const option kLongOptions[] = { { "help", no_argument, NULL, 'h' },
Expand All @@ -794,8 +779,9 @@ int NinjaMain::ToolInputs(const Options* options, int argc, char* argv[]) {
printf(
"Usage '-t inputs [options] [targets]\n"
"\n"
"List all inputs used for a set of targets. Note that this includes\n"
"explicit, implicit and order-only inputs, but not validation ones.\n\n"
"List all inputs used for a set of targets.\n"
"Note that results are shell escaped, and sorted alphabetically,\n"
"and never include validation target paths.\n\n"
"Options:\n"
" -h, --help Print this message.\n");
// clang-format on
Expand All @@ -805,24 +791,22 @@ int NinjaMain::ToolInputs(const Options* options, int argc, char* argv[]) {
argv += optind;
argc -= optind;

vector<Node*> nodes;
string err;
std::vector<Node*> nodes;
std::string err;
if (!CollectTargetsFromArgs(argc, argv, &nodes, &err)) {
Error("%s", err.c_str());
return 1;
}

std::set<Edge*> seen;
std::vector<std::string> result;
for (vector<Node*>::iterator in = nodes.begin(); in != nodes.end(); ++in)
CollectInputs((*in)->in_edge(), &seen, &result);
InputsCollector collector;
for (const Node* node : nodes)
collector.VisitNode(node);

// Make output deterministic by sorting then removing duplicates.
std::sort(result.begin(), result.end());
result.erase(std::unique(result.begin(), result.end()), result.end());
std::vector<std::string> inputs = collector.GetInputsAsStrings(true);
std::sort(inputs.begin(), inputs.end());

for (size_t n = 0; n < result.size(); ++n)
puts(result[n].c_str());
for (const std::string& input : inputs)
puts(input.c_str());

return 0;
}
Expand Down

0 comments on commit 5b94d34

Please sign in to comment.