UNPKG

6.87 kBJavaScriptView Raw
1"use strict";
2
3const
4 FS = require("fs"),
5 Path = require("path"),
6 Util = require("util");
7
8
9/**
10 * @param {string} root Root folder in which we will search.
11 * @param {rx|array} filters If it is not an array, it is considered
12 * as an array with only one element. In the array, the last element
13 * is the regexp of a file to match, the other elements are regexp for
14 * containing folders.
15 * If filter is missing, return all files in `root`.
16 * @param {number} index Used internally for recursion purpose.
17 *
18 * @return {array} Array of full pathes of found files.
19 */
20function findFiles(root, filters, index) {
21 if (!FS.existsSync(root)) return [];
22 if (!isDirectory(root)) return [];
23 if (typeof index === 'undefined') index = 0;
24 if (!Array.isArray(filters)) filters = [filters];
25 if (index >= filters.length) return [];
26 var files = [];
27 var filter;
28 if (filters.length > index + 1) {
29 // Looking for directories.
30 filter = filters[index];
31 FS.readdirSync(root).forEach(
32 function(filename) {
33 if (isDirectory(Path.join(root, filename))) {
34 if (!filters || !filter || filter.test(filename)) {
35 files = files.concat(
36 findFiles(Path.join(root, filename), filters, index + 1)
37 );
38 }
39 }
40 }
41 );
42 } else {
43 // Looking for files.
44 filter = filters[index];
45 FS.readdirSync(root).forEach(
46 function(filename) {
47 if (isDirectory(Path.join(root, filename))) return;
48 if (!filters || !filter || filter.test(filename)) {
49 files.push(
50 Path.join(root, filename)
51 );
52 }
53 }
54 );
55 }
56 return files;
57}
58
59
60function findFilesByExtension(root, ext) {
61 var path;
62 var files = [];
63 var fringe = [root];
64 while (fringe.length > 0) {
65 path = fringe.pop();
66 if (FS.existsSync(path)) {
67 FS.readdirSync(path).forEach(function(filename) {
68 var file = Path.join(path, filename);
69 var stat = FS.statSync(file);
70 if (stat.isFile()) {
71 if (filename.substr(-ext.length) == ext) {
72 files.push(file);
73 }
74 } else {
75 fringe.push(file);
76 }
77 });
78 }
79 }
80 return files;
81}
82
83
84function addPrefix(path, prefix) {
85 return Path.join(
86 Path.dirname(path),
87 prefix + Path.basename(path)
88 ).split(Path.sep).join("/");
89}
90
91
92function isDirectory(path) {
93 if (!FS.existsSync(path)) return false;
94 var stat = FS.statSync(path);
95 return stat.isDirectory();
96}
97
98function mkdir() {
99 var key, arg, items = [];
100 for (key in arguments) {
101 arg = arguments[key].trim();
102 items.push(arg);
103 }
104 var path = Path.resolve(Path.normalize(items.join("/"))),
105 item, i,
106 curPath = "";
107 items = path.replace(/\\/g, '/').split("/");
108 for (i = 0; i < items.length; i++) {
109 item = items[i];
110 curPath += item + "/";
111 if (FS.existsSync(curPath)) {
112 var stat = FS.statSync(curPath);
113 if (!stat.isDirectory()) {
114 break;
115 }
116 } else {
117 try {
118 if (curPath != '.') {
119 FS.mkdirSync(curPath);
120 }
121 } catch (ex) {
122 throw { fatal: "Unable to create directory \"" + curPath + "\"!\n" + ex };
123 }
124 }
125 }
126 return path;
127}
128
129
130function rmdir(path) {
131 if (!FS.existsSync(path)) return false;
132 var stat = FS.statSync(path);
133 if (stat.isDirectory()) {
134 FS.readdirSync(path).forEach(
135 function(filename) {
136 var fullpath = Path.join(path, filename);
137 try {
138 rmdir(fullpath);
139 } catch (ex) {
140 console.error(`Unable to remove directory "${fullpath.redBG.white}"!`);
141 console.error(("" + ex).red);
142 }
143 }
144 );
145 try {
146 FS.rmdirSync(path);
147 } catch (err) {
148 console.error("Unable to remove directory '" + path + "'!");
149 console.error(err);
150 }
151 } else {
152 try {
153 FS.unlinkSync(path);
154 } catch (err) {
155 console.error("Unable to delete file '" + path + "'!");
156 console.error(err);
157 }
158 }
159 return true;
160}
161
162/**
163 * Read or write the content of a file.
164 *
165 * If `content` is undefined, the content is read, otherwise it is
166 * written.
167 * If the file to be written is in a non-existent subfolder, the whole
168 * path will be created with the `mkdir`function.
169 *
170 * @param {string} path - Path of the file to read or write.
171 * @param {string} content - Optional. If omitted, we return the content of the file.
172 * Otherwise, we save this content to the file.
173 * @returns {string} The file content.
174 */
175function file(path, content) {
176 try {
177 if (typeof content === 'undefined') {
178 if (!FS.existsSync(path)) return null;
179 return FS.readFileSync(path);
180 }
181 const dir = Path.dirname(path);
182 mkdir(dir);
183 FS.writeFileSync(path, content);
184 return content;
185 } catch (ex) {
186 console.warn("content:", content);
187 throw new Error(`${ex}\n...in pathutils/file("${path}", ${typeof content})`);
188 }
189}
190
191/**
192 * @return `true` if `sourcePath` exists and is more recent than `referencePath`./
193 * `true` if `referencePath` does not exist.
194 * `false` otherwise.
195 */
196function isNewer(sourcePath, referencePath) {
197 if (!FS.existsSync(referencePath)) return true;
198 if (!FS.existsSync(sourcePath)) return false;
199 var statSrc = FS.statSync(sourcePath);
200 var statRef = FS.statSync(referencePath);
201 var timeSrc = statSrc.mtime.getTime();
202 var timeRef = statRef.mtime.getTime();
203 return timeSrc > timeRef;
204}
205
206/**
207 * Set current date as modification time to a file.
208 */
209function touch(path) {
210 if (FS.existsSync(path)) {
211 var now = Date.now();
212 var fd = FS.openSync(path, "w");
213 FS.futimes(fd, now, now);
214 FS.closeSync(fd);
215 }
216}
217
218exports.findFilesByExtension = findFilesByExtension;
219exports.findFiles = findFiles;
220exports.addPrefix = addPrefix;
221exports.mkdir = mkdir;
222exports.rmdir = rmdir;
223exports.file = file;
224exports.isDirectory = isDirectory;
225exports.isNewer = isNewer;
226exports.touch = touch;
\No newline at end of file