Skip to content

Commit

Permalink
Refactor project proto transforms.
Browse files Browse the repository at this point in the history
Move `ProjectProtoTransform` interface to a top level class. Require transforms to be registered by the code that defined them, rather than creating them directly inside `ProjectLoader`. This allows the transforms be be defined more dynamically.

Create a registry class to enable this and pass it into constructors where necessary.

This also allows us to remove the equivalent method from `ArtifactTracker`.

PiperOrigin-RevId: 605003949
  • Loading branch information
Googler authored and copybara-github committed Feb 7, 2024
1 parent 5263dee commit 26003e9
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 46 deletions.
13 changes: 0 additions & 13 deletions base/src/com/google/idea/blaze/base/qsync/ArtifactTracker.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,9 @@

import com.google.common.collect.ImmutableSet;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.common.Context;
import com.google.idea.blaze.common.Label;
import com.google.idea.blaze.exception.BuildException;
import com.google.idea.blaze.qsync.cc.CcDependenciesInfo;
import com.google.idea.blaze.qsync.project.BuildGraphData;
import com.google.idea.blaze.qsync.project.ProjectProto;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
Expand All @@ -38,16 +35,6 @@ public interface ArtifactTracker {
ArtifactTrackerUpdateResult update(
Set<Label> targets, OutputInfo outputInfo, BlazeContext context) throws BuildException;

/**
* Makes the project snapshot reflect the current state of tracked artifacts.
*
* <p>When additional artifacts are brought into the IDE they may require additional configuration
* to be applied to the IDE project.
*/
ProjectProto.Project updateProjectProto(
ProjectProto.Project projectProto, BuildGraphData graph, Context<?> context)
throws BuildException;

/**
* Returns a list of local cache files that build by target provided. Returns Optional.empty() if
* the target has not yet been built.
Expand Down
13 changes: 7 additions & 6 deletions base/src/com/google/idea/blaze/base/qsync/ProjectLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import com.google.idea.blaze.base.projectview.section.sections.TestSourceSection;
import com.google.idea.blaze.base.qsync.cache.ArtifactFetcher;
import com.google.idea.blaze.base.qsync.cache.ArtifactTrackerImpl;
import com.google.idea.blaze.base.qsync.cc.CcProjectProtoTransform;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.settings.BlazeImportSettings;
import com.google.idea.blaze.base.settings.BlazeImportSettingsManager;
Expand All @@ -46,7 +45,8 @@
import com.google.idea.blaze.exception.BuildException;
import com.google.idea.blaze.qsync.BlazeProject;
import com.google.idea.blaze.qsync.BlazeProjectSnapshotBuilder;
import com.google.idea.blaze.qsync.BlazeProjectSnapshotBuilder.ProjectProtoTransform;
import com.google.idea.blaze.qsync.ProjectProtoTransform;
import com.google.idea.blaze.qsync.ProjectProtoTransform.Registry;
import com.google.idea.blaze.qsync.ProjectRefresher;
import com.google.idea.blaze.qsync.VcsStateDiffer;
import com.google.idea.blaze.qsync.java.PackageStatementParser;
Expand Down Expand Up @@ -133,6 +133,7 @@ public QuerySyncProject loadProject(BlazeContext context) throws BuildException
ProjectPath.Resolver projectPathResolver =
ProjectPath.Resolver.create(workspaceRoot.path(), ideProjectBasePath);

ProjectProtoTransform.Registry projectTransformRegistry = new Registry();
BlazeProject graph = new BlazeProject();
graph.addListener((c, i) -> projectModificationTracker.incModificationCount());
ArtifactFetcher<OutputArtifact> artifactFetcher = createArtifactFetcher();
Expand All @@ -142,7 +143,8 @@ public QuerySyncProject loadProject(BlazeContext context) throws BuildException
ideProjectBasePath,
artifactFetcher,
projectPathResolver,
latestProjectDef);
latestProjectDef,
projectTransformRegistry);
artifactTracker.initialize();
DependencyTracker dependencyTracker =
new DependencyTrackerImpl(project, graph, dependencyBuilder, artifactTracker);
Expand All @@ -161,8 +163,6 @@ public QuerySyncProject loadProject(BlazeContext context) throws BuildException
createWorkspaceRelativePackageReader(),
workspaceRoot.path(),
handledRules,
ProjectProtoTransform.compose(
artifactTracker::updateProjectProto, new CcProjectProtoTransform(artifactTracker)),
QuerySync.USE_NEW_RES_DIR_LOGIC::getValue,
() -> !QuerySync.EXTRACT_RES_PACKAGES_AT_BUILD_TIME.getValue());
QueryRunner queryRunner = createQueryRunner(buildSystem);
Expand Down Expand Up @@ -192,7 +192,8 @@ public QuerySyncProject loadProject(BlazeContext context) throws BuildException
workspaceLanguageSettings,
sourceToTargetMap,
projectViewManager,
buildSystem);
buildSystem,
projectTransformRegistry);
BlazeProjectListenerProvider.registerListenersFor(querySyncProject);

return querySyncProject;
Expand Down
13 changes: 10 additions & 3 deletions base/src/com/google/idea/blaze/base/qsync/QuerySyncProject.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import com.google.idea.blaze.exception.BuildException;
import com.google.idea.blaze.qsync.BlazeProject;
import com.google.idea.blaze.qsync.BlazeProjectSnapshotBuilder;
import com.google.idea.blaze.qsync.ProjectProtoTransform;
import com.google.idea.blaze.qsync.project.BlazeProjectSnapshot;
import com.google.idea.blaze.qsync.project.PostQuerySyncData;
import com.google.idea.blaze.qsync.project.ProjectDefinition;
Expand Down Expand Up @@ -100,6 +101,7 @@ public class QuerySyncProject {

private final ProjectViewManager projectViewManager;
private final BuildSystem buildSystem;
private final ProjectProtoTransform.Registry projectProtoTransforms;

private volatile QuerySyncProjectData projectData;

Expand All @@ -124,7 +126,8 @@ public QuerySyncProject(
WorkspaceLanguageSettings workspaceLanguageSettings,
QuerySyncSourceToTargetMap sourceToTargetMap,
ProjectViewManager projectViewManager,
BuildSystem buildSystem) {
BuildSystem buildSystem,
ProjectProtoTransform.Registry projectProtoTransforms) {
this.project = project;
this.snapshotFilePath = snapshotFilePath;
this.snapshotHolder = snapshotHolder;
Expand All @@ -146,6 +149,7 @@ public QuerySyncProject(
this.sourceToTargetMap = sourceToTargetMap;
this.projectViewManager = projectViewManager;
this.buildSystem = buildSystem;
this.projectProtoTransforms = projectProtoTransforms;
projectData = new QuerySyncProjectData(workspacePathResolver, workspaceLanguageSettings);
}

Expand Down Expand Up @@ -236,7 +240,8 @@ public void sync(BlazeContext parentContext, Optional<PostQuerySyncData> lastQue
? projectQuerier.fullQuery(projectDefinition, context)
: projectQuerier.update(projectDefinition, lastQuery.get(), context);
BlazeProjectSnapshot newSnapshot =
blazeProjectSnapshotBuilder.createBlazeProjectSnapshot(context, postQuerySyncData);
blazeProjectSnapshotBuilder.createBlazeProjectSnapshot(
context, postQuerySyncData, projectProtoTransforms.getComposedTransform());
onNewSnapshot(context, newSnapshot);

// TODO: Revisit SyncListeners once we switch fully to qsync
Expand Down Expand Up @@ -313,7 +318,9 @@ public void build(BlazeContext parentContext, Set<Label> projectTargets)
if (getDependencyTracker().buildDependenciesForTargets(context, projectTargets)) {
BlazeProjectSnapshot newSnapshot =
blazeProjectSnapshotBuilder.createBlazeProjectSnapshot(
context, snapshotHolder.getCurrent().orElseThrow().queryData());
context,
snapshotHolder.getCurrent().orElseThrow().queryData(),
projectProtoTransforms.getComposedTransform());
onNewSnapshot(context, newSnapshot);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,14 @@
import com.google.idea.blaze.base.qsync.cache.FileCache.CacheLayout;
import com.google.idea.blaze.base.qsync.cache.FileCache.OutputArtifactDestination;
import com.google.idea.blaze.base.qsync.cache.FileCache.OutputArtifactDestinationAndLayout;
import com.google.idea.blaze.base.qsync.cc.CcProjectProtoTransform;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.common.Context;
import com.google.idea.blaze.common.DownloadTrackingScope;
import com.google.idea.blaze.common.Label;
import com.google.idea.blaze.common.PrintOutput;
import com.google.idea.blaze.exception.BuildException;
import com.google.idea.blaze.qsync.ProjectProtoTransform;
import com.google.idea.blaze.qsync.TestSourceGlobMatcher;
import com.google.idea.blaze.qsync.cc.CcDependenciesInfo;
import com.google.idea.blaze.qsync.java.AndroidResPackagesProjectUpdater;
Expand Down Expand Up @@ -162,7 +164,8 @@ public ArtifactTrackerImpl(
Path ideProjectBasePath,
ArtifactFetcher<OutputArtifact> artifactFetcher,
ProjectPath.Resolver projectPathResolver,
ProjectDefinition projectDefinition) {
ProjectDefinition projectDefinition,
ProjectProtoTransform.Registry transformRegistry) {
this.ideProjectBasePath = ideProjectBasePath;
this.artifactFetcher = artifactFetcher;
this.projectPathResolver = projectPathResolver;
Expand Down Expand Up @@ -209,6 +212,8 @@ public ArtifactTrackerImpl(
projectDirectory.resolve(DIGESTS_DIRECTORY_NAME),
fileCacheCreator.getCacheDirectories());
persistentFile = projectDirectory.resolve("artifact_tracker_state");
transformRegistry.add(this::updateProjectProto);
transformRegistry.add(new CcProjectProtoTransform(this));
}

private static class FileCacheCreator {
Expand Down Expand Up @@ -622,7 +627,12 @@ private static boolean hasJarOrZipExtension(Path p) {
return JAR_ZIP_EXTENSIONS.contains(FileUtilRt.getExtension(p.toString()));
}

@Override
/**
* Makes the project snapshot reflect the current state of tracked artifacts.
*
* <p>When additional artifacts are brought into the IDE they may require additional configuration
* to be applied to the IDE project.
*/
public ProjectProto.Project updateProjectProto(
ProjectProto.Project projectProto, BuildGraphData graph, Context<?> context)
throws BuildException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import com.google.idea.blaze.base.qsync.ArtifactTracker;
import com.google.idea.blaze.common.Context;
import com.google.idea.blaze.exception.BuildException;
import com.google.idea.blaze.qsync.BlazeProjectSnapshotBuilder.ProjectProtoTransform;
import com.google.idea.blaze.qsync.ProjectProtoTransform;
import com.google.idea.blaze.qsync.cc.CcWorkspaceBuilder;
import com.google.idea.blaze.qsync.project.BuildGraphData;
import com.google.idea.blaze.qsync.project.ProjectProto.Project;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import com.google.idea.blaze.qsync.project.BlazeProjectSnapshot;
import com.google.idea.blaze.qsync.project.BuildGraphData;
import com.google.idea.blaze.qsync.project.PostQuerySyncData;
import com.google.idea.blaze.qsync.project.ProjectProto;
import com.google.idea.blaze.qsync.project.ProjectProto.Project;
import com.google.idea.blaze.qsync.query.QuerySummary;
import java.nio.file.Path;
Expand All @@ -40,7 +39,6 @@ public class BlazeProjectSnapshotBuilder {
private final PackageReader workspaceRelativePackageReader;
private final Path workspaceRoot;
private final ImmutableSet<String> handledRuleKinds;
private final ProjectProtoTransform projectProtoTransform;
private final Supplier<Boolean> useNewResDirLogic;
private final Supplier<Boolean> guessAndroidResPackages;

Expand All @@ -49,41 +47,26 @@ public BlazeProjectSnapshotBuilder(
PackageReader workspaceRelativePackageReader,
Path workspaceRoot,
ImmutableSet<String> handledRuleKinds,
ProjectProtoTransform projectProtoTransform,
Supplier<Boolean> useNewResDirLogic,
Supplier<Boolean> guessAndroidResPackages) {
this.executor = executor;
this.workspaceRelativePackageReader = workspaceRelativePackageReader;
this.workspaceRoot = workspaceRoot;
this.handledRuleKinds = handledRuleKinds;
this.projectProtoTransform = projectProtoTransform;
this.useNewResDirLogic = useNewResDirLogic;
this.guessAndroidResPackages = guessAndroidResPackages;
}

/** {@code Function<ProjectProto.Project, ProjectProto.Project>} that can throw exceptions. */
@FunctionalInterface
public interface ProjectProtoTransform {
ProjectProto.Project apply(ProjectProto.Project proto, BuildGraphData graph, Context<?> context)
throws BuildException;

public static ProjectProtoTransform compose(ProjectProtoTransform... transforms) {
return (proto, graph, context) -> {
for (ProjectProtoTransform transform : transforms) {
proto = transform.apply(proto, graph, context);
}
return proto;
};
}
}

/**
* Creates a {@link BlazeProjectSnapshot}, which includes an expected IDE project structure, from
* the {@code postQuerySyncData} and a function {@code applyBuiltDependenciesTransform} that
* applies transformations required to account for any currently synced(i.e. built) dependencies.
*/
public BlazeProjectSnapshot createBlazeProjectSnapshot(
Context<?> context, PostQuerySyncData postQuerySyncData) throws BuildException {
Context<?> context,
PostQuerySyncData postQuerySyncData,
ProjectProtoTransform projectProtoTransform)
throws BuildException {
Path effectiveWorkspaceRoot =
postQuerySyncData.vcsState().flatMap(s -> s.workspaceSnapshotPath).orElse(workspaceRoot);
WorkspaceResolvingPackageReader packageReader =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright 2024 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.qsync;

import com.google.common.collect.Lists;
import com.google.idea.blaze.common.Context;
import com.google.idea.blaze.exception.BuildException;
import com.google.idea.blaze.qsync.project.BuildGraphData;
import com.google.idea.blaze.qsync.project.ProjectProto;
import java.util.List;

/** Applies a transform to a project proto instance, yielding a new instance. */
@FunctionalInterface
public interface ProjectProtoTransform {

/**
* Apply the transform.
*
* @param proto The existing project proto. This is derived from {@code graph} and may have had
* other transforms applied to it.
* @param graph The graph from which {@code proto} was derived from.
* @param context Context.
* @return A project proto instance to replace the existing one. May return {@code proto}
* unchanged if this transform doesn't need to change anything.
*/
ProjectProto.Project apply(ProjectProto.Project proto, BuildGraphData graph, Context<?> context)
throws BuildException;

static ProjectProtoTransform compose(Iterable<ProjectProtoTransform> transforms) {
return (proto, graph, context) -> {
for (ProjectProtoTransform transform : transforms) {
proto = transform.apply(proto, graph, context);
}
return proto;
};
}

/**
* Simple registry for transforms that also supports returning all transforms combined into one.
*/
class Registry {
private final List<ProjectProtoTransform> transforms = Lists.newArrayList();

public void add(ProjectProtoTransform transform) {
transforms.add(transform);
}

public ProjectProtoTransform getComposedTransform() {
return compose(transforms);
}
}
}

0 comments on commit 26003e9

Please sign in to comment.