json-sort-cli 4.2.1 → 4.2.3
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/CHANGELOG.md +7 -0
- package/cli.js +376 -309
- package/json-formatter.js +421 -0
- package/package.json +1 -3
- package/process-files.js +169 -86
- package/json-file.js +0 -42
package/cli.js
CHANGED
|
@@ -1,121 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// VARS
|
|
4
|
-
// -----------------------------------------------------------------------------
|
|
5
|
-
|
|
6
3
|
import { createRequire } from "node:module";
|
|
7
4
|
import path from "node:path";
|
|
8
5
|
import { glob } from "codsen-glob";
|
|
9
|
-
import { codsenCLI } from "codsen-utils";
|
|
10
6
|
import updateNotifier from "update-notifier";
|
|
11
7
|
import { ProcessingError, processFiles } from "./process-files.js";
|
|
12
8
|
|
|
13
9
|
const require1 = createRequire(import.meta.url);
|
|
14
10
|
const pkg = require1("./package.json");
|
|
15
|
-
|
|
16
|
-
const colours = {
|
|
17
|
-
green: 32,
|
|
18
|
-
grey: 90,
|
|
19
|
-
red: 31,
|
|
20
|
-
white: 37,
|
|
21
|
-
yellow: 33,
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
function colour(str, colourCode) {
|
|
25
|
-
return `\u001b[${colourCode}m${str}\u001b[39m`;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
11
|
const prefix = "✨ json-sort-cli: ";
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
`
|
|
32
|
-
Usage
|
|
33
|
-
$ jsonsort YOURFILE.json
|
|
34
|
-
$ sortjson YOURFILE.json
|
|
35
|
-
$ sortjson templatesfolder1 templatesfolder2 package.json
|
|
36
|
-
or, just type "jsonsort" and it will let you pick a file.
|
|
37
|
-
|
|
38
|
-
Options
|
|
39
|
-
-n, --nodemodules Don't ignore any node_modules folders
|
|
40
|
-
-t, --tabs Use tabs for JSON file indentation
|
|
41
|
-
-i, --indentationCount How many spaces/tabs to use (default: 2 for spaces or 1 for tabs)
|
|
42
|
-
-s, --silent Does not show the result per-file, only totals in the end
|
|
43
|
-
-h, --help Shows this help
|
|
44
|
-
-v, --version Shows the current version
|
|
45
|
-
-a, --arrays Also sort any arrays if they contain only string elements
|
|
46
|
-
-d, --dry Only list all the files about to be processed
|
|
47
|
-
-p, --pack Exclude all package.json files
|
|
48
|
-
-c, --ci Only exits with non-zero code if files COULD BE sorted
|
|
49
|
-
-l, --lineEnding Set to "cr", "crlf" or "lf" to override the default
|
|
50
|
-
(which is either EOL format used in the file, or Mac LF)
|
|
51
|
-
|
|
52
|
-
Example
|
|
53
|
-
Call anywhere using glob patterns. If you put them as string, this library
|
|
54
|
-
will parse globs. If you put as system globs without quotes, your shell will expand them.
|
|
55
|
-
`,
|
|
56
|
-
{
|
|
57
|
-
pkg,
|
|
58
|
-
flags: {
|
|
59
|
-
nodemodules: {
|
|
60
|
-
type: "boolean",
|
|
61
|
-
shortFlag: "n",
|
|
62
|
-
default: false,
|
|
63
|
-
},
|
|
64
|
-
tabs: {
|
|
65
|
-
type: "boolean",
|
|
66
|
-
shortFlag: "t",
|
|
67
|
-
default: false,
|
|
68
|
-
},
|
|
69
|
-
silent: {
|
|
70
|
-
type: "boolean",
|
|
71
|
-
shortFlag: "s",
|
|
72
|
-
default: false,
|
|
73
|
-
},
|
|
74
|
-
arrays: {
|
|
75
|
-
type: "boolean",
|
|
76
|
-
shortFlag: "a",
|
|
77
|
-
default: false,
|
|
78
|
-
},
|
|
79
|
-
pack: {
|
|
80
|
-
type: "boolean",
|
|
81
|
-
shortFlag: "p",
|
|
82
|
-
default: false,
|
|
83
|
-
},
|
|
84
|
-
dry: {
|
|
85
|
-
type: "boolean",
|
|
86
|
-
shortFlag: "d",
|
|
87
|
-
default: false,
|
|
88
|
-
},
|
|
89
|
-
ci: {
|
|
90
|
-
type: "boolean",
|
|
91
|
-
shortFlag: "c",
|
|
92
|
-
default: false,
|
|
93
|
-
},
|
|
94
|
-
help: {
|
|
95
|
-
type: "boolean",
|
|
96
|
-
shortFlag: "h",
|
|
97
|
-
default: false,
|
|
98
|
-
},
|
|
99
|
-
version: {
|
|
100
|
-
type: "boolean",
|
|
101
|
-
shortFlag: "v",
|
|
102
|
-
default: false,
|
|
103
|
-
},
|
|
104
|
-
indentationCount: {
|
|
105
|
-
type: "number",
|
|
106
|
-
shortFlag: "i",
|
|
107
|
-
},
|
|
108
|
-
lineEnding: {
|
|
109
|
-
type: "string",
|
|
110
|
-
shortFlag: "l",
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
},
|
|
114
|
-
);
|
|
115
|
-
updateNotifier({ pkg }).notify();
|
|
116
|
-
|
|
117
|
-
const nonJsonFormats = ["yml", "toml", "yaml"]; // to save time
|
|
118
|
-
const badFiles = [
|
|
12
|
+
const nonJsonFormats = new Set([".yml", ".toml", ".yaml"]);
|
|
13
|
+
const ignoredBasenames = new Set([
|
|
119
14
|
".DS_Store",
|
|
120
15
|
"npm-debug.log",
|
|
121
16
|
".svn",
|
|
@@ -124,236 +19,408 @@ const badFiles = [
|
|
|
124
19
|
".lock-wscript",
|
|
125
20
|
"package-lock.json",
|
|
126
21
|
"npm-shrinkwrap.json",
|
|
127
|
-
|
|
22
|
+
"yarn.lock",
|
|
23
|
+
]);
|
|
24
|
+
const flagDefinitions = {
|
|
25
|
+
arrays: { short: "a", type: "boolean" },
|
|
26
|
+
ci: { short: "c", type: "boolean" },
|
|
27
|
+
dry: { short: "d", type: "boolean" },
|
|
28
|
+
help: { short: "h", type: "boolean" },
|
|
29
|
+
indentationCount: { short: "i", type: "value" },
|
|
30
|
+
lineEnding: { short: "l", type: "value" },
|
|
31
|
+
nodemodules: { short: "n", type: "boolean" },
|
|
32
|
+
pack: { short: "p", type: "boolean" },
|
|
33
|
+
silent: { short: "s", type: "boolean" },
|
|
34
|
+
tabs: { short: "t", type: "boolean" },
|
|
35
|
+
version: { short: "v", type: "boolean" },
|
|
36
|
+
};
|
|
37
|
+
const shortToLong = new Map(
|
|
38
|
+
Object.entries(flagDefinitions).map(([long, definition]) => [
|
|
39
|
+
definition.short,
|
|
40
|
+
long,
|
|
41
|
+
]),
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const help = `
|
|
45
|
+
Usage
|
|
46
|
+
$ jsonsort YOURFILE.json
|
|
47
|
+
$ sortjson templatesfolder1 templatesfolder2 package.json
|
|
48
|
+
$ jsonsort
|
|
49
|
+
|
|
50
|
+
With no arguments, jsonsort recursively sorts JSON files below the current
|
|
51
|
+
directory. Discovered symbolic links are not followed. An explicitly selected
|
|
52
|
+
symbolic-link directory is resolved as the selected root; symbolic-link files
|
|
53
|
+
are rejected before reading.
|
|
54
|
+
|
|
55
|
+
Options
|
|
56
|
+
-n, --nodemodules Include JSON files inside node_modules; lockfiles remain excluded
|
|
57
|
+
-t, --tabs Use tabs for indentation
|
|
58
|
+
-i, --indentationCount Use 0-10 spaces or tabs (default: 2 spaces or 1 tab)
|
|
59
|
+
-s, --silent Suppress all terminal output; use the exit code for the result
|
|
60
|
+
-h, --help Show this help
|
|
61
|
+
-v, --version Show the current version
|
|
62
|
+
-a, --arrays Sort arrays that contain only strings
|
|
63
|
+
-d, --dry List candidate files without reading or writing them
|
|
64
|
+
-p, --pack Exclude package.json files
|
|
65
|
+
-c, --ci Check without writing; exit 9 when canonical output differs
|
|
66
|
+
-l, --lineEnding Use "cr", "crlf", or "lf" instead of the detected line ending
|
|
67
|
+
|
|
68
|
+
Use -- before a path that begins with a dash. Invalid options exit 1 before
|
|
69
|
+
file discovery. Processing failures exit 1 and don't stop independent files.
|
|
70
|
+
|
|
71
|
+
Example
|
|
72
|
+
$ jsonsort "templates/**/*.json" --arrays --lineEnding lf
|
|
73
|
+
`;
|
|
128
74
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
75
|
+
function argumentError(message) {
|
|
76
|
+
throw new TypeError(
|
|
77
|
+
`json-sort-cli/parseArguments(): [THROW_ID_01] ${message}`,
|
|
78
|
+
);
|
|
133
79
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
80
|
+
|
|
81
|
+
function requestsSilent(rawArguments) {
|
|
82
|
+
let optionsEnded = false;
|
|
83
|
+
for (const argument of rawArguments) {
|
|
84
|
+
if (optionsEnded) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (argument === "--") {
|
|
88
|
+
optionsEnded = true;
|
|
89
|
+
} else if (argument === "--silent") {
|
|
90
|
+
return true;
|
|
91
|
+
} else if (argument.startsWith("-") && !argument.startsWith("--")) {
|
|
92
|
+
for (const short of argument.slice(1)) {
|
|
93
|
+
const name = shortToLong.get(short);
|
|
94
|
+
if (!name) {
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
if (name === "silent") {
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
if (flagDefinitions[name].type === "value") {
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return false;
|
|
137
107
|
}
|
|
138
108
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
109
|
+
function parseArguments(rawArguments) {
|
|
110
|
+
const expanded = rawArguments.flatMap((argument) => {
|
|
111
|
+
const match = argument.match(/^-(i|l)\s+(.+)$/u);
|
|
112
|
+
return match ? [`-${match[1]}`, match[2]] : [argument];
|
|
113
|
+
});
|
|
114
|
+
const flags = Object.fromEntries(
|
|
115
|
+
Object.keys(flagDefinitions).map((name) => [name, false]),
|
|
116
|
+
);
|
|
117
|
+
flags.indentationCount = undefined;
|
|
118
|
+
flags.lineEnding = undefined;
|
|
119
|
+
const input = [];
|
|
120
|
+
const seen = new Set();
|
|
121
|
+
let optionsEnded = false;
|
|
122
|
+
|
|
123
|
+
function setFlag(name, value = true) {
|
|
124
|
+
if (seen.has(name)) {
|
|
125
|
+
argumentError(`Option --${name} was provided more than once`);
|
|
126
|
+
}
|
|
127
|
+
seen.add(name);
|
|
128
|
+
flags[name] = value;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
for (let index = 0; index < expanded.length; index += 1) {
|
|
132
|
+
const argument = expanded[index];
|
|
133
|
+
if (optionsEnded) {
|
|
134
|
+
input.push(argument);
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
if (argument === "--") {
|
|
138
|
+
optionsEnded = true;
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (!argument.startsWith("-") || argument === "-") {
|
|
142
|
+
input.push(argument);
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
142
145
|
|
|
143
|
-
if (
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
146
|
+
if (argument.startsWith("--")) {
|
|
147
|
+
const equalsIndex = argument.indexOf("=");
|
|
148
|
+
const name = argument.slice(
|
|
149
|
+
2,
|
|
150
|
+
equalsIndex === -1 ? undefined : equalsIndex,
|
|
151
|
+
);
|
|
152
|
+
const definition = flagDefinitions[name];
|
|
153
|
+
if (!definition) {
|
|
154
|
+
argumentError(`Unknown option --${name}`);
|
|
155
|
+
}
|
|
156
|
+
if (definition.type === "boolean") {
|
|
157
|
+
if (equalsIndex !== -1) {
|
|
158
|
+
argumentError(`Option --${name} doesn't accept a value`);
|
|
159
|
+
}
|
|
160
|
+
setFlag(name);
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
let value =
|
|
165
|
+
equalsIndex === -1 ? undefined : argument.slice(equalsIndex + 1);
|
|
166
|
+
if (value === undefined) {
|
|
167
|
+
value = expanded[index + 1];
|
|
168
|
+
const flagShapedValue =
|
|
169
|
+
value?.startsWith("-") &&
|
|
170
|
+
!(name === "indentationCount" && /^-\d/u.test(value));
|
|
171
|
+
if (value === undefined || flagShapedValue) {
|
|
172
|
+
argumentError(`Option --${name} requires a value`);
|
|
173
|
+
}
|
|
174
|
+
index += 1;
|
|
175
|
+
}
|
|
176
|
+
if (value === "") {
|
|
177
|
+
argumentError(`Option --${name} requires a value`);
|
|
178
|
+
}
|
|
179
|
+
setFlag(name, value);
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
let shortFlags = argument.slice(1);
|
|
184
|
+
while (shortFlags.length) {
|
|
185
|
+
const short = shortFlags[0];
|
|
186
|
+
const name = shortToLong.get(short);
|
|
187
|
+
if (!name) {
|
|
188
|
+
argumentError(`Unknown option -${short}`);
|
|
189
|
+
}
|
|
190
|
+
const definition = flagDefinitions[name];
|
|
191
|
+
shortFlags = shortFlags.slice(1);
|
|
192
|
+
if (definition.type === "boolean") {
|
|
193
|
+
setFlag(name);
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
let value = shortFlags.replace(/^=/u, "");
|
|
198
|
+
shortFlags = "";
|
|
199
|
+
if (!value) {
|
|
200
|
+
value = expanded[index + 1];
|
|
201
|
+
const flagShapedValue =
|
|
202
|
+
value?.startsWith("-") &&
|
|
203
|
+
!(name === "indentationCount" && /^-\d/u.test(value));
|
|
204
|
+
if (value === undefined || flagShapedValue) {
|
|
205
|
+
argumentError(`Option -${short} requires a value`);
|
|
206
|
+
}
|
|
207
|
+
index += 1;
|
|
208
|
+
}
|
|
209
|
+
setFlag(name, value);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const defaultIndentation = flags.tabs ? 1 : 2;
|
|
214
|
+
const indentationCount =
|
|
215
|
+
flags.indentationCount === undefined
|
|
216
|
+
? defaultIndentation
|
|
217
|
+
: Number(flags.indentationCount);
|
|
218
|
+
if (
|
|
219
|
+
!Number.isInteger(indentationCount) ||
|
|
220
|
+
indentationCount < 0 ||
|
|
221
|
+
indentationCount > 10
|
|
222
|
+
) {
|
|
223
|
+
argumentError("indentationCount must be an integer from 0 to 10");
|
|
224
|
+
}
|
|
225
|
+
if (
|
|
226
|
+
flags.lineEnding !== undefined &&
|
|
227
|
+
!["cr", "crlf", "lf"].includes(flags.lineEnding)
|
|
228
|
+
) {
|
|
229
|
+
argumentError('lineEnding must be "cr", "crlf", or "lf"');
|
|
230
|
+
}
|
|
231
|
+
if (
|
|
232
|
+
input.length === 0 &&
|
|
233
|
+
expanded.length > 0 &&
|
|
234
|
+
!flags.help &&
|
|
235
|
+
!flags.version
|
|
236
|
+
) {
|
|
237
|
+
argumentError(
|
|
238
|
+
"Provide at least one path, or run jsonsort with no arguments",
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return {
|
|
243
|
+
flags,
|
|
244
|
+
indentationCount,
|
|
245
|
+
input: input.length ? input : ["**/*.json"],
|
|
246
|
+
};
|
|
149
247
|
}
|
|
150
248
|
|
|
151
|
-
|
|
152
|
-
|
|
249
|
+
function isCandidate(filePath) {
|
|
250
|
+
const basename = path.basename(filePath);
|
|
251
|
+
if (ignoredBasenames.has(basename)) {
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
153
254
|
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
255
|
+
const extension = path.extname(filePath).toLowerCase();
|
|
256
|
+
return (
|
|
257
|
+
extension === ".json" ||
|
|
258
|
+
(basename.startsWith(".") && !nonJsonFormats.has(extension))
|
|
259
|
+
);
|
|
157
260
|
}
|
|
158
261
|
|
|
159
|
-
|
|
160
|
-
|
|
262
|
+
function createPrinter() {
|
|
263
|
+
const useColour = Boolean(process.stdout.isTTY && !process.env.NO_COLOR);
|
|
264
|
+
const colours = { green: 32, grey: 90, red: 31, white: 37, yellow: 33 };
|
|
265
|
+
const colour = (value, name) =>
|
|
266
|
+
useColour ? `\u001b[${colours[name]}m${value}\u001b[39m` : value;
|
|
267
|
+
return { colour };
|
|
268
|
+
}
|
|
161
269
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
dot: true,
|
|
172
|
-
expandDirectories: { files: [".*", "*.json"] },
|
|
173
|
-
},
|
|
174
|
-
)
|
|
175
|
-
.then((paths) => {
|
|
176
|
-
// flip out of the pipeline if there are no paths resolved
|
|
177
|
-
if (paths.length === 0 && !cli.flags.silent) {
|
|
178
|
-
log(
|
|
179
|
-
`${colour(prefix, colours.grey)}${colour(
|
|
180
|
-
"The inputs don't lead to any json files! Exiting.",
|
|
181
|
-
colours.red,
|
|
182
|
-
)}`,
|
|
183
|
-
);
|
|
184
|
-
process.exit(0);
|
|
270
|
+
async function main() {
|
|
271
|
+
const rawArguments = process.argv.slice(2);
|
|
272
|
+
const silentRequested = requestsSilent(rawArguments);
|
|
273
|
+
let parsed;
|
|
274
|
+
try {
|
|
275
|
+
parsed = parseArguments(rawArguments);
|
|
276
|
+
} catch (error) {
|
|
277
|
+
if (!silentRequested) {
|
|
278
|
+
console.error(error.message);
|
|
185
279
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
.
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
.
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
280
|
+
process.exitCode = 1;
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const { flags, indentationCount, input } = parsed;
|
|
285
|
+
if (flags.version) {
|
|
286
|
+
console.log(pkg.version);
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
if (flags.help) {
|
|
290
|
+
console.log(help);
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (!flags.silent && !flags.ci && process.stdout.isTTY) {
|
|
295
|
+
try {
|
|
296
|
+
updateNotifier({ pkg }).notify();
|
|
297
|
+
} catch {}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const { colour } = createPrinter();
|
|
301
|
+
let paths;
|
|
302
|
+
try {
|
|
303
|
+
paths = await glob(
|
|
304
|
+
[
|
|
305
|
+
...input,
|
|
306
|
+
"!**/package-lock.json",
|
|
307
|
+
"!**/npm-shrinkwrap.json",
|
|
308
|
+
"!**/yarn.lock",
|
|
309
|
+
...(flags.nodemodules ? [] : ["!**/node_modules/**"]),
|
|
310
|
+
...(flags.pack ? ["!**/package.json"] : []),
|
|
311
|
+
],
|
|
312
|
+
{
|
|
313
|
+
dot: true,
|
|
314
|
+
expandDirectories: { files: [".*", "*.json", "*.JSON"] },
|
|
315
|
+
followSymbolicLinks: false,
|
|
316
|
+
},
|
|
317
|
+
);
|
|
318
|
+
paths = paths.filter(isCandidate);
|
|
319
|
+
} catch (error) {
|
|
320
|
+
if (!flags.silent) {
|
|
321
|
+
console.error(`${prefix}${error}`);
|
|
322
|
+
}
|
|
323
|
+
process.exitCode = 1;
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (!paths.length) {
|
|
328
|
+
if (!flags.silent) {
|
|
329
|
+
console.log(`${prefix}The inputs don't lead to any JSON files. Exiting.`);
|
|
330
|
+
}
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
220
333
|
|
|
221
|
-
.
|
|
222
|
-
if (
|
|
223
|
-
log(
|
|
224
|
-
`${
|
|
225
|
-
"We'd try to sort the following files:",
|
|
226
|
-
colours.yellow,
|
|
227
|
-
)}\n${paths.join("\n")}`,
|
|
334
|
+
if (flags.dry) {
|
|
335
|
+
if (!flags.silent) {
|
|
336
|
+
console.log(
|
|
337
|
+
`${prefix}We'd try to sort the following files:\n${paths.join("\n")}`,
|
|
228
338
|
);
|
|
229
|
-
return;
|
|
230
339
|
}
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
231
342
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
343
|
+
try {
|
|
344
|
+
const { successful, unsorted } = await processFiles(paths, {
|
|
345
|
+
arrays: flags.arrays,
|
|
346
|
+
ci: flags.ci,
|
|
235
347
|
indentationCount,
|
|
236
|
-
lineEnding:
|
|
237
|
-
pack:
|
|
238
|
-
tabs:
|
|
348
|
+
lineEnding: flags.lineEnding || undefined,
|
|
349
|
+
pack: flags.pack,
|
|
350
|
+
tabs: flags.tabs,
|
|
239
351
|
onOutcome(outcome) {
|
|
240
|
-
if (
|
|
352
|
+
if (flags.silent) {
|
|
241
353
|
return;
|
|
242
354
|
}
|
|
243
355
|
if (outcome.status === "failure") {
|
|
244
|
-
|
|
245
|
-
`${
|
|
246
|
-
"BAD",
|
|
247
|
-
colours.red,
|
|
248
|
-
)} (${outcome.stage}) - ${outcome.error}`,
|
|
249
|
-
);
|
|
250
|
-
} else if (!cli.flags.ci) {
|
|
251
|
-
log(
|
|
252
|
-
`${colour(prefix, colours.grey)}${outcome.path} - ${colour(
|
|
253
|
-
"OK",
|
|
254
|
-
colours.green,
|
|
255
|
-
)}`,
|
|
356
|
+
console.error(
|
|
357
|
+
`${prefix}${outcome.path} - BAD (${outcome.stage}) - ${outcome.error}`,
|
|
256
358
|
);
|
|
359
|
+
} else if (!flags.ci) {
|
|
360
|
+
console.log(`${prefix}${outcome.path} - OK`);
|
|
257
361
|
}
|
|
258
362
|
},
|
|
259
|
-
};
|
|
363
|
+
});
|
|
260
364
|
|
|
261
|
-
|
|
262
|
-
.
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
log(
|
|
272
|
-
`${colour(prefix, colours.grey)}${colour(
|
|
273
|
-
"Unsorted files:",
|
|
274
|
-
colours.red,
|
|
275
|
-
)}\n${unsorted.join("\n")}`,
|
|
276
|
-
);
|
|
277
|
-
process.exitCode = 9;
|
|
278
|
-
} else {
|
|
279
|
-
log(
|
|
280
|
-
`${colour(prefix, colours.grey)}${colour(
|
|
281
|
-
"All files were already sorted:",
|
|
282
|
-
colours.white,
|
|
283
|
-
)}\n${successful.join("\n")}`,
|
|
284
|
-
);
|
|
285
|
-
}
|
|
286
|
-
return;
|
|
287
|
-
}
|
|
288
|
-
log(
|
|
289
|
-
`\n${colour(prefix, colours.grey)}${colour(
|
|
290
|
-
`All ${successful.length} file${
|
|
291
|
-
successful.length === 1 ? "" : "s"
|
|
292
|
-
} sorted`,
|
|
293
|
-
colours.green,
|
|
294
|
-
)}`,
|
|
365
|
+
if (flags.silent) {
|
|
366
|
+
if (flags.ci && unsorted.length) {
|
|
367
|
+
process.exitCode = 9;
|
|
368
|
+
}
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
if (flags.ci) {
|
|
372
|
+
if (unsorted.length) {
|
|
373
|
+
console.log(
|
|
374
|
+
`${prefix}${colour("Unsorted files:", "red")}\n${unsorted.join("\n")}`,
|
|
295
375
|
);
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
`${error.successful.length} file${
|
|
329
|
-
error.successful.length === 1 ? "" : "s"
|
|
330
|
-
} sorted`,
|
|
331
|
-
colours.green,
|
|
332
|
-
)}`,
|
|
333
|
-
);
|
|
334
|
-
}
|
|
335
|
-
log(
|
|
336
|
-
`${colour(prefix, colours.grey)}${colour(
|
|
337
|
-
`${error.failures.length} file${
|
|
338
|
-
error.failures.length === 1 ? "" : "s"
|
|
339
|
-
} could not be ${cli.flags.ci ? "checked" : "sorted"}`,
|
|
340
|
-
colours.red,
|
|
341
|
-
)} ${colour(
|
|
342
|
-
` - ${error.failures
|
|
343
|
-
.map(({ path: failedPath }) => failedPath)
|
|
344
|
-
.join(" - ")}`,
|
|
345
|
-
colours.grey,
|
|
346
|
-
)}`,
|
|
376
|
+
process.exitCode = 9;
|
|
377
|
+
} else {
|
|
378
|
+
console.log(
|
|
379
|
+
`${prefix}${colour("All files were already sorted:", "white")}\n${successful.join("\n")}`,
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
console.log(
|
|
385
|
+
`\n${prefix}${colour(
|
|
386
|
+
`All ${successful.length} file${successful.length === 1 ? "" : "s"} sorted`,
|
|
387
|
+
"green",
|
|
388
|
+
)}`,
|
|
389
|
+
);
|
|
390
|
+
} catch (error) {
|
|
391
|
+
if (!(error instanceof ProcessingError)) {
|
|
392
|
+
if (!flags.silent) {
|
|
393
|
+
console.error(`${prefix}${error}`);
|
|
394
|
+
}
|
|
395
|
+
process.exitCode = 1;
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
if (!flags.silent) {
|
|
400
|
+
if (flags.ci) {
|
|
401
|
+
const unsorted = new Set(error.unsorted);
|
|
402
|
+
const alreadySorted = error.successful.filter(
|
|
403
|
+
(filePath) => !unsorted.has(filePath),
|
|
404
|
+
);
|
|
405
|
+
if (alreadySorted.length) {
|
|
406
|
+
console.log(
|
|
407
|
+
`${prefix}${alreadySorted.length} file${alreadySorted.length === 1 ? "" : "s"} already sorted:\n${alreadySorted.join("\n")}`,
|
|
347
408
|
);
|
|
348
409
|
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
410
|
+
if (error.unsorted.length) {
|
|
411
|
+
console.log(`${prefix}Unsorted files:\n${error.unsorted.join("\n")}`);
|
|
412
|
+
}
|
|
413
|
+
} else if (error.successful.length) {
|
|
414
|
+
console.log(
|
|
415
|
+
`\n${prefix}${error.successful.length} file${error.successful.length === 1 ? "" : "s"} sorted`,
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
console.error(
|
|
419
|
+
`${prefix}${error.failures.length} file${error.failures.length === 1 ? "" : "s"} could not be ${flags.ci ? "checked" : "sorted"} - ${error.failures.map(({ path: failedPath }) => failedPath).join(" - ")}`,
|
|
356
420
|
);
|
|
357
421
|
}
|
|
358
422
|
process.exitCode = 1;
|
|
359
|
-
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
await main();
|