Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Side by Side Diff: tools/gn/command_path.cc

Issue 1130423006: Add a "gn path" command for finding deps. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/gn/BUILD.gn ('k') | tools/gn/commands.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/command_line.h"
6 #include "base/strings/stringprintf.h"
7 #include "tools/gn/commands.h"
8 #include "tools/gn/setup.h"
9 #include "tools/gn/standard_out.h"
10
11 namespace commands {
12
13 namespace {
14
15 enum DepType {
16 DEP_NONE,
17 DEP_PUBLIC,
18 DEP_PRIVATE,
19 DEP_DATA
20 };
21
22 // As we do a depth-first search, this vector will store the current path
23 // the current target for printing when a match is found.
24 using TargetDep = std::pair<const Target*, DepType>;
25 using DepStack = std::vector<TargetDep>;
26
27 void PrintDepStack(const DepStack& stack) {
28 // Don't print toolchains unless they differ from the first target.
29 const Label& default_toolchain = stack[0].first->label().GetToolchainLabel();
30
31 for (const auto& pair : stack) {
32 OutputString(pair.first->label().GetUserVisibleName(default_toolchain));
33 switch (pair.second) {
34 case DEP_NONE:
35 break;
36 case DEP_PUBLIC:
37 OutputString(" --[public]-->", DECORATION_DIM);
38 break;
39 case DEP_PRIVATE:
40 OutputString(" --[private]-->", DECORATION_DIM);
41 break;
42 case DEP_DATA:
43 OutputString(" --[data]-->", DECORATION_DIM);
44 break;
45 }
46 OutputString("\n");
47 }
48 OutputString("\n");
49 }
50
51 // Increments *found_count to reflect how many results are found. If print_all
52 // is not set, only the first result will be printed.
53 void RecursiveFindPath(const Target* current,
54 const Target* desired,
55 DepStack* stack,
56 int* found_count,
57 bool print_all) {
58 if (current == desired) {
59 (*found_count)++;
Dirk Pranke 2015/05/19 19:43:29 If I'm reading this correctly, this routine will s
brettw 2015/05/19 21:09:54 Correct. I want to find the number of items which
60 if (print_all || *found_count == 1) {
61 stack->push_back(TargetDep(current, DEP_NONE));
62 PrintDepStack(*stack);
63 stack->pop_back();
64 }
65 return;
66 }
67
68 stack->push_back(TargetDep(current, DEP_PUBLIC));
69 for (const auto& pair : current->public_deps())
70 RecursiveFindPath(pair.ptr, desired, stack, found_count, print_all);
71
72 stack->back().second = DEP_PRIVATE;
73 for (const auto& pair : current->private_deps())
74 RecursiveFindPath(pair.ptr, desired, stack, found_count, print_all);
75
76 stack->back().second = DEP_DATA;
77 for (const auto& pair : current->data_deps())
78 RecursiveFindPath(pair.ptr, desired, stack, found_count, print_all);
79 stack->pop_back();
80 }
81
82 } // namespace
83
84 const char kPath[] = "path";
85 const char kPath_HelpShort[] =
86 "path: Find paths between two targets.";
87 const char kPath_Help[] =
88 "gn path <out_dir> <target_one> <target_two>\n"
89 "\n"
90 " Finds paths of dependencies between two targets. Each unique path\n"
91 " will be printed in one group, and groups will be separate by newlines.\n"
92 " The two targets can appear in either order: paths will be found going\n"
93 " in either direction.\n"
94 "\n"
95 " Each dependency will be annotated with its type. By default, only the\n"
96 " first path encountered will be printed, which is not necessarily the\n"
97 " shortest path.\n"
98 "\n"
99 "Options\n"
100 "\n"
101 " --all\n"
102 " Prints all paths found rather than just the first one.\n"
103 "\n"
104 "Example\n"
105 "\n"
106 " gn path out/Default //base //tools/gn\n";
107
108 int RunPath(const std::vector<std::string>& args) {
109 if (args.size() != 3) {
110 Err(Location(), "You're holding it wrong.",
111 "Usage: \"gn path <out_dir> <target_one> <target_two>\"")
112 .PrintToStdout();
113 return 1;
114 }
115
116 Setup* setup = new Setup;
117 if (!setup->DoSetup(args[0], false))
118 return 1;
119 if (!setup->Run())
120 return 1;
121
122 const Target* target1 = ResolveTargetFromCommandLineString(setup, args[1]);
123 if (!target1)
124 return 1;
125 const Target* target2 = ResolveTargetFromCommandLineString(setup, args[2]);
126 if (!target2)
127 return 1;
128
129 bool print_all = base::CommandLine::ForCurrentProcess()->HasSwitch("all");
130
131 // If we don't find a path going "forwards", try the reverse direction. Deps
132 // can only go in one direction without having a cycle, which will have
133 // caused a run failure above.
134 DepStack stack;
135 int found = 0;
136 RecursiveFindPath(target1, target2, &stack, &found, print_all);
137 if (found == 0)
138 RecursiveFindPath(target2, target1, &stack, &found, print_all);
139
140 if (found == 0) {
141 OutputString("No paths found between these two targets.\n",
142 DECORATION_YELLOW);
143 } else if (found == 1) {
144 OutputString("1 path found.\n", DECORATION_YELLOW);
145 } else {
146 if (print_all) {
147 OutputString(base::StringPrintf("%d unique paths found.\n", found),
148 DECORATION_YELLOW);
149 } else {
150 OutputString(
151 base::StringPrintf("Showing the first of %d unique paths. ", found),
152 DECORATION_YELLOW);
153 OutputString("Use --all to print all paths.\n");
154 }
155 }
156 return 0;
157 }
158
159 } // namespace commands
OLDNEW
« no previous file with comments | « tools/gn/BUILD.gn ('k') | tools/gn/commands.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698