-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcli.js
More file actions
executable file
·115 lines (100 loc) · 3.88 KB
/
cli.js
File metadata and controls
executable file
·115 lines (100 loc) · 3.88 KB
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
#!/usr/bin/env node
const { Command } = require('commander');
const Shuttle = require('./shuttle');
const fs = require('fs-extra');
const path = require('path');
const ora = require('ora');
const chokidar = require('chokidar');
const program = new Command();
const shuttle = new Shuttle();
async function scanDirectory(dir, baseDir = '') {
let results = [];
const list = await fs.readdir(dir);
for (const file of list) {
const filePath = path.join(dir, file);
const relativePath = path.join(baseDir, file);
const stat = await fs.stat(filePath);
if (stat.isDirectory()) {
results = results.concat(await scanDirectory(filePath, relativePath));
} else {
const content = await fs.readFile(filePath);
results.push({ path: relativePath, content: content.toString('base64') });
}
}
return results;
}
program.command('push')
.argument('<target>')
.option('--live', 'Manter sincronização ativa')
.option('--allow-changes', 'Permitir propostas de mudanças')
.option('--auto-accept', 'Aceitar automaticamente mudanças propostas')
.action(async (target, options) => {
const spinner = ora('Lendo arquivos...').start();
const absolutePath = path.resolve(target);
let payload = [];
if (!(await fs.exists(absolutePath))) {
spinner.fail('Caminho não encontrado');
process.exit(1);
}
if ((await fs.stat(absolutePath)).isDirectory()) {
payload = await scanDirectory(absolutePath);
} else {
const content = await fs.readFile(absolutePath);
payload.push({ path: path.basename(absolutePath), content: content.toString('base64') });
}
spinner.text = 'Aguardando peer...';
const { id, peerPromise } = await shuttle.push(payload, { live: options.live, allowChanges: options.allowChanges, autoAccept: options.autoAccept, root: absolutePath });
spinner.succeed(`ID: ${id}`);
const p = await peerPromise;
let watcher;
if (options.live) {
watcher = chokidar.watch(absolutePath, { ignoreInitial: true });
watcher.on('change', async (filePath) => {
if (!p || p.destroyed || !p.connected) return;
const rel = path.relative(absolutePath, filePath);
const content = await fs.readFile(filePath);
try {
p.send(JSON.stringify({ t: 'propose-change', path: rel, content: content.toString('base64') }));
} catch {}
});
}
p.on('close', () => {
if (watcher) watcher.close();
});
});
program.command('pull')
.argument('<id>')
.option('--live', 'Receber atualizaçes contínuas')
.option('--allow-changes', 'Permitir aplicar mudanças recebidas')
.option('--auto-accept', 'Aceitar automaticamente mudanças recebidas')
.action(async (id, options) => {
const spinner = ora('Conectando...').start();
const root = process.cwd();
let peerRef;
let watcher;
await shuttle.pull(id, async (data) => {
if (spinner.isSpinning) spinner.succeed('Recebido');
for (const file of data) {
const dest = path.resolve(file.path);
await fs.ensureDir(path.dirname(dest));
await fs.writeFile(dest, Buffer.from(file.content, 'base64'));
}
}, { live: options.live, onPeer: (p) => { peerRef = p; }, allowChanges: options.allowChanges, autoAccept: options.autoAccept, root });
if (options.live) {
watcher = chokidar.watch(root, { ignoreInitial: true });
watcher.on('change', async (filePath) => {
if (!peerRef || peerRef.destroyed || !peerRef.connected) return;
const rel = path.relative(root, filePath);
const content = await fs.readFile(filePath);
try {
peerRef.send(JSON.stringify({ t: 'propose-change', path: rel, content: content.toString('base64') }));
} catch {}
});
}
if (peerRef) {
peerRef.on('close', () => {
if (watcher) watcher.close();
});
}
});
program.parse();