microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
3a0bfdb2c230b6319fe09bfd70e3bae29d0fe088

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/common/node/fileSystem.ts

206lines · 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 fs from "fs";
5import * as path from "path";
6import * as Q from "q";
7
8export class FileSystem {
9
10 public ensureDirectory(dir: string): Q.Promise<void> {
11 return Q.nfcall(fs.stat, dir).then((stat: fs.Stats): void => {
12 if (stat.isDirectory()) {
13 return;
14 }
15 throw new Error(`Expected ${dir} to be a directory`);
16 }, (err: Error & { code?: string }): Q.Promise<any> => {
17 if (err && err.code === "ENOENT") {
18 return Q.nfcall(fs.mkdir, dir);
19 }
20 throw err;
21 });
22 }
23
24 public ensureFileWithContents(file: string, contents: string): Q.Promise<void> {
25 return Q.nfcall(fs.stat, file).then((stat: fs.Stats) => {
26 if (!stat.isFile()) {
27 throw new Error(`Expected ${file} to be a file`);
28 }
29
30 return this.readFile(file).then(existingContents => {
31 if (contents !== existingContents) {
32 return this.writeFile(file, contents);
33 }
34 });
35 }, (err: Error & { code?: string }): Q.Promise<any> => {
36 if (err && err.code === "ENOENT") {
37 return Q.nfcall(fs.writeFile, file, contents);
38 }
39 throw err;
40 });
41 }
42
43 /**
44 * Helper function to check if a file or directory exists
45 */
46 public existsSync(filename: string) {
47 try {
48 fs.statSync(filename);
49 return true;
50 } catch (error) {
51 return false;
52 }
53 }
54
55 /**
56 * Helper (asynchronous) function to check if a file or directory exists
57 */
58 public exists(filename: string): Q.Promise<boolean> {
59 return Q.nfcall(fs.stat, filename)
60 .then(function() {
61 return Q.resolve(true);
62 })
63 .catch(function(err) {
64 return Q.resolve(false);
65 });
66 }
67
68 /**
69 * Helper async function to read the contents of a directory
70 */
71 public readDir(directory: string): Q.Promise<string[]> {
72 return Q.nfcall<string[]>(fs.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 fs.mkdirSync(dirPath);
85 }
86
87 /**
88 * Helper function to asynchronously copy a file
89 */
90 public copyFile(from: string, to: string, encoding?: string): Q.Promise<void> {
91 let deferred: Q.Deferred<void> = Q.defer<void>();
92 let destFile: fs.WriteStream = fs.createWriteStream(to, { encoding: encoding });
93 let srcFile: fs.ReadStream = fs.createReadStream(from, { encoding: encoding });
94 destFile.on("finish", function(): void {
95 deferred.resolve(void 0);
96 });
97
98 destFile.on("error", function(e: Error): void {
99 deferred.reject(e);
100 });
101
102 srcFile.on("error", function(e: Error): void {
103 deferred.reject(e);
104 });
105
106 srcFile.pipe(destFile);
107 return deferred.promise;
108 }
109
110 public deleteFileIfExistsSync(filename: string) {
111 if (this.existsSync(filename)) {
112 fs.unlinkSync(filename);
113 }
114 }
115
116 public readFile(filename: string, encoding: string = "utf8"): Q.Promise<string> {
117 return Q.nfcall<string>(fs.readFile, filename, encoding);
118 }
119
120 public writeFile(filename: string, data: any): Q.Promise<void> {
121 return Q.nfcall<void>(fs.writeFile, filename, data);
122 }
123
124 public unlink(filename: string): Q.Promise<void> {
125 return Q.nfcall<void>(fs.unlink, filename);
126 }
127
128 public findFilesByExtension(folder: string, extension: string): Q.Promise<string[]> {
129 return Q.nfcall(fs.readdir, folder).then((files: string[]) => {
130 const extFiles = files.filter((file: string) => path.extname(file) === `.${extension}`);
131 if (extFiles.length === 0) {
132 throw new Error(`Unable to find any ${extension} files.`);
133 }
134 return extFiles;
135 });
136 }
137
138 public mkDir(p: string): Q.Promise<void> {
139 return Q.nfcall<void>(fs.mkdir, p);
140 }
141
142 /**
143 * Recursively copy 'source' to 'target' asynchronously
144 *
145 * @param {string} source Location to copy from
146 * @param {string} target Location to copy to
147 * @returns {Q.Promise} A promise which is fulfilled when the copy completes, and is rejected on error
148 */
149 public copyRecursive(source: string, target: string): Q.Promise<void> {
150 return Q.nfcall<fs.Stats>(fs.stat, source).then(stats => {
151 if (stats.isDirectory()) {
152 return this.exists(target).then(exists => {
153 if (!exists) {
154 return Q.nfcall<void>(fs.mkdir, target);
155 }
156 })
157 .then(() => {
158 return Q.nfcall<string[]>(fs.readdir, source);
159 })
160 .then(contents => {
161 Q.all(contents.map((childPath: string): Q.Promise<void> => {
162 return this.copyRecursive(path.join(source, childPath), path.join(target, childPath));
163 }));
164 });
165 } else {
166 return this.copyFile(source, target);
167 }
168 });
169 }
170
171 public removePathRecursivelyAsync(p: string): Q.Promise<void> {
172 return this.exists(p).then(exists => {
173 if (exists) {
174 return Q.nfcall<fs.Stats>(fs.stat, p).then((stats: fs.Stats) => {
175 if (stats.isDirectory()) {
176 return Q.nfcall<string[]>(fs.readdir, p).then((childPaths: string[]) => {
177 let result = Q<void>(void 0);
178 childPaths.forEach(childPath =>
179 result = result.then<void>(() => this.removePathRecursivelyAsync(path.join(p, childPath))));
180 return result;
181 }).then(() =>
182 Q.nfcall<void>(fs.rmdir, p));
183 } else {
184 /* file */
185 return Q.nfcall<void>(fs.unlink, p);
186 }
187 });
188 }
189 });
190 }
191
192 public removePathRecursivelySync(p: string): void {
193 if (fs.existsSync(p)) {
194 let stats = fs.statSync(p);
195 if (stats.isDirectory()) {
196 let contents = fs.readdirSync(p);
197 contents.forEach(childPath =>
198 this.removePathRecursivelySync(path.join(p, childPath)));
199 fs.rmdirSync(p);
200 } else {
201 /* file */
202 fs.unlinkSync(p);
203 }
204 }
205 }
206}
207