1 | var path = require('path'),
|
2 | fs = require('fs'),
|
3 | exec = require('child_process').exec,
|
4 | util = require('util'),
|
5 | async = require('async'),
|
6 | walk = require('./lib/walk');
|
7 |
|
8 | var defaultRegExcludes = [/^\.+.*/, /node_modules/]
|
9 |
|
10 | exports.mvFile = function(currentDir, sourceAbsPath, destAbsPath, options, cb) {
|
11 | fs.exists(sourceAbsPath, function(exists) {
|
12 | if (!exists) return cb(new Error('File ' + sourceAbsPath + ' does not exist!'));
|
13 |
|
14 | steps = [];
|
15 | if (options.git) {
|
16 | steps.push(function(cb) {
|
17 | exec('git mv ' + sourceAbsPath + ' ' + destAbsPath, function(err, stdout, stderr) {
|
18 | if (err) return cb(err);
|
19 | if (stderr) return cb(stderr);
|
20 | cb();
|
21 | })
|
22 | })
|
23 | } else {
|
24 | steps.push(function(cb) {
|
25 | fs.rename(sourceAbsPath, destAbsPath, cb);
|
26 | })
|
27 | }
|
28 |
|
29 | var excludes = defaultRegExcludes;
|
30 | if (options.excludes) {
|
31 | excludes = excludes.concat(options.excludes);
|
32 | }
|
33 |
|
34 | steps.push(function(cb) {exports.updateReferenceInFile(sourceAbsPath, destAbsPath, cb)});
|
35 | steps.push(function(cb) {exports.updateReferenceToMovedFile(currentDir, sourceAbsPath, destAbsPath, excludes, cb)});
|
36 |
|
37 | async.series(steps, cb);
|
38 | });
|
39 | };
|
40 |
|
41 | exports.updateReferenceInFile = function(sourceAbsPath, destAbsPath, cb) {
|
42 | fs.readFile(destAbsPath, 'utf8', function(err, data) {
|
43 | if (err) return cb(err);
|
44 |
|
45 | var re = /require(\(|\s)('|")(\.\S+)('|")(\))?/g,
|
46 | re1 = /require(\(|\s)('|")(\.\S+)('|")(\))?/,
|
47 | matches = data.match(re);
|
48 |
|
49 | if (matches) {
|
50 | matches.forEach(function(match) {
|
51 | var oldRequire = match,
|
52 | groups = re1.exec(match),
|
53 | oldPath = groups[3],
|
54 | oldAsbPath = path.join(path.dirname(sourceAbsPath), oldPath),
|
55 | newRelativePath = path.relative(path.dirname(destAbsPath), oldAsbPath);
|
56 |
|
57 | if (newRelativePath.indexOf(".") != 0 ) {
|
58 | newRelativePath = './' + newRelativePath;
|
59 | }
|
60 |
|
61 | var newRequire = oldRequire.replace(re1, 'require$1$2' + newRelativePath + '$4$5');
|
62 | data = data.replace(oldRequire, newRequire);
|
63 | })
|
64 | }
|
65 | fs.writeFile(destAbsPath, data, {encoding: 'utf8'}, cb);
|
66 | });
|
67 | }
|
68 |
|
69 | exports.updateReferenceToMovedFile = function(currentDir, sourceAbsPath, destAbsPath, regExcludes, cb) {
|
70 | walk(currentDir, regExcludes, function(err, files) {
|
71 | if (err) return cb(err);
|
72 |
|
73 | function updateReferenceForFile(file, cb) {
|
74 | var oldRelativePath = path.relative(path.dirname(file), sourceAbsPath).replace(/\.(js|coffee)$/, ''),
|
75 | newRelativePath = path.relative(path.dirname(file), destAbsPath).replace(/\.(js|coffee)$/, '');
|
76 | if (oldRelativePath.indexOf(".") != 0 ) {
|
77 | oldRelativePath = './' + oldRelativePath;
|
78 | }
|
79 | if (newRelativePath.indexOf(".") != 0 ) {
|
80 | newRelativePath = './' + newRelativePath;
|
81 | }
|
82 |
|
83 | var regex = exports.generateRequireRegex(oldRelativePath);
|
84 | fs.readFile(file, 'utf8', function(err, data) {
|
85 | if (err) return cb(err);
|
86 | if (data.indexOf(regex)) {
|
87 | var result = data.replace(regex, 'require$1$2' + newRelativePath + '$4$5');
|
88 | fs.writeFile(file, result, {encoding: 'utf8'}, cb);
|
89 | } else {
|
90 | return cb()
|
91 | }
|
92 |
|
93 | })
|
94 | }
|
95 | async.eachLimit(files, 20, updateReferenceForFile, cb);
|
96 | })
|
97 | }
|
98 |
|
99 | exports.generateRequireRegex = function(filePath) {
|
100 | return new RegExp("require(\\(|\\s)('|\")(" + filePath + ")('|\")(\\))?", "g");
|
101 | }
|