Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
mtoader committed Aug 28, 2024
1 parent f1bafd1 commit 8d055dc
Show file tree
Hide file tree
Showing 17 changed files with 806 additions and 309 deletions.
17 changes: 9 additions & 8 deletions MODULE.bazel.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions base/src/META-INF/blaze-base.xml
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@
<editorNotificationProvider implementation="com.google.idea.blaze.base.qsync.UnsyncedFileEditorNotificationProvider" />

<projectService serviceImplementation="com.google.idea.blaze.base.command.info.BlazeInfoProvider"/>
<projectService serviceImplementation="com.google.idea.blaze.base.model.ExternalWorkspaceDataProvider"/>
<projectService serviceImplementation="com.google.idea.blaze.base.sync.SyncPhaseCoordinator"/>
<projectService serviceInterface="com.google.idea.blaze.base.sync.status.BlazeSyncStatus"
serviceImplementation="com.google.idea.blaze.base.sync.status.BlazeSyncStatusImpl"/>
Expand All @@ -281,6 +282,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 Expand Up @@ -373,6 +376,7 @@
<codeInsight.lineMarkerProvider
language="BUILD"
implementationClass="com.google.idea.blaze.base.query.MacroLineMarkerProvider"/>
<lookup.charFilter implementation="com.google.idea.blaze.base.lang.buildfile.references.ExternalWorkspaceReferenceFragment$CharFilter"/>
<runLineMarkerContributor
language="BUILD"
implementationClass="com.google.idea.blaze.base.run.producers.BuildFileRunLineMarkerContributor"/>
Expand Down Expand Up @@ -602,6 +606,7 @@
<SyncListener implementation="com.google.idea.blaze.base.sync.autosync.ProjectTargetManagerImpl$TargetSyncListener"/>
<SyncListener implementation="com.google.idea.blaze.base.lang.buildfile.language.semantics.BuildLanguageSpecProviderImpl$Listener"/>
<SyncListener implementation="com.google.idea.blaze.base.command.info.BlazeInfoProvider$Invalidator"/>
<SyncListener implementation="com.google.idea.blaze.base.model.ExternalWorkspaceDataProvider$Invalidator"/>
<SyncListener implementation="com.google.idea.blaze.base.qsync.QuerySyncAsyncFileListener$QuerySyncListener"/>
<SyncPlugin implementation="com.google.idea.blaze.base.lang.buildfile.sync.BuildLangSyncPlugin"/>
<SyncPlugin implementation="com.google.idea.blaze.base.sync.libraries.ExternalLibraryManager$SyncPlugin"/>
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 @@ -172,7 +172,7 @@ public InputStream runQuery(
line -> {
line = rootReplacement.apply(line);
// errors are expected, so limit logging to info level
Logger.getInstance(this.getClass()).info(line.stripTrailing());
Logger.getInstance(this.getClass()).warn(line.stripTrailing());
context.output(PrintOutput.output(line.stripTrailing()));
return true;
}))
Expand Down 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 =
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,16 @@
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,72 @@
/*
* Copyright 2016 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.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.components.ServiceManager;
import com.intellij.openapi.project.Project;

import java.util.List;

/** Runs the blaze info command. The results may be cached in the workspace. */
public abstract class BlazeModRunner {

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

/**
* @param blazeFlags The blaze flags that will be passed to Blaze.
* @param key The key passed to blaze info
* @return The blaze info value associated with the specified key
*/
public abstract ListenableFuture<String> runBlazeMod(
Project project,
BuildInvoker invoker,
BlazeContext context,
List<String> blazeFlags,
String key);

/**
* @param blazeFlags The blaze flags that will be passed to Blaze.
* @param key The key passed to blaze info
* @return The blaze info value associated with the specified key
*/
public abstract ListenableFuture<byte[]> runBlazeModGetBytes(
Project project,
BuildInvoker invoker,
BlazeContext context,
List<String> blazeFlags,
String key);

/**
* This calls blaze info without any specific key so blaze info will return all keys and values
* that it has.
*
* @param blazeFlags The blaze flags that will be passed to Blaze.
* @return The blaze info data fields.
*/
public abstract ListenableFuture<ExternalWorkspaceData> dumpRepoMapping(
Project project,
BuildInvoker invoker,
BlazeContext context,
BuildSystemName buildSystemName,
List<String> blazeFlags);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
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.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<String> runBlazeMod(Project project, BuildSystem.BuildInvoker invoker, BlazeContext context, List<String> blazeFlags, String key) {
return null;
}

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

ImmutableList<ExternalWorkspace> externalWorkspaces = jsonObject.asMap().entrySet().stream()
.filter(entry -> entry.getValue().isJsonPrimitive())
.filter(entry -> !entry.getValue().getAsString().trim().isEmpty())
.map(entry -> ExternalWorkspace.create(entry.getValue().getAsString(), entry.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> blazeFlags, String query_type) {
return BlazeExecutor.getInstance().submit(() -> {
BlazeCommand.Builder builder = BlazeCommand.builder(invoker, BlazeCommandName.MOD);
builder.addBlazeFlags(blazeFlags);

if (query_type != null) {
builder.addBlazeFlags(query_type, "workspace");
}

try (BuildResultHelper buildResultHelper = invoker.createBuildResultHelper()) {
try (InputStream stream = invoker.getCommandRunner().runBlazeMod(project, builder, buildResultHelper, context)) {
return stream.readAllBytes();
}
}
});
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.google.idea.blaze.base.lang.buildfile.completion;

import com.google.idea.blaze.base.lang.buildfile.references.QuoteType;
import com.google.idea.blaze.base.model.primitives.ExternalWorkspace;
import com.intellij.codeInsight.completion.InsertionContext;
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
import com.intellij.codeInsight.lookup.Lookup;
import com.intellij.util.PlatformIcons;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;

public class WorkspaceLookupElement extends BuildLookupElement {

final ExternalWorkspace workspace;
public WorkspaceLookupElement(ExternalWorkspace workspace) {
super(workspace.repoName(), QuoteType.NoQuotes);
this.workspace = workspace;
}

@Override
public String getLookupString() {
if (workspace.repoName() == null || workspace.repoName().isEmpty()) {
return "@" + workspace.name();
}

return "@" + workspace.repoName();
}

@Override
protected @Nullable String getTypeText() {
return workspace.name();
}

@Override
protected @Nullable String getTailText() {
return "//";
}

@Override
public @Nullable Icon getIcon() {
return PlatformIcons.IMPORT_ICON;
}

protected String getItemText() {
if (workspace.repoName() == null || workspace.repoName().isEmpty()) {
return "@" + workspace.name();
}

return "@" + workspace.repoName();
}

@Override
public void handleInsert(InsertionContext context) {
switch (context.getCompletionChar()) {
case Lookup.REPLACE_SELECT_CHAR:
case Lookup.NORMAL_SELECT_CHAR:
}
super.handleInsert(context);
}
}
Loading

0 comments on commit 8d055dc

Please sign in to comment.