Add no_check_targets config option. Bug: 179 Change-Id: I6c58caa95353554a99036d0a2111f42b5467501b Reviewed-on: https://gn-review.googlesource.com/c/gn/+/9120 Reviewed-by: Brett Wilson <brettw@chromium.org> Commit-Queue: Brett Wilson <brettw@chromium.org>
diff --git a/docs/reference.md b/docs/reference.md index 8d8d30e..ad1ef27 100644 --- a/docs/reference.md +++ b/docs/reference.md
@@ -383,8 +383,10 @@ ``` The .gn file may specify a list of targets to be checked in the list - check_targets (see "gn help dotfile"). If a label pattern is specified - on the command line, check_targets is not used. + check_targets (see "gn help dotfile"). Alternatively, the .gn file may + specify a list of targets not to be checked in no_check_targets. If a label + pattern is specified on the command line, neither check_targets or + no_check_targets is used. Targets can opt-out from checking with "check_includes = false" (see "gn help check_includes"). @@ -6593,9 +6595,21 @@ check_targets [optional] A list of labels and label patterns that should be checked when running - "gn check" or "gn gen --check". If unspecified, all targets will be - checked. If it is the empty list, no targets will be checked. To - bypass this list, request an explicit check of targets, like "//*". + "gn check" or "gn gen --check". If neither check_targets or + no_check_targets (see below) is specified, all targets will be checked. + It is an error to specify both check_targets and no_check_targets. If it + is the empty list, no targets will be checked. To bypass this list, + request an explicit check of targets, like "//*". + + The format of this list is identical to that of "visibility" so see "gn + help visibility" for examples. + + no_check_targets [optional] + A list of labels and label patterns that should *not* be checked when + running "gn check" or "gn gen --check". All other targets will be checked. + If neither check_targets (see above) or no_check_targets is specified, all + targets will be checked. It is an error to specify both check_targets and + no_check_targets. The format of this list is identical to that of "visibility" so see "gn help visibility" for examples.
diff --git a/src/gn/command_check.cc b/src/gn/command_check.cc index 98a5e1c..38a474c 100644 --- a/src/gn/command_check.cc +++ b/src/gn/command_check.cc
@@ -88,8 +88,10 @@ What gets checked The .gn file may specify a list of targets to be checked in the list - check_targets (see "gn help dotfile"). If a label pattern is specified - on the command line, check_targets is not used. + check_targets (see "gn help dotfile"). Alternatively, the .gn file may + specify a list of targets not to be checked in no_check_targets. If a label + pattern is specified on the command line, neither check_targets or + no_check_targets is used. Targets can opt-out from checking with "check_includes = false" (see "gn help check_includes"). @@ -225,6 +227,10 @@ FilterTargetsByPatterns(all_targets, *setup->check_patterns(), &targets_to_check); filtered_by_build_config = targets_to_check.size() != all_targets.size(); + } else if (setup->no_check_patterns()) { + FilterOutTargetsByPatterns(all_targets, *setup->no_check_patterns(), + &targets_to_check); + filtered_by_build_config = targets_to_check.size() != all_targets.size(); } else { // No global filter, check everything. targets_to_check = all_targets; @@ -245,8 +251,8 @@ if (filtered_by_build_config) { // Tell the user about the implicit filtering since this is obscure. OutputString(base::StringPrintf( - "%d targets out of %d checked based on the check_targets defined in" - " \".gn\".\n", + "%d targets out of %d checked based on the check_targets or " + "no_check_targets defined in \".gn\".\n", static_cast<int>(targets_to_check.size()), static_cast<int>(all_targets.size()))); }
diff --git a/src/gn/commands.cc b/src/gn/commands.cc index 431f8d2..8f1a1a7 100644 --- a/src/gn/commands.cc +++ b/src/gn/commands.cc
@@ -534,6 +534,19 @@ } } +void FilterOutTargetsByPatterns(const std::vector<const Target*>& input, + const std::vector<LabelPattern>& filter, + std::vector<const Target*>* output) { + for (auto* target : input) { + for (const auto& pattern : filter) { + if (!pattern.Matches(target->label())) { + output->push_back(target); + break; + } + } + } +} + bool FilterPatternsFromString(const BuildSettings* build_settings, const std::string& label_list_string, std::vector<LabelPattern>* filters,
diff --git a/src/gn/commands.h b/src/gn/commands.h index 41b99bc..28d713a 100644 --- a/src/gn/commands.h +++ b/src/gn/commands.h
@@ -165,6 +165,11 @@ const std::vector<LabelPattern>& filter, UniqueVector<const Target*>* output); +// Removes targets from the input that match the given pattern list. +void FilterOutTargetsByPatterns(const std::vector<const Target*>& input, + const std::vector<LabelPattern>& filter, + std::vector<const Target*>* output); + // Builds a list of pattern from a semicolon-separated list of labels. bool FilterPatternsFromString(const BuildSettings* build_settings, const std::string& label_list_string,
diff --git a/src/gn/setup.cc b/src/gn/setup.cc index c1d8688..bf48e38 100644 --- a/src/gn/setup.cc +++ b/src/gn/setup.cc
@@ -70,9 +70,21 @@ check_targets [optional] A list of labels and label patterns that should be checked when running - "gn check" or "gn gen --check". If unspecified, all targets will be - checked. If it is the empty list, no targets will be checked. To - bypass this list, request an explicit check of targets, like "//*". + "gn check" or "gn gen --check". If neither check_targets or + no_check_targets (see below) is specified, all targets will be checked. + It is an error to specify both check_targets and no_check_targets. If it + is the empty list, no targets will be checked. To bypass this list, + request an explicit check of targets, like "//*". + + The format of this list is identical to that of "visibility" so see "gn + help visibility" for examples. + + no_check_targets [optional] + A list of labels and label patterns that should *not* be checked when + running "gn check" or "gn gen --check". All other targets will be checked. + If neither check_targets (see above) or no_check_targets is specified, all + targets will be checked. It is an error to specify both check_targets and + no_check_targets. The format of this list is identical to that of "visibility" so see "gn help visibility" for examples. @@ -862,7 +874,7 @@ const Value* check_targets_value = dotfile_scope_.GetValue("check_targets", true); if (check_targets_value) { - check_patterns_.reset(new std::vector<LabelPattern>); + check_patterns_ = std::make_unique<std::vector<LabelPattern>>(); ExtractListOfLabelPatterns(&build_settings_, *check_targets_value, current_dir, check_patterns_.get(), err); if (err->has_error()) { @@ -870,6 +882,27 @@ } } + // Targets not to check. + const Value* no_check_targets_value = + dotfile_scope_.GetValue("no_check_targets", true); + if (no_check_targets_value) { + if (check_targets_value) { + Err(Location(), "Conflicting check settings.", + "Your .gn file (\"" + FilePathToUTF8(dotfile_name_) + + "\")\n" + "specified both check_targets and no_check_targets and at most " + "one is allowed.") + .PrintToStdout(); + return false; + } + no_check_patterns_ = std::make_unique<std::vector<LabelPattern>>(); + ExtractListOfLabelPatterns(&build_settings_, *no_check_targets_value, + current_dir, no_check_patterns_.get(), err); + if (err->has_error()) { + return false; + } + } + const Value* check_system_includes_value = dotfile_scope_.GetValue("check_system_includes", true); if (check_system_includes_value) {
diff --git a/src/gn/setup.h b/src/gn/setup.h index bf1e1ca..1c5d280 100644 --- a/src/gn/setup.h +++ b/src/gn/setup.h
@@ -106,6 +106,14 @@ return check_patterns_.get(); } + // Read from the .gn file, these are the targets *not* to check. If the .gn + // file does not specify anything, this will be null. If the .gn file + // specifies the empty list, this will be non-null but empty. At least one of + // check_patterns() and no_check_patterns() will be null. + const std::vector<LabelPattern>* no_check_patterns() const { + return no_check_patterns_.get(); + } + BuildSettings& build_settings() { return build_settings_; } Builder& builder() { return builder_; } LoaderImpl* loader() { return loader_.get(); } @@ -167,6 +175,7 @@ // See getter for info. std::unique_ptr<std::vector<LabelPattern>> check_patterns_; + std::unique_ptr<std::vector<LabelPattern>> no_check_patterns_; Scheduler scheduler_;