microsoft/vscode-react-native

Public

mirrored from https://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
1011f2a8b46b47563a9f79c863e8edf8fa2c3724

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/utils/node/fileSystem.ts

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