forked from devcontainers/cli
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathworkspaces.ts
More file actions
106 lines (94 loc) · 3.69 KB
/
Copy pathworkspaces.ts
File metadata and controls
106 lines (94 loc) · 3.69 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
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as path from 'path';
import { parse } from 'jsonc-parser';
import { URI } from 'vscode-uri'; // avoid vscode.Uri reference for tests
export interface Workspace {
readonly isWorkspaceFile: boolean;
readonly workspaceOrFolderPath: string;
readonly rootFolderPath: string;
readonly configFolderPath: string;
}
export function workspaceFromPath(path_: typeof path.posix | typeof path.win32, workspaceOrFolderPath: string): Workspace {
if (isWorkspacePath(workspaceOrFolderPath)) {
const workspaceFolder = path_.dirname(workspaceOrFolderPath);
return {
isWorkspaceFile: true,
workspaceOrFolderPath,
rootFolderPath: workspaceFolder, // use workspaceFolder as root folder
configFolderPath: workspaceFolder, // have config file in workspaceFolder (to be discussed...)
};
}
return {
isWorkspaceFile: false,
workspaceOrFolderPath,
rootFolderPath: workspaceOrFolderPath,
configFolderPath: workspaceOrFolderPath,
};
}
export function isWorkspacePath(workspaceOrFolderPath: string) {
return path.extname(workspaceOrFolderPath) === '.code-workspace'; // TODO: Remove VS Code specific code.
}
export async function canUseWorkspacePathInRemote(cliHost: { platform: NodeJS.Platform; path: typeof path.posix | typeof path.win32; readFile(filepath: string): Promise<Buffer> }, workspace: Workspace): Promise<string | undefined> {
if (!workspace.isWorkspaceFile) {
return undefined;
}
try {
const rootFolder = workspace.rootFolderPath;
const workspaceFileContent = (await cliHost.readFile(workspace.workspaceOrFolderPath)).toString();
const workspaceFile = parse(workspaceFileContent);
const folders = workspaceFile['folders'];
if (folders && folders.length > 0) {
for (const folder of folders) {
const folderPath = folder['path'];
let fullPath;
if (!folderPath) {
const folderURI = folder['uri'];
if (!folderURI) {
return `Workspace contains a folder that defines neither a path nor a URI.`;
}
const uri = URI.parse(folderURI);
if (uri.scheme !== 'file') {
return `Workspace contains folder '${folderURI}' not on the local file system.`;
}
return `Workspace contains an absolute folder path '${folderURI}'.`;
} else {
if (cliHost.path.isAbsolute(folderPath)) {
return `Workspace contains an absolute folder path '${folderPath}'.`;
}
fullPath = cliHost.path.resolve(rootFolder, folderPath);
}
if (!isEqualOrParent(cliHost, fullPath, rootFolder)) {
return `Folder '${fullPath}' is not a subfolder of shared root folder '${rootFolder}'.`;
}
}
return;
}
return `Workspace does not define any folders`;
} catch (e) {
return `Problems loading workspace file ${workspace.workspaceOrFolderPath}: ${e && (e.message || e.toString())}`;
}
}
export function isEqualOrParent(cliHost: { platform: NodeJS.Platform; path: typeof path.posix | typeof path.win32 }, c: string, parent: string): boolean {
if (c === parent) {
return true;
}
if (!c || !parent) {
return false;
}
if (parent.length > c.length) {
return false;
}
if (c.length > parent.length && c.charAt(parent.length) !== cliHost.path.sep) {
return false;
}
return equalPaths(cliHost.platform, parent, c.substr(0, parent.length));
}
function equalPaths(platform: NodeJS.Platform, a: string, b: string) {
if (platform === 'linux') {
return a === b;
}
return a.toLowerCase() === b.toLowerCase();
}