microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
d55f3c22ee18a37c605867c8bf588451292bd24e

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/common/node/fileSystem.ts

172lines · 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((stat: nodeFs.Stats): void => {
16 if (stat.isDirectory()) {
17 return;
18 }
19 throw new Error(`Expected ${dir} to be a directory`);
20 }, (err: Error & { code?: string }): Promise<any> => {
21 if (err && err.code === "ENOENT") {
22 return this.mkDir(dir);
23 }
24 throw err;
25 });
26 }
27
28 public ensureFileWithContents(file: string, contents: string): Promise<void> {
29 return this.stat(file).then((stat: nodeFs.Stats) => {
30 if (!stat.isFile()) {
31 throw new Error(`Expected ${file} to be a file`);
32 }
33
34 return this.readFile(file).then(existingContents => {
35 if (contents !== existingContents) {
36 return this.writeFile(file, contents);
37 }
38 return Promise.resolve();
39 });
40 }, (err: Error & { code?: string }): Promise<any> => {
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 exists(filename: string): Promise<boolean> {
59 return this.stat(filename)
60 .then(() => {
61 return Promise.resolve(true);
62 })
63 .catch((err) => {
64 return Promise.resolve(false);
65 });
66 }
67
68 /**
69 * Helper async function to read the contents of a directory
70 */
71 public readDir(directory: string): Promise<string[]> {
72 return this.fs.promises.readdir(directory);
73 }
74
75 /**
76 * Helper (synchronous) function to create a directory recursively
77 */
78 public makeDirectoryRecursiveSync(dirPath: string): void {
79 let parentPath = path.dirname(dirPath);
80 if (!this.existsSync(parentPath)) {
81 this.makeDirectoryRecursiveSync(parentPath);
82 }
83
84 this.fs.mkdirSync(dirPath);
85 }
86
87 /**
88 * Helper function to asynchronously copy a file
89 */
90 public copyFile(from: string, to: string): Promise<void> {
91 return this.fs.promises.copyFile(from, to);
92 }
93
94 public deleteFileIfExistsSync(filename: string) {
95 if (this.existsSync(filename)) {
96 this.fs.unlinkSync(filename);
97 }
98 }
99
100 public readFile(filename: string, encoding: string = "utf8"): Promise<string | Buffer> {
101 return this.fs.promises.readFile(filename, { encoding });
102 }
103
104 public writeFile(filename: string, data: any): Promise<void> {
105 return this.fs.promises.writeFile(filename, data);
106 }
107
108 public unlink(filename: string): Promise<void> {
109 return this.fs.promises.unlink(filename);
110 }
111
112 public mkDir(p: string): Promise<void> {
113 return this.fs.promises.mkdir(p);
114 }
115
116 public stat(fsPath: string): Promise<nodeFs.Stats> {
117 return this.fs.promises.stat(fsPath);
118 }
119
120 public directoryExists(directoryPath: string): Promise<boolean> {
121 return this.stat(directoryPath).then(stats => {
122 return stats.isDirectory();
123 }).catch(reason => {
124 return reason.code === "ENOENT"
125 ? false
126 : Promise.reject<boolean>(reason);
127 });
128 }
129
130 /**
131 * Delete 'dirPath' if it's an empty folder. If not fail.
132 *
133 * @param {dirPath} path to the folder
134 * @returns {void} Nothing
135 */
136 public rmdir(dirPath: string): Promise<void> {
137 return this.fs.promises.rmdir(dirPath);
138 }
139
140 public async removePathRecursivelyAsync(p: string): Promise<void> {
141 const exists = await this.exists(p);
142 if (exists) {
143 const stats = await this.stat(p);
144 if (stats.isDirectory()) {
145 const childPaths = await this.readDir(p);
146 childPaths.forEach(childPath => {
147 return new Promise(() => this.removePathRecursivelyAsync(path.join(p, childPath)));
148 });
149 this.rmdir(p);
150 } else {
151 /* file */
152 return this.unlink(p);
153 }
154 }
155 return Promise.resolve();
156 }
157
158 public removePathRecursivelySync(p: string): void {
159 if (this.fs.existsSync(p)) {
160 let stats = this.fs.statSync(p);
161 if (stats.isDirectory()) {
162 let contents = this.fs.readdirSync(p);
163 contents.forEach(childPath =>
164 this.removePathRecursivelySync(path.join(p, childPath)));
165 this.fs.rmdirSync(p);
166 } else {
167 /* file */
168 this.fs.unlinkSync(p);
169 }
170 }
171 }
172}
173