@naturalcycles/dev-lib 19.29.0 → 19.31.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.
- package/dist/build.util.js +6 -3
- package/dist/lint.util.d.ts +6 -2
- package/dist/lint.util.js +80 -75
- package/package.json +1 -1
package/dist/build.util.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs';
|
|
2
|
-
import {
|
|
2
|
+
import { dimGrey } from '@naturalcycles/nodejs-lib/colors';
|
|
3
3
|
import { exec2 } from '@naturalcycles/nodejs-lib/exec2';
|
|
4
4
|
import { fs2 } from '@naturalcycles/nodejs-lib/fs2';
|
|
5
5
|
import { kpySync } from '@naturalcycles/nodejs-lib/kpy';
|
|
@@ -38,7 +38,7 @@ export async function runTSCInFolder(dir, args = []) {
|
|
|
38
38
|
const tscPath = findPackageBinPath('typescript', 'tsc');
|
|
39
39
|
const cacheLocation = `node_modules/.cache/${dir}.tsbuildinfo`;
|
|
40
40
|
const cacheFound = existsSync(cacheLocation);
|
|
41
|
-
console.log(
|
|
41
|
+
console.log(dimGrey(`${check(cacheFound)} tsc ${dir} cache found: ${cacheFound}`));
|
|
42
42
|
await exec2.spawnAsync(tscPath, {
|
|
43
43
|
args: ['-P', tsconfigPath, ...args],
|
|
44
44
|
shell: false,
|
|
@@ -49,7 +49,7 @@ export async function runTSCProd(args = []) {
|
|
|
49
49
|
const tscPath = findPackageBinPath('typescript', 'tsc');
|
|
50
50
|
const cacheLocation = `node_modules/.cache/src.tsbuildinfo`;
|
|
51
51
|
const cacheFound = existsSync(cacheLocation);
|
|
52
|
-
console.log(
|
|
52
|
+
console.log(dimGrey(` tsc src cache found: ${cacheFound}`));
|
|
53
53
|
await exec2.spawnAsync(tscPath, {
|
|
54
54
|
args: ['-P', tsconfigPath, '--noEmit', 'false', '--noCheck', ...args],
|
|
55
55
|
shell: false,
|
|
@@ -73,3 +73,6 @@ export function buildCopy() {
|
|
|
73
73
|
dotfiles: true,
|
|
74
74
|
});
|
|
75
75
|
}
|
|
76
|
+
function check(predicate) {
|
|
77
|
+
return predicate ? '✔️ ' : ' ';
|
|
78
|
+
}
|
package/dist/lint.util.d.ts
CHANGED
|
@@ -11,8 +11,12 @@ interface EslintAllOptions {
|
|
|
11
11
|
* Runs `eslint` command for all predefined paths (e.g /src, /scripts, etc).
|
|
12
12
|
*/
|
|
13
13
|
export declare function eslintAll(opt?: EslintAllOptions): Promise<void>;
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
interface RunPrettierOptions {
|
|
15
|
+
experimentalCli?: boolean;
|
|
16
|
+
fix?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare function runPrettier(opt?: RunPrettierOptions): void;
|
|
19
|
+
export declare function stylelintAll(fix?: boolean): void;
|
|
16
20
|
export declare function lintStagedCommand(): Promise<void>;
|
|
17
21
|
export declare function runCommitlintCommand(): void;
|
|
18
22
|
export declare function requireActionlintVersion(): void;
|
package/dist/lint.util.js
CHANGED
|
@@ -7,9 +7,8 @@ import { _since } from '@naturalcycles/js-lib/datetime/time.util.js';
|
|
|
7
7
|
import { _assert } from '@naturalcycles/js-lib/error/assert.js';
|
|
8
8
|
import { _filterFalsyValues } from '@naturalcycles/js-lib/object/object.util.js';
|
|
9
9
|
import { semver2 } from '@naturalcycles/js-lib/semver';
|
|
10
|
-
import { _truncate } from '@naturalcycles/js-lib/string/string.util.js';
|
|
11
10
|
import { git2 } from '@naturalcycles/nodejs-lib';
|
|
12
|
-
import { boldGrey, dimGrey
|
|
11
|
+
import { boldGrey, dimGrey } from '@naturalcycles/nodejs-lib/colors';
|
|
13
12
|
import { exec2 } from '@naturalcycles/nodejs-lib/exec2';
|
|
14
13
|
import { fs2 } from '@naturalcycles/nodejs-lib/fs2';
|
|
15
14
|
import { _yargs } from '@naturalcycles/nodejs-lib/yargs';
|
|
@@ -21,52 +20,60 @@ const { CI, ESLINT_CONCURRENCY } = process.env;
|
|
|
21
20
|
*/
|
|
22
21
|
export async function lintAllCommand() {
|
|
23
22
|
const started = Date.now();
|
|
24
|
-
const { commitOnChanges, failOnChanges } = _yargs().options({
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}).argv
|
|
34
|
-
const needToTrackChanges = commitOnChanges || failOnChanges
|
|
35
|
-
const gitStatusAtStart = gitStatus()
|
|
36
|
-
if (needToTrackChanges && gitStatusAtStart) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
23
|
+
// const { commitOnChanges, failOnChanges } = _yargs().options({
|
|
24
|
+
// commitOnChanges: {
|
|
25
|
+
// type: 'boolean',
|
|
26
|
+
// default: false,
|
|
27
|
+
// },
|
|
28
|
+
// failOnChanges: {
|
|
29
|
+
// type: 'boolean',
|
|
30
|
+
// default: false,
|
|
31
|
+
// },
|
|
32
|
+
// }).argv
|
|
33
|
+
// const needToTrackChanges = commitOnChanges || failOnChanges
|
|
34
|
+
// const gitStatusAtStart = gitStatus()
|
|
35
|
+
// if (needToTrackChanges && gitStatusAtStart) {
|
|
36
|
+
// console.log('lint-all: git shows changes before run:')
|
|
37
|
+
// console.log(gitStatusAtStart)
|
|
38
|
+
// }
|
|
39
|
+
// In CI, Github Actions doesn't allow us to push and then run CI on changes again
|
|
40
|
+
// (known limitation / "infinite run loop" prevention)
|
|
41
|
+
// That's why we run in "no-fix" mode in CI, and "fix" mode locally
|
|
42
|
+
const fix = !CI;
|
|
40
43
|
// Fast linters (that run in <1 second) go first
|
|
41
44
|
runActionLint();
|
|
42
|
-
runBiome();
|
|
45
|
+
runBiome(fix);
|
|
43
46
|
// From this point we start the "slow" linters, with ESLint leading the way
|
|
44
47
|
// We run eslint BEFORE Prettier, because eslint can delete e.g unused imports.
|
|
45
|
-
await eslintAll(
|
|
48
|
+
await eslintAll({
|
|
49
|
+
fix,
|
|
50
|
+
});
|
|
46
51
|
if (existsSync(`node_modules/stylelint`) &&
|
|
47
52
|
existsSync(`node_modules/stylelint-config-standard-scss`)) {
|
|
48
|
-
stylelintAll();
|
|
49
|
-
}
|
|
50
|
-
runPrettier();
|
|
51
|
-
await runKTLint();
|
|
52
|
-
console.log(`${boldGrey('lint-all')} ${dimGrey(`took ` + _since(started))}`);
|
|
53
|
-
if (needToTrackChanges) {
|
|
54
|
-
const gitStatusAfter = gitStatus();
|
|
55
|
-
const hasChanges = gitStatusAfter !== gitStatusAtStart;
|
|
56
|
-
if (!hasChanges)
|
|
57
|
-
return;
|
|
58
|
-
const msg = 'style(ci): ' + _truncate(git2.commitMessageToTitleMessage(git2.getLastGitCommitMsg()), 60);
|
|
59
|
-
// pull, commit, push changes
|
|
60
|
-
git2.pull();
|
|
61
|
-
git2.commitAll(msg);
|
|
62
|
-
git2.push();
|
|
63
|
-
// fail on changes
|
|
64
|
-
if (failOnChanges) {
|
|
65
|
-
console.log(gitStatusAfter);
|
|
66
|
-
console.log('lint-all failOnChanges: exiting with status 1');
|
|
67
|
-
process.exitCode = 1;
|
|
68
|
-
}
|
|
53
|
+
stylelintAll(fix);
|
|
69
54
|
}
|
|
55
|
+
runPrettier({ fix });
|
|
56
|
+
await runKTLint(fix);
|
|
57
|
+
console.log(`${boldGrey(`${check(true)} lint-all`)} ${dimGrey(`took ` + _since(started))}`);
|
|
58
|
+
// if (needToTrackChanges) {
|
|
59
|
+
// const gitStatusAfter = gitStatus()
|
|
60
|
+
// const hasChanges = gitStatusAfter !== gitStatusAtStart
|
|
61
|
+
// if (!hasChanges) return
|
|
62
|
+
// const msg =
|
|
63
|
+
// 'style(ci): ' + _truncate(git2.commitMessageToTitleMessage(git2.getLastGitCommitMsg()), 60)
|
|
64
|
+
//
|
|
65
|
+
// // pull, commit, push changes
|
|
66
|
+
// git2.pull()
|
|
67
|
+
// git2.commitAll(msg)
|
|
68
|
+
// git2.push()
|
|
69
|
+
//
|
|
70
|
+
// // fail on changes
|
|
71
|
+
// if (failOnChanges) {
|
|
72
|
+
// console.log(gitStatusAfter)
|
|
73
|
+
// console.log('lint-all failOnChanges: exiting with status 1')
|
|
74
|
+
// process.exitCode = 1
|
|
75
|
+
// }
|
|
76
|
+
// }
|
|
70
77
|
}
|
|
71
78
|
/**
|
|
72
79
|
* Runs `eslint` command for all predefined paths (e.g /src, /scripts, etc).
|
|
@@ -80,7 +87,7 @@ export async function eslintAll(opt) {
|
|
|
80
87
|
},
|
|
81
88
|
fix: {
|
|
82
89
|
type: 'boolean',
|
|
83
|
-
default: true
|
|
90
|
+
default: !CI, // defaults to false in CI, true otherwise
|
|
84
91
|
},
|
|
85
92
|
});
|
|
86
93
|
const { ext, fix } = {
|
|
@@ -88,26 +95,22 @@ export async function eslintAll(opt) {
|
|
|
88
95
|
...opt,
|
|
89
96
|
};
|
|
90
97
|
const extensions = ext.split(',');
|
|
91
|
-
|
|
98
|
+
// The only time we don't parallelize is when run locally with no-fix,
|
|
99
|
+
// so errors can be seen properly
|
|
100
|
+
const runInParallel = fix || !!CI;
|
|
101
|
+
if (runInParallel) {
|
|
92
102
|
await Promise.all([
|
|
93
|
-
// /src
|
|
94
103
|
runESLint(`src`, extensions, fix),
|
|
95
|
-
// /scripts
|
|
96
104
|
runESLint(`scripts`, extensions, fix),
|
|
97
|
-
// /e2e
|
|
98
105
|
runESLint(`e2e`, extensions, fix),
|
|
99
106
|
]);
|
|
100
107
|
}
|
|
101
108
|
else {
|
|
102
|
-
// with no-fix - let's run serially
|
|
103
|
-
// /src
|
|
104
109
|
await runESLint(`src`, extensions, fix);
|
|
105
|
-
// /scripts
|
|
106
110
|
await runESLint(`scripts`, extensions, fix);
|
|
107
|
-
// /e2e
|
|
108
111
|
await runESLint(`e2e`, extensions, fix);
|
|
109
112
|
}
|
|
110
|
-
console.log(`${boldGrey(
|
|
113
|
+
console.log(`${boldGrey(`${check(true)} eslint-all`)} ${dimGrey(`took ` + _since(started))}`);
|
|
111
114
|
}
|
|
112
115
|
async function runESLint(dir, extensions = eslintExtensions.split(','), fix = true) {
|
|
113
116
|
let configDir = dir;
|
|
@@ -123,8 +126,9 @@ async function runESLint(dir, extensions = eslintExtensions.split(','), fix = tr
|
|
|
123
126
|
const eslintPath = findPackageBinPath('eslint', 'eslint');
|
|
124
127
|
const cacheLocation = `node_modules/.cache/eslint_${dir}`;
|
|
125
128
|
const cacheFound = existsSync(cacheLocation);
|
|
126
|
-
console.log(
|
|
129
|
+
console.log(dimGrey(`${check(cacheFound)} eslint ${dir} cache found: ${cacheFound}`));
|
|
127
130
|
await exec2.spawnAsync(eslintPath, {
|
|
131
|
+
name: ['eslint', dir, !fix && '--no-fix'].filter(Boolean).join(' '),
|
|
128
132
|
args: [
|
|
129
133
|
`--config`,
|
|
130
134
|
eslintConfigPath,
|
|
@@ -138,7 +142,7 @@ async function runESLint(dir, extensions = eslintExtensions.split(','), fix = tr
|
|
|
138
142
|
cacheLocation,
|
|
139
143
|
`--no-error-on-unmatched-pattern`,
|
|
140
144
|
`--report-unused-disable-directives`, // todo: unnecessary with flat, as it's defined in the config
|
|
141
|
-
fix ? `--fix` : '',
|
|
145
|
+
fix ? `--fix` : '--no-fix',
|
|
142
146
|
].filter(_isTruthy),
|
|
143
147
|
shell: false,
|
|
144
148
|
env: _filterFalsyValues({
|
|
@@ -155,18 +159,20 @@ const prettierPaths = [
|
|
|
155
159
|
// Exclude
|
|
156
160
|
...lintExclude.map((s) => `!${s}`),
|
|
157
161
|
];
|
|
158
|
-
export function runPrettier(
|
|
162
|
+
export function runPrettier(opt = {}) {
|
|
163
|
+
const { experimentalCli = true, fix = true } = opt;
|
|
159
164
|
const prettierConfigPath = [`./prettier.config.js`].find(f => existsSync(f));
|
|
160
165
|
if (!prettierConfigPath)
|
|
161
166
|
return;
|
|
162
167
|
const prettierPath = findPackageBinPath('prettier', 'prettier');
|
|
163
168
|
const cacheLocation = 'node_modules/.cache/prettier';
|
|
164
169
|
const cacheFound = existsSync(cacheLocation);
|
|
165
|
-
console.log(
|
|
170
|
+
console.log(dimGrey(`${check(cacheFound)} prettier cache found: ${cacheFound}`));
|
|
166
171
|
// prettier --write 'src/**/*.{js,ts,css,scss,graphql}'
|
|
167
172
|
exec2.spawn(prettierPath, {
|
|
173
|
+
name: fix ? 'prettier' : 'prettier --check',
|
|
168
174
|
args: [
|
|
169
|
-
`--write
|
|
175
|
+
fix ? `--write` : '--check',
|
|
170
176
|
`--log-level=warn`,
|
|
171
177
|
'--cache-location',
|
|
172
178
|
cacheLocation,
|
|
@@ -184,18 +190,20 @@ const stylelintPaths = [
|
|
|
184
190
|
// Exclude
|
|
185
191
|
...lintExclude.map((s) => `!${s}`),
|
|
186
192
|
];
|
|
187
|
-
export function stylelintAll() {
|
|
188
|
-
const
|
|
193
|
+
export function stylelintAll(fix) {
|
|
194
|
+
const argv = _yargs().options({
|
|
189
195
|
fix: {
|
|
190
196
|
type: 'boolean',
|
|
191
|
-
default: true
|
|
197
|
+
default: !CI, // defaults to false in CI, true otherwise
|
|
192
198
|
},
|
|
193
199
|
}).argv;
|
|
200
|
+
fix ??= argv.fix;
|
|
194
201
|
const config = [`./stylelint.config.js`].find(f => existsSync(f));
|
|
195
202
|
if (!config)
|
|
196
203
|
return;
|
|
197
204
|
// stylelint is never hoisted from dev-lib, so, no need to search for its path
|
|
198
205
|
exec2.spawn('stylelint', {
|
|
206
|
+
name: fix ? 'stylelint' : 'stylelint --no-fix',
|
|
199
207
|
args: [fix ? `--fix` : '', `--allow-empty-input`, `--config`, config, ...stylelintPaths].filter(Boolean),
|
|
200
208
|
shell: false,
|
|
201
209
|
});
|
|
@@ -229,12 +237,12 @@ export function runCommitlintCommand() {
|
|
|
229
237
|
log: false,
|
|
230
238
|
});
|
|
231
239
|
}
|
|
232
|
-
async function runKTLint() {
|
|
240
|
+
async function runKTLint(fix = true) {
|
|
233
241
|
if (!existsSync(`node_modules/@naturalcycles/ktlint`))
|
|
234
242
|
return;
|
|
235
243
|
// @ts-expect-error ktlint is not installed (due to size in node_modules), but it's ok
|
|
236
244
|
const { ktlintAll } = await import('@naturalcycles/ktlint');
|
|
237
|
-
await ktlintAll();
|
|
245
|
+
await ktlintAll(fix ? ['-F'] : []);
|
|
238
246
|
}
|
|
239
247
|
function runActionLint() {
|
|
240
248
|
// Only run if there is a folder of `.github/workflows`, otherwise actionlint will fail
|
|
@@ -261,12 +269,6 @@ export function getActionLintVersion() {
|
|
|
261
269
|
return exec2.exec('actionlint --version').split('\n')[0];
|
|
262
270
|
}
|
|
263
271
|
export function runBiome(fix = true) {
|
|
264
|
-
// if (!fs.existsSync(`node_modules/@biomejs/biome`)) {
|
|
265
|
-
// if (verbose) {
|
|
266
|
-
// console.log(`biome is not installed (checked in node_modules/@biomejs/biome), skipping`)
|
|
267
|
-
// }
|
|
268
|
-
// return
|
|
269
|
-
// }
|
|
270
272
|
const configPath = `biome.jsonc`;
|
|
271
273
|
if (!existsSync(configPath)) {
|
|
272
274
|
console.log(`biome is skipped, because ./biome.jsonc is not present`);
|
|
@@ -275,6 +277,7 @@ export function runBiome(fix = true) {
|
|
|
275
277
|
const biomePath = findPackageBinPath('@biomejs/biome', 'biome');
|
|
276
278
|
const dirs = [`src`, `scripts`, `e2e`].filter(d => existsSync(d));
|
|
277
279
|
exec2.spawn(biomePath, {
|
|
280
|
+
name: fix ? 'biome' : 'biome --no-fix',
|
|
278
281
|
args: [`lint`, fix && '--write', fix && '--unsafe', '--no-errors-on-unmatched', ...dirs].filter(_isTruthy),
|
|
279
282
|
logFinish: false,
|
|
280
283
|
shell: false,
|
|
@@ -289,17 +292,19 @@ function canRunBinary(name) {
|
|
|
289
292
|
return false;
|
|
290
293
|
}
|
|
291
294
|
}
|
|
292
|
-
function gitStatus() {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
}
|
|
295
|
+
// function gitStatus(): string | undefined {
|
|
296
|
+
// try {
|
|
297
|
+
// return execSync('git status -s', {
|
|
298
|
+
// encoding: 'utf8',
|
|
299
|
+
// })
|
|
300
|
+
// } catch {}
|
|
301
|
+
// }
|
|
300
302
|
const require = createRequire(import.meta.url);
|
|
301
303
|
export function findPackageBinPath(pkg, cmd) {
|
|
302
304
|
const packageJsonPath = require.resolve(`${pkg}/package.json`);
|
|
303
305
|
const { bin } = fs2.readJson(packageJsonPath);
|
|
304
306
|
return path.join(path.dirname(packageJsonPath), typeof bin === 'string' ? bin : bin[cmd]);
|
|
305
307
|
}
|
|
308
|
+
function check(predicate) {
|
|
309
|
+
return predicate ? '✔️ ' : ' ';
|
|
310
|
+
}
|