forked from zont/copy-and-watch
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
123 lines (101 loc) · 2.69 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* IMPORTS */
const fs = require('fs');
const path = require('path');
const chokidar = require('chokidar');
const glob = require('glob');
const globParent = require('glob-parent');
require('colors');
/* EVIL GLOBALS */
let destination, parents;
/* FUNCTIONS */
function findTarget(from) {
const parent = parents
.filter(parent => from.indexOf(parent) >= 0)
.sort()
.reverse()[0];
return path.join(destination, path.relative(parent, from));
}
function createDirIfNotExist(to) {
'use strict';
const dirs = [];
let dir = path.dirname(to);
while (dir !== path.dirname(dir)) {
dirs.unshift(dir);
dir = path.dirname(dir);
}
dirs.forEach(dir => {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}
});
}
function copy(from) {
const pathFrom = path.normalize(from);
const to = findTarget(pathFrom);
createDirIfNotExist(to);
const stats = fs.statSync(pathFrom);
if (stats.isDirectory()) {
fs.readdirSync(pathFrom).map(fileName => path.join(pathFrom, fileName))
.forEach(copy); // recursively copy directory contents
} else {
fs.writeFileSync(to, fs.readFileSync(pathFrom));
console.log('[COPY]'.yellow, pathFrom, 'to'.yellow, to);
}
}
function remove(from) {
const to = findTarget(from);
fs.unlinkSync(to);
console.log('[DELETE]'.red, to);
}
function rimraf(dir) {
if (fs.existsSync(dir)) {
fs.readdirSync(dir).forEach(entry => {
const entryPath = path.join(dir, entry);
if (fs.lstatSync(entryPath).isDirectory()) {
rimraf(entryPath);
} else {
console.log('[CLEAN]'.magenta, entryPath);
fs.unlinkSync(entryPath);
}
});
fs.rmdirSync(dir);
}
}
/* CODE */
const args = process.argv.slice(2);
let watch = false, clean = false;
const sourceGlobs = [];
for (const arg of args) {
if (arg === '--watch') {
watch = true;
} else if (arg === '--clean') {
clean = true;
} else {
sourceGlobs.push(path.normalize(arg));
}
}
if (sourceGlobs.length < 2) {
console.error('Not enough arguments: copy-and-watch [options] <sources> <target>'.red);
process.exit(1);
}
destination = sourceGlobs.pop(); // pick last path as destination
parents = [...new Set(sourceGlobs.map(globParent).map(path.normalize))];
if (clean) {
console.log('Cleaning...');
rimraf(destination);
}
// initial copy
sourceGlobs.forEach(s => glob.sync(s).forEach(copy));
// watch
if (watch) {
chokidar.watch(sourceGlobs, {
ignoreInitial: true
})
.on('ready', () => sourceGlobs.forEach(s => console.log('[WATCHING]'.cyan, s)))
.on('add', copy)
.on('addDir', copy)
.on('change', copy)
.on('unlink', remove)
.on('unlinkDir', remove)
.on('error', e => console.log('[ERROR]'.red, e));
}