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

Add support for custom GRADLE_USER_HOME #314

Merged
merged 9 commits into from
Apr 29, 2020
Merged
Show file tree
Hide file tree
Changes from all 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
46 changes: 33 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,16 @@ Run Gradle tasks in VS Code.

## Features

This extension provides a UI layer over Gradle builds. It shows Gradle projects and tasks and allows you to run tasks within the context of the editor.
This extension provides a visual interface for your Gradle build. You can view Gradle projects and run Gradle tasks.

This extension supports whatever Gradle supports and is language/project agnostic, but it can work nicely alongside other extensions like the [Java language support extension](https://github.com/redhat-developer/vscode-java).

- 👉 [All Features](./FEATURES.md)
- 👉 [Architecture Overview](./ARCHITECTURE.md)
👉 [All Features](./FEATURES.md)

## Requirements

- [Java >= 8](https://adoptopenjdk.net/) must be installed
- Local Gradle wrapper executables must exist at the root of the workspace folders (either `gradlew` or `gradlew.bat`, depending on your environment)
- Local Gradle wrapper executables must exist at the root of the workspace folders

## Settings

Expand All @@ -37,13 +36,31 @@ This extension contributes the following settings:

This extension supports the following settings:

- `java.home`: Absolute path to JDK home folder used to launch the gradle daemons. (Contributed by [vscode-java](https://github.com/redhat-developer/vscode-java).)
- `java.home`: Absolute path to JDK home folder used to launch the gradle daemons (Contributed by [vscode-java](https://github.com/redhat-developer/vscode-java))
- `java.import.gradle.user.home`: Setting for GRADLE_HOME (Contributed by [vscode-java](https://github.com/redhat-developer/vscode-java))

## Supported Environment Variables

Most of the standard Java & Gradle environment variables are supported:

- `JAVE_HOME` (overridden by `java.home`)
- `GRADLE_USER_HOME` (overridden by `java.import.gradle.user.home`)

### Setting Project Environment Variables

## Usage
You can use an environment manager like [direnv](https://direnv.net/) to set project specific environment variables, or set the variables in the terminal settings within `.vscode/settings.json`, for example:

```json
{
"terminal.integrated.env.osx": {
"GRADLE_USER_HOME": "${workspaceFolder}/.gradle"
}
}
```

Open a Gradle project to use the extension. The extension first starts a process to discover tasks, and progress for this process is reported in the statusbar. Once tasks are discovered, a "Gradle Tasks" view is displayed in the explorer view, where you can view the Gradle project & task hierarchy and run specific tasks. You can also run Gradle tasks via vscode tasks by executing the "Run Task" command from the Command Palette and choosing a Gradle task.
Note, the VS Code settings take precedence over the environment variables.

### Debugging JavaExec Tasks
## Debugging JavaExec Tasks

![Debug Screencast](images/debug-screencast.gif)

Expand All @@ -63,7 +80,7 @@ To enable this feature you need to specify which tasks can be debugged within yo

You should now see a `debug` command next to the `run` command in the Gradle Tasks view. The `debug` command will start the Gradle task with [jdwp](https://docs.oracle.com/en/java/javase/11/docs/specs/jpda/conninv.html#oracle-vm-invocation-options) `jvmArgs` and start the vscode Java debugger.

#### Debugging Limitations
### Debugging Limitations

You'll need to remove any `jdwp` options that might have been set in your task configuration (eg via `jvmArgs`).

Expand Down Expand Up @@ -160,21 +177,24 @@ The reason for the incompatibility is due to the extensions providing the same t

</details>

## Contributing

Refer to [CONTRIBUTING.md](./CONTRIBUTING.md) for instructions on how to run the project.

## Support

For general support queries, use the [#gradle-tasks](https://vscode-dev-community.slack.com/archives/C011NUFTHLM) channel in the [slack development community workspace](https://aka.ms/vscode-dev-community), or

- 👉 [Submit a bug report](https://github.com/badsyntax/vscode-gradle/issues/new?assignees=badsyntax&labels=bug&template=bug_report.md&title=)
- 👉 [Submit a feature request](https://github.com/badsyntax/vscode-gradle/issues/new?assignees=badsyntax&labels=enhancement&template=feature_request.md&title=)

## Contributing

Refer to [CONTRIBUTING.md](./CONTRIBUTING.md) for instructions on how to run the project.

- 👉 [Architecture Overview](./ARCHITECTURE.md)

## Credits

- Originally forked from [Cazzar/vscode-gradle](https://github.com/Cazzar/vscode-gradle)
- Inspired by the built-in [npm extension](https://github.com/microsoft/vscode/tree/master/extensions/npm)
- Thanks to all who have submitted bug reports and feedback 👍

## Release Notes

Expand Down
5 changes: 5 additions & 0 deletions extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -349,21 +349,25 @@
"gradle.enableTasksExplorer": {
"type": "boolean",
"default": true,
"scope": "resource",
"description": "%extension.config.enableTasksExplorer.description%"
},
"gradle.debug": {
"type": "boolean",
"default": false,
"scope": "window",
"description": "%extension.config.debug.description%"
},
"gradle.focusTaskInExplorer": {
"type": "boolean",
"default": true,
"scope": "resource",
"description": "%extension.config.focusTaskInExplorer.description%"
},
"gradle.javaDebug": {
"type": "object",
"description": "%extension.config.javaDebug.description%",
"scope": "resource",
"properties": {
"tasks": {
"type": "array",
Expand Down Expand Up @@ -393,6 +397,7 @@
"gradle.taskPresentationOptions": {
"type": "object",
"description": "%extension.config.taskPresentationOptions.description%",
"scope": "resource",
"properties": {
"reveal": {
"type": "string",
Expand Down
30 changes: 27 additions & 3 deletions extension/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
Cancelled,
GradleBuild,
CancelRunTasksRequest,
Environment,
} from './proto/gradle_tasks_pb';

import { GradleTasksClient as GrpcClient } from './proto/gradle_tasks_grpc_pb';
Expand Down Expand Up @@ -94,15 +95,22 @@ export class GradleTasksClient implements vscode.Disposable {
}
}

public async getBuild(projectFolder: string): Promise<GradleBuild | void> {
public async getBuild(
projectFolder: string,
gradleUserHome: string | null
): Promise<GradleBuild | void> {
this.statusBarItem.text = localize(
// TODO
'client.refreshingTasks',
'{0} Gradle: Refreshing Tasks',
'{0} Gradle: Building...',
'$(sync~spin)'
);
this.statusBarItem.show();
const request = new GetBuildRequest();
request.setProjectDir(projectFolder);
if (gradleUserHome) {
request.setGradleUserHome(gradleUserHome);
}
const getBuildStream = this.grpcClient!.getBuild(request);
try {
return await new Promise((resolve, reject) => {
Expand All @@ -122,6 +130,9 @@ export class GradleTasksClient implements vscode.Disposable {
case GetBuildReply.KindCase.GET_BUILD_RESULT:
build = getBuildReply.getGetBuildResult()!.getBuild();
break;
case GetBuildReply.KindCase.ENVIRONMENT:
this.handleGetBuildEnvironment(getBuildReply.getEnvironment()!);
break;
}
})
.on('error', reject)
Expand All @@ -148,17 +159,21 @@ export class GradleTasksClient implements vscode.Disposable {
task: vscode.Task,
args: string[] = [],
javaDebugPort: number | null,
gradleUserHome: string | null,
onOutput: (output: Output) => void
): Promise<void> {
this.statusBarItem.show();
const request = new RunTaskRequest();
request.setProjectDir(projectFolder);
request.setTask(task.definition.script);
request.setJavaDebug(task.definition.javaDebug);
request.setArgsList(args);
if (javaDebugPort !== null) {
request.setJavaDebugPort(javaDebugPort);
}
request.setArgsList(args);
if (gradleUserHome) {
request.setGradleUserHome(gradleUserHome);
}
const runTaskStream = this.grpcClient!.runTask(request);
try {
await new Promise((resolve, reject) => {
Expand Down Expand Up @@ -303,6 +318,15 @@ export class GradleTasksClient implements vscode.Disposable {
}
}

private handleGetBuildEnvironment(environment: Environment): void {
const javaEnv = environment.getJavaEnvironment()!;
const gradleEnv = environment.getGradleEnvironment()!;
logger.info('Java Home:', javaEnv.getJavaHome());
logger.info('JVM Args:', javaEnv.getJvmArgsList().join(','));
logger.info('Gradle User Home:', gradleEnv.getGradleUserHome());
logger.info('Gradle Version:', gradleEnv.getGradleVersion());
}

private handleRunTaskCancelled = (
task: vscode.Task,
cancelled: Cancelled
Expand Down
6 changes: 6 additions & 0 deletions extension/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ export function getConfigJavaHome(): string | null {
.get<string | null>('home', null);
}

export function getConfigJavaImportGradleUserHome(): string | null {
return vscode.workspace
.getConfiguration('java')
.get<string | null>('import.gradle.user.home', null);
}

export function getConfigIsDebugEnabled(): boolean {
return vscode.workspace
.getConfiguration('gradle')
Expand Down
1 change: 1 addition & 0 deletions extension/src/gradleView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ export class GradleTasksTreeDataProvider
'gradle:explorerCollapsed',
collapsed
);
this.buildTreeItems();
this.render();
}

Expand Down
16 changes: 8 additions & 8 deletions extension/src/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,21 @@ export class Logger {
return `[${type}] ${message}`;
}

public info(message: string): void {
this.log(message, 'info');
public info(...messages: string[]): void {
this.log(messages.join(' '), 'info');
}

public warning(message: string): void {
this.log(message, 'warning');
public warning(...messages: string[]): void {
this.log(messages.join(' '), 'warning');
}

public error(message: string): void {
this.log(message, 'error');
public error(...messages: string[]): void {
this.log(messages.join(' '), 'error');
}

public debug(message: string): void {
public debug(...messages: string[]): void {
if (getConfigIsDebugEnabled() || isTest()) {
this.log(message, 'debug');
this.log(messages.join(' '), 'debug');
}
}

Expand Down
40 changes: 28 additions & 12 deletions extension/src/tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
ConfigTaskPresentationOptionsPanelKind,
ConfigTaskPresentationOptions,
getConfigTaskPresentationOptions,
getConfigJavaImportGradleUserHome,
} from './config';
import { logger } from './logger';
import { GradleTasksClient } from './client';
Expand Down Expand Up @@ -122,15 +123,14 @@ export function getRestartingTask(task: vscode.Task): vscode.Task | void {
return restartingTasks.get(task.definition.id);
}

async function hasGradleBuildFile(
folder: vscode.WorkspaceFolder
): Promise<boolean> {
const files = fg.sync('*{.gradle,.gradle.kts}', {
function getGradleBuildFile(folder: vscode.WorkspaceFolder): string {
const files = fg.sync('!(*settings){.gradle,.gradle.kts}', {
onlyFiles: true,
cwd: folder.uri.fsPath,
deep: 1,
absolute: true,
});
return files.length > 0;
return files[0];
}

function getTaskPresentationOptions(): vscode.TaskPresentationOptions {
Expand Down Expand Up @@ -166,11 +166,15 @@ export class GradleTaskProvider implements vscode.TaskProvider {
const allTasks: vscode.Task[] = [];
const taskPresentationOptions = getTaskPresentationOptions();
for (const workspaceFolder of folders) {
if (
getConfigIsAutoDetectionEnabled(workspaceFolder) &&
hasGradleBuildFile(workspaceFolder)
) {
const gradleBuild = await this.getGradleBuild(workspaceFolder);
if (getConfigIsAutoDetectionEnabled(workspaceFolder)) {
const buildFile = getGradleBuildFile(workspaceFolder);
if (!buildFile) {
continue;
}
const gradleBuild = await this.getGradleBuild(
workspaceFolder,
vscode.Uri.file(buildFile)
);
const gradleProject = gradleBuild && gradleBuild.getProject();
if (gradleProject) {
allTasks.push(
Expand Down Expand Up @@ -214,9 +218,19 @@ export class GradleTaskProvider implements vscode.TaskProvider {
}

private async getGradleBuild(
projectFolder: vscode.WorkspaceFolder
projectFolder: vscode.WorkspaceFolder,
buildFile: vscode.Uri
): Promise<GradleBuild | void> {
return await this.client?.getBuild(projectFolder.uri.fsPath);
const gradleUserHome = getConfigJavaImportGradleUserHome();
const build = await this.client?.getBuild(
projectFolder.uri.fsPath,
gradleUserHome
);
vscode.commands.executeCommand(
'gradle.updateJavaProjectConfiguration',
buildFile
);
return build;
}

private getVSCodeTasksFromGradleProject(
Expand Down Expand Up @@ -399,11 +413,13 @@ class CustomBuildTaskTerminal implements vscode.Pseudoterminal {
try {
const javaDebugEnabled = this.task.definition.javaDebug;
const javaDebugPort = javaDebugEnabled ? await getPort() : null;
const gradleUserHome = getConfigJavaImportGradleUserHome();
const runTask = this.client.runTask(
this.projectFolder,
this.task,
args,
javaDebugPort,
gradleUserHome,
(output: Output): void => {
this.handleOutput(output.getMessage().trim());
}
Expand Down
22 changes: 21 additions & 1 deletion proto/gradle_tasks.proto
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,18 @@ message CancelGetBuildsReply { string message = 1; }

message GetTasksRequest { string project_dir = 1; }

message GetBuildRequest { string project_dir = 1; }
message GetBuildRequest {
string project_dir = 1;
string gradle_user_home = 2;
}

message GetBuildReply {
oneof kind {
GetBuildResult get_build_result = 1;
Progress progress = 2;
Output output = 3;
Cancelled cancelled = 4;
Environment environment = 5;
}
}

Expand All @@ -47,6 +51,7 @@ message RunTaskRequest {
repeated string args = 3;
bool java_debug = 4;
int32 java_debug_port = 5;
string gradle_user_home = 6;
}

message RunTaskResult {
Expand Down Expand Up @@ -105,6 +110,21 @@ message Cancelled {

message Progress { string message = 1; }

message Environment {
JavaEnvironment java_environment = 1;
GradleEnvironment gradle_environment = 2;
}

message JavaEnvironment {
string java_home = 1;
repeated string jvm_args = 2;
}

message GradleEnvironment {
string gradle_user_home = 1;
string gradle_version = 2;
}

message Output {
enum OutputType {
STDERR = 0;
Expand Down
Loading