1 | (function (require, exports) {
|
2 |
|
3 | var Q = require("qq");
|
4 | var FS_BOOT = require("fs-boot");
|
5 | var ROOT = require("./root");
|
6 | var MOCK = require("./mock");
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | var concat = function (arrays) {
|
14 | return Array.prototype.concat.apply([], arrays);
|
15 | };
|
16 |
|
17 | exports.update = function (exports, workingDirectory) {
|
18 |
|
19 | for (var name in FS_BOOT)
|
20 | exports[name] = FS_BOOT[name];
|
21 |
|
22 | |
23 |
|
24 |
|
25 |
|
26 |
|
27 | exports.read = function (path, flags, charset, options) {
|
28 | if (typeof flags == "object") {
|
29 | options = flags;
|
30 | } else {
|
31 | options = options || {};
|
32 | options.flags = flags;
|
33 | options.carset = charset;
|
34 | }
|
35 | options.flags = "r" + (options.flags || "").replace(/r/g, "");
|
36 | return Q.when(exports.open(path, options), function (stream) {
|
37 | return stream.read();
|
38 | }, function (reason) {
|
39 | var message = "Can't read " + path;
|
40 | return Q.reject({
|
41 | "toString": function () {
|
42 | return JSON.stringify(this);
|
43 | },
|
44 | "message": message,
|
45 | "path": path,
|
46 | "flags": flags,
|
47 | "charset": charset,
|
48 | "cause": reason,
|
49 | "stack": new Error(message).stack
|
50 | });
|
51 | });
|
52 | };
|
53 |
|
54 | |
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 | exports.write = function (path, content, flags, charset, options) {
|
62 | if (typeof flags == "object") {
|
63 | options = flags;
|
64 | } else {
|
65 | options = options || {};
|
66 | options.flags = flags;
|
67 | options.carset = charset;
|
68 | }
|
69 | options.flags = "w" + (options.flags || "").replace(/w/g, "");
|
70 | return Q.when(exports.open(path, options), function (stream) {
|
71 | return Q.when(stream.write(content), function () {
|
72 | return stream.close();
|
73 | });
|
74 | });
|
75 | };
|
76 |
|
77 |
|
78 | exports.append = function (path, content, flags, charset, options) {
|
79 | if (typeof flags == "object") {
|
80 | options = flags;
|
81 | } else {
|
82 | options = options || {};
|
83 | options.flags = flags;
|
84 | options.carset = charset;
|
85 | }
|
86 | options.flags = "w+" + (options.flags || "").replace(/[w\+]/g, "");
|
87 | return Q.when(exports.open(path, options), function (stream) {
|
88 | return Q.when(stream.write(content), function () {
|
89 | return stream.close();
|
90 | });
|
91 | });
|
92 | };
|
93 |
|
94 |
|
95 |
|
96 | |
97 |
|
98 | exports.listTree = function (basePath, guard) {
|
99 | basePath = String(basePath || '');
|
100 | if (!basePath)
|
101 | basePath = ".";
|
102 | guard = guard || function () {
|
103 | return true;
|
104 | };
|
105 | var stat = exports.stat(basePath);
|
106 | return Q.Lazy(Array, Q.when(stat, function (stat) {
|
107 | var paths = [];
|
108 | var mode;
|
109 | try {
|
110 | var include = guard(basePath, stat);
|
111 | } catch (exception) {
|
112 | return Q.reject(exception);
|
113 | }
|
114 | return Q.when(include, function (include) {
|
115 | if (include) {
|
116 | paths.push([basePath]);
|
117 | }
|
118 | if (include !== null && stat.isDirectory()) {
|
119 | return Q.when(exports.list(basePath), function (children) {
|
120 | paths.push.apply(paths, children.map(function (child) {
|
121 | var path = exports.join(basePath, child);
|
122 | return exports.listTree(path, guard);
|
123 | }));
|
124 | return paths;
|
125 | });
|
126 | } else {
|
127 | return paths;
|
128 | }
|
129 | });
|
130 | }, function noSuchFile(reason) {
|
131 | return [];
|
132 | }).then(Q.shallow).then(concat));
|
133 | };
|
134 |
|
135 | exports.listDirectoryTree = function (path) {
|
136 | return exports.listTree(path, function (path, stat) {
|
137 | return stat.isDirectory();
|
138 | });
|
139 | };
|
140 |
|
141 | exports.makeTree = function (path, mode) {
|
142 | var parts = exports.split(path);
|
143 | var at = [];
|
144 | if (exports.isAbsolute(path))
|
145 | at.push(exports.ROOT);
|
146 | return parts.reduce(function (parent, part) {
|
147 | return Q.when(parent, function () {
|
148 | at.push(part);
|
149 | var parts = exports.join(at);
|
150 | var made = exports.makeDirectory(parts, mode);
|
151 | return Q.when(made, null, function rejected(reason) {
|
152 |
|
153 | if (reason.code == "EEXIST") {
|
154 | return;
|
155 | } else {
|
156 | return Q.reject(reason);
|
157 | }
|
158 | });
|
159 | });
|
160 | }, undefined);
|
161 | };
|
162 |
|
163 | exports.removeTree = function (path) {
|
164 | return Q.when(exports.stat(path), function (stat) {
|
165 | if (stat.isLink()) {
|
166 | return exports.remove(path);
|
167 | } else if (stat.isDirectory()) {
|
168 | var list = exports.list(path);
|
169 | return Q.when(list, function (list) {
|
170 |
|
171 | var done = list.reduce(function (prev, name) {
|
172 | var child = exports.join(path, name);
|
173 | var next = exports.removeTree(child);
|
174 |
|
175 | return Q.when(prev, function () {
|
176 | return next;
|
177 | });
|
178 | });
|
179 | return Q.when(done, function () {
|
180 | exports.removeDirectory(path);
|
181 | });
|
182 | });
|
183 | } else {
|
184 | return exports.remove(path);
|
185 | }
|
186 | });
|
187 | };
|
188 |
|
189 | exports.exists = function (path) {
|
190 | return Q.when(exports.stat(path), function () {
|
191 | return true;
|
192 | }, function () {
|
193 | return false;
|
194 | });
|
195 | };
|
196 |
|
197 | exports.isFile = function (path) {
|
198 | return Q.when(exports.stat(path), function (stat) {
|
199 | return stat.isFile();
|
200 | }, function (reason) {
|
201 | return false;
|
202 | });
|
203 | };
|
204 |
|
205 | exports.isDirectory = function (path) {
|
206 | return Q.when(exports.stat(path), function (stat) {
|
207 | return stat.isDirectory();
|
208 | }, function (reason) {
|
209 | return false;
|
210 | });
|
211 | };
|
212 |
|
213 | exports.absolute = function (path) {
|
214 | if (exports.isAbsolute(path))
|
215 | return path;
|
216 | return exports.join(workingDirectory(), path);
|
217 | };
|
218 |
|
219 | exports.relative = function (source, target) {
|
220 | return Q.when(exports.isDirectory(source), function (isDirectory) {
|
221 | if (isDirectory) {
|
222 | return exports.relativeFromDirectory(source, target);
|
223 | } else {
|
224 | return exports.relativeFromFile(source, target);
|
225 | }
|
226 | });
|
227 | };
|
228 |
|
229 | exports.relativeFromFile = function (source, target) {
|
230 | source = exports.absolute(source);
|
231 | target = exports.absolute(target);
|
232 | source = source.split(exports.SEPARATORS_RE());
|
233 | target = target.split(exports.SEPARATORS_RE());
|
234 | source.pop();
|
235 | while (
|
236 | source.length &&
|
237 | target.length &&
|
238 | target[0] == source[0]
|
239 | ) {
|
240 | source.shift();
|
241 | target.shift();
|
242 | }
|
243 | while (source.length) {
|
244 | source.shift();
|
245 | target.unshift("..");
|
246 | }
|
247 | return target.join(exports.SEPARATOR);
|
248 | };
|
249 |
|
250 | exports.relativeFromDirectory = function (source, target) {
|
251 | if (!target) {
|
252 | target = source;
|
253 | source = workingDirectory();
|
254 | }
|
255 | source = exports.absolute(source);
|
256 | target = exports.absolute(target);
|
257 | source = source.split(exports.SEPARATORS_RE());
|
258 | target = target.split(exports.SEPARATORS_RE());
|
259 | if (source.length === 2 && source[1] === "")
|
260 | source.pop();
|
261 | while (
|
262 | source.length &&
|
263 | target.length &&
|
264 | target[0] == source[0]
|
265 | ) {
|
266 | source.shift();
|
267 | target.shift();
|
268 | }
|
269 | while (source.length) {
|
270 | source.shift();
|
271 | target.unshift("..");
|
272 | }
|
273 | return target.join(exports.SEPARATOR);
|
274 | };
|
275 |
|
276 | exports.contains = function (parent, child) {
|
277 | var i, ii;
|
278 | parent = exports.absolute(parent);
|
279 | child = exports.absolute(child);
|
280 | parent = parent.split(exports.SEPARATORS_RE());
|
281 | child = child.split(exports.SEPARATORS_RE());
|
282 | if (parent.length === 2 && parent[1] === "")
|
283 | parent.pop();
|
284 | if (parent.length > child.length)
|
285 | return false;
|
286 | for (i = 0, ii = parent.length; i < ii; i++) {
|
287 | if (parent[i] !== child[i])
|
288 | break;
|
289 | }
|
290 | return i == ii;
|
291 | };
|
292 |
|
293 | exports.reroot = reroot;
|
294 | function reroot(path) {
|
295 | path = path || exports.ROOT;
|
296 | return Q.when(exports.list(path), function (list) {
|
297 | if (list.length !== 1)
|
298 | return ROOT.Fs(exports, path);
|
299 | var nextPath = exports.join(path, list[0]);
|
300 | return Q.when(exports.stat(nextPath), function (stat) {
|
301 | if (stat.isDirectory()) {
|
302 | return reroot(nextPath);
|
303 | } else {
|
304 | return ROOT.Fs(exports, path);
|
305 | }
|
306 | });
|
307 | });
|
308 | }
|
309 |
|
310 | exports.toObject = function (path) {
|
311 | var list = exports.listTree(path || "", function (path, stat) {
|
312 | return stat.isFile();
|
313 | });
|
314 | return Q.when(list, function (list) {
|
315 | var tree = {};
|
316 | var done;
|
317 | list.forEach(function (path) {
|
318 | tree[path] = exports.read(path, "rb");
|
319 | });
|
320 | return Q.when(done, function () {
|
321 | return Q.shallow(tree);
|
322 | });
|
323 | });
|
324 | };
|
325 |
|
326 | exports.merge = function (fss) {
|
327 | var tree = {};
|
328 | var done;
|
329 | fss.forEach(function (fs) {
|
330 |
|
331 | var list = fs.listTree("", function (path, stat) {
|
332 | return stat.isFile();
|
333 | });
|
334 |
|
335 | done = Q.when(done, function () {
|
336 | return Q.when(list, function (list) {
|
337 | list.forEach(function (path) {
|
338 | tree[path] = fs.read(path, "rb");
|
339 | });
|
340 | });
|
341 | });
|
342 | });
|
343 | return Q.when(done, function () {
|
344 | return Q.when(Q.shallow(tree), MOCK.Fs);
|
345 | });
|
346 | };
|
347 |
|
348 | var stats = [
|
349 | "isDirectory",
|
350 | "isFile",
|
351 | "isBlockDevice",
|
352 | "isCharacterDevice",
|
353 | "isSymbolicLink",
|
354 | "isFIFO",
|
355 | "isSocket"
|
356 | ];
|
357 |
|
358 | var Stats = exports.Stats = function (copy) {
|
359 | var self = Object.create(copy);
|
360 | stats.forEach(function (name) {
|
361 | if (copy["_" + name] !== undefined) {
|
362 | self["_" + name] = copy["_" + name];
|
363 | } else {
|
364 | self["_" + name] = copy[name]();
|
365 | }
|
366 | });
|
367 | return self;
|
368 | };
|
369 |
|
370 | stats.forEach(function (name) {
|
371 | Stats.prototype[name] = function () {
|
372 | return this["_" + name];
|
373 | };
|
374 | });
|
375 |
|
376 | }
|
377 |
|
378 | }).apply(null, typeof exports !== "undefined" ?
|
379 | [require, exports] :
|
380 | [
|
381 | function (id) {
|
382 | id = id.toUpperCase()
|
383 | .replace(".", "Q_FS")
|
384 | .replace("/", "$")
|
385 | .replace("-", "_");
|
386 | return window[id] = window[id] || {};
|
387 | },
|
388 | Q_FS$COMMON = {}
|
389 | ]
|
390 | )
|