rman 0.3.0 → 0.6.0

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.
@@ -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
+ cwd: 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 { cwd } = args;
39
+ await this._fsDelete(path.join(cwd, 'node_modules'));
40
+ await this._fsDelete(path.join(cwd, 'package-lock.json'));
41
+ await this._fsDelete(path.join(cwd, '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();
@@ -31,6 +29,9 @@ export class MultiTaskCommand extends Command {
31
29
  });
32
30
  await this._task.toPromise().catch(() => void (0));
33
31
  }
32
+ async _getPackages() {
33
+ return this.repository.getPackages({ toposort: !this.options.parallel });
34
+ }
34
35
  }
35
36
  (function (MultiTaskCommand) {
36
37
  MultiTaskCommand.cliCommandOptions = {
@@ -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
+ cwd: 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,30 @@ 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
+ cwd: string;
17
+ dependencies?: string[];
18
+ }, ctx?: any): Task | undefined;
19
+ protected _exec(args: {
20
+ name: string;
21
+ cwd: string;
22
+ dependencies?: string[];
23
+ command: string;
24
+ stdio?: 'inherit' | 'pipe';
25
+ json?: any;
26
+ logLevel?: string;
27
+ noThrow?: boolean;
28
+ }, options?: any): Promise<ExecuteCommandResult>;
16
29
  }
17
30
  export declare namespace RunCommand {
18
31
  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,26 +11,45 @@ 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
+ cwd: 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
+ cwd: 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
  }
@@ -43,37 +61,41 @@ export class RunCommand extends MultiTaskCommand {
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);
50
69
  }, {
51
- name: p.name + ':' + s.name,
70
+ name: args.name + ':' + s.name,
52
71
  dependencies: s.name.startsWith('pre') || s.name.startsWith('post') ?
53
- undefined : p.dependencies
72
+ undefined : args.dependencies
54
73
  });
55
74
  children.push(task);
56
75
  }
57
76
  }
58
77
  if (children.length) {
59
78
  return new Task(children, {
60
- name: p.name,
79
+ name: args.name,
61
80
  bail: true,
62
81
  serial: true,
63
82
  });
64
83
  }
65
84
  }
66
- async _exec(pkg, command, options, ctx) {
67
- 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
+ const logLevel = args.logLevel == null ? 'info' : args.logLevel;
87
+ if (logLevel)
88
+ logger.log(logLevel, this.commandName, chalk.cyan(args.name), chalk.cyanBright.bold('executing'), logger.separator, args.command);
68
89
  const t = Date.now();
69
- const r = await exec(command, options);
70
- if (r.error) {
71
- 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());
72
- logger.verbose(this.commandName, chalk.gray(figures.lineVerticalDashed0), r.stderr || r.stdout);
73
- }
74
- else
75
- 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'));
76
- if (r.error)
90
+ const r = await exec(args.command, { cwd: args.cwd, stdio: args.stdio });
91
+ if (logLevel)
92
+ if (r.error) {
93
+ logger.error(this.commandName, chalk.cyan(args.name), chalk.red.bold('failed'), logger.separator, args.command, logger.separator, r.error.message.trim());
94
+ logger.verbose(this.commandName, '', r.stderr || r.stdout);
95
+ }
96
+ else
97
+ logger.log(logLevel, this.commandName, chalk.cyan(args.name), chalk.green.bold('executed'), logger.separator, args.command, chalk.yellow(' (' + (Date.now() - t) + ' ms)'));
98
+ if (r.error && !args.noThrow)
77
99
  throw r.error;
78
100
  return r;
79
101
  }
@@ -3,21 +3,27 @@ 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
+ cwd: 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 {
17
23
  unified?: boolean;
18
24
  all?: boolean;
19
25
  ignoreDirty?: boolean;
20
- forceDirty?: boolean;
26
+ noTag?: boolean;
21
27
  }
22
28
  const cliCommandOptions: Record<string, yargs.Options>;
23
29
  function initCli(repository: Repository, program: yargs.Argv): void;
@@ -1,25 +1,24 @@
1
1
  import path from 'path';
2
- import fs from 'fs';
3
2
  import chalk from 'chalk';
4
3
  import semver from 'semver';
5
4
  import logger from 'npmlog';
6
5
  import stripColor from 'strip-color';
7
- import figures from 'figures';
6
+ import { Task } from 'power-tasks';
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';
10
+ import fs from 'fs/promises';
11
11
  export class VersionCommand extends RunCommand {
12
12
  constructor(repository, bump, options) {
13
13
  super(repository, 'version', options);
14
14
  this.repository = repository;
15
15
  this.bump = bump;
16
16
  }
17
- async _prepareTasks() {
17
+ async _prepareTasks(packages) {
18
18
  const { repository } = this;
19
19
  const git = new GitHelper({ cwd: repository.dirname });
20
20
  const dirtyFiles = await git.listDirtyFiles();
21
21
  const committedFiles = await git.listCommittedFiles();
22
- const packages = repository.getPackages({ toposort: true });
23
22
  const newVersions = {};
24
23
  let errorCount = 0;
25
24
  const selectedPackages = [];
@@ -29,7 +28,7 @@ export class VersionCommand extends RunCommand {
29
28
  let message = '';
30
29
  let newVer = '';
31
30
  const logPkgName = chalk.yellow(p.name);
32
- if (!this.options.forceDirty) {
31
+ if (!this.options.noTag) {
33
32
  const isDirty = dirtyFiles.find(f => !path.relative(relDir, f).startsWith('..'));
34
33
  if (isDirty) {
35
34
  if (!this.options.ignoreDirty)
@@ -60,47 +59,63 @@ export class VersionCommand extends RunCommand {
60
59
  message: stripColor(message),
61
60
  });
62
61
  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);
62
+ logger.log(this.options.ignoreDirty ? 'info' : 'error', this.commandName, logPkgName, chalk.whiteBright(p.version), status, logger.separator, message);
64
63
  continue;
65
64
  }
66
65
  selectedPackages.push(p);
67
66
  }
68
67
  if (errorCount)
69
68
  throw new Error('Unable to bump version due to error(s)');
69
+ const maxVer = Object.values(newVersions).reduce((m, v) => {
70
+ return semver.gt(m, v) ? m : v;
71
+ }, '0.0.0');
70
72
  if (this.options.unified) {
71
- const maxVer = Object.values(newVersions).reduce((m, v) => {
72
- return semver.gt(m, v) ? m : v;
73
- }, '0.0.0');
74
73
  Object.keys(newVersions).forEach(k => newVersions[k] = maxVer);
75
74
  }
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
- }
75
+ const tasks = await super._prepareTasks(selectedPackages, { newVersions });
76
+ tasks.forEach(t => t.options.exclusive = true);
77
+ if (this.options.unified)
78
+ tasks.push(new Task(async () => {
79
+ try {
80
+ await super._exec({
81
+ name: 'rman',
82
+ command: 'git tag -a "v' + maxVer + '" -m "version ' + maxVer + '"',
83
+ cwd: this.repository.dirname,
84
+ stdio: logger.levelIndex <= 1000 ? 'inherit' : 'pipe',
85
+ logLevel: 'silly'
86
+ });
87
+ }
88
+ catch {
89
+ //
90
+ }
91
+ }, { exclusive: true }));
88
92
  return tasks;
89
93
  }
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
- delete pkg.json.scripts.version;
97
- const f = path.join(pkg.dirname, 'package.json');
98
- const data = JSON.stringify(pkg.json, undefined, 2);
99
- fs.writeFileSync(f, data, 'utf-8');
100
- logger.info(this.commandName, chalk.gray(figures.lineVerticalDashed0), pkg.name, chalk.gray(figures.lineVerticalDashed0), 'Version changed from ' + chalk.cyan(oldVer) + ' to ' + chalk.cyan(newVer));
94
+ async _exec(args, options) {
95
+ if (args.name === 'root')
96
+ return { code: 0 };
97
+ if (args.command === '#') {
98
+ const { newVersions } = options;
99
+ const oldVer = args.json.version;
100
+ const newVer = newVersions[args.name];
101
+ args.json.version = newVer;
102
+ delete args.json.scripts.version;
103
+ const f = path.join(args.cwd, 'package.json');
104
+ const data = JSON.stringify(args.json, undefined, 2);
105
+ await fs.writeFile(f, data, 'utf-8');
106
+ if (!this.options.noTag) {
107
+ await super._exec({
108
+ name: args.name,
109
+ command: 'git commit -m "' + newVer + '" package.json',
110
+ cwd: args.cwd,
111
+ stdio: logger.levelIndex <= 1000 ? 'inherit' : 'pipe',
112
+ logLevel: 'silly'
113
+ });
114
+ }
115
+ logger.info(this.commandName, args.name, logger.separator, 'Version changed from ' + chalk.cyan(oldVer) + ' to ' + chalk.cyan(newVer));
101
116
  return { code: 0 };
102
117
  }
103
- return super._exec(pkg, command, options);
118
+ return super._exec(args, options);
104
119
  }
105
120
  }
106
121
  VersionCommand.commandName = 'version';
@@ -118,12 +133,12 @@ VersionCommand.commandName = 'version';
118
133
  },
119
134
  'ignore-dirty': {
120
135
  alias: 'i',
121
- describe: '# Ignore dirty packages',
136
+ describe: '# Do not bump version for dirty packages',
122
137
  type: 'boolean'
123
138
  },
124
- 'force-dirty': {
125
- alias: 'f',
126
- describe: '# Force bump version for dirty packages',
139
+ 'no-tag': {
140
+ alias: 'n',
141
+ describe: '# Do not crate git version tag. (Ignores dirty check)',
127
142
  type: 'boolean'
128
143
  }
129
144
  };
@@ -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;