Skip to content

Commit

Permalink
Allow manual tags to be synced to the project (#5085)
Browse files Browse the repository at this point in the history
* Adds a allow_manual_tags_sync in the .bazelproject to allow manual tags to be synced in the repo.

* Add integration tests

* Remove section
  • Loading branch information
rogerhu authored Jul 27, 2023
1 parent cbb6f2b commit a57b5d4
Show file tree
Hide file tree
Showing 8 changed files with 215 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,14 @@ public class BlazeQueryDirectoryToTargetProvider implements DirectoryToTargetPro
@Override
public List<TargetInfo> 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) {
protected static String getQueryString(ImportRoots directories, boolean allowManualTargetsSync) {
StringBuilder targets = new StringBuilder();
targets.append(
directories.rootDirectories().stream()
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,12 @@ static boolean hasProvider() {
@Nullable
static List<TargetInfo> 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);
Expand All @@ -63,6 +64,7 @@ static List<TargetInfo> expandDirectoryTargets(
@Nullable
List<TargetInfo> doExpandDirectoryTargets(
Project project,
Boolean shouldManualTargetSync,
ImportRoots directories,
WorkspacePathResolver pathResolver,
BlazeContext context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class Sections {
ImportSection.PARSER,
DirectorySection.PARSER,
AutomaticallyDeriveTargetsSection.PARSER,
SyncManualTargetsSection.PARSER,
TargetSection.PARSER,
WorkspaceTypeSection.PARSER,
AdditionalLanguagesSection.PARSER,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* 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<Boolean, ScalarSection<Boolean>> KEY =
SectionKey.of("allow_manual_targets_sync");
public static final SectionParser PARSER = new SyncManualTargetsParser();

private static class SyncManualTargetsParser
extends ScalarSectionParser<Boolean> {
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.";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<TargetExpression> deriveTargetsFromDirectories(
Project project,
BlazeContext context,
Expand Down Expand Up @@ -120,7 +125,7 @@ private static ImmutableList<TargetExpression> 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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import com.google.idea.blaze.base.projectview.section.sections.Sections;
import com.google.idea.blaze.base.projectview.section.sections.ShardBlazeBuildsSection;
import com.google.idea.blaze.base.projectview.section.sections.SyncFlagsSection;
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.projectview.section.sections.TargetShardSizeSection;
import com.google.idea.blaze.base.projectview.section.sections.TestFlagsSection;
Expand Down Expand Up @@ -102,6 +103,7 @@ public void testProjectViewSetSerializable() {
ListSection.builder(RunConfigurationsSection.KEY)
.add(new WorkspacePath("test")))
.add(ScalarSection.builder(AutomaticallyDeriveTargetsSection.KEY).set(false))
.add(ScalarSection.builder(SyncManualTargetsSection.KEY).set(false))
.add(ScalarSection.builder(ShardBlazeBuildsSection.KEY).set(false))
.add(ScalarSection.builder(TargetShardSizeSection.KEY).set(500))
.add(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.google.idea.blaze.java.sync;

import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.base.dependencies.BlazeQueryDirectoryToTargetProvider;
import com.google.idea.blaze.base.dependencies.TargetInfo;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.sync.projectview.ImportRoots;
import com.google.idea.blaze.base.sync.workspace.WorkspacePathResolver;
import com.intellij.openapi.project.Project;

import javax.annotation.Nullable;
import java.util.List;

/**
* Need to mock out this target provider since it attempts to execute Bazel outside of the sandbox
* environment. Used primarily within JavaSyncTest to validate the behavior of the
* allow_manual_targets_sync: option.
*/
class FakeBlazeQueryProvider extends BlazeQueryDirectoryToTargetProvider {

private static final String MANUAL_EXCLUDE_TAG = "((?!manual)";

// Need to override in order to be able to execute getQueryString().
@Nullable
@Override
public List<TargetInfo> doExpandDirectoryTargets(
Project project,
Boolean shouldManualTargetSync,
ImportRoots directories,
WorkspacePathResolver pathResolver,
BlazeContext context) {
return runQuery(project, getQueryString(directories, shouldManualTargetSync), context);
}

@Nullable
private static ImmutableList<TargetInfo> runQuery(Project project, String query, BlazeContext context) {
if (!query.contains(MANUAL_EXCLUDE_TAG)) {
TargetInfo targetInfo = TargetInfo.builder(Label.create("//java/com/google:lib"), "java_library").build();
return ImmutableList.of(targetInfo);
} else {
return ImmutableList.of();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import static com.google.common.truth.Truth.assertThat;

import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.base.dependencies.BlazeQueryDirectoryToTargetProvider;
import com.google.idea.blaze.base.dependencies.DirectoryToTargetProvider;
import com.google.idea.blaze.base.ideinfo.JavaIdeInfo;
import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
import com.google.idea.blaze.base.ideinfo.TargetMap;
Expand Down Expand Up @@ -155,6 +157,83 @@ public void testSimpleSync() throws Exception {
.isEqualTo(WorkspaceType.JAVA);
}

public void runWorkspaceSync() {
workspace.createFile(
new WorkspacePath("java/com/google/Source.java"),
"package com.google;",
"public class Source {}");

workspace.createFile(
new WorkspacePath("java/com/google/Other.java"),
"package com.google;",
"public class Other {}");

TargetMap targetMap =
TargetMapBuilder.builder()
.addTarget(
TargetIdeInfo.builder()
.setBuildFile(sourceRoot("java/com/google/BUILD"))
.setLabel("//java/com/google:lib")
.setKind("java_library")
.addTag("manual")
.addSource(sourceRoot("java/com/google/Source.java"))
.addSource(sourceRoot("java/com/google/Other.java")))
.build();

setTargetMap(targetMap);

runBlazeSync(
BlazeSyncParams.builder()
.setTitle("Sync")
.setSyncMode(SyncMode.INCREMENTAL)
.setSyncOrigin("test")
.setAddProjectViewTargets(true)
.build());
}

void mockBazelQueryDirectorProvider() {
DirectoryToTargetProvider.EP_NAME.getPoint().unregisterExtension(BlazeQueryDirectoryToTargetProvider.class);
registerExtensionFirst(DirectoryToTargetProvider.EP_NAME, new FakeBlazeQueryProvider());
}

@Test
public void testManualTargetSyncTrue() throws Exception {
mockBazelQueryDirectorProvider();

setProjectView(
"directories:",
" java/com/google",
"derive_targets_from_directories: true",
"allow_manual_targets_sync: true");
runWorkspaceSync();

errorCollector.assertNoIssues();
List<SyncStats> syncStatsList = getSyncStats();
SyncStats syncStats = syncStatsList.get(0);

assertThat(syncStats.buildPhaseStats().get(0).targets()).hasSize(1);
}

@Test
public void testManualTargetSyncFalse() throws Exception {
mockBazelQueryDirectorProvider();

setProjectView(
"directories:",
" java/com/google",
"derive_targets_from_directories: true",
"allow_manual_targets_sync: false");

runWorkspaceSync();

errorCollector.assertNoIssues();
List<SyncStats> syncStatsList = getSyncStats();
SyncStats syncStats = syncStatsList.get(0);

assertThat(syncStats.buildPhaseStats().get(0).targets()).hasSize(0);
}


@Test
public void testSimpleSyncLogging() throws Exception {
setProjectView("directories:", " java/com/google", "targets:", " //java/com/google:lib");
Expand Down

0 comments on commit a57b5d4

Please sign in to comment.