-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathworkspaceUtils.ts
More file actions
109 lines (97 loc) · 4.73 KB
/
workspaceUtils.ts
File metadata and controls
109 lines (97 loc) · 4.73 KB
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
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { UserCancelledError, type IActionContext, type IAzureQuickPickItem } from "@microsoft/vscode-azext-utils";
import { basename, relative } from "path";
import { RelativePattern, Uri, window, workspace, type OpenDialogOptions, type WorkspaceFolder } from "vscode";
import { browseItem, dockerfileGlobPattern, envFileGlobPattern } from "../constants";
import { type SetTelemetryProps } from "../telemetry/SetTelemetryProps";
import { type WorkspaceFileTelemetryProps as TelemetryProps } from "../telemetry/WorkspaceFileTelemetryProps";
import { localize } from "./localize";
interface SelectWorkspaceFileOptions extends OpenDialogOptions {
/**
* Include a 'skipForNow` option in the prompting. Selection of `skipForNow` should correspond to a value of `undefined`
*/
allowSkip?: boolean;
/**
* Optional label for the 'skipForNow' option; will default to 'Skip for now' if not provided
*/
skipLabel?: string;
/**
* If searching through the workspace file path returns only one matching result, automatically return its path without additional prompting
*/
autoSelectIfOne?: boolean;
}
/**
* Opens a quick pick menu with files matching the file extension filters provided, otherwise shows files in the current workspace.
*
* @returns Returns a string representing the workspace file path chosen. A return of undefined is only possible when the `allowSkip` option is set to true.
*/
export async function selectWorkspaceFile(
context: IActionContext & SetTelemetryProps<TelemetryProps> & { rootFolder?: WorkspaceFolder },
placeHolder: string,
options: SelectWorkspaceFileOptions,
globPattern?: string
): Promise<string | undefined> {
if (!workspace.workspaceFolders?.length) {
throw new Error(localize('noWorkspaceOpen', 'No workspace is open to search through.'));
} else if (workspace.workspaceFolders.length > 1 && !context.rootFolder) {
throw new Error(localize('couldNotDetermineWorkspaceFolder', 'Could not determine which workspace folder to search through.'));
}
const pattern: RelativePattern = new RelativePattern(
context.rootFolder ?? workspace.workspaceFolders[0],
globPattern ?? '**/*'
);
const files: Uri[] = await workspace.findFiles(pattern);
// If dockerfile(s), log the count
if (globPattern === dockerfileGlobPattern || globPattern === `**/${dockerfileGlobPattern}`) {
context.telemetry.properties.dockerfileCount = String(files.length);
}
// If environment variable file(s), log the count
if (globPattern === envFileGlobPattern || globPattern === `**/${envFileGlobPattern}`) {
context.telemetry.properties.environmentVariableFileCount = String(files.length);
}
if (options.autoSelectIfOne && files.length === 1) {
return files[0].fsPath;
}
const quickPicks: IAzureQuickPickItem<string | undefined>[] = [];
quickPicks.push(...files.map((uri: Uri) => {
return {
label: basename(uri.path),
description: relative(pattern.baseUri.path, uri.path),
data: uri.fsPath
};
}));
quickPicks.push(browseItem);
const skipForNow: string = 'skipForNow';
if (options.allowSkip) {
quickPicks.push({
label: options.skipLabel ?? localize('skipForNow', '$(clock) Skip for now'),
description: '',
data: skipForNow
});
}
const input: string | undefined = (await context.ui.showQuickPick(quickPicks, { placeHolder })).data;
if (input === skipForNow) {
return undefined;
} else {
return input || (await context.ui.showOpenDialog(options))[0].fsPath;
}
}
export async function getRootWorkspaceFolder(placeHolder?: string): Promise<WorkspaceFolder | undefined> {
if (!workspace.workspaceFolders?.length) {
return undefined;
} else if (workspace.workspaceFolders?.length === 1) {
return workspace.workspaceFolders[0];
} else {
const folder = await window.showWorkspaceFolderPick({ placeHolder: placeHolder ?? localize('selectRootWorkspace', 'Select a folder for your workspace') });
if (!folder) {
throw new UserCancelledError('selectRootWorkspace');
}
return folder;
}
}
export function getWorkspaceFolderFromPath(path: string): WorkspaceFolder | undefined {
return workspace.workspaceFolders?.find(folder => folder.uri.fsPath === Uri.file(path).fsPath);
}