microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
e866487435c097b8faba759339189dbe5705eea9

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/common/node/fileSystem.ts

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