microsoft/vscode-react-native

Public

mirrored fromhttps://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
f5b444ffaba7fee50748cbae19f89af3e0369438

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/common/node/fileSystem.ts

181lines · modecode

1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for details.
3
4import * as nodeFs from "fs";
5import * as path from "path";
6
7export class FileSystem {
8 private fs: typeof nodeFs;
9
10 constructor({ fs = nodeFs } = {}) {
11 this.fs = fs;
12 }
13
14 public ensureDirectory(dir: string): Promise<void> {
15 return this.stat(dir).then(
16 (stat: nodeFs.Stats): void => {
17 if (stat.isDirectory()) {
18 return;
19 }
20 throw new Error(`Expected ${dir} to be a directory`);
21 },
22 (err: Error & { code?: string }): Promise<any> => {
23 if (err && err.code === "ENOENT") {
24 return this.mkDir(dir);
25 }
26 throw err;
27 },
28 );
29 }
30
31 public ensureFileWithContents(file: string, contents: string): Promise<void> {
32 return this.stat(file).then(
33 (stat: nodeFs.Stats) => {
34 if (!stat.isFile()) {
35 throw new Error(`Expected ${file} to be a file`);
36 }
37
38 return this.readFile(file).then(existingContents => {
39 if (contents !== existingContents) {
40 return this.writeFile(file, contents);
41 }
42 return Promise.resolve();
43 });
44 },
45 (err: Error & { code?: string }): Promise<any> => {
46 if (err && err.code === "ENOENT") {
47 return this.writeFile(file, contents);
48 }
49 throw err;
50 },
51 );
52 }
53
54 /**
55 * Helper function to check if a file or directory exists
56 */
57 public existsSync(filename: string): boolean {
58 return this.fs.existsSync(filename);
59 }
60
61 /**
62 * Helper (asynchronous) function to check if a file or directory exists
63 */
64 public exists(filename: string): Promise<boolean> {
65 return this.stat(filename)
66 .then(() => {
67 return Promise.resolve(true);
68 })
69 .catch(() => {
70 return Promise.resolve(false);
71 });
72 }
73
74 /**
75 * Helper async function to read the contents of a directory
76 */
77 public readDir(directory: string): Promise<string[]> {
78 return this.fs.promises.readdir(directory);
79 }
80
81 /**
82 * Helper (synchronous) function to create a directory recursively
83 */
84 public makeDirectoryRecursiveSync(dirPath: string): void {
85 let parentPath = path.dirname(dirPath);
86 if (!this.existsSync(parentPath)) {
87 this.makeDirectoryRecursiveSync(parentPath);
88 }
89
90 this.fs.mkdirSync(dirPath);
91 }
92
93 /**
94 * Helper function to asynchronously copy a file
95 */
96 public copyFile(from: string, to: string): Promise<void> {
97 return this.fs.promises.copyFile(from, to);
98 }
99
100 public deleteFileIfExistsSync(filename: string): void {
101 if (this.existsSync(filename)) {
102 this.fs.unlinkSync(filename);
103 }
104 }
105
106 public readFile(filename: string, encoding: string = "utf8"): Promise<string | Buffer> {
107 return this.fs.promises.readFile(filename, { encoding });
108 }
109
110 public writeFile(filename: string, data: any): Promise<void> {
111 return this.fs.promises.writeFile(filename, data);
112 }
113
114 public unlink(filename: string): Promise<void> {
115 return this.fs.promises.unlink(filename);
116 }
117
118 public mkDir(p: string): Promise<void> {
119 return this.fs.promises.mkdir(p);
120 }
121
122 public stat(fsPath: string): Promise<nodeFs.Stats> {
123 return this.fs.promises.stat(fsPath);
124 }
125
126 public directoryExists(directoryPath: string): Promise<boolean> {
127 return this.stat(directoryPath)
128 .then(stats => {
129 return stats.isDirectory();
130 })
131 .catch(reason => {
132 return reason.code === "ENOENT" ? false : Promise.reject<boolean>(reason);
133 });
134 }
135
136 /**
137 * Delete 'dirPath' if it's an empty folder. If not fail.
138 *
139 * @param {dirPath} path to the folder
140 * @returns {void} Nothing
141 */
142 public rmdir(dirPath: string): Promise<void> {
143 return this.fs.promises.rmdir(dirPath);
144 }
145
146 public async removePathRecursivelyAsync(p: string): Promise<void> {
147 const exists = await this.exists(p);
148 if (exists) {
149 const stats = await this.stat(p);
150 if (stats.isDirectory()) {
151 const childPaths = await this.readDir(p);
152 await Promise.all(
153 childPaths.map(childPath =>
154 this.removePathRecursivelyAsync(path.join(p, childPath)),
155 ),
156 );
157 await this.rmdir(p);
158 } else {
159 /* file */
160 return this.unlink(p);
161 }
162 }
163 return Promise.resolve();
164 }
165
166 public removePathRecursivelySync(p: string): void {
167 if (this.fs.existsSync(p)) {
168 let stats = this.fs.statSync(p);
169 if (stats.isDirectory()) {
170 let contents = this.fs.readdirSync(p);
171 contents.forEach(childPath =>
172 this.removePathRecursivelySync(path.join(p, childPath)),
173 );
174 this.fs.rmdirSync(p);
175 } else {
176 /* file */
177 this.fs.unlinkSync(p);
178 }
179 }
180 }
181}
182