Update V8 to version 4.6.61.
[chromium-blink-merge.git] / tools / gn / command_check.cc
blob73660c9ec7be88e43f62ed63a6637854fcca9ab7
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() > 1) {
74 // Compute the targets to check.
75 std::vector<std::string> inputs(args.begin() + 1, args.end());
76 UniqueVector<const Target*> target_matches;
77 UniqueVector<const Config*> config_matches;
78 UniqueVector<const Toolchain*> toolchain_matches;
79 UniqueVector<SourceFile> file_matches;
80 if (!ResolveFromCommandLineInput(setup, inputs, false,
81 &target_matches, &config_matches,
82 &toolchain_matches, &file_matches))
83 return 1;
85 if (target_matches.size() == 0) {
86 OutputString("No matching targets.\n");
87 return 1;
89 targets_to_check.insert(targets_to_check.begin(),
90 target_matches.begin(), target_matches.end());
91 } else {
92 // No argument means to check everything allowed by the filter in
93 // the build config file.
94 if (setup->check_patterns()) {
95 FilterTargetsByPatterns(all_targets, *setup->check_patterns(),
96 &targets_to_check);
97 filtered_by_build_config = targets_to_check.size() != all_targets.size();
98 } else {
99 // No global filter, check everything.
100 targets_to_check = all_targets;
104 const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
105 bool force = cmdline->HasSwitch("force");
107 if (!CheckPublicHeaders(&setup->build_settings(), all_targets,
108 targets_to_check, force))
109 return 1;
111 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kQuiet)) {
112 if (filtered_by_build_config) {
113 // Tell the user about the implicit filtering since this is obscure.
114 OutputString(base::StringPrintf(
115 "%d targets out of %d checked based on the check_targets defined in"
116 " \".gn\".\n",
117 static_cast<int>(targets_to_check.size()),
118 static_cast<int>(all_targets.size())));
120 OutputString("Header dependency check OK\n", DECORATION_GREEN);
122 return 0;
125 bool CheckPublicHeaders(const BuildSettings* build_settings,
126 const std::vector<const Target*>& all_targets,
127 const std::vector<const Target*>& to_check,
128 bool force_check) {
129 ScopedTrace trace(TraceItem::TRACE_CHECK_HEADERS, "Check headers");
131 scoped_refptr<HeaderChecker> header_checker(
132 new HeaderChecker(build_settings, all_targets));
134 std::vector<Err> header_errors;
135 header_checker->Run(to_check, force_check, &header_errors);
136 for (size_t i = 0; i < header_errors.size(); i++) {
137 if (i > 0)
138 OutputString("___________________\n", DECORATION_YELLOW);
139 header_errors[i].PrintToStdout();
141 return header_errors.empty();
144 } // namespace commands