Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#6664] Add blaze mod ... runner implementation - 2/n #6673

Merged
merged 8 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions base/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ java_library(
"//shared:vcs",
"//third_party/auto_value",
"@error_prone_annotations//jar",
"@gson//jar"
],
)

Expand Down
2 changes: 2 additions & 0 deletions base/src/META-INF/blaze-base.xml
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,8 @@
serviceImplementation="com.google.idea.blaze.base.io.VirtualFileSystemProviderImpl"/>
<applicationService serviceInterface="com.google.idea.blaze.base.command.info.BlazeInfoRunner"
serviceImplementation="com.google.idea.blaze.base.command.info.BlazeInfoRunnerImpl"/>
<applicationService serviceInterface="com.google.idea.blaze.base.command.mod.BlazeModRunner"
serviceImplementation="com.google.idea.blaze.base.command.mod.BlazeModRunnerImpl"/>
<applicationService serviceImplementation="com.google.idea.blaze.base.model.primitives.Kind$ApplicationState"/>
<applicationService serviceInterface="com.google.idea.blaze.base.io.TempDirectoryProvider"
serviceImplementation="com.google.idea.blaze.base.io.TempDirectoryProviderImpl"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public final class BlazeCommandName {
public static final BlazeCommandName INFO = fromString("info");
public static final BlazeCommandName MOBILE_INSTALL = fromString("mobile-install");
public static final BlazeCommandName COVERAGE = fromString("coverage");
public static final BlazeCommandName MOD = fromString("mod");

public static BlazeCommandName fromString(String name) {
knownCommands.putIfAbsent(name, new BlazeCommandName(name));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ InputStream runBlazeInfo(
BlazeContext context)
throws BuildException;

@MustBeClosed
InputStream runBlazeMod(
Project project,
BlazeCommand.Builder blazeCommandBuilder,
BuildResultHelper buildResultHelper,
BlazeContext context)
throws BuildException;

/** Allows enabling the use of command runner for restricted set of users. */
default boolean canUseCli() {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,41 @@ public InputStream runBlazeInfo(
}
}

@Override
@MustBeClosed
public InputStream runBlazeMod(
Project project,
BlazeCommand.Builder blazeCommandBuilder,
BuildResultHelper buildResultHelper,
BlazeContext context)
throws BuildException {
performGuardCheckAsBuildException(project, context);

try (Closer closer = Closer.create()) {
Path tmpFile =
mtoader marked this conversation as resolved.
Show resolved Hide resolved
Files.createTempFile(
String.format("intellij-bazel-%s-", blazeCommandBuilder.build().getName()),
".stdout");
OutputStream out = closer.register(Files.newOutputStream(tmpFile));
OutputStream stderr =
closer.register(LineProcessingOutputStream.of(new PrintOutputLineProcessor(context)));
int exitCode =
ExternalTask.builder(WorkspaceRoot.fromProject(project))
.addBlazeCommand(blazeCommandBuilder.build())
.context(context)
.stdout(out)
.stderr(stderr)
.ignoreExitCode(true)
.build()
.run();
BazelExitCodeException.throwIfFailed(blazeCommandBuilder, exitCode);
return new BufferedInputStream(
Files.newInputStream(tmpFile, StandardOpenOption.DELETE_ON_CLOSE));
} catch (IOException e) {
throw new BuildException(e);
}
}

private BuildResult issueBuild(
BlazeCommand.Builder blazeCommandBuilder, WorkspaceRoot workspaceRoot, Map<String, String> envVars, BlazeContext context) {
blazeCommandBuilder.addBlazeFlags(getExtraBuildFlags(blazeCommandBuilder));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2020 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.command.mod;

import com.google.idea.blaze.exception.BuildException;

import javax.annotation.concurrent.Immutable;

@Immutable
public final class BlazeModException extends BuildException {
public BlazeModException(String message) {
super(message);
}

public BlazeModException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright 2016 The Bazel Authors. All rights reserved.
mtoader marked this conversation as resolved.
Show resolved Hide resolved
*
* 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.command.mod;

import com.google.common.util.concurrent.ListenableFuture;
import com.google.idea.blaze.base.bazel.BuildSystem.BuildInvoker;
import com.google.idea.blaze.base.model.ExternalWorkspaceData;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.settings.BuildSystemName;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;

import java.util.List;

/** Runs the {@code blaze mod ...} command. The results may be cached in the workspace. */
public abstract class BlazeModRunner {

public static BlazeModRunner getInstance() {
return ApplicationManager.getApplication().getService(BlazeModRunner.class);
}

/**
* This calls {@code blaze mod dump_repo_mapping workspace} so blaze mod will return all mapped
* repos visible to the current workspace.
*
* @param flags The blaze flags that will be passed to Blaze.
* @return a ListenableFuture<ExternalWorkspaceData>
*/
public abstract ListenableFuture<ExternalWorkspaceData> dumpRepoMapping(
Project project,
BuildInvoker invoker,
BlazeContext context,
BuildSystemName buildSystemName,
List<String> flags);

/**
* @param args The arguments passed into `blaze mod ...`
* @param flags The blaze flags that will be passed to {@code blaze ...}
* @return the stdout bytes of the command
*/
protected abstract ListenableFuture<byte[]> runBlazeModGetBytes(
Project project,
BuildInvoker invoker,
BlazeContext context,
List<String> args,
List<String> flags);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Copyright 2020 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.command.mod;

import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.idea.blaze.base.async.executor.BlazeExecutor;
import com.google.idea.blaze.base.bazel.BuildSystem;
import com.google.idea.blaze.base.command.BlazeCommand;
import com.google.idea.blaze.base.command.BlazeCommandName;
import com.google.idea.blaze.base.command.BlazeCommandRunner;
import com.google.idea.blaze.base.command.buildresult.BuildResultHelper;
import com.google.idea.blaze.base.model.ExternalWorkspaceData;
import com.google.idea.blaze.base.model.primitives.ExternalWorkspace;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.settings.BuildSystemName;
import com.intellij.openapi.project.Project;

import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;

public class BlazeModRunnerImpl extends BlazeModRunner {

@Override
public ListenableFuture<ExternalWorkspaceData> dumpRepoMapping(
Project project,
BuildSystem.BuildInvoker invoker,
BlazeContext context,
BuildSystemName buildSystemName,
List<String> flags) {
return Futures.transform(
runBlazeModGetBytes(project, invoker, context, ImmutableList.of( "dump_repo_mapping", "workspace"), flags),
bytes -> {
JsonObject json = JsonParser.parseString(new String(bytes, StandardCharsets.UTF_8).trim()).getAsJsonObject();

ImmutableList<ExternalWorkspace> externalWorkspaces =
json.entrySet().stream()
.filter(e -> e.getValue().isJsonPrimitive())
.filter(e -> !e.getValue().getAsString().trim().isEmpty())
.map(e -> ExternalWorkspace.create(e.getValue().getAsString(), e.getKey()))
.collect(ImmutableList.toImmutableList());

return ExternalWorkspaceData.create(externalWorkspaces);
},
BlazeExecutor.getInstance().getExecutor());
}

@Override
public ListenableFuture<byte[]> runBlazeModGetBytes(
Project project,
BuildSystem.BuildInvoker invoker,
BlazeContext context,
List<String> args,
List<String> flags) {
return BlazeExecutor.getInstance()
.submit(() -> {
BlazeCommand.Builder builder =
BlazeCommand.builder(invoker, BlazeCommandName.MOD)
.addBlazeFlags(flags);

if (args != null) {
builder.addBlazeFlags(args);
}

try (BuildResultHelper buildResultHelper = invoker.createBuildResultHelper()) {
BlazeCommandRunner runner = invoker.getCommandRunner();
try (InputStream stream = runner.runBlazeMod(project, builder, buildResultHelper, context)) {
return stream.readAllBytes();
}
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.google.idea.blaze.base.command.buildresult.BuildResultHelper;
import com.google.idea.blaze.base.command.buildresult.BuildResultHelper.GetArtifactsException;
import com.google.idea.blaze.base.command.info.BlazeInfoException;
import com.google.idea.blaze.base.command.mod.BlazeModException;
import com.google.idea.blaze.base.logging.utils.querysync.BuildDepsStatsScope;
import com.google.idea.blaze.base.logging.utils.querysync.SyncQueryStatsScope;
import com.google.idea.blaze.base.run.testlogs.BlazeTestResults;
Expand All @@ -29,6 +30,7 @@
import com.google.idea.blaze.base.sync.aspects.BuildResult;
import com.google.idea.blaze.exception.BuildException;
import com.intellij.openapi.project.Project;

import java.io.InputStream;
import java.util.Map;

Expand Down Expand Up @@ -59,11 +61,11 @@ public FakeBlazeCommandRunner(BuildFunction buildFunction) {

@Override
public BlazeBuildOutputs run(
Project project,
BlazeCommand.Builder blazeCommandBuilder,
BuildResultHelper buildResultHelper,
BlazeContext context,
Map<String, String> envVars)
Project project,
BlazeCommand.Builder blazeCommandBuilder,
BuildResultHelper buildResultHelper,
BlazeContext context,
Map<String, String> envVars)
throws BuildException {
command = blazeCommandBuilder.build();
try {
Expand All @@ -78,11 +80,11 @@ public BlazeBuildOutputs run(

@Override
public BlazeTestResults runTest(
Project project,
BlazeCommand.Builder blazeCommandBuilder,
BuildResultHelper buildResultHelper,
BlazeContext context,
Map<String, String> envVars) {
Project project,
BlazeCommand.Builder blazeCommandBuilder,
BuildResultHelper buildResultHelper,
BlazeContext context,
Map<String, String> envVars) {
return BlazeTestResults.NO_RESULTS;
}

Expand All @@ -108,6 +110,17 @@ public InputStream runBlazeInfo(
return InputStream.nullInputStream();
}

@Override
@MustBeClosed
public InputStream runBlazeMod(
Project project,
BlazeCommand.Builder blazeCommandBuilder,
BuildResultHelper buildResultHelper,
BlazeContext context)
throws BlazeModException {
return InputStream.nullInputStream();
}

public BlazeCommand getIssuedCommand() {
return command;
}
Expand Down