forked from microsoft/vscode-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfs-paths.ts
More file actions
144 lines (129 loc) · 4.78 KB
/
Copy pathfs-paths.ts
File metadata and controls
144 lines (129 loc) · 4.78 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
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
144
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import * as nodepath from 'path';
import { getOSType, OSType } from '../utils/platform';
import { IExecutables, IFileSystemPaths, IFileSystemPathUtils } from './types';
// tslint:disable-next-line:no-var-requires no-require-imports
const untildify = require('untildify');
// The parts of node's 'path' module used by FileSystemPaths.
interface INodePath {
sep: string;
join(...filenames: string[]): string;
dirname(filename: string): string;
basename(filename: string, ext?: string): string;
normalize(filename: string): string;
}
export class FileSystemPaths implements IFileSystemPaths {
constructor(
// "true" if targeting a case-insensitive host (like Windows)
private readonly isCaseInsensitive: boolean,
// (effectively) the node "path" module to use
private readonly raw: INodePath
) {}
// Create a new object using common-case default values.
// We do not use an alternate constructor because defaults in the
// constructor runs counter to our typical approach.
public static withDefaults(
// default: use "isWindows"
isCaseInsensitive?: boolean
): FileSystemPaths {
if (isCaseInsensitive === undefined) {
isCaseInsensitive = getOSType() === OSType.Windows;
}
return new FileSystemPaths(
isCaseInsensitive,
// Use the actual node "path" module.
nodepath
);
}
public get sep(): string {
return this.raw.sep;
}
public join(...filenames: string[]): string {
return this.raw.join(...filenames);
}
public dirname(filename: string): string {
return this.raw.dirname(filename);
}
public basename(filename: string, suffix?: string): string {
return this.raw.basename(filename, suffix);
}
public normalize(filename: string): string {
return this.raw.normalize(filename);
}
public normCase(filename: string): string {
filename = this.raw.normalize(filename);
return this.isCaseInsensitive ? filename.toUpperCase() : filename;
}
}
export class Executables {
constructor(
// the $PATH delimiter to use
public readonly delimiter: string,
// the OS type to target
private readonly osType: OSType
) {}
// Create a new object using common-case default values.
// We do not use an alternate constructor because defaults in the
// constructor runs counter to our typical approach.
public static withDefaults(): Executables {
return new Executables(
// Use node's value.
nodepath.delimiter,
// Use the current OS.
getOSType()
);
}
public get envVar(): string {
return this.osType === OSType.Windows ? 'Path' : 'PATH';
}
}
// The dependencies FileSystemPathUtils has on node's path module.
interface IRawPaths {
relative(relpath: string, rootpath: string): string;
}
export class FileSystemPathUtils implements IFileSystemPathUtils {
constructor(
// the user home directory to use (and expose)
public readonly home: string,
// the low-level FS path operations to use (and expose)
public readonly paths: IFileSystemPaths,
// the low-level OS "executables" to use (and expose)
public readonly executables: IExecutables,
// other low-level FS path operations to use
private readonly raw: IRawPaths
) {}
// Create a new object using common-case default values.
// We do not use an alternate constructor because defaults in the
// constructor runs counter to our typical approach.
public static withDefaults(
// default: a new FileSystemPaths object (using defaults)
paths?: IFileSystemPaths
): FileSystemPathUtils {
if (paths === undefined) {
paths = FileSystemPaths.withDefaults();
}
return new FileSystemPathUtils(
// Use the current user's home directory.
untildify('~'),
paths,
Executables.withDefaults(),
// Use the actual node "path" module.
nodepath
);
}
public arePathsSame(path1: string, path2: string): boolean {
path1 = this.paths.normCase(path1);
path2 = this.paths.normCase(path2);
return path1 === path2;
}
public getDisplayName(filename: string, cwd?: string): string {
if (cwd && filename.startsWith(cwd)) {
return `.${this.paths.sep}${this.raw.relative(cwd, filename)}`;
} else if (filename.startsWith(this.home)) {
return `~${this.paths.sep}${this.raw.relative(this.home, filename)}`;
} else {
return filename;
}
}
}