1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | var grunt = require('../grunt');
|
11 |
|
12 |
|
13 | var fs = require('fs');
|
14 | var path = require('path');
|
15 |
|
16 |
|
17 | var file = module.exports = {};
|
18 |
|
19 |
|
20 | file.glob = require('glob-whatev');
|
21 |
|
22 |
|
23 | file.setBase = function() {
|
24 | var dirpath = path.join.apply(path, arguments);
|
25 | process.chdir(dirpath);
|
26 | };
|
27 |
|
28 |
|
29 |
|
30 | file.isMatch = function(patterns, filepath) {
|
31 | patterns = Array.isArray(patterns) ? patterns : [patterns];
|
32 | return patterns.some(function(pattern) {
|
33 | return file.glob.minimatch(filepath, pattern, {matchBase: true});
|
34 | });
|
35 | };
|
36 |
|
37 |
|
38 | file.expand = function() {
|
39 | var args = grunt.utils.toArray(arguments);
|
40 |
|
41 |
|
42 | var options = grunt.utils.kindOf(args[0]) === 'object' ? args.shift() : {};
|
43 |
|
44 |
|
45 | var patterns = Array.isArray(args[0]) ? args[0] : args;
|
46 |
|
47 | var uid = +new Date();
|
48 |
|
49 | return grunt.utils._(patterns).chain().flatten().map(function(pattern) {
|
50 |
|
51 | pattern = grunt.template.process(pattern);
|
52 |
|
53 | if (grunt.task.getDirectiveParts(pattern)) { return pattern; }
|
54 |
|
55 | return file.glob.glob(pattern, options);
|
56 | }).flatten().uniq(false, function(filepath) {
|
57 |
|
58 |
|
59 | return grunt.task.getDirectiveParts(filepath) ? ++uid : filepath;
|
60 | }).value();
|
61 | };
|
62 |
|
63 |
|
64 | function expandByType(type) {
|
65 | var args = grunt.utils.toArray(arguments).slice(1);
|
66 | return file.expand.apply(file, args).filter(function(filepath) {
|
67 |
|
68 | if (grunt.task.getDirectiveParts(filepath)) { return filepath; }
|
69 | try {
|
70 | return fs.statSync(filepath)[type]();
|
71 | } catch(e) {
|
72 | throw grunt.task.taskError(e.message, e);
|
73 | }
|
74 | });
|
75 | }
|
76 |
|
77 |
|
78 | file.expandDirs = expandByType.bind(file, 'isDirectory');
|
79 | file.expandFiles = expandByType.bind(file, 'isFile');
|
80 |
|
81 |
|
82 |
|
83 | file.expandFileURLs = function() {
|
84 |
|
85 |
|
86 | var patterns = Array.isArray(arguments[0]) ? arguments[0] : grunt.utils.toArray(arguments);
|
87 | var urls = [];
|
88 |
|
89 | patterns = patterns.filter(function(pattern) {
|
90 | if (/^(?:file|https?):\/\//i.test(pattern)) {
|
91 |
|
92 | urls.push(pattern);
|
93 |
|
94 | return false;
|
95 | }
|
96 |
|
97 | return true;
|
98 | });
|
99 |
|
100 | return file.expandFiles(patterns).map(function(filepath) {
|
101 | var abspath = path.resolve(filepath);
|
102 |
|
103 | if (abspath.indexOf('/') !== 0) {
|
104 | abspath = ('/' + abspath).replace(/\\/g, '/');
|
105 | }
|
106 | return 'file://' + abspath;
|
107 | }).concat(urls);
|
108 | };
|
109 |
|
110 |
|
111 | file.mkdir = function(dirpath) {
|
112 | if (grunt.option('no-write')) { return; }
|
113 | dirpath.split(/[\/\\]/).reduce(function(parts, part) {
|
114 | parts += part + '/';
|
115 | var subpath = path.resolve(parts);
|
116 | if (!path.existsSync(subpath)) {
|
117 | try {
|
118 | fs.mkdirSync(subpath, '0755');
|
119 | } catch(e) {
|
120 | throw grunt.task.taskError('Unable to create directory "' + subpath + '" (Error code: ' + e.code + ').', e);
|
121 | }
|
122 | }
|
123 | return parts;
|
124 | }, '');
|
125 | };
|
126 |
|
127 |
|
128 | file.recurse = function recurse(rootdir, callback, subdir) {
|
129 | var abspath = subdir ? path.join(rootdir, subdir) : rootdir;
|
130 | fs.readdirSync(abspath).forEach(function(filename) {
|
131 | var filepath = path.join(abspath, filename);
|
132 | if (fs.statSync(filepath).isDirectory()) {
|
133 | recurse(rootdir, callback, path.join(subdir, filename));
|
134 | } else {
|
135 | callback(path.join(rootdir, subdir, filename), rootdir, subdir, filename);
|
136 | }
|
137 | });
|
138 | };
|
139 |
|
140 |
|
141 | file.isPathAbsolute = function() {
|
142 | var filepath = path.join.apply(path, arguments);
|
143 | return path.resolve(filepath) === filepath;
|
144 | };
|
145 |
|
146 |
|
147 | file.findup = function findup(dirpath, filename) {
|
148 | var filepath = path.join(dirpath, filename);
|
149 |
|
150 | if (path.existsSync(filepath)) { return filepath; }
|
151 |
|
152 | var parentpath = path.resolve(dirpath, '..');
|
153 | return parentpath === dirpath ? null : findup(parentpath, filename);
|
154 | };
|
155 |
|
156 |
|
157 | file.write = function(filepath, contents) {
|
158 | var nowrite = grunt.option('no-write');
|
159 | grunt.verbose.write((nowrite ? 'Not actually writing ' : 'Writing ') + filepath + '...');
|
160 |
|
161 | file.mkdir(path.dirname(filepath));
|
162 | try {
|
163 | if (!nowrite) {
|
164 |
|
165 | fs.writeFileSync(filepath, contents);
|
166 | }
|
167 | grunt.verbose.ok();
|
168 | return true;
|
169 | } catch(e) {
|
170 | grunt.verbose.error();
|
171 | throw grunt.task.taskError('Unable to write "' + filepath + '" file (Error code: ' + e.code + ').', e);
|
172 | }
|
173 | };
|
174 |
|
175 |
|
176 | file.read = function(filepath, encoding) {
|
177 | var src;
|
178 | grunt.verbose.write('Reading ' + filepath + '...');
|
179 | try {
|
180 | src = fs.readFileSync(String(filepath), encoding ? null : 'utf8');
|
181 | grunt.verbose.ok();
|
182 | return src;
|
183 | } catch(e) {
|
184 | grunt.verbose.error();
|
185 | throw grunt.task.taskError('Unable to read "' + filepath + '" file (Error code: ' + e.code + ').', e);
|
186 | }
|
187 | };
|
188 |
|
189 |
|
190 | file.copy = function(srcpath, destpath, options) {
|
191 | if (!options) { options = {}; }
|
192 | var src = file.read(srcpath, true);
|
193 | if (options.process && options.noProcess !== true &&
|
194 | !(options.noProcess && file.isMatch(options.noProcess, srcpath))) {
|
195 | grunt.verbose.write('Processing source...');
|
196 | try {
|
197 | src = options.process(src.toString('utf8'));
|
198 | grunt.verbose.ok();
|
199 | } catch(e) {
|
200 | grunt.verbose.error();
|
201 | throw grunt.task.taskError('Error while processing "' + srcpath + '" file.', e);
|
202 | }
|
203 | }
|
204 | file.write(destpath, src);
|
205 | };
|
206 |
|
207 |
|
208 | file.readJSON = function(filepath) {
|
209 | var src = this.read(String(filepath));
|
210 | var result;
|
211 | grunt.verbose.write('Parsing ' + filepath + '...');
|
212 | try {
|
213 | result = JSON.parse(src);
|
214 | grunt.verbose.ok();
|
215 | return result;
|
216 | } catch(e) {
|
217 | grunt.verbose.error();
|
218 | throw grunt.task.taskError('Unable to parse "' + filepath + '" file (' + e.message + ').', e);
|
219 | }
|
220 | };
|
221 |
|
222 |
|
223 | file.clearRequireCache = function() {
|
224 |
|
225 |
|
226 | var filepaths = typeof arguments[0] !== 'string' ? arguments[0] : grunt.utils.toArray(arguments);
|
227 |
|
228 | filepaths.forEach(function(filepath) {
|
229 | var abspath = path.resolve(filepath);
|
230 | if (require.cache[abspath]) {
|
231 | grunt.verbose.write('Clearing require cache for "' + filepath + '" file...').ok();
|
232 | delete require.cache[abspath];
|
233 | }
|
234 | });
|
235 | };
|
236 |
|
237 |
|
238 | file.userDir = function() {
|
239 | var dirpath = path.join.apply(path, arguments);
|
240 | var win32 = process.platform === 'win32';
|
241 | var homepath = process.env[win32 ? 'USERPROFILE' : 'HOME'];
|
242 | dirpath = path.resolve(homepath, '.grunt', dirpath);
|
243 | return path.existsSync(dirpath) ? dirpath : null;
|
244 | };
|