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_;