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();