Skip to content

Commit

Permalink
Merge branch 'develop' into cs/onWillUpdate
Browse files Browse the repository at this point in the history
  • Loading branch information
jdneo authored Sep 7, 2023
2 parents 650fb8e + 10515e4 commit 1c6cda4
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jdt.ls.core.internal.AbstractProjectImporter;
import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin;
import org.eclipse.jdt.ls.core.internal.ProjectUtils;
Expand Down Expand Up @@ -83,6 +84,15 @@ public boolean applies(IProgressMonitor monitor) throws OperationCanceledExcepti
directories = gradleDetector.scan(monitor);
}

for (java.nio.file.Path directory : directories) {
IProject project = ProjectUtils.getProjectFromUri(directory.toUri().toString());
// skip this importer if any of the project in workspace is already
// imported by other importers.
if (project != null && !Utils.isGradleBuildServerProject(project)) {
return false;
}
}

return !directories.isEmpty();
}

Expand Down Expand Up @@ -211,13 +221,17 @@ private IProject createProject(File directory, IProgressMonitor monitor) throws
}

private void updateProjectDescription(IProject project, IProgressMonitor monitor) throws CoreException {
SubMonitor progress = SubMonitor.convert(monitor, 1);
IProjectDescription projectDescription = project.getDescription();
Utils.removeBuildshipConfigurations(projectDescription);

ICommand problemReporter = projectDescription.newCommand();
problemReporter.setBuilderName(JavaProblemChecker.BUILDER_ID);
Utils.addBuildSpec(project, new ICommand[] {
Utils.addBuildSpec(projectDescription, new ICommand[] {
Utils.getBuildServerBuildSpec(projectDescription),
problemReporter
}, monitor);
});
project.setDescription(projectDescription, IResource.AVOID_NATURE_CONFIG, progress.newChild(1));

// Here we don't use the public API: {@code project.setDescription()} to update the project,
// because that API will ignore the variable descriptions.
Expand Down Expand Up @@ -254,19 +268,6 @@ private BuildServerPreferences getBuildServerPreferences() {
private boolean isBuildServerEnabled() {
Preferences preferences = getPreferences();
String bspImporterEnabled = getString(preferences.asMap(), JAVA_BUILD_SERVER_GRADLE_ENABLED);
if (bspImporterEnabled == null) {
return false;
}

if ("on".equalsIgnoreCase(bspImporterEnabled)) {
return true;
} else if ("auto".equalsIgnoreCase(bspImporterEnabled)){
// Rely on the workspace storage path to determine if the client is VSCode Insiders.
// This may not always true if user changes the storage path manually, but should
// work in most cases.
return ResourcesPlugin.getPlugin().getStateLocation().toString().contains("Code - Insiders");
}

return false;
return "on".equalsIgnoreCase(bspImporterEnabled);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.URIUtil;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.ls.core.internal.ProjectUtils;

import com.microsoft.gradle.bs.importer.builder.BuildServerBuilder;
Expand Down Expand Up @@ -115,53 +116,67 @@ public static void addNature(IProject project, String natureId, IProgressMonitor
}

/**
* Add the builders to the project if the input builders do not exist in project description.
* Add the builders to the project description if the input builders do not exist in description.
* All the configuration of the builder will be set to default.
*
* @param project the project to add the builder to.
* @param project the project description.
* @param buildNames the names of the builder.
* @param monitor the progress monitor.
* @throws CoreException
*/
public static void addBuildSpec(IProject project, String[] buildNames, IProgressMonitor monitor) throws CoreException {
IProjectDescription description = project.getDescription();
public static void addBuildSpec(IProjectDescription description, String[] buildNames) {
ICommand[] commands = Arrays.stream(buildNames).map(buildName -> {
ICommand buildSpec = description.newCommand();
buildSpec.setBuilderName(buildName);
return buildSpec;
}).toArray(ICommand[]::new);
addBuildSpec(project, commands, monitor);
addBuildSpec(description, commands);
}

/**
* Add the builders to the project if the input builders do not exist in project description.
* Add the builders to the project description if the input builders do not exist in description.
*
* @param project the project to add the builder to.
* @param project the project description.
* @param buildSpecs the builders to add.
* @param monitor the progress monitor.
* @throws CoreException
*/
public static void addBuildSpec(IProject project, ICommand[] buildSpecs, IProgressMonitor monitor) throws CoreException {
SubMonitor progress = SubMonitor.convert(monitor, 1);
// get the description
IProjectDescription description = project.getDescription();
public static void addBuildSpec(IProjectDescription description, ICommand[] buildSpecs) {
List<ICommand> currentBuildSpecs = Arrays.asList(description.getBuildSpec());
List<ICommand> newSpecs = new LinkedList<>();
newSpecs.addAll(currentBuildSpecs);
for (ICommand buildSpec : buildSpecs) {
if (currentBuildSpecs.stream().anyMatch(spec -> Objects.equals(spec.getBuilderName(), buildSpec.getBuilderName()))) {
continue;
}

newSpecs.add(0, buildSpec);
}

if (newSpecs.size() == currentBuildSpecs.size()) {
return;
}
description.setBuildSpec(newSpecs.toArray(new ICommand[newSpecs.size()]));
}

/**
* Remove the builders and natures that are introduced by Buildship.
*/
public static void removeBuildshipConfigurations(IProjectDescription description) {
ICommand[] commands = description.getBuildSpec();
List<ICommand> newSpecs = new LinkedList<>();
for (ICommand command : commands) {
if (!isExcludedBuilder(command.getBuilderName())) {
newSpecs.add(command);
}
}
description.setBuildSpec(newSpecs.toArray(new ICommand[newSpecs.size()]));
project.setDescription(description, IResource.AVOID_NATURE_CONFIG, progress.newChild(1));

String[] natureIds = description.getNatureIds();
List<String> newNatureIds = new LinkedList<>();
for (String natureId : natureIds) {
if (!Objects.equals(natureId, "org.eclipse.buildship.core.gradleprojectnature")) {
newNatureIds.add(natureId);
}
}
description.setNatureIds(newNatureIds.toArray(new String[newNatureIds.size()]));
}

private static boolean isExcludedBuilder(String builderName) {
return Objects.equals(builderName, JavaCore.BUILDER_ID)
|| Objects.equals(builderName, "org.eclipse.buildship.core.gradleprojectbuilder");
}

/**
Expand Down
5 changes: 2 additions & 3 deletions extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -831,12 +831,11 @@
"java.gradle.buildServer.enabled": {
"type": "string",
"enum": [
"auto",
"on",
"off"
],
"markdownDescription": "[Experimental] Use build server to synchronize Gradle project when enabled. When set to `auto`, the build server will be enabled in Visual Studio Code - Insiders.",
"default": "auto"
"markdownDescription": "Whether to use build server to synchronize Gradle project. It will replace the original Buildship to import the Gradle when enabled.",
"default": "on"
},
"java.gradle.buildServer.openBuildOutput": {
"type": "string",
Expand Down
39 changes: 38 additions & 1 deletion extension/src/bs/BuildServerController.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
import { Disposable, ExtensionContext, OutputChannel, commands, languages, window } from "vscode";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import {
ConfigurationChangeEvent,
Disposable,
ExtensionContext,
OutputChannel,
commands,
languages,
window,
workspace,
} from "vscode";
import { GradleBuildLinkProvider } from "./GradleBuildLinkProvider";
import { sendInfo } from "vscode-extension-telemetry-wrapper";
import { OpenBuildOutputValue, getOpenBuildOutput } from "../util/config";
import * as path from "path";
import * as fse from "fs-extra";

const APPEND_BUILD_LOG_CMD = "_java.gradle.buildServer.appendBuildLog";
const LOG_CMD = "_java.gradle.buildServer.log";
Expand Down Expand Up @@ -48,6 +62,29 @@ export class BuildServerController implements Disposable {
commands.registerCommand(SEND_TELEMETRY_CMD, (jsonString: string) => {
const log = JSON.parse(jsonString);
sendInfo("", log);
}),
workspace.onDidChangeConfiguration((e: ConfigurationChangeEvent) => {
if (e.affectsConfiguration("java.gradle.buildServer.enabled")) {
const storagePath = context.storageUri?.fsPath;
if (!storagePath) {
return;
}

const msg =
"Please reload to make the change of 'java.gradle.buildServer.enabled' take effect. Reload now?";
const action = "Reload";
window.showWarningMessage(msg, action).then(async (selection) => {
if (action === selection) {
// generate a flag file to make it a clean reload.
// https://github.com/redhat-developer/vscode-java/blob/d02cf8ecfee1f3f528770a51ada825d522356967/src/settings.ts#L46
const jlsWorkspacePath = path.resolve(storagePath, "..", "redhat.java", "jdt_ws");
await fse.ensureDir(jlsWorkspacePath);
const flagFile = path.resolve(jlsWorkspacePath, ".cleanWorkspace");
await fse.writeFile(flagFile, "");
commands.executeCommand("workbench.action.reloadWindow");
}
});
}
})
);
}
Expand Down
3 changes: 3 additions & 0 deletions extension/src/bs/GradleBuildLinkProvider.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import { DocumentLink, DocumentLinkProvider, ProviderResult, Range, TextDocument, Uri } from "vscode";

export class GradleBuildLinkProvider implements DocumentLinkProvider {
Expand Down

0 comments on commit 1c6cda4

Please sign in to comment.