我已经尝试了一切,到处寻找,甚至试图编写我自己的程序。我迷路了。
理念:两个目录具有相同的文件集。将文件重命名为一个文件将其重命名为另一个文件。在一个文件中编辑文件在另一个文件中编辑它。同样适用于删除。即使另一个程序自动进行更改,这些更改也应适用。
所有这一切,还有两种方式。因此,在目录A中进行更改会对目录B进行相同的更改,但此外,对目录B进行更改会对目录A进行更改。
问题是,可以吗?
/* Require Packages */
const $ = Object.assign.apply(0, ([
'fs',
'path',
'readline'
]).map(a => ({ [a]: require(a) })));
/* Define Functions */
const _ = ({
sls: {
index: {},
listen: function (a, b) {
_.sls.index[a] = b;
},
trigger: function (a, b) {
_.sls.index[a](b);
}
},
inquire: function (a, b) {
let x = $.readline.createInterface({
input: process.stdin,
output: process.stdout
});
x.question(a, c => _.sls.trigger('question', c));
_.sls.listen('question');
return _.sls.listen('question', b);
},
walk: function (a) {
return $.fs.statSync(a).isDirectory() ? $.fs.readdirSync(a).map(b => _.walk($.path.join(a, b))) : a;
},
regex: function (a, b) {
return new RegExp(a.replace(/[-\/\\^$+?.()|[\]{}]/g, '\\$&').split('*').join(b));
},
match: function (a, b, c) {
let x = $.path.parse(a), y = null, z = false;
for (let i = 0; i < b.length; ++b) {
y = $.path.parse(c + b[i].context).dir.split('/');
for (let j = 0; j < x.dir.split('/').length; ++j) {
if (_.regex(y[j], '.').test(x.dir.split('/')[j])) {
for (let k = 0; k < b[i].match.length; ++k) {
if (b.type == 'regex') {
z = new RegExp(b[i].match[k]).test(x.base);
} else {
z = _.regex(b[i].match[k], '.*').test(x.base);
if (b.type == 'exclude') z = !z;
}
}
}
}
}
return z;
},
watch: function (a, b) {
for (let i of b) $.fs.watch($.path.format({
dir: $.path.parse($.path.normalize(i) + $.path.normalize(a).split($.path.normalize(b[0])).join('')).dir,
base: $.path.parse(a).base
}), {}, function (a, b) {
console.log(b);
});
}
});
/* Execute Script */
$.fs.readFile('sync.json', function (a, b) {
if (a) {
console.log('No configuration file was found. One is being generated now.');
$.fs.writeFile('sync.json', JSON.stringify({
targets: [
'C:/sync-this-directory',
'C:/and-this-one',
'D:/and-this-one'
],
patterns: [{
type: 'include',
context: '/include-matches-only-in-this-directory',
match: ['*.*', 'by default all files are excluded']
}, {
type: 'exclude',
context: '/exclude-matches-only-in-the-subdirectories-of-this-directory/*',
match: ['*.exclude_this_extension', 'exclude_this_filename.*']
}, {
type: 'include',
context: '/*',
match: ['(a,b,c,d)', 'would match any file with a, b, c, and d in the name']
}, {
type: 'include',
context: '/*',
match: ['[1,2,3,4].*', 'would match any file with 1, 2, 3, or 4 in the name']
}, {
type: 'include',
context: '/*',
match: ['{1,b,3,d}.*', 'would match any file with ONLY 1, b, 3, or d in the name']
}, {
type: 'include',
context: '/*',
match: ['these-characters{([1,a],[2,b]),([3,c],[4,d])}', 'patterns are checked in entry order']
}, {
type: 'regex',
context: '/*',
match: ['these matches are regex-enabled', 'all matches will be included, not excluded']
}]
}));
} else {
_.inquire('Once you have ensured all configured target directories and their contents match, press enter.', function () {
let x = null;
try { x = JSON.parse(String(b).split('/').join('\/')); } catch (g) {
console.log('Parsing Error: Your config is fucked. Fix it.');
throw new Error();
}
console.log('Your files are now in sync. A change to one is a change to all.');
let y = Object.assign.apply(0, _.walk(x.targets[0]).map(function (a) {
return a.constructor.name == 'Array' ? a : [a];
}));
for (let i of y) if (_.match(i, x.patterns, x.targets[0])) _.watch(i, x.targets);
});
}
});