UNPKG

4.71 kBJavaScriptView Raw
1import { debounceTime, filter } from 'rxjs/operators';
2import { exec, constants, copy, dependsOn, elapsed, file, filter as filterUtil, fs, listr, loadSettings, log, moment, updatePackageRef, util, } from '../common';
3import * as listCommand from './ls.cmd';
4export const name = 'sync';
5export const alias = ['s', 'sl'];
6export const description = `Syncs each module's dependency tree within the workspace.`;
7export const args = {
8 '-i': 'Include ignored modules.',
9 '-w': 'Sync on changes to files.',
10 '-v': 'Update version reference in package.json files.',
11};
12export async function cmd(args) {
13 const options = (args && args.options) || {};
14 const watch = options.w || false;
15 const includeIgnored = options.i || false;
16 const updateVersions = options.v || false;
17 const config = { includeIgnored, updateVersions };
18 if (watch) {
19 await syncWatch(config);
20 }
21 else {
22 await sync(config);
23 }
24}
25export async function sync(options = {}) {
26 const { includeIgnored = false } = options;
27 const write = (msg) => util.write(msg, options.silent);
28 const settings = await loadSettings();
29 if (!settings) {
30 write(log.yellow(constants.CONFIG_NOT_FOUND_ERROR));
31 return;
32 }
33 const modules = settings.modules
34 .filter((pkg) => filterUtil.localDeps(pkg).length > 0)
35 .filter((pkg) => filterUtil.includeIgnored(pkg, includeIgnored));
36 await syncModules(modules, options);
37 return {
38 settings: settings,
39 modules,
40 };
41}
42export async function syncModules(modules, options = {}) {
43 const startedAt = new Date();
44 const { includeIgnored = false, updateVersions = false, silent = false } = options;
45 const write = (msg) => util.write(msg, options.silent);
46 const sync = async (sources, target) => {
47 for (const source of sources) {
48 if (source.package) {
49 await copy.module(source.package, target);
50 await copy.logUpdate(target);
51 await chmod(target);
52 if (updateVersions) {
53 await updatePackageRef(target, source.package.name, source.package.version, {
54 save: true,
55 });
56 }
57 }
58 }
59 };
60 const tasks = modules.map((target) => {
61 const sources = filterUtil
62 .localDeps(target)
63 .filter((dep) => filterUtil.includeIgnored(dep.package, includeIgnored));
64 const sourceNames = sources.map((dep) => ` ${log.cyan(dep.name)}`);
65 const title = `${log.magenta(target.name)} ${log.cyan(sourceNames.length > 0 ? '⬅' : '')}${sourceNames}`;
66 return {
67 title,
68 task: () => sync(sources, target),
69 };
70 });
71 try {
72 if (silent) {
73 for (const item of tasks) {
74 await item.task();
75 }
76 }
77 else {
78 const taskList = listr(tasks, { concurrent: false });
79 await taskList.run();
80 write(log.gray(` ${elapsed(startedAt)}, ${moment().format('h:mm:ssa')}`));
81 write('');
82 }
83 }
84 catch (error) {
85 write(log.yellow(`\nFailed while syncing module '${error.message}'.`));
86 }
87 return modules;
88}
89export async function chmod(module) {
90 const dir = fs.join(module.dir, 'node_modules/.bin');
91 if (!(await fs.pathExistsSync(dir))) {
92 return [];
93 }
94 const cmd = exec.command(`chmod 777`);
95 const files = (await fs.readdir(dir)).map((name) => fs.join(dir, name));
96 const wait = files.map((path) => {
97 return cmd.clone().add(path).run({ silent: true });
98 });
99 await Promise.all(wait);
100 return files;
101}
102export async function syncWatch(options = {}) {
103 const { includeIgnored = false, silent = false } = options;
104 const write = (msg) => util.write(msg, options.silent);
105 write(log.magenta('\nSync watching:'));
106 const result = await listCommand.ls({
107 dependencies: 'local',
108 includeIgnored,
109 });
110 if (!result) {
111 return;
112 }
113 const { modules, settings } = result;
114 modules.forEach((pkg) => watch(pkg, modules, settings.watchPattern, includeIgnored, silent));
115}
116function watch(pkg, modules, watchPattern, includeIgnored, silent) {
117 const sync = () => {
118 const dependants = dependsOn(pkg, modules);
119 if (dependants.length > 0) {
120 util.write(log.green(`${pkg.name} changed: `), silent);
121 syncModules(dependants, { includeIgnored });
122 }
123 };
124 file
125 .watch(fs.join(pkg.dir, watchPattern))
126 .pipe(filter((path) => !path.includes('node_modules/')), debounceTime(1000))
127 .subscribe(() => sync());
128}