Change next_proto member type.
[chromium-blink-merge.git] / tools / gn / command_check.cc
blob3d039506f2d20d549e6d779163cd8f3d9a91339a
1 // Copyright 2014 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.
5 #include "base/command_line.h"
6 #include "base/strings/stringprintf.h"
7 #include "tools/gn/commands.h"
8 #include "tools/gn/header_checker.h"
9 #include "tools/gn/setup.h"
10 #include "tools/gn/standard_out.h"
11 #include "tools/gn/switches.h"
12 #include "tools/gn/target.h"
13 #include "tools/gn/trace.h"
15 namespace commands {
17 const char kCheck[] = "check";
18 const char kCheck_HelpShort[] =
19 "check: Check header dependencies.";
20 const char kCheck_Help[] =
21 "gn check <out_dir> [<label_pattern>] [--force]\n"
22 "\n"
23 " \"gn check\" is the same thing as \"gn gen\" with the \"--check\" flag\n"
24 " except that this command does not write out any build files. It's\n"
25 " intended to be an easy way to manually trigger include file checking.\n"
26 "\n"
27 " The <label_pattern> can take exact labels or patterns that match more\n"
28 " than one (although not general regular expressions). If specified,\n"
29 " only those matching targets will be checked. See\n"
30 " \"gn help label_pattern\" for details.\n"
31 "\n"
32 " The .gn file may specify a list of targets to be checked. Only these\n"
33 " targets will be checked if no label_pattern is specified on the\n"
34 " command line. Otherwise, the command-line list is used instead. See\n"
35 " \"gn help dotfile\".\n"
36 "\n"
37 "Command-specific switches\n"
38 "\n"
39 " --force\n"
40 " Ignores specifications of \"check_includes = false\" and checks\n"
41 " all target's files that match the target label.\n"
42 "\n"
43 "Examples\n"
44 "\n"
45 " gn check out/Debug\n"
46 " Check everything.\n"
47 "\n"
48 " gn check out/Default //foo:bar\n"
49 " Check only the files in the //foo:bar target.\n"
50 "\n"
51 " gn check out/Default \"//foo/*\n"
52 " Check only the files in targets in the //foo directory tree.\n";
54 int RunCheck(const std::vector<std::string>& args) {
55 if (args.size() != 1 && args.size() != 2) {
56 Err(Location(), "You're holding it wrong.",
57 "Usage: \"gn check <out_dir> [<target_label>]\"").PrintToStdout();
58 return 1;
61 // Deliberately leaked to avoid expensive process teardown.
62 Setup* setup = new Setup();
63 if (!setup->DoSetup(args[0], false))
64 return 1;
65 if (!setup->Run())
66 return 1;
68 std::vector<const Target*> all_targets =
69 setup->builder()->GetAllResolvedTargets();
71 bool filtered_by_build_config = false;
72 std::vector<const Target*> targets_to_check;
73 if (args.size() == 2) {
74 // Compute the target to check.
75 if (!ResolveTargetsFromCommandLinePattern(setup, args[1], false,
76 &targets_to_check))
77 return 1;
78 if (targets_to_check.size() == 0) {
79 OutputString("No matching targets.\n");
80 return 1;
82 } else {
83 // No argument means to check everything allowed by the filter in
84 // the build config file.
85 if (setup->check_patterns()) {
86 FilterTargetsByPatterns(all_targets, *setup->check_patterns(),
87 &targets_to_check);
88 filtered_by_build_config = targets_to_check.size() != all_targets.size();
89 } else {
90 // No global filter, check everything.
91 targets_to_check = all_targets;
95 const CommandLine* cmdline = CommandLine::ForCurrentProcess();
96 bool force = cmdline->HasSwitch("force");
98 if (!CheckPublicHeaders(&setup->build_settings(), all_targets,
99 targets_to_check, force))
100 return 1;
102 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kQuiet)) {
103 if (filtered_by_build_config) {
104 // Tell the user about the implicit filtering since this is obscure.
105 OutputString(base::StringPrintf(
106 "%d targets out of %d checked based on the check_targets defined in"
107 " \".gn\".\n",
108 static_cast<int>(targets_to_check.size()),
109 static_cast<int>(all_targets.size())));
111 OutputString("Header dependency check OK\n", DECORATION_GREEN);
113 return 0;
116 bool CheckPublicHeaders(const BuildSettings* build_settings,
117 const std::vector<const Target*>& all_targets,
118 const std::vector<const Target*>& to_check,
119 bool force_check) {
120 ScopedTrace trace(TraceItem::TRACE_CHECK_HEADERS, "Check headers");
122 scoped_refptr<HeaderChecker> header_checker(
123 new HeaderChecker(build_settings, all_targets));
125 std::vector<Err> header_errors;
126 header_checker->Run(to_check, force_check, &header_errors);
127 for (size_t i = 0; i < header_errors.size(); i++) {
128 if (i > 0)
129 OutputString("___________________\n", DECORATION_YELLOW);
130 header_errors[i].PrintToStdout();
132 return header_errors.empty();
135 void FilterTargetsByPatterns(const std::vector<const Target*>& input,
136 const std::vector<LabelPattern>& filter,
137 std::vector<const Target*>* output) {
138 for (const auto& target : input) {
139 for (const auto& pattern : filter) {
140 if (pattern.Matches(target->label())) {
141 output->push_back(target);
142 break;
148 } // namespace commands