1 | var path = require('path');
|
2 | var fs = require('fs');
|
3 | var assert = require("assert");
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | exports.mkdirs = function (_path, mode, callback) {
|
15 | _path = exports.path.abspath(_path);
|
16 |
|
17 | var dirs = _path.split("/");
|
18 | var walker = [dirs.shift()];
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 | var walk = function (ds, acc, m, cb) {
|
26 | if (ds.length > 0) {
|
27 | var d = ds.shift();
|
28 |
|
29 | acc.push(d);
|
30 | var dir = acc.join("/");
|
31 |
|
32 |
|
33 |
|
34 |
|
35 | fs.stat(dir, function (err, stat) {
|
36 |
|
37 | if (err) {
|
38 |
|
39 | if (err.errno == 2 || err.errno == 34) {
|
40 | fs.mkdir(dir, m, function (erro) {
|
41 | if (erro && erro.errno != 17 && erro.errno != 34) {
|
42 | assert(false)
|
43 | return cb(erro);
|
44 | } else {
|
45 | return walk(ds, acc, m, cb);
|
46 | }
|
47 | });
|
48 | } else {
|
49 | return cb(err);
|
50 | }
|
51 | } else {
|
52 | if (stat.isDirectory()) {
|
53 | return walk(ds, acc, m, cb);
|
54 | } else {
|
55 | return cb(new Error("Failed to mkdir " + dir + ": File exists\n"));
|
56 | }
|
57 | }
|
58 | });
|
59 | } else {
|
60 | return cb();
|
61 | }
|
62 | };
|
63 | return walk(dirs, walker, mode, callback);
|
64 | };
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 |
|
76 | exports.mkdirsSync = function (_path, mode) {
|
77 | if (_path[0] !== "/") {
|
78 | _path = path.join(process.cwd(), _path)
|
79 | }
|
80 |
|
81 | var dirs = _path.split("/");
|
82 | var walker = [dirs.shift()];
|
83 |
|
84 | dirs.reduce(function (acc, d) {
|
85 | acc.push(d);
|
86 | var dir = acc.join("/");
|
87 |
|
88 | try {
|
89 | var stat = fs.statSync(dir);
|
90 | if (!stat.isDirectory()) {
|
91 | throw "Failed to mkdir " + dir + ": File exists";
|
92 | }
|
93 | } catch (err) {
|
94 | fs.mkdirSync(dir, mode);
|
95 | }
|
96 | return acc;
|
97 | }, walker);
|
98 | };
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 |
|
111 |
|
112 | exports.walk = function (start, callback) {
|
113 | fs.lstat(start, function (err, stat) {
|
114 | if (err) { return callback(err) }
|
115 | if (stat.isDirectory()) {
|
116 |
|
117 | fs.readdir(start, function (err, files) {
|
118 | var coll = files.reduce(function (acc, i) {
|
119 | var abspath = path.join(start, i);
|
120 |
|
121 | if (fs.statSync(abspath).isDirectory()) {
|
122 | exports.walk(abspath, callback);
|
123 | acc.dirs.push(abspath);
|
124 | } else {
|
125 | acc.names.push(abspath);
|
126 | }
|
127 |
|
128 | return acc;
|
129 | }, {"names": [], "dirs": []});
|
130 |
|
131 | return callback(null, start, coll.dirs, coll.names);
|
132 | });
|
133 | } else {
|
134 | return callback(new Error("path: " + start + " is not a directory"));
|
135 | }
|
136 | });
|
137 | };
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 |
|
150 |
|
151 |
|
152 |
|
153 | exports.walkSync = function (start, callback) {
|
154 | var stat = fs.statSync(start);
|
155 |
|
156 | if (stat.isDirectory()) {
|
157 | var filenames = fs.readdirSync(start);
|
158 |
|
159 | var coll = filenames.reduce(function (acc, name) {
|
160 | var abspath = path.join(start, name);
|
161 |
|
162 | if (fs.statSync(abspath).isDirectory()) {
|
163 | acc.dirs.push(name);
|
164 | } else {
|
165 | acc.names.push(name);
|
166 | }
|
167 |
|
168 | return acc;
|
169 | }, {"names": [], "dirs": []});
|
170 |
|
171 | callback(start, coll.dirs, coll.names);
|
172 |
|
173 | coll.dirs.forEach(function (d) {
|
174 | var abspath = path.join(start, d);
|
175 | exports.walkSync(abspath, callback);
|
176 | });
|
177 |
|
178 | } else {
|
179 | throw new Error("path: " + start + " is not a directory");
|
180 | }
|
181 | };
|
182 |
|
183 | exports.path = {};
|
184 |
|
185 | exports.path.abspath = function (to) {
|
186 | var from;
|
187 | switch (to.charAt(0)) {
|
188 | case "~": from = process.env.HOME; to = to.substr(1); break
|
189 | case "/": from = ""; break
|
190 | default : from = process.cwd(); break
|
191 | }
|
192 | return path.join(from, to);
|
193 | }
|
194 |
|
195 | exports.path.relativePath = function (base, compare) {
|
196 | base = base.split("/");
|
197 | compare = compare.split("/");
|
198 |
|
199 | if (base[0] == "") {
|
200 | base.shift();
|
201 | }
|
202 |
|
203 | if (compare[0] == "") {
|
204 | compare.shift();
|
205 | }
|
206 |
|
207 | var l = compare.length;
|
208 |
|
209 | for (var i = 0; i < l; i++) {
|
210 | if (!base[i] || (base[i] != compare[i])) {
|
211 | return compare.slice(i).join("/");
|
212 | }
|
213 | }
|
214 |
|
215 | return ""
|
216 | };
|
217 |
|
218 | exports.path.join = function (head, tail) {
|
219 | if (head == "") {
|
220 | return tail;
|
221 | } else {
|
222 | return path.join(head, tail);
|
223 | }
|
224 | };
|
225 |
|