@oclif/plugin-command-snapshot 4.0.15 → 4.0.16
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/README.md +5 -4
- package/lib/commands/schema/compare.d.ts +5 -5
- package/lib/commands/schema/compare.js +49 -46
- package/lib/commands/schema/generate.d.ts +6 -6
- package/lib/commands/schema/generate.js +79 -79
- package/lib/commands/snapshot/compare.d.ts +13 -13
- package/lib/commands/snapshot/compare.js +45 -47
- package/lib/commands/snapshot/generate.d.ts +2 -2
- package/lib/commands/snapshot/generate.js +19 -17
- package/lib/index.js +1 -3
- package/lib/snapshot-command.d.ts +6 -5
- package/lib/snapshot-command.js +24 -20
- package/lib/util.js +3 -12
- package/oclif.lock +7020 -0
- package/oclif.manifest.json +107 -47
- package/package.json +45 -30
- package/schemas/schema-compare.json +4 -15
- package/schemas/snapshot-compare.json +35 -47
- package/schemas/snapshot-generate.json +11 -18
|
@@ -1,12 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import difference from 'lodash.difference';
|
|
4
|
+
import * as fs from 'node:fs';
|
|
5
|
+
import { EOL } from 'node:os';
|
|
6
|
+
import SnapshotCommand from '../../snapshot-command.js';
|
|
7
|
+
export default class Compare extends SnapshotCommand {
|
|
8
|
+
static flags = {
|
|
9
|
+
filepath: Flags.string({
|
|
10
|
+
default: './command-snapshot.json',
|
|
11
|
+
description: 'path of the generated snapshot file',
|
|
12
|
+
}),
|
|
13
|
+
};
|
|
14
|
+
get changed() {
|
|
15
|
+
return this.commands.map((command) => ({
|
|
16
|
+
alias: command.aliases.map((alias) => ({ name: alias })),
|
|
17
|
+
// we can assert as string because of the filter
|
|
18
|
+
chars: Object.values(command.flags)
|
|
19
|
+
.map((flag) => flag.char)
|
|
20
|
+
.filter((char) => typeof char === 'string')
|
|
21
|
+
.map((char) => ({ name: char })),
|
|
22
|
+
flags: Object.entries(command.flags).map((flagName) => ({ name: flagName[0] })),
|
|
23
|
+
name: command.id,
|
|
24
|
+
plugin: command.pluginName || '',
|
|
25
|
+
}));
|
|
26
|
+
}
|
|
10
27
|
/**
|
|
11
28
|
* Compare a snapshot with the current commands
|
|
12
29
|
* @param {CommandChange[]} initialCommands Command list from the snapshot
|
|
@@ -17,7 +34,7 @@ class Compare extends snapshot_command_1.SnapshotCommand {
|
|
|
17
34
|
const removedCommands = [];
|
|
18
35
|
const diffCommands = [];
|
|
19
36
|
for (const initialCommand of initialCommands) {
|
|
20
|
-
const updatedCommand = updatedCommands.find(updatedCommand => {
|
|
37
|
+
const updatedCommand = updatedCommands.find((updatedCommand) => {
|
|
21
38
|
// Protect against old snapshot files that don't have the plugin entry filled out.
|
|
22
39
|
const samePlugin = initialCommand.plugin ? initialCommand.plugin === updatedCommand.plugin : true;
|
|
23
40
|
return initialCommand.command === updatedCommand.name && samePlugin;
|
|
@@ -46,16 +63,16 @@ class Compare extends snapshot_command_1.SnapshotCommand {
|
|
|
46
63
|
removedCommands.push(initialCommand.command);
|
|
47
64
|
}
|
|
48
65
|
}
|
|
49
|
-
const initialCommandNames = initialCommands.map(initialCommand => initialCommand.command);
|
|
50
|
-
const updatedCommandNames = updatedCommands.map(updatedCommand => updatedCommand.name);
|
|
51
|
-
const addedCommands =
|
|
66
|
+
const initialCommandNames = initialCommands.map((initialCommand) => initialCommand.command);
|
|
67
|
+
const updatedCommandNames = updatedCommands.map((updatedCommand) => updatedCommand.name);
|
|
68
|
+
const addedCommands = difference(updatedCommandNames, initialCommandNames);
|
|
52
69
|
if (removedCommands.length === 0 && addedCommands.length === 0 && diffCommands.length === 0) {
|
|
53
70
|
this.log('No changes have been detected.');
|
|
54
71
|
return {};
|
|
55
72
|
}
|
|
56
73
|
// Fail the process since there are changes to the snapshot file
|
|
57
74
|
process.exitCode = 1;
|
|
58
|
-
this.log(`The following commands and flags have modified: (${chalk.green('+')} added, ${chalk.red('-')} removed)${
|
|
75
|
+
this.log(`The following commands and flags have modified: (${chalk.green('+')} added, ${chalk.red('-')} removed)${EOL}`);
|
|
59
76
|
for (const command of removedCommands) {
|
|
60
77
|
this.log(chalk.red(`\t-${command}`));
|
|
61
78
|
}
|
|
@@ -64,7 +81,7 @@ class Compare extends snapshot_command_1.SnapshotCommand {
|
|
|
64
81
|
}
|
|
65
82
|
const removedProperties = [];
|
|
66
83
|
const printCommandDiff = (properties, propertyName) => {
|
|
67
|
-
if (properties.some(prop => prop.added || prop.removed))
|
|
84
|
+
if (properties.some((prop) => prop.added || prop.removed))
|
|
68
85
|
this.log(`\t ${propertyName}:`);
|
|
69
86
|
for (const prop of properties) {
|
|
70
87
|
if (prop.added || prop.removed) {
|
|
@@ -81,23 +98,23 @@ class Compare extends snapshot_command_1.SnapshotCommand {
|
|
|
81
98
|
printCommandDiff(command.chars, 'Short Flags');
|
|
82
99
|
printCommandDiff(command.alias, 'Aliases');
|
|
83
100
|
}
|
|
84
|
-
this.log(`${
|
|
101
|
+
this.log(`${EOL}Command, flag, flag characters, or alias differences detected. If intended, please update the snapshot file and run again.`);
|
|
85
102
|
// Check if existent commands, or properties (flags, aliases) have been deleted
|
|
86
103
|
if (removedCommands.length > 0 || removedProperties.length > 0) {
|
|
87
|
-
this.log(chalk.red(`${
|
|
104
|
+
this.log(chalk.red(`${EOL}Since there are deletions, a major version bump is required.`));
|
|
88
105
|
}
|
|
89
|
-
return { addedCommands, removedCommands, removedFlags: removedCommands
|
|
106
|
+
return { addedCommands, diffCommands, removedCommands, removedFlags: removedCommands };
|
|
90
107
|
}
|
|
91
108
|
/**
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
109
|
+
* compares two command's properties to each other
|
|
110
|
+
* @return a list of added, removed, updated, and changed properties
|
|
111
|
+
* @param initial initial command property to compare against
|
|
112
|
+
* @param updated generated command property to compare with
|
|
113
|
+
*/
|
|
97
114
|
diffCommandProperty(initial, updated) {
|
|
98
|
-
const updatedPropertyNames = updated.map(update => update.name);
|
|
99
|
-
const addedProperty =
|
|
100
|
-
const removedProperty =
|
|
115
|
+
const updatedPropertyNames = updated.map((update) => update.name);
|
|
116
|
+
const addedProperty = difference(updatedPropertyNames, initial);
|
|
117
|
+
const removedProperty = difference(initial, updatedPropertyNames);
|
|
101
118
|
const changedProperty = [];
|
|
102
119
|
for (const update of updated) {
|
|
103
120
|
if (addedProperty.includes(update.name)) {
|
|
@@ -111,31 +128,12 @@ class Compare extends snapshot_command_1.SnapshotCommand {
|
|
|
111
128
|
// so it shows removed.
|
|
112
129
|
updated.push({ name: remove, removed: true });
|
|
113
130
|
}
|
|
114
|
-
return { addedProperty, removedProperty, updated
|
|
115
|
-
}
|
|
116
|
-
get changed() {
|
|
117
|
-
return this.commands.map(command => {
|
|
118
|
-
return {
|
|
119
|
-
name: command.id,
|
|
120
|
-
plugin: command.pluginName || '',
|
|
121
|
-
flags: Object.entries(command.flags).map(flagName => ({ name: flagName[0] })),
|
|
122
|
-
alias: command.aliases.map(alias => ({ name: alias })),
|
|
123
|
-
// we can assert as string because of the filter
|
|
124
|
-
chars: Object.values(command.flags).map(flag => flag.char).filter(char => typeof char === 'string').map(char => ({ name: char })),
|
|
125
|
-
};
|
|
126
|
-
});
|
|
131
|
+
return { addedProperty, changedProperty, removedProperty, updated };
|
|
127
132
|
}
|
|
128
133
|
async run() {
|
|
129
134
|
const { flags } = await this.parse(Compare);
|
|
130
|
-
const oldCommands = JSON.parse(fs.readFileSync(flags.filepath
|
|
135
|
+
const oldCommands = JSON.parse(fs.readFileSync(flags.filepath, 'utf8'));
|
|
131
136
|
const newCommands = this.changed;
|
|
132
137
|
return this.compareSnapshot(oldCommands, newCommands);
|
|
133
138
|
}
|
|
134
139
|
}
|
|
135
|
-
exports.default = Compare;
|
|
136
|
-
Compare.flags = {
|
|
137
|
-
filepath: core_1.Flags.string({
|
|
138
|
-
description: 'path of the generated snapshot file',
|
|
139
|
-
default: './command-snapshot.json',
|
|
140
|
-
}),
|
|
141
|
-
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import SnapshotCommand, { SnapshotEntry } from '../../snapshot-command.js';
|
|
2
2
|
export type Snapshots = SnapshotEntry[];
|
|
3
3
|
export default class Generate extends SnapshotCommand {
|
|
4
4
|
static flags: {
|
|
5
|
-
filepath: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
5
|
+
filepath: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
6
6
|
};
|
|
7
7
|
run(): Promise<Snapshots>;
|
|
8
8
|
}
|
|
@@ -1,32 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
|
+
import SnapshotCommand from '../../snapshot-command.js';
|
|
3
|
+
export default class Generate extends SnapshotCommand {
|
|
4
|
+
static flags = {
|
|
5
|
+
filepath: Flags.string({
|
|
6
|
+
default: './command-snapshot.json',
|
|
7
|
+
description: 'path to save the generated snapshot file; can use "{version}" to replace the current CLI/plugin version',
|
|
8
|
+
}),
|
|
9
|
+
};
|
|
7
10
|
async run() {
|
|
8
11
|
const numberOfSpaceChar = 4;
|
|
9
12
|
const { flags } = await this.parse(Generate);
|
|
10
13
|
const resultCommands = this.entries;
|
|
11
|
-
const duplicatedChar = resultCommands.find(command => command.flags.length > 1 && new Set(command.flagChars).size !== command.flagChars.length);
|
|
14
|
+
const duplicatedChar = resultCommands.find((command) => command.flags.length > 1 && new Set(command.flagChars).size !== command.flagChars.length);
|
|
12
15
|
if (duplicatedChar) {
|
|
13
16
|
throw new Error(`Command "${duplicatedChar.command}" has duplicate short-flag characters "${duplicatedChar.flagChars.filter((item, index) => duplicatedChar.flagChars.indexOf(item) !== index)}"`);
|
|
14
17
|
}
|
|
15
|
-
const charConflictCommand = resultCommands.find(command => command.flags.length > 1 &&
|
|
18
|
+
const charConflictCommand = resultCommands.find((command) => command.flags.length > 1 &&
|
|
19
|
+
new Set([...command.flags, ...command.flagChars, ...command.flagAliases]).size !==
|
|
20
|
+
[...command.flags, ...command.flagChars, ...command.flagAliases].length);
|
|
16
21
|
if (charConflictCommand) {
|
|
17
|
-
const conflictFlags = [
|
|
22
|
+
const conflictFlags = [
|
|
23
|
+
...charConflictCommand.flags,
|
|
24
|
+
...charConflictCommand.flagChars,
|
|
25
|
+
...charConflictCommand.flagAliases,
|
|
26
|
+
].filter((item, index, array) => array.indexOf(item) !== index);
|
|
18
27
|
throw new Error(`Command "${charConflictCommand.command}" has conflicting flags "${conflictFlags}"`);
|
|
19
28
|
}
|
|
20
29
|
const filePath = flags.filepath.replace('{version}', this.config.version);
|
|
21
|
-
|
|
30
|
+
this.write(filePath, JSON.stringify(resultCommands, null, numberOfSpaceChar));
|
|
22
31
|
this.log(`Generated snapshot file "${filePath}"`);
|
|
23
32
|
return resultCommands;
|
|
24
33
|
}
|
|
25
34
|
}
|
|
26
|
-
exports.default = Generate;
|
|
27
|
-
Generate.flags = {
|
|
28
|
-
filepath: core_1.Flags.string({
|
|
29
|
-
description: 'path to save the generated snapshot file; can use "{version}" to replace the current CLI/plugin version',
|
|
30
|
-
default: './command-snapshot.json',
|
|
31
|
-
}),
|
|
32
|
-
};
|
package/lib/index.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
2
|
export type SnapshotEntry = {
|
|
3
|
-
command: string;
|
|
4
|
-
plugin: string;
|
|
5
|
-
flags: string[];
|
|
6
3
|
alias: string[];
|
|
7
|
-
|
|
4
|
+
command: string;
|
|
8
5
|
flagAliases: string[];
|
|
6
|
+
flagChars: string[];
|
|
7
|
+
flags: string[];
|
|
8
|
+
plugin: string;
|
|
9
9
|
};
|
|
10
|
-
export
|
|
10
|
+
export default abstract class SnapshotCommand extends Command {
|
|
11
11
|
get commands(): Command.Loadable[];
|
|
12
12
|
get entries(): SnapshotEntry[];
|
|
13
|
+
write(path: string, data: string): void;
|
|
13
14
|
}
|
package/lib/snapshot-command.js
CHANGED
|
@@ -1,29 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const _ = require("lodash");
|
|
6
|
-
class SnapshotCommand extends core_1.Command {
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import sortBy from 'lodash.sortby';
|
|
3
|
+
import { writeFileSync } from 'node:fs';
|
|
4
|
+
export default class SnapshotCommand extends Command {
|
|
7
5
|
get commands() {
|
|
8
6
|
const devPlugins = this.config.pjson.oclif.devPlugins ?? [];
|
|
9
7
|
const commands = this.config.commands
|
|
10
8
|
// Ignore dev plugins
|
|
11
|
-
.filter(command => !devPlugins.includes(command.pluginName ?? ''))
|
|
9
|
+
.filter((command) => !devPlugins.includes(command.pluginName ?? ''))
|
|
12
10
|
// remove aliases that reference themselves
|
|
13
|
-
.filter(command => !command.aliases.includes(command.id));
|
|
14
|
-
return
|
|
11
|
+
.filter((command) => !command.aliases.includes(command.id));
|
|
12
|
+
return sortBy(commands, 'id');
|
|
15
13
|
}
|
|
16
14
|
get entries() {
|
|
17
|
-
return this.commands.map(command => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
15
|
+
return this.commands.map((command) => ({
|
|
16
|
+
alias: command.aliases,
|
|
17
|
+
command: command.id,
|
|
18
|
+
flagAliases: Object.values(command.flags)
|
|
19
|
+
.flatMap((flag) => flag.aliases)
|
|
20
|
+
.filter(Boolean)
|
|
21
|
+
.sort(),
|
|
22
|
+
flagChars: Object.values(command.flags)
|
|
23
|
+
.map((flag) => flag.char)
|
|
24
|
+
.filter(Boolean)
|
|
25
|
+
.sort(),
|
|
26
|
+
flags: Object.keys(command.flags).sort(),
|
|
27
|
+
plugin: command.pluginName,
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
write(path, data) {
|
|
31
|
+
writeFileSync(path, data);
|
|
27
32
|
}
|
|
28
33
|
}
|
|
29
|
-
exports.SnapshotCommand = SnapshotCommand;
|
package/lib/util.js
CHANGED
|
@@ -1,24 +1,15 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getKeyNameFromFilename = exports.getSchemaFileName = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* Get the file name for a given command ID replacing "-" with "__" and ":" with "-"
|
|
6
3
|
* @param cmdId - command ID
|
|
7
4
|
* @returns {string} - file name
|
|
8
5
|
*/
|
|
9
|
-
const getSchemaFileName = (cmdId) => {
|
|
10
|
-
const baseName = cmdId.
|
|
6
|
+
export const getSchemaFileName = (cmdId) => {
|
|
7
|
+
const baseName = cmdId.replaceAll('-', '__').replaceAll(':', '-');
|
|
11
8
|
return `${baseName}.json`;
|
|
12
9
|
};
|
|
13
|
-
exports.getSchemaFileName = getSchemaFileName;
|
|
14
10
|
/**
|
|
15
11
|
* Get the command ID from a given file name replacing "-" with ":" and "__" with "-"
|
|
16
12
|
* @param file - file name
|
|
17
13
|
* @returns {string} - command ID
|
|
18
14
|
*/
|
|
19
|
-
const getKeyNameFromFilename = (file) =>
|
|
20
|
-
return file.replace(/-/g, ':')
|
|
21
|
-
.replace(/__/g, '-')
|
|
22
|
-
.replace('.json', '');
|
|
23
|
-
};
|
|
24
|
-
exports.getKeyNameFromFilename = getKeyNameFromFilename;
|
|
15
|
+
export const getKeyNameFromFilename = (file) => file.replaceAll('-', ':').replaceAll('__', '-').replace('.json', '');
|