forked from swiftlang/vscode-swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSwiftPluginTaskProvider.ts
143 lines (132 loc) · 5.03 KB
/
SwiftPluginTaskProvider.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//===----------------------------------------------------------------------===//
//
// This source file is part of the VSCode Swift open source project
//
// Copyright (c) 2021-2022 the VSCode Swift project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of VSCode Swift project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
import * as vscode from "vscode";
import * as path from "path";
import { WorkspaceContext } from "./WorkspaceContext";
import { PackagePlugin } from "./SwiftPackage";
import configuration from "./configuration";
import { getSwiftExecutable, swiftRuntimeEnv, withSwiftFlags } from "./utilities/utilities";
// Interface class for defining task configuration
interface TaskConfig {
cwd: vscode.Uri;
scope: vscode.WorkspaceFolder;
presentationOptions?: vscode.TaskPresentationOptions;
prefix?: string;
}
/**
* A {@link vscode.TaskProvider TaskProvider} for tasks that match the definition
* in **package.json**: `{ type: 'swift'; command: string; args: string[] }`.
*
* See {@link SwiftTaskProvider.provideTasks provideTasks} for a list of provided tasks.
*/
export class SwiftPluginTaskProvider implements vscode.TaskProvider {
constructor(private workspaceContext: WorkspaceContext) {}
/**
* Provides tasks to run swift plugins:
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async provideTasks(token: vscode.CancellationToken): Promise<vscode.Task[]> {
if (this.workspaceContext.folders.length === 0) {
return [];
}
const tasks = [];
for (const folderContext of this.workspaceContext.folders) {
for (const plugin of folderContext.swiftPackage.plugins) {
tasks.push(
this.createSwiftPluginTask(plugin, [], {
cwd: folderContext.folder,
scope: folderContext.workspaceFolder,
presentationOptions: {
reveal: vscode.TaskRevealKind.Always,
},
})
);
}
}
return tasks;
}
/**
* Resolves a {@link vscode.Task Task} specified in **tasks.json**.
*
* Other than its definition, this `Task` may be incomplete,
* so this method should fill in the blanks.
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
resolveTask(task: vscode.Task, token: vscode.CancellationToken): vscode.Task {
// We need to create a new Task object here.
// Reusing the task parameter doesn't seem to work.
const swift = getSwiftExecutable();
const sandboxArg = task.definition.disableSandbox ? ["--disable-sandbox"] : [];
let swiftArgs = [
"package",
...sandboxArg,
task.definition.command,
...task.definition.args,
];
swiftArgs = withSwiftFlags(swiftArgs, undefined);
const newTask = new vscode.Task(
task.definition,
task.scope ?? vscode.TaskScope.Workspace,
task.definition.command,
"swift",
new vscode.ShellExecution(swift, swiftArgs, {
cwd: task.definition.cwd,
}),
task.problemMatchers
);
newTask.detail = task.detail ?? `swift ${swiftArgs.join(" ")}`;
newTask.presentationOptions = task.presentationOptions;
return newTask;
}
/**
*
* @param plugin Helper function to create a swift plugin task
* @param args arguments sent to plugin
* @param config
* @returns
*/
createSwiftPluginTask(plugin: PackagePlugin, args: string[], config: TaskConfig): vscode.Task {
const swift = getSwiftExecutable();
let swiftArgs = ["package", plugin.command, ...args];
swiftArgs = withSwiftFlags(swiftArgs, undefined);
// Add relative path current working directory
const relativeCwd = path.relative(config.scope.uri.fsPath, config.cwd?.fsPath);
const cwd = relativeCwd !== "" ? relativeCwd : undefined;
const task = new vscode.Task(
{
type: "swift-plugin",
command: plugin.command,
args: args,
disableSandbox: false,
cwd: cwd,
},
config.scope ?? vscode.TaskScope.Workspace,
plugin.name,
"swift",
new vscode.ShellExecution(swift, swiftArgs, {
cwd: cwd,
env: { ...configuration.swiftEnvironmentVariables, ...swiftRuntimeEnv() },
})
);
let prefix: string;
if (config.prefix) {
prefix = `(${config.prefix}) `;
} else {
prefix = "";
}
task.detail = `${prefix}swift ${swiftArgs.join(" ")}`;
task.presentationOptions = config?.presentationOptions ?? {};
return task;
}
}