diff --git a/base/src/META-INF/blaze-base.xml b/base/src/META-INF/blaze-base.xml
index 7aaa7e05500..1d815d775d3 100644
--- a/base/src/META-INF/blaze-base.xml
+++ b/base/src/META-INF/blaze-base.xml
@@ -527,6 +527,7 @@
+
diff --git a/base/src/com/google/idea/blaze/base/dependencies/BlazeQueryDirectoryToTargetProvider.java b/base/src/com/google/idea/blaze/base/dependencies/BlazeQueryDirectoryToTargetProvider.java
index 8cbe8891382..dc34030cccf 100644
--- a/base/src/com/google/idea/blaze/base/dependencies/BlazeQueryDirectoryToTargetProvider.java
+++ b/base/src/com/google/idea/blaze/base/dependencies/BlazeQueryDirectoryToTargetProvider.java
@@ -51,13 +51,14 @@ public class BlazeQueryDirectoryToTargetProvider implements DirectoryToTargetPro
@Override
public List doExpandDirectoryTargets(
Project project,
+ Boolean shouldManualTargetSync,
ImportRoots directories,
WorkspacePathResolver pathResolver,
BlazeContext context) {
- return runQuery(project, getQueryString(directories), context);
+ return runQuery(project, getQueryString(directories, shouldManualTargetSync), context);
}
- private static String getQueryString(ImportRoots directories) {
+ private static String getQueryString(ImportRoots directories, boolean allowManualTargetsSync) {
StringBuilder targets = new StringBuilder();
targets.append(
directories.rootDirectories().stream()
@@ -67,6 +68,10 @@ private static String getQueryString(ImportRoots directories) {
targets.append(" - " + TargetExpression.allFromPackageRecursive(excluded).toString());
}
+ if (allowManualTargetsSync) {
+ return targets.toString();
+ }
+
// exclude 'manual' targets, which shouldn't be built when expanding wildcard target patterns
if (SystemInfo.isWindows) {
// TODO(b/201974254): Windows support for Bazel sync (see
diff --git a/base/src/com/google/idea/blaze/base/dependencies/DirectoryToTargetProvider.java b/base/src/com/google/idea/blaze/base/dependencies/DirectoryToTargetProvider.java
index 8d772d00486..a41a0cdb303 100644
--- a/base/src/com/google/idea/blaze/base/dependencies/DirectoryToTargetProvider.java
+++ b/base/src/com/google/idea/blaze/base/dependencies/DirectoryToTargetProvider.java
@@ -46,11 +46,12 @@ static boolean hasProvider() {
@Nullable
static List expandDirectoryTargets(
Project project,
+ Boolean shouldManualTargetSync,
ImportRoots directories,
WorkspacePathResolver pathResolver,
BlazeContext context) {
return Arrays.stream(EP_NAME.getExtensions())
- .map(p -> p.doExpandDirectoryTargets(project, directories, pathResolver, context))
+ .map(p -> p.doExpandDirectoryTargets(project, shouldManualTargetSync, directories, pathResolver, context))
.filter(Objects::nonNull)
.findFirst()
.orElse(null);
@@ -63,6 +64,7 @@ static List expandDirectoryTargets(
@Nullable
List doExpandDirectoryTargets(
Project project,
+ Boolean shouldManualTargetSync,
ImportRoots directories,
WorkspacePathResolver pathResolver,
BlazeContext context);
diff --git a/base/src/com/google/idea/blaze/base/projectview/section/sections/Sections.java b/base/src/com/google/idea/blaze/base/projectview/section/sections/Sections.java
index 10e9eccd94f..82dbce14e2d 100644
--- a/base/src/com/google/idea/blaze/base/projectview/section/sections/Sections.java
+++ b/base/src/com/google/idea/blaze/base/projectview/section/sections/Sections.java
@@ -30,6 +30,7 @@ public class Sections {
ImportSection.PARSER,
DirectorySection.PARSER,
AutomaticallyDeriveTargetsSection.PARSER,
+ SyncManualTargetsSection.PARSER,
TargetSection.PARSER,
WorkspaceTypeSection.PARSER,
AdditionalLanguagesSection.PARSER,
diff --git a/base/src/com/google/idea/blaze/base/projectview/section/sections/SyncManualTargetsSection.java b/base/src/com/google/idea/blaze/base/projectview/section/sections/SyncManualTargetsSection.java
new file mode 100644
index 00000000000..e01fb14c6fb
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/projectview/section/sections/SyncManualTargetsSection.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2019 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.base.projectview.section.sections;
+
+import com.google.idea.blaze.base.projectview.ProjectView;
+import com.google.idea.blaze.base.projectview.ProjectViewSet;
+import com.google.idea.blaze.base.projectview.parser.ParseContext;
+import com.google.idea.blaze.base.projectview.parser.ProjectViewParser;
+import com.google.idea.blaze.base.projectview.section.ProjectViewDefaultValueProvider;
+import com.google.idea.blaze.base.projectview.section.ScalarSection;
+import com.google.idea.blaze.base.projectview.section.ScalarSectionParser;
+import com.google.idea.blaze.base.projectview.section.SectionKey;
+import com.google.idea.blaze.base.projectview.section.SectionParser;
+import com.google.idea.blaze.base.settings.BuildSystemName;
+import javax.annotation.Nullable;
+
+/** If set to true, automatically derives targets from the project directories. */
+public class SyncManualTargetsSection {
+ public static final SectionKey> KEY =
+ SectionKey.of("allow_manual_targets_sync");
+ public static final SectionParser PARSER = new SyncManualTargetsParser();
+
+ private static class SyncManualTargetsParser
+ extends ScalarSectionParser {
+ SyncManualTargetsParser() {
+ super(KEY, ':');
+ }
+
+ @Override
+ @Nullable
+ protected Boolean parseItem(ProjectViewParser parser, ParseContext parseContext, String text) {
+ if (text.equals("true")) {
+ return true;
+ }
+ if (text.equals("false")) {
+ return false;
+ }
+ parseContext.addError(
+ "'allow_manual_tags_sync' must be set to 'true' or 'false' (e.g."
+ + " 'allow_manual_tags_sync: true')");
+ return null;
+ }
+
+ @Override
+ protected void printItem(StringBuilder sb, Boolean item) {
+ sb.append(item);
+ }
+
+ @Override
+ public ItemType getItemType() {
+ return ItemType.Other;
+ }
+
+ @Override
+ public String quickDocs() {
+ return "If set to true, project targets will be derived from the directories.";
+ }
+ }
+
+ static class DefaultValueProvider implements ProjectViewDefaultValueProvider {
+ @Override
+ public ProjectView addProjectViewDefaultValue(
+ BuildSystemName buildSystemName,
+ ProjectViewSet projectViewSet,
+ ProjectView topLevelProjectView) {
+ if (!topLevelProjectView.getSectionsOfType(KEY).isEmpty()) {
+ return topLevelProjectView;
+ }
+ return ProjectView.builder(topLevelProjectView)
+ .add(
+ TextBlockSection.of(
+ TextBlock.of(
+ "# Automatically targets tagged as manual to be synced")))
+ .add(ScalarSection.builder(KEY).set(false))
+ .add(TextBlockSection.of(TextBlock.newLine()))
+ .build();
+ }
+
+ @Override
+ public SectionKey, ?> getSectionKey() {
+ return KEY;
+ }
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/sync/SyncProjectTargetsHelper.java b/base/src/com/google/idea/blaze/base/sync/SyncProjectTargetsHelper.java
index f2834728055..86327a130f2 100644
--- a/base/src/com/google/idea/blaze/base/sync/SyncProjectTargetsHelper.java
+++ b/base/src/com/google/idea/blaze/base/sync/SyncProjectTargetsHelper.java
@@ -24,6 +24,7 @@
import com.google.idea.blaze.base.model.primitives.TargetExpression;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.projectview.section.sections.AutomaticallyDeriveTargetsSection;
+import com.google.idea.blaze.base.projectview.section.sections.SyncManualTargetsSection;
import com.google.idea.blaze.base.projectview.section.sections.TargetSection;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.scope.Scope;
@@ -88,6 +89,10 @@ private static boolean shouldDeriveSyncTargetsFromDirectories(ProjectViewSet vie
return viewSet.getScalarValue(AutomaticallyDeriveTargetsSection.KEY).orElse(false);
}
+ private static boolean shouldSyncManualTargets(ProjectViewSet viewSet) {
+ return viewSet.getScalarValue(SyncManualTargetsSection.KEY).orElse(false);
+ }
+
private static ImmutableList deriveTargetsFromDirectories(
Project project,
BlazeContext context,
@@ -120,7 +125,7 @@ private static ImmutableList deriveTargetsFromDirectories(
// We don't want blaze build errors to fail the whole sync
childContext.setPropagatesErrors(false);
return DirectoryToTargetProvider.expandDirectoryTargets(
- project, importRoots, pathResolver, childContext);
+ project, shouldSyncManualTargets(projectViewSet), importRoots, pathResolver, childContext);
});
if (context.isCancelled()) {
throw new SyncCanceledException();