rman 0.2.5 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cjs/cli.js CHANGED
@@ -18,6 +18,7 @@ const execute_command_1 = require("./commands/execute-command");
18
18
  const run_command_1 = require("./commands/run-command");
19
19
  const version_command_1 = require("./commands/version-command");
20
20
  const publish_command_1 = require("./commands/publish-command");
21
+ const ci_command_1 = require("./commands/ci-command");
21
22
  async function runCli(options) {
22
23
  const s = path_1.default.resolve((0, utils_1.getDirname)(), '../package.json');
23
24
  const pkgJson = JSON.parse(await promises_1.default.readFile(s, 'utf-8'));
@@ -48,6 +49,7 @@ async function runCli(options) {
48
49
  run_command_1.RunCommand.initCli(repository, program);
49
50
  version_command_1.VersionCommand.initCli(repository, program);
50
51
  publish_command_1.PublishCommand.initCli(repository, program);
52
+ ci_command_1.CleanInstallCommand.initCli(repository, program);
51
53
  if (!_argv.length)
52
54
  program.showHelp();
53
55
  else
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CleanInstallCommand = void 0;
7
+ const power_tasks_1 = require("power-tasks");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const npmlog_1 = __importDefault(require("npmlog"));
10
+ const command_1 = require("../core/command");
11
+ const run_command_1 = require("./run-command");
12
+ const file_utils_1 = require("../utils/file-utils");
13
+ const path_1 = __importDefault(require("path"));
14
+ class CleanInstallCommand extends run_command_1.RunCommand {
15
+ constructor(repository, options) {
16
+ super(repository, 'clean_', options);
17
+ this.repository = repository;
18
+ }
19
+ async _prepareTasks(packages) {
20
+ const tasks = await super._prepareTasks(packages);
21
+ const client = this.repository.config.client || 'npm';
22
+ if (!(client === 'npm' || client === 'yargs'))
23
+ throw new Error(`Invalid npm client "${client}"`);
24
+ tasks.push(new power_tasks_1.Task(async () => {
25
+ const dirname = this.repository.dirname;
26
+ await this._fsDelete(path_1.default.join(dirname, 'node_modules'));
27
+ await this._fsDelete(path_1.default.join(dirname, 'package-lock.json'));
28
+ await this._fsDelete(path_1.default.join(dirname, 'yarn-lock.json'));
29
+ npmlog_1.default.info(this.commandName, chalk_1.default.yellow('installing'), 'Running ' + client + ' install');
30
+ return super._exec({
31
+ name: 'root',
32
+ dirname: this.repository.dirname,
33
+ json: { ...this.repository.json },
34
+ command: client + ' install',
35
+ stdio: 'inherit'
36
+ });
37
+ }, { exclusive: true }));
38
+ return tasks;
39
+ }
40
+ async _exec(args, ctx) {
41
+ if (args.command === '#') {
42
+ if (args.name === 'root')
43
+ return { code: 0 };
44
+ const { dirname } = args;
45
+ await this._fsDelete(path_1.default.join(dirname, 'node_modules'));
46
+ await this._fsDelete(path_1.default.join(dirname, 'package-lock.json'));
47
+ await this._fsDelete(path_1.default.join(dirname, 'yarn-lock.json'));
48
+ return { code: 0 };
49
+ }
50
+ return super._exec(args, ctx);
51
+ }
52
+ async _fsDelete(fileOrDir) {
53
+ if (await (0, file_utils_1.fsExists)(fileOrDir)) {
54
+ npmlog_1.default.info(this.commandName, chalk_1.default.yellow('clean'), 'Deleting ' + fileOrDir);
55
+ await (0, file_utils_1.fsDelete)(fileOrDir);
56
+ }
57
+ }
58
+ }
59
+ exports.CleanInstallCommand = CleanInstallCommand;
60
+ CleanInstallCommand.commandName = 'ci';
61
+ (function (CleanInstallCommand) {
62
+ CleanInstallCommand.cliCommandOptions = {
63
+ ...run_command_1.RunCommand.cliCommandOptions
64
+ };
65
+ function initCli(repository, program) {
66
+ program.command({
67
+ command: 'ci [...options]',
68
+ describe: 'Deletes all dependency modules and re-installs',
69
+ builder: (cmd) => {
70
+ return cmd
71
+ .example("$0 ci", '')
72
+ .option(CleanInstallCommand.cliCommandOptions);
73
+ },
74
+ handler: async (args) => {
75
+ const options = command_1.Command.composeOptions(CleanInstallCommand.commandName, args, repository.config);
76
+ await new CleanInstallCommand(repository, options).execute();
77
+ }
78
+ });
79
+ }
80
+ CleanInstallCommand.initCli = initCli;
81
+ })(CleanInstallCommand = exports.CleanInstallCommand || (exports.CleanInstallCommand = {}));
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.ExecuteCommand = void 0;
7
7
  const npmlog_1 = __importDefault(require("npmlog"));
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
- const figures_1 = __importDefault(require("figures"));
10
9
  const multi_task_command_1 = require("./multi-task-command");
11
10
  const power_tasks_1 = require("power-tasks");
12
11
  const exec_1 = require("../utils/exec");
@@ -18,18 +17,18 @@ class ExecuteCommand extends multi_task_command_1.MultiTaskCommand {
18
17
  this.cmd = cmd;
19
18
  this.argv = argv;
20
19
  }
21
- _prepareTasks() {
22
- const packages = this.repository.getPackages({ toposort: !this.options.parallel });
20
+ _prepareTasks(packages) {
23
21
  const tasks = [];
24
22
  for (const p of packages) {
25
23
  const task = new power_tasks_1.Task(async () => {
26
24
  const t = Date.now();
27
- npmlog_1.default.verbose(this.commandName, p.name, chalk_1.default.gray(figures_1.default.lineVerticalDashed0), chalk_1.default.cyanBright.bold('executing'), chalk_1.default.gray(figures_1.default.lineVerticalDashed0), this.cmd + ' ' + (this.argv?.join(' ') || ''));
25
+ npmlog_1.default.verbose(this.commandName, p.name, chalk_1.default.cyanBright.bold('executing'), npmlog_1.default.separator, this.cmd + ' ' + (this.argv?.join(' ') || ''));
28
26
  const r = await (0, exec_1.exec)(this.cmd, {
29
27
  cwd: p.dirname,
30
- argv: this.argv
28
+ argv: this.argv,
29
+ stdio: npmlog_1.default.levelIndex <= 1000 ? 'inherit' : 'pipe'
31
30
  });
32
- npmlog_1.default.log((r.error ? 'error' : 'verbose'), this.commandName, chalk_1.default.gray(figures_1.default.lineVerticalDashed0), p.name, chalk_1.default.gray(figures_1.default.lineVerticalDashed0), (r.error ? chalk_1.default.red.bold('failed') : chalk_1.default.green.bold('success')), chalk_1.default.gray(figures_1.default.lineVerticalDashed0), 'Completed in ' + chalk_1.default.yellow('' + (Date.now() - t) + ' ms'));
31
+ npmlog_1.default.log((r.error ? 'error' : 'info'), this.commandName, p.name, (r.error ? chalk_1.default.red.bold('failed') : chalk_1.default.green.bold('success')), npmlog_1.default.separator, this.cmd, chalk_1.default.yellow(' (' + (Date.now() - t) + ' ms') + ')');
33
32
  }, {
34
33
  name: p.name,
35
34
  dependencies: this.options.parallel ? undefined : p.dependencies,
@@ -5,13 +5,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.MultiTaskCommand = void 0;
7
7
  const os_1 = __importDefault(require("os"));
8
- const chalk_1 = __importDefault(require("chalk"));
9
8
  const npmlog_1 = __importDefault(require("npmlog"));
10
- const figures_1 = __importDefault(require("figures"));
11
9
  const power_tasks_1 = require("power-tasks");
12
10
  const command_1 = require("../core/command");
13
11
  const constants_1 = require("../utils/constants");
14
- const logSeparator = chalk_1.default.gray(figures_1.default.lineVerticalDashed0);
15
12
  class MultiTaskCommand extends command_1.Command {
16
13
  constructor(repository, options) {
17
14
  super(options);
@@ -25,9 +22,10 @@ class MultiTaskCommand extends command_1.Command {
25
22
  this.options.bail = true;
26
23
  }
27
24
  async _execute() {
28
- const childTasks = await this._prepareTasks();
25
+ const packages = await this._getPackages();
26
+ const childTasks = await this._prepareTasks(packages);
29
27
  if (!(childTasks && childTasks.length)) {
30
- npmlog_1.default.info(this.commandName, logSeparator, 'There is no task to process');
28
+ npmlog_1.default.info(this.commandName, '', 'There is no task to process');
31
29
  return;
32
30
  }
33
31
  // this.enableProgress();
@@ -35,7 +33,10 @@ class MultiTaskCommand extends command_1.Command {
35
33
  concurrency: this.options.concurrency || os_1.default.cpus().length,
36
34
  bail: this.options.bail,
37
35
  });
38
- await this._task.catch(() => void (0));
36
+ await this._task.toPromise().catch(() => void (0));
37
+ }
38
+ async _getPackages() {
39
+ return this.repository.getPackages({ toposort: !this.options.parallel });
39
40
  }
40
41
  }
41
42
  exports.MultiTaskCommand = MultiTaskCommand;
@@ -7,7 +7,6 @@ exports.PublishCommand = void 0;
7
7
  const chalk_1 = __importDefault(require("chalk"));
8
8
  const package_json_1 = __importDefault(require("package-json"));
9
9
  const npmlog_1 = __importDefault(require("npmlog"));
10
- const figures_1 = __importDefault(require("figures"));
11
10
  const command_1 = require("../core/command");
12
11
  const run_command_1 = require("./run-command");
13
12
  class PublishCommand extends run_command_1.RunCommand {
@@ -15,33 +14,27 @@ class PublishCommand extends run_command_1.RunCommand {
15
14
  super(repository, 'publish', options);
16
15
  this.repository = repository;
17
16
  }
18
- async _prepareTasks() {
19
- const { repository } = this;
20
- const packages = repository.getPackages({ toposort: true });
17
+ async _prepareTasks(packages) {
21
18
  const newVersions = {};
22
19
  const selectedPackages = [];
23
20
  for (const p of packages) {
24
21
  const logPkgName = chalk_1.default.yellow(p.name);
25
22
  const r = await (0, package_json_1.default)(p.json.name);
26
23
  if (r.version === p.version) {
27
- npmlog_1.default.info(this.commandName, logPkgName, chalk_1.default.gray(figures_1.default.lineVerticalDashed0), `Ignored. Same version (${p.version}) in repository`);
24
+ npmlog_1.default.info(this.commandName, logPkgName, npmlog_1.default.separator, `Ignored. Same version (${p.version}) in repository`);
28
25
  continue;
29
26
  }
30
27
  selectedPackages.push(p);
31
28
  }
32
- const tasks = [];
33
- for (const p of selectedPackages) {
34
- const json = { ...p.json };
35
- json.scripts = json.scripts || {};
36
- json.scripts.publish = json.scripts.publish || 'npm publish';
37
- const _p = { json };
38
- Object.setPrototypeOf(_p, p);
39
- const childTask = this._preparePackageTask(_p, { newVersions });
40
- if (childTask) {
41
- tasks.push(childTask);
42
- }
29
+ return super._prepareTasks(selectedPackages, { newVersions });
30
+ }
31
+ async _exec(args, options) {
32
+ if (args.command === '#') {
33
+ if (args.name === 'root')
34
+ return { code: 0 };
35
+ return super._exec({ ...args, command: 'npm publish' }, { ...options, stdio: 'inherit' });
43
36
  }
44
- return tasks;
37
+ return super._exec(args, options);
45
38
  }
46
39
  }
47
40
  exports.PublishCommand = PublishCommand;
@@ -7,7 +7,6 @@ exports.RunCommand = void 0;
7
7
  const npmlog_1 = __importDefault(require("npmlog"));
8
8
  const power_tasks_1 = require("power-tasks");
9
9
  const chalk_1 = __importDefault(require("chalk"));
10
- const figures_1 = __importDefault(require("figures"));
11
10
  const parse_npm_script_1 = __importDefault(require("@netlify/parse-npm-script"));
12
11
  const multi_task_command_1 = require("./multi-task-command");
13
12
  const command_1 = require("../core/command");
@@ -18,63 +17,87 @@ class RunCommand extends multi_task_command_1.MultiTaskCommand {
18
17
  this.repository = repository;
19
18
  this.script = script;
20
19
  }
21
- async _preExecute() {
22
- npmlog_1.default.info('run', `Executing script "${this.script}" for packages`);
23
- }
24
- _prepareTasks() {
25
- const packages = this.repository.getPackages({ toposort: true });
26
- const tasks = [];
20
+ _prepareTasks(packages, options) {
21
+ const packageTasks = [];
27
22
  for (const p of packages) {
28
23
  if (p.json.scripts) {
29
- const childTask = this._preparePackageTask(p);
24
+ const childTask = this._prepareScriptTask({
25
+ name: p.name,
26
+ dirname: p.dirname,
27
+ json: p.json,
28
+ dependencies: p.dependencies
29
+ }, options);
30
30
  if (childTask) {
31
- tasks.push(childTask);
31
+ packageTasks.push(childTask);
32
32
  }
33
33
  }
34
34
  }
35
+ const mainTask = this._prepareScriptTask({
36
+ name: 'root',
37
+ dirname: this.repository.dirname,
38
+ json: this.repository.json
39
+ });
40
+ if (!mainTask?.children)
41
+ return packageTasks;
42
+ const tasks = [];
43
+ const pre = mainTask.children.filter((t => t.name.endsWith(':pre' + this.script)));
44
+ const post = mainTask.children.filter((t => t.name.endsWith(':post' + this.script)));
45
+ pre.forEach(t => t.options.exclusive = true);
46
+ post.forEach(t => t.options.exclusive = true);
47
+ tasks.push(...pre);
48
+ tasks.push(...packageTasks);
49
+ tasks.push(...post);
35
50
  return tasks;
36
51
  }
37
- _preparePackageTask(p, ctx) {
52
+ _prepareScriptTask(args, ctx) {
53
+ const json = { ...args.json };
54
+ json.scripts = json.scripts || {};
55
+ json.scripts[this.script] = json.scripts[this.script] || '#';
38
56
  let scriptInfo;
39
57
  try {
40
- scriptInfo = (0, parse_npm_script_1.default)(p.json, 'npm run ' + this.script);
58
+ scriptInfo = (0, parse_npm_script_1.default)(json, 'npm run ' + this.script);
41
59
  if (!(scriptInfo && scriptInfo.raw))
42
60
  return;
43
61
  }
44
62
  catch {
45
63
  return;
46
64
  }
47
- const tasks = [];
65
+ const children = [];
48
66
  for (const s of scriptInfo.steps) {
49
67
  const parsed = Array.isArray(s.parsed) ? s.parsed : [s.parsed];
50
68
  for (const cmd of parsed) {
51
69
  const task = new power_tasks_1.Task(async () => {
52
- return await this._exec(p, cmd, {
53
- cwd: p.dirname,
54
- argv: this.argv
70
+ return await this._exec({
71
+ ...args,
72
+ command: cmd,
73
+ stdio: npmlog_1.default.levelIndex <= 1000 ? 'inherit' : 'pipe'
55
74
  }, ctx);
75
+ }, {
76
+ name: args.name + ':' + s.name,
77
+ dependencies: s.name.startsWith('pre') || s.name.startsWith('post') ?
78
+ undefined : args.dependencies
56
79
  });
57
- tasks.push(task);
80
+ children.push(task);
58
81
  }
59
82
  }
60
- if (tasks.length)
61
- return new power_tasks_1.Task(tasks, {
62
- name: p.name,
63
- dependencies: this.options.parallel ? undefined : p.dependencies,
64
- bail: this.options.bail,
65
- concurrency: this.options.concurrency
83
+ if (children.length) {
84
+ return new power_tasks_1.Task(children, {
85
+ name: args.name,
86
+ bail: true,
87
+ serial: true,
66
88
  });
89
+ }
67
90
  }
68
- async _exec(pkg, command, options, ctx) {
69
- npmlog_1.default.verbose(this.commandName, pkg.name, chalk_1.default.gray(figures_1.default.lineVerticalDashed0), chalk_1.default.cyanBright.bold('executing'), chalk_1.default.gray(figures_1.default.lineVerticalDashed0), command);
91
+ async _exec(args, options) {
92
+ npmlog_1.default.verbose(this.commandName, chalk_1.default.cyan(args.name), chalk_1.default.cyanBright.bold('executing'), npmlog_1.default.separator, args.command);
70
93
  const t = Date.now();
71
- const r = await (0, exec_1.exec)(command, options);
94
+ const r = await (0, exec_1.exec)(args.command, { cwd: args.dirname, stdio: args.stdio });
72
95
  if (r.error) {
73
- npmlog_1.default.error(this.commandName, chalk_1.default.gray(figures_1.default.lineVerticalDashed0), pkg.name, chalk_1.default.gray(figures_1.default.lineVerticalDashed0), chalk_1.default.red.bold('failed'), chalk_1.default.gray(figures_1.default.lineVerticalDashed0), command, chalk_1.default.gray(figures_1.default.lineVerticalDashed0), r.error.message.trim());
74
- npmlog_1.default.verbose(this.commandName, chalk_1.default.gray(figures_1.default.lineVerticalDashed0), r.stderr || r.stdout);
96
+ npmlog_1.default.error(this.commandName, chalk_1.default.cyan(args.name), chalk_1.default.red.bold('failed'), npmlog_1.default.separator, args.command, npmlog_1.default.separator, r.error.message.trim());
97
+ npmlog_1.default.verbose(this.commandName, '', r.stderr || r.stdout);
75
98
  }
76
99
  else
77
- npmlog_1.default.info(this.commandName, chalk_1.default.gray(figures_1.default.lineVerticalDashed0), pkg.name, chalk_1.default.gray(figures_1.default.lineVerticalDashed0), chalk_1.default.green.bold('success'), chalk_1.default.gray(figures_1.default.lineVerticalDashed0), command, chalk_1.default.gray(figures_1.default.lineVerticalDashed0), 'Completed in ' + chalk_1.default.yellow('' + (Date.now() - t) + ' ms'));
100
+ npmlog_1.default.info(this.commandName, chalk_1.default.cyan(args.name), chalk_1.default.green.bold('executed'), npmlog_1.default.separator, args.command, chalk_1.default.yellow(' (' + (Date.now() - t) + ' ms)'));
78
101
  if (r.error)
79
102
  throw r.error;
80
103
  return r;
@@ -10,7 +10,6 @@ const chalk_1 = __importDefault(require("chalk"));
10
10
  const semver_1 = __importDefault(require("semver"));
11
11
  const npmlog_1 = __importDefault(require("npmlog"));
12
12
  const strip_color_1 = __importDefault(require("strip-color"));
13
- const figures_1 = __importDefault(require("figures"));
14
13
  const run_command_1 = require("./run-command");
15
14
  const git_utils_1 = require("../utils/git-utils");
16
15
  const command_1 = require("../core/command");
@@ -20,12 +19,11 @@ class VersionCommand extends run_command_1.RunCommand {
20
19
  this.repository = repository;
21
20
  this.bump = bump;
22
21
  }
23
- async _prepareTasks() {
22
+ async _prepareTasks(packages) {
24
23
  const { repository } = this;
25
24
  const git = new git_utils_1.GitHelper({ cwd: repository.dirname });
26
25
  const dirtyFiles = await git.listDirtyFiles();
27
26
  const committedFiles = await git.listCommittedFiles();
28
- const packages = repository.getPackages({ toposort: true });
29
27
  const newVersions = {};
30
28
  let errorCount = 0;
31
29
  const selectedPackages = [];
@@ -66,7 +64,7 @@ class VersionCommand extends run_command_1.RunCommand {
66
64
  message: (0, strip_color_1.default)(message),
67
65
  });
68
66
  else
69
- npmlog_1.default.log(this.options.ignoreDirty ? 'info' : 'error', this.commandName, logPkgName, chalk_1.default.gray(figures_1.default.lineVerticalDashed0), chalk_1.default.whiteBright(p.version), chalk_1.default.gray(figures_1.default.lineVerticalDashed0), status, chalk_1.default.gray(figures_1.default.lineVerticalDashed0), message);
67
+ npmlog_1.default.log(this.options.ignoreDirty ? 'info' : 'error', this.commandName, logPkgName, chalk_1.default.whiteBright(p.version), status, npmlog_1.default.separator, message);
70
68
  continue;
71
69
  }
72
70
  selectedPackages.push(p);
@@ -79,33 +77,24 @@ class VersionCommand extends run_command_1.RunCommand {
79
77
  }, '0.0.0');
80
78
  Object.keys(newVersions).forEach(k => newVersions[k] = maxVer);
81
79
  }
82
- const tasks = [];
83
- for (const p of selectedPackages) {
84
- const json = { ...p.json };
85
- json.scripts = json.scripts || {};
86
- json.scripts.version = json.scripts.version || '#version';
87
- const _p = { json };
88
- Object.setPrototypeOf(_p, p);
89
- const childTask = this._preparePackageTask(_p, { newVersions });
90
- if (childTask) {
91
- tasks.push(childTask);
92
- }
93
- }
94
- return tasks;
80
+ return super._prepareTasks(selectedPackages, { newVersions });
95
81
  }
96
- async _exec(pkg, command, options, ctx) {
97
- if (command === '#version') {
98
- const { newVersions } = ctx;
99
- const oldVer = pkg.version;
100
- const newVer = newVersions[pkg.name];
101
- pkg.json.version = newVer;
102
- const f = path_1.default.join(pkg.dirname, 'package.json');
103
- const data = JSON.stringify(pkg.json, undefined, 2);
82
+ async _exec(args, options) {
83
+ if (args.name === 'root')
84
+ return { code: 0 };
85
+ if (args.command === '#') {
86
+ const { newVersions } = options;
87
+ const oldVer = args.json.version;
88
+ const newVer = newVersions[args.name];
89
+ args.json.version = newVer;
90
+ delete args.json.scripts.version;
91
+ const f = path_1.default.join(args.dirname, 'package.json');
92
+ const data = JSON.stringify(args.json, undefined, 2);
104
93
  fs_1.default.writeFileSync(f, data, 'utf-8');
105
- npmlog_1.default.info(this.commandName, chalk_1.default.gray(figures_1.default.lineVerticalDashed0), pkg.name, chalk_1.default.gray(figures_1.default.lineVerticalDashed0), 'Version changed from ' + chalk_1.default.cyan(oldVer) + ' to ' + chalk_1.default.cyan(newVer));
94
+ npmlog_1.default.info(this.commandName, args.name, npmlog_1.default.separator, 'Version changed from ' + chalk_1.default.cyan(oldVer) + ' to ' + chalk_1.default.cyan(newVer));
106
95
  return { code: 0 };
107
96
  }
108
- return super._exec(pkg, command, options);
97
+ return super._exec(args, options);
109
98
  }
110
99
  }
111
100
  exports.VersionCommand = VersionCommand;
@@ -10,6 +10,9 @@ const is_ci_1 = __importDefault(require("is-ci"));
10
10
  const putil_merge_1 = __importDefault(require("putil-merge"));
11
11
  require("./logger");
12
12
  const constants_1 = require("../utils/constants");
13
+ const chalk_1 = __importDefault(require("chalk"));
14
+ const figures_1 = __importDefault(require("figures"));
15
+ const npmlog_2 = __importDefault(require("npmlog"));
13
16
  const noOp = () => void (0);
14
17
  class Command extends (0, strict_typed_events_1.TypedEventEmitterClass)(strict_typed_events_1.AsyncEventEmitter) {
15
18
  constructor(options) {
@@ -20,6 +23,12 @@ class Command extends (0, strict_typed_events_1.TypedEventEmitterClass)(strict_t
20
23
  this._options = options || {};
21
24
  if (is_ci_1.default)
22
25
  this.options.ci = true;
26
+ this.logger.separator = chalk_1.default.gray(figures_1.default.lineVerticalDashed0);
27
+ Object.defineProperty(this.logger, 'levelIndex', {
28
+ get() {
29
+ return npmlog_2.default.levels[npmlog_2.default.level] || 0;
30
+ }
31
+ });
23
32
  }
24
33
  get options() {
25
34
  return this._options;
@@ -56,7 +65,7 @@ class Command extends (0, strict_typed_events_1.TypedEventEmitterClass)(strict_t
56
65
  await this.emitAsync('finish', undefined, v).catch(noOp);
57
66
  this.disableProgress();
58
67
  this.logger.resume();
59
- this.logger.success('', 'Command completed');
68
+ this.logger.info('', 'Command completed');
60
69
  return v;
61
70
  }
62
71
  catch (e) {
@@ -76,6 +85,10 @@ class Command extends (0, strict_typed_events_1.TypedEventEmitterClass)(strict_t
76
85
  return;
77
86
  }
78
87
  disableProgress() {
88
+ //
89
+ }
90
+ async _preExecute() {
91
+ npmlog_2.default.info('rman', `Executing "${this.commandName}" command`);
79
92
  }
80
93
  }
81
94
  exports.Command = Command;
@@ -100,8 +113,8 @@ exports.Command = Command;
100
113
  function composeOptions(commandName, yargArgs, config) {
101
114
  const result = (0, putil_merge_1.default)({}, yargArgs);
102
115
  (0, putil_merge_1.default)(result, config, { filter: (_, key) => key !== 'command' });
103
- const cfgCmd = config.commans && typeof config.command === 'object' ?
104
- config.command : undefined;
116
+ const cfgCmd = config.command && typeof config.command === 'object' ?
117
+ config.command[commandName] : undefined;
105
118
  if (cfgCmd && typeof cfgCmd === 'object')
106
119
  (0, putil_merge_1.default)(result, cfgCmd);
107
120
  return result;
@@ -4,5 +4,4 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const npmlog_1 = __importDefault(require("npmlog"));
7
- npmlog_1.default.addLevel("success", 1500, { fg: "green", bold: true });
8
7
  npmlog_1.default.addLevel('output', 3300, {}, '');
package/cjs/index.js CHANGED
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.fsDelete = exports.tryStat = exports.fsExists = void 0;
7
+ const promises_1 = __importDefault(require("fs/promises"));
8
+ const path_1 = __importDefault(require("path"));
9
+ async function fsExists(s) {
10
+ return promises_1.default.lstat(s).then(() => true).catch(() => false);
11
+ }
12
+ exports.fsExists = fsExists;
13
+ async function tryStat(s) {
14
+ return promises_1.default.lstat(s).catch(() => undefined);
15
+ }
16
+ exports.tryStat = tryStat;
17
+ async function fsDelete(fileOrDir) {
18
+ const stat = await tryStat(fileOrDir);
19
+ if (stat) {
20
+ if (stat.isFile() || stat.isSymbolicLink()) {
21
+ await promises_1.default.unlink(fileOrDir);
22
+ return true;
23
+ }
24
+ if (stat.isDirectory()) {
25
+ const list = await promises_1.default.readdir(fileOrDir);
26
+ for (const file of list)
27
+ await fsDelete(path_1.default.join(fileOrDir, file));
28
+ await promises_1.default.rmdir(fileOrDir);
29
+ return true;
30
+ }
31
+ }
32
+ return false;
33
+ }
34
+ exports.fsDelete = fsDelete;
package/esm/cli.mjs CHANGED
@@ -12,6 +12,7 @@ import { ExecuteCommand } from './commands/execute-command.mjs';
12
12
  import { RunCommand } from './commands/run-command.mjs';
13
13
  import { VersionCommand } from './commands/version-command.mjs';
14
14
  import { PublishCommand } from './commands/publish-command.mjs';
15
+ import { CleanInstallCommand } from './commands/ci-command.mjs';
15
16
  export async function runCli(options) {
16
17
  const s = path.resolve(getDirname(), '../package.json');
17
18
  const pkgJson = JSON.parse(await fs.readFile(s, 'utf-8'));
@@ -42,6 +43,7 @@ export async function runCli(options) {
42
43
  RunCommand.initCli(repository, program);
43
44
  VersionCommand.initCli(repository, program);
44
45
  PublishCommand.initCli(repository, program);
46
+ CleanInstallCommand.initCli(repository, program);
45
47
  if (!_argv.length)
46
48
  program.showHelp();
47
49
  else
@@ -0,0 +1,26 @@
1
+ import yargs from 'yargs';
2
+ import { Task } from 'power-tasks';
3
+ import { Repository } from '../core/repository';
4
+ import { Package } from '../core/package';
5
+ import { RunCommand } from './run-command';
6
+ import { ExecuteCommandResult } from '../utils/exec';
7
+ export declare class CleanInstallCommand extends RunCommand<CleanInstallCommand.Options> {
8
+ readonly repository: Repository;
9
+ static commandName: string;
10
+ constructor(repository: Repository, options?: CleanInstallCommand.Options);
11
+ protected _prepareTasks(packages: Package[]): Promise<Task[]>;
12
+ protected _exec(args: {
13
+ name: string;
14
+ json: any;
15
+ dirname: string;
16
+ dependencies?: string[];
17
+ command: string;
18
+ }, ctx?: any): Promise<ExecuteCommandResult>;
19
+ protected _fsDelete(fileOrDir: string): Promise<void>;
20
+ }
21
+ export declare namespace CleanInstallCommand {
22
+ interface Options extends RunCommand.Options {
23
+ }
24
+ const cliCommandOptions: Record<string, yargs.Options>;
25
+ function initCli(repository: Repository, program: yargs.Argv): void;
26
+ }
@@ -0,0 +1,74 @@
1
+ import { Task } from 'power-tasks';
2
+ import chalk from 'chalk';
3
+ import logger from 'npmlog';
4
+ import { Command } from './../core/command.mjs';
5
+ import { RunCommand } from './run-command.mjs';
6
+ import { fsDelete, fsExists } from './../utils/file-utils.mjs';
7
+ import path from 'path';
8
+ export class CleanInstallCommand extends RunCommand {
9
+ constructor(repository, options) {
10
+ super(repository, 'clean_', options);
11
+ this.repository = repository;
12
+ }
13
+ async _prepareTasks(packages) {
14
+ const tasks = await super._prepareTasks(packages);
15
+ const client = this.repository.config.client || 'npm';
16
+ if (!(client === 'npm' || client === 'yargs'))
17
+ throw new Error(`Invalid npm client "${client}"`);
18
+ tasks.push(new Task(async () => {
19
+ const dirname = this.repository.dirname;
20
+ await this._fsDelete(path.join(dirname, 'node_modules'));
21
+ await this._fsDelete(path.join(dirname, 'package-lock.json'));
22
+ await this._fsDelete(path.join(dirname, 'yarn-lock.json'));
23
+ logger.info(this.commandName, chalk.yellow('installing'), 'Running ' + client + ' install');
24
+ return super._exec({
25
+ name: 'root',
26
+ dirname: this.repository.dirname,
27
+ json: { ...this.repository.json },
28
+ command: client + ' install',
29
+ stdio: 'inherit'
30
+ });
31
+ }, { exclusive: true }));
32
+ return tasks;
33
+ }
34
+ async _exec(args, ctx) {
35
+ if (args.command === '#') {
36
+ if (args.name === 'root')
37
+ return { code: 0 };
38
+ const { dirname } = args;
39
+ await this._fsDelete(path.join(dirname, 'node_modules'));
40
+ await this._fsDelete(path.join(dirname, 'package-lock.json'));
41
+ await this._fsDelete(path.join(dirname, 'yarn-lock.json'));
42
+ return { code: 0 };
43
+ }
44
+ return super._exec(args, ctx);
45
+ }
46
+ async _fsDelete(fileOrDir) {
47
+ if (await fsExists(fileOrDir)) {
48
+ logger.info(this.commandName, chalk.yellow('clean'), 'Deleting ' + fileOrDir);
49
+ await fsDelete(fileOrDir);
50
+ }
51
+ }
52
+ }
53
+ CleanInstallCommand.commandName = 'ci';
54
+ (function (CleanInstallCommand) {
55
+ CleanInstallCommand.cliCommandOptions = {
56
+ ...RunCommand.cliCommandOptions
57
+ };
58
+ function initCli(repository, program) {
59
+ program.command({
60
+ command: 'ci [...options]',
61
+ describe: 'Deletes all dependency modules and re-installs',
62
+ builder: (cmd) => {
63
+ return cmd
64
+ .example("$0 ci", '')
65
+ .option(CleanInstallCommand.cliCommandOptions);
66
+ },
67
+ handler: async (args) => {
68
+ const options = Command.composeOptions(CleanInstallCommand.commandName, args, repository.config);
69
+ await new CleanInstallCommand(repository, options).execute();
70
+ }
71
+ });
72
+ }
73
+ CleanInstallCommand.initCli = initCli;
74
+ })(CleanInstallCommand || (CleanInstallCommand = {}));
@@ -2,13 +2,14 @@ import yargs from 'yargs';
2
2
  import { Repository } from '../core/repository';
3
3
  import { MultiTaskCommand } from './multi-task-command';
4
4
  import { Task } from 'power-tasks';
5
+ import { Package } from '../core/package';
5
6
  export declare class ExecuteCommand extends MultiTaskCommand<ExecuteCommand.Options> {
6
7
  readonly repository: Repository;
7
8
  cmd: string;
8
9
  argv?: string[] | undefined;
9
10
  static commandName: string;
10
11
  constructor(repository: Repository, cmd: string, argv?: string[] | undefined, options?: ExecuteCommand.Options);
11
- protected _prepareTasks(): Task[];
12
+ protected _prepareTasks(packages: Package[]): Task[];
12
13
  }
13
14
  export declare namespace ExecuteCommand {
14
15
  interface Options extends MultiTaskCommand.Options {
@@ -1,6 +1,5 @@
1
1
  import logger from 'npmlog';
2
2
  import chalk from 'chalk';
3
- import figures from 'figures';
4
3
  import { MultiTaskCommand } from './multi-task-command.mjs';
5
4
  import { Task } from 'power-tasks';
6
5
  import { exec } from './../utils/exec.mjs';
@@ -12,18 +11,18 @@ export class ExecuteCommand extends MultiTaskCommand {
12
11
  this.cmd = cmd;
13
12
  this.argv = argv;
14
13
  }
15
- _prepareTasks() {
16
- const packages = this.repository.getPackages({ toposort: !this.options.parallel });
14
+ _prepareTasks(packages) {
17
15
  const tasks = [];
18
16
  for (const p of packages) {
19
17
  const task = new Task(async () => {
20
18
  const t = Date.now();
21
- logger.verbose(this.commandName, p.name, chalk.gray(figures.lineVerticalDashed0), chalk.cyanBright.bold('executing'), chalk.gray(figures.lineVerticalDashed0), this.cmd + ' ' + (this.argv?.join(' ') || ''));
19
+ logger.verbose(this.commandName, p.name, chalk.cyanBright.bold('executing'), logger.separator, this.cmd + ' ' + (this.argv?.join(' ') || ''));
22
20
  const r = await exec(this.cmd, {
23
21
  cwd: p.dirname,
24
- argv: this.argv
22
+ argv: this.argv,
23
+ stdio: logger.levelIndex <= 1000 ? 'inherit' : 'pipe'
25
24
  });
26
- logger.log((r.error ? 'error' : 'verbose'), this.commandName, chalk.gray(figures.lineVerticalDashed0), p.name, chalk.gray(figures.lineVerticalDashed0), (r.error ? chalk.red.bold('failed') : chalk.green.bold('success')), chalk.gray(figures.lineVerticalDashed0), 'Completed in ' + chalk.yellow('' + (Date.now() - t) + ' ms'));
25
+ logger.log((r.error ? 'error' : 'info'), this.commandName, p.name, (r.error ? chalk.red.bold('failed') : chalk.green.bold('success')), logger.separator, this.cmd, chalk.yellow(' (' + (Date.now() - t) + ' ms') + ')');
27
26
  }, {
28
27
  name: p.name,
29
28
  dependencies: this.options.parallel ? undefined : p.dependencies,
@@ -2,12 +2,14 @@ import yargs from 'yargs';
2
2
  import { Task } from 'power-tasks';
3
3
  import { Repository } from '../core/repository';
4
4
  import { Command } from '../core/command';
5
+ import { Package } from '../core/package';
5
6
  export declare abstract class MultiTaskCommand<TOptions extends MultiTaskCommand.Options = MultiTaskCommand.Options> extends Command<TOptions> {
6
7
  readonly repository: Repository;
7
8
  protected _task?: Task;
8
9
  protected constructor(repository: Repository, options?: TOptions);
9
10
  protected _execute(): Promise<any>;
10
- protected abstract _prepareTasks(): Task[] | Promise<Task[]> | void;
11
+ protected _getPackages(): Promise<Package[]>;
12
+ protected abstract _prepareTasks(packages: Package[]): Task[] | Promise<Task[]> | void;
11
13
  }
12
14
  export declare namespace MultiTaskCommand {
13
15
  interface Options extends Command.GlobalOptions {
@@ -1,11 +1,8 @@
1
1
  import os from 'os';
2
- import chalk from 'chalk';
3
2
  import logger from 'npmlog';
4
- import figures from 'figures';
5
3
  import { Task } from 'power-tasks';
6
4
  import { Command } from './../core/command.mjs';
7
5
  import { isTTY } from './../utils/constants.mjs';
8
- const logSeparator = chalk.gray(figures.lineVerticalDashed0);
9
6
  export class MultiTaskCommand extends Command {
10
7
  constructor(repository, options) {
11
8
  super(options);
@@ -19,9 +16,10 @@ export class MultiTaskCommand extends Command {
19
16
  this.options.bail = true;
20
17
  }
21
18
  async _execute() {
22
- const childTasks = await this._prepareTasks();
19
+ const packages = await this._getPackages();
20
+ const childTasks = await this._prepareTasks(packages);
23
21
  if (!(childTasks && childTasks.length)) {
24
- logger.info(this.commandName, logSeparator, 'There is no task to process');
22
+ logger.info(this.commandName, '', 'There is no task to process');
25
23
  return;
26
24
  }
27
25
  // this.enableProgress();
@@ -29,7 +27,10 @@ export class MultiTaskCommand extends Command {
29
27
  concurrency: this.options.concurrency || os.cpus().length,
30
28
  bail: this.options.bail,
31
29
  });
32
- await this._task.catch(() => void (0));
30
+ await this._task.toPromise().catch(() => void (0));
31
+ }
32
+ async _getPackages() {
33
+ return this.repository.getPackages({ toposort: !this.options.parallel });
33
34
  }
34
35
  }
35
36
  (function (MultiTaskCommand) {
@@ -1,12 +1,21 @@
1
1
  import yargs from 'yargs';
2
2
  import { Task } from 'power-tasks';
3
3
  import { Repository } from '../core/repository';
4
+ import { Package } from '../core/package';
4
5
  import { RunCommand } from './run-command';
6
+ import { ExecuteCommandResult } from '../utils/exec';
5
7
  export declare class PublishCommand extends RunCommand<PublishCommand.Options> {
6
8
  readonly repository: Repository;
7
9
  static commandName: string;
8
10
  constructor(repository: Repository, options?: PublishCommand.Options);
9
- protected _prepareTasks(): Promise<Task[]>;
11
+ protected _prepareTasks(packages: Package[]): Promise<Task[]>;
12
+ protected _exec(args: {
13
+ name: string;
14
+ json: any;
15
+ dirname: string;
16
+ dependencies?: string[];
17
+ command: string;
18
+ }, options?: any): Promise<ExecuteCommandResult>;
10
19
  }
11
20
  export declare namespace PublishCommand {
12
21
  interface Options extends RunCommand.Options {
@@ -1,7 +1,6 @@
1
1
  import chalk from 'chalk';
2
2
  import fetchPackageInfo from 'package-json';
3
3
  import logger from 'npmlog';
4
- import figures from 'figures';
5
4
  import { Command } from './../core/command.mjs';
6
5
  import { RunCommand } from './run-command.mjs';
7
6
  export class PublishCommand extends RunCommand {
@@ -9,33 +8,27 @@ export class PublishCommand extends RunCommand {
9
8
  super(repository, 'publish', options);
10
9
  this.repository = repository;
11
10
  }
12
- async _prepareTasks() {
13
- const { repository } = this;
14
- const packages = repository.getPackages({ toposort: true });
11
+ async _prepareTasks(packages) {
15
12
  const newVersions = {};
16
13
  const selectedPackages = [];
17
14
  for (const p of packages) {
18
15
  const logPkgName = chalk.yellow(p.name);
19
16
  const r = await fetchPackageInfo(p.json.name);
20
17
  if (r.version === p.version) {
21
- logger.info(this.commandName, logPkgName, chalk.gray(figures.lineVerticalDashed0), `Ignored. Same version (${p.version}) in repository`);
18
+ logger.info(this.commandName, logPkgName, logger.separator, `Ignored. Same version (${p.version}) in repository`);
22
19
  continue;
23
20
  }
24
21
  selectedPackages.push(p);
25
22
  }
26
- const tasks = [];
27
- for (const p of selectedPackages) {
28
- const json = { ...p.json };
29
- json.scripts = json.scripts || {};
30
- json.scripts.publish = json.scripts.publish || 'npm publish';
31
- const _p = { json };
32
- Object.setPrototypeOf(_p, p);
33
- const childTask = this._preparePackageTask(_p, { newVersions });
34
- if (childTask) {
35
- tasks.push(childTask);
36
- }
23
+ return super._prepareTasks(selectedPackages, { newVersions });
24
+ }
25
+ async _exec(args, options) {
26
+ if (args.command === '#') {
27
+ if (args.name === 'root')
28
+ return { code: 0 };
29
+ return super._exec({ ...args, command: 'npm publish' }, { ...options, stdio: 'inherit' });
37
30
  }
38
- return tasks;
31
+ return super._exec(args, options);
39
32
  }
40
33
  }
41
34
  PublishCommand.commandName = 'publish';
@@ -2,17 +2,28 @@ import yargs from 'yargs';
2
2
  import { Task } from 'power-tasks';
3
3
  import { Repository } from '../core/repository';
4
4
  import { MultiTaskCommand } from './multi-task-command';
5
+ import { ExecuteCommandResult } from '../utils/exec';
5
6
  import { Package } from '../core/package';
6
- import { ExecuteCommandResult, IExecutorOptions } from '../utils/exec';
7
7
  export declare class RunCommand<TOptions extends RunCommand.Options> extends MultiTaskCommand<TOptions> {
8
8
  readonly repository: Repository;
9
9
  script: string;
10
10
  static commandName: string;
11
11
  constructor(repository: Repository, script: string, options?: TOptions);
12
- protected _preExecute(): Promise<void>;
13
- protected _prepareTasks(): Task[] | Promise<Task[]>;
14
- protected _preparePackageTask(p: Package, ctx?: any): Task | undefined;
15
- protected _exec(pkg: Package, command: string, options: IExecutorOptions, ctx?: any): Promise<ExecuteCommandResult>;
12
+ protected _prepareTasks(packages: Package[], options?: any): Task[] | Promise<Task[]>;
13
+ protected _prepareScriptTask(args: {
14
+ name: string;
15
+ json: any;
16
+ dirname: string;
17
+ dependencies?: string[];
18
+ }, ctx?: any): Task | undefined;
19
+ protected _exec(args: {
20
+ name: string;
21
+ json: any;
22
+ dirname: string;
23
+ dependencies?: string[];
24
+ command: string;
25
+ stdio?: 'inherit' | 'pipe';
26
+ }, options?: any): Promise<ExecuteCommandResult>;
16
27
  }
17
28
  export declare namespace RunCommand {
18
29
  interface Options extends MultiTaskCommand.Options {
@@ -1,7 +1,6 @@
1
1
  import logger from 'npmlog';
2
2
  import { Task } from 'power-tasks';
3
3
  import chalk from 'chalk';
4
- import figures from 'figures';
5
4
  import parseNpmScript from '@netlify/parse-npm-script';
6
5
  import { MultiTaskCommand } from './multi-task-command.mjs';
7
6
  import { Command } from './../core/command.mjs';
@@ -12,63 +11,87 @@ export class RunCommand extends MultiTaskCommand {
12
11
  this.repository = repository;
13
12
  this.script = script;
14
13
  }
15
- async _preExecute() {
16
- logger.info('run', `Executing script "${this.script}" for packages`);
17
- }
18
- _prepareTasks() {
19
- const packages = this.repository.getPackages({ toposort: true });
20
- const tasks = [];
14
+ _prepareTasks(packages, options) {
15
+ const packageTasks = [];
21
16
  for (const p of packages) {
22
17
  if (p.json.scripts) {
23
- const childTask = this._preparePackageTask(p);
18
+ const childTask = this._prepareScriptTask({
19
+ name: p.name,
20
+ dirname: p.dirname,
21
+ json: p.json,
22
+ dependencies: p.dependencies
23
+ }, options);
24
24
  if (childTask) {
25
- tasks.push(childTask);
25
+ packageTasks.push(childTask);
26
26
  }
27
27
  }
28
28
  }
29
+ const mainTask = this._prepareScriptTask({
30
+ name: 'root',
31
+ dirname: this.repository.dirname,
32
+ json: this.repository.json
33
+ });
34
+ if (!mainTask?.children)
35
+ return packageTasks;
36
+ const tasks = [];
37
+ const pre = mainTask.children.filter((t => t.name.endsWith(':pre' + this.script)));
38
+ const post = mainTask.children.filter((t => t.name.endsWith(':post' + this.script)));
39
+ pre.forEach(t => t.options.exclusive = true);
40
+ post.forEach(t => t.options.exclusive = true);
41
+ tasks.push(...pre);
42
+ tasks.push(...packageTasks);
43
+ tasks.push(...post);
29
44
  return tasks;
30
45
  }
31
- _preparePackageTask(p, ctx) {
46
+ _prepareScriptTask(args, ctx) {
47
+ const json = { ...args.json };
48
+ json.scripts = json.scripts || {};
49
+ json.scripts[this.script] = json.scripts[this.script] || '#';
32
50
  let scriptInfo;
33
51
  try {
34
- scriptInfo = parseNpmScript(p.json, 'npm run ' + this.script);
52
+ scriptInfo = parseNpmScript(json, 'npm run ' + this.script);
35
53
  if (!(scriptInfo && scriptInfo.raw))
36
54
  return;
37
55
  }
38
56
  catch {
39
57
  return;
40
58
  }
41
- const tasks = [];
59
+ const children = [];
42
60
  for (const s of scriptInfo.steps) {
43
61
  const parsed = Array.isArray(s.parsed) ? s.parsed : [s.parsed];
44
62
  for (const cmd of parsed) {
45
63
  const task = new Task(async () => {
46
- return await this._exec(p, cmd, {
47
- cwd: p.dirname,
48
- argv: this.argv
64
+ return await this._exec({
65
+ ...args,
66
+ command: cmd,
67
+ stdio: logger.levelIndex <= 1000 ? 'inherit' : 'pipe'
49
68
  }, ctx);
69
+ }, {
70
+ name: args.name + ':' + s.name,
71
+ dependencies: s.name.startsWith('pre') || s.name.startsWith('post') ?
72
+ undefined : args.dependencies
50
73
  });
51
- tasks.push(task);
74
+ children.push(task);
52
75
  }
53
76
  }
54
- if (tasks.length)
55
- return new Task(tasks, {
56
- name: p.name,
57
- dependencies: this.options.parallel ? undefined : p.dependencies,
58
- bail: this.options.bail,
59
- concurrency: this.options.concurrency
77
+ if (children.length) {
78
+ return new Task(children, {
79
+ name: args.name,
80
+ bail: true,
81
+ serial: true,
60
82
  });
83
+ }
61
84
  }
62
- async _exec(pkg, command, options, ctx) {
63
- logger.verbose(this.commandName, pkg.name, chalk.gray(figures.lineVerticalDashed0), chalk.cyanBright.bold('executing'), chalk.gray(figures.lineVerticalDashed0), command);
85
+ async _exec(args, options) {
86
+ logger.verbose(this.commandName, chalk.cyan(args.name), chalk.cyanBright.bold('executing'), logger.separator, args.command);
64
87
  const t = Date.now();
65
- const r = await exec(command, options);
88
+ const r = await exec(args.command, { cwd: args.dirname, stdio: args.stdio });
66
89
  if (r.error) {
67
- logger.error(this.commandName, chalk.gray(figures.lineVerticalDashed0), pkg.name, chalk.gray(figures.lineVerticalDashed0), chalk.red.bold('failed'), chalk.gray(figures.lineVerticalDashed0), command, chalk.gray(figures.lineVerticalDashed0), r.error.message.trim());
68
- logger.verbose(this.commandName, chalk.gray(figures.lineVerticalDashed0), r.stderr || r.stdout);
90
+ logger.error(this.commandName, chalk.cyan(args.name), chalk.red.bold('failed'), logger.separator, args.command, logger.separator, r.error.message.trim());
91
+ logger.verbose(this.commandName, '', r.stderr || r.stdout);
69
92
  }
70
93
  else
71
- logger.info(this.commandName, chalk.gray(figures.lineVerticalDashed0), pkg.name, chalk.gray(figures.lineVerticalDashed0), chalk.green.bold('success'), chalk.gray(figures.lineVerticalDashed0), command, chalk.gray(figures.lineVerticalDashed0), 'Completed in ' + chalk.yellow('' + (Date.now() - t) + ' ms'));
94
+ logger.info(this.commandName, chalk.cyan(args.name), chalk.green.bold('executed'), logger.separator, args.command, chalk.yellow(' (' + (Date.now() - t) + ' ms)'));
72
95
  if (r.error)
73
96
  throw r.error;
74
97
  return r;
@@ -3,14 +3,20 @@ import { Task } from 'power-tasks';
3
3
  import { Repository } from '../core/repository';
4
4
  import { RunCommand } from './run-command';
5
5
  import { Package } from '../core/package';
6
- import { ExecuteCommandResult, IExecutorOptions } from '../utils/exec';
6
+ import { ExecuteCommandResult } from '../utils/exec';
7
7
  export declare class VersionCommand extends RunCommand<VersionCommand.Options> {
8
8
  readonly repository: Repository;
9
9
  bump: string;
10
10
  static commandName: string;
11
11
  constructor(repository: Repository, bump: string, options?: VersionCommand.Options);
12
- protected _prepareTasks(): Promise<Task[]>;
13
- protected _exec(pkg: Package, command: string, options: IExecutorOptions, ctx: any): Promise<ExecuteCommandResult>;
12
+ protected _prepareTasks(packages: Package[]): Promise<Task[]>;
13
+ protected _exec(args: {
14
+ name: string;
15
+ json: any;
16
+ dirname: string;
17
+ dependencies?: string[];
18
+ command: string;
19
+ }, options?: any): Promise<ExecuteCommandResult>;
14
20
  }
15
21
  export declare namespace VersionCommand {
16
22
  interface Options extends RunCommand.Options {
@@ -4,7 +4,6 @@ import chalk from 'chalk';
4
4
  import semver from 'semver';
5
5
  import logger from 'npmlog';
6
6
  import stripColor from 'strip-color';
7
- import figures from 'figures';
8
7
  import { RunCommand } from './run-command.mjs';
9
8
  import { GitHelper } from './../utils/git-utils.mjs';
10
9
  import { Command } from './../core/command.mjs';
@@ -14,12 +13,11 @@ export class VersionCommand extends RunCommand {
14
13
  this.repository = repository;
15
14
  this.bump = bump;
16
15
  }
17
- async _prepareTasks() {
16
+ async _prepareTasks(packages) {
18
17
  const { repository } = this;
19
18
  const git = new GitHelper({ cwd: repository.dirname });
20
19
  const dirtyFiles = await git.listDirtyFiles();
21
20
  const committedFiles = await git.listCommittedFiles();
22
- const packages = repository.getPackages({ toposort: true });
23
21
  const newVersions = {};
24
22
  let errorCount = 0;
25
23
  const selectedPackages = [];
@@ -60,7 +58,7 @@ export class VersionCommand extends RunCommand {
60
58
  message: stripColor(message),
61
59
  });
62
60
  else
63
- logger.log(this.options.ignoreDirty ? 'info' : 'error', this.commandName, logPkgName, chalk.gray(figures.lineVerticalDashed0), chalk.whiteBright(p.version), chalk.gray(figures.lineVerticalDashed0), status, chalk.gray(figures.lineVerticalDashed0), message);
61
+ logger.log(this.options.ignoreDirty ? 'info' : 'error', this.commandName, logPkgName, chalk.whiteBright(p.version), status, logger.separator, message);
64
62
  continue;
65
63
  }
66
64
  selectedPackages.push(p);
@@ -73,33 +71,24 @@ export class VersionCommand extends RunCommand {
73
71
  }, '0.0.0');
74
72
  Object.keys(newVersions).forEach(k => newVersions[k] = maxVer);
75
73
  }
76
- const tasks = [];
77
- for (const p of selectedPackages) {
78
- const json = { ...p.json };
79
- json.scripts = json.scripts || {};
80
- json.scripts.version = json.scripts.version || '#version';
81
- const _p = { json };
82
- Object.setPrototypeOf(_p, p);
83
- const childTask = this._preparePackageTask(_p, { newVersions });
84
- if (childTask) {
85
- tasks.push(childTask);
86
- }
87
- }
88
- return tasks;
74
+ return super._prepareTasks(selectedPackages, { newVersions });
89
75
  }
90
- async _exec(pkg, command, options, ctx) {
91
- if (command === '#version') {
92
- const { newVersions } = ctx;
93
- const oldVer = pkg.version;
94
- const newVer = newVersions[pkg.name];
95
- pkg.json.version = newVer;
96
- const f = path.join(pkg.dirname, 'package.json');
97
- const data = JSON.stringify(pkg.json, undefined, 2);
76
+ async _exec(args, options) {
77
+ if (args.name === 'root')
78
+ return { code: 0 };
79
+ if (args.command === '#') {
80
+ const { newVersions } = options;
81
+ const oldVer = args.json.version;
82
+ const newVer = newVersions[args.name];
83
+ args.json.version = newVer;
84
+ delete args.json.scripts.version;
85
+ const f = path.join(args.dirname, 'package.json');
86
+ const data = JSON.stringify(args.json, undefined, 2);
98
87
  fs.writeFileSync(f, data, 'utf-8');
99
- logger.info(this.commandName, chalk.gray(figures.lineVerticalDashed0), pkg.name, chalk.gray(figures.lineVerticalDashed0), 'Version changed from ' + chalk.cyan(oldVer) + ' to ' + chalk.cyan(newVer));
88
+ logger.info(this.commandName, args.name, logger.separator, 'Version changed from ' + chalk.cyan(oldVer) + ' to ' + chalk.cyan(newVer));
100
89
  return { code: 0 };
101
90
  }
102
- return super._exec(pkg, command, options);
91
+ return super._exec(args, options);
103
92
  }
104
93
  }
105
94
  VersionCommand.commandName = 'version';
@@ -20,7 +20,7 @@ export declare abstract class Command<TOptions extends Command.GlobalOptions = C
20
20
  protected enableProgress(): Promise<void>;
21
21
  protected disableProgress(): void;
22
22
  protected abstract _execute(): Promise<any>;
23
- protected _preExecute?(): Promise<void>;
23
+ protected _preExecute(): Promise<void>;
24
24
  protected _postExecute?(): Promise<void>;
25
25
  }
26
26
  export declare namespace Command {
@@ -4,6 +4,9 @@ import isCi from 'is-ci';
4
4
  import merge from 'putil-merge';
5
5
  import './logger.mjs';
6
6
  import { isTTY } from './../utils/constants.mjs';
7
+ import chalk from 'chalk';
8
+ import figures from 'figures';
9
+ import logger from 'npmlog';
7
10
  const noOp = () => void (0);
8
11
  export class Command extends TypedEventEmitterClass(AsyncEventEmitter) {
9
12
  constructor(options) {
@@ -14,6 +17,12 @@ export class Command extends TypedEventEmitterClass(AsyncEventEmitter) {
14
17
  this._options = options || {};
15
18
  if (isCi)
16
19
  this.options.ci = true;
20
+ this.logger.separator = chalk.gray(figures.lineVerticalDashed0);
21
+ Object.defineProperty(this.logger, 'levelIndex', {
22
+ get() {
23
+ return logger.levels[logger.level] || 0;
24
+ }
25
+ });
17
26
  }
18
27
  get options() {
19
28
  return this._options;
@@ -50,7 +59,7 @@ export class Command extends TypedEventEmitterClass(AsyncEventEmitter) {
50
59
  await this.emitAsync('finish', undefined, v).catch(noOp);
51
60
  this.disableProgress();
52
61
  this.logger.resume();
53
- this.logger.success('', 'Command completed');
62
+ this.logger.info('', 'Command completed');
54
63
  return v;
55
64
  }
56
65
  catch (e) {
@@ -70,6 +79,10 @@ export class Command extends TypedEventEmitterClass(AsyncEventEmitter) {
70
79
  return;
71
80
  }
72
81
  disableProgress() {
82
+ //
83
+ }
84
+ async _preExecute() {
85
+ logger.info('rman', `Executing "${this.commandName}" command`);
73
86
  }
74
87
  }
75
88
  (function (Command) {
@@ -93,8 +106,8 @@ export class Command extends TypedEventEmitterClass(AsyncEventEmitter) {
93
106
  function composeOptions(commandName, yargArgs, config) {
94
107
  const result = merge({}, yargArgs);
95
108
  merge(result, config, { filter: (_, key) => key !== 'command' });
96
- const cfgCmd = config.commans && typeof config.command === 'object' ?
97
- config.command : undefined;
109
+ const cfgCmd = config.command && typeof config.command === 'object' ?
110
+ config.command[commandName] : undefined;
98
111
  if (cfgCmd && typeof cfgCmd === 'object')
99
112
  merge(result, cfgCmd);
100
113
  return result;
@@ -5,6 +5,8 @@ declare module 'npmlog' {
5
5
  disp: Record<string, string>;
6
6
  showProgress(): any;
7
7
  hideProgress(): any;
8
+ separator: string;
9
+ levelIndex: number;
8
10
  }
9
11
  }
10
12
  export {};
@@ -1,3 +1,2 @@
1
1
  import logger from 'npmlog';
2
- logger.addLevel("success", 1500, { fg: "green", bold: true });
3
2
  logger.addLevel('output', 3300, {}, '');
@@ -0,0 +1,5 @@
1
+ /// <reference types="node" />
2
+ import { Stats } from 'node:fs';
3
+ export declare function fsExists(s: string): Promise<boolean>;
4
+ export declare function tryStat(s: any): Promise<Stats | undefined>;
5
+ export declare function fsDelete(fileOrDir: string): Promise<boolean>;
@@ -0,0 +1,25 @@
1
+ import fsa from 'fs/promises';
2
+ import path from 'path';
3
+ export async function fsExists(s) {
4
+ return fsa.lstat(s).then(() => true).catch(() => false);
5
+ }
6
+ export async function tryStat(s) {
7
+ return fsa.lstat(s).catch(() => undefined);
8
+ }
9
+ export async function fsDelete(fileOrDir) {
10
+ const stat = await tryStat(fileOrDir);
11
+ if (stat) {
12
+ if (stat.isFile() || stat.isSymbolicLink()) {
13
+ await fsa.unlink(fileOrDir);
14
+ return true;
15
+ }
16
+ if (stat.isDirectory()) {
17
+ const list = await fsa.readdir(fileOrDir);
18
+ for (const file of list)
19
+ await fsDelete(path.join(fileOrDir, file));
20
+ await fsa.rmdir(fileOrDir);
21
+ return true;
22
+ }
23
+ }
24
+ return false;
25
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rman",
3
3
  "description": "Monorepo repository manager",
4
- "version": "0.2.5",
4
+ "version": "0.5.1",
5
5
  "author": "Panates",
6
6
  "license": "MIT",
7
7
  "contributors": [
@@ -43,7 +43,7 @@
43
43
  "npmlog": "^6.0.0",
44
44
  "package-json": "^7.0.0",
45
45
  "path-key": "^4.0.0",
46
- "power-tasks": "^0.0.2",
46
+ "power-tasks": "^0.4.0",
47
47
  "putil-merge": "^3.7.0",
48
48
  "putil-varhelpers": "^1.6.3",
49
49
  "semver": "^7.3.5",