Skip to content

Commit 08b8641

Browse files
committed
Creates lint command
1 parent fe822bc commit 08b8641

12 files changed

+153
-111
lines changed

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@
2121
"clean:modules": "rm -rf node_modules {packages,tools}/*/node_modules",
2222
"fix": "lg-lint --fix",
2323
"link": "lg-link",
24-
"lint": "lg-lint",
24+
"lint": "lg lint",
2525
"prepublishOnly": "yarn build",
26+
"prepublish:ts-downlevel": "rm -rf packages/*/dist/ts3.4 && echo packages/*/dist | NODE_NO_WARNINGS=1 xargs -I{} -n1 -P8 downlevel-dts {} {}/ts3.4",
2627
"publish": "yarn changeset publish --public",
2728
"slackbot": "lg-slackbot",
2829
"start": "storybook dev -p 9001 --no-version-updates",

tools/cli/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"build": "rollup -c rollup.config.mjs"
1414
},
1515
"dependencies": {
16+
"@lg-tools/lint": "^0.0.1",
1617
"@lg-tools/test": "^0.0.1",
1718
"chalk": "^4.0.0",
1819
"commander": "^11.0.0",

tools/cli/src/index.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
import { Command } from 'commander';
22
import { test } from '@lg-tools/test';
3+
import { lint } from '@lg-tools/lint';
34

45
const cli = new Command('lg');
56

6-
/** Test Command */
7+
/** Test */
78
cli
89
.command('test')
910
.description('Tests leafygreen-ui packages with unified config.')
1011
.option('--watch', 'Watch all files you intend to test', false)
1112
.action(test);
1213

14+
/** Lint */
15+
cli
16+
.command('lint')
17+
.option('-f, --fix', 'fix linting errors', false)
18+
.option('-e, --eslintOnly', 'run eslint only', false)
19+
.option('-p, --prettierOnly', 'run prettier only', false)
20+
.option('--pkgJsonOnly', 'run npmPackageJsonLint only', false)
21+
.option('--verbose', 'verbose mode', false)
22+
.action(lint);
23+
1324
cli.parse(process.argv);

tools/cli/tsconfig.json

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
{
1515
"path": "../build"
1616
},
17+
{
18+
"path": "../lint"
19+
},
1720
{
1821
"path": "../test"
1922
}

tools/lint/package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "@lg-tools/lint",
33
"version": "0.0.1",
44
"description": "Lint rules & config for LeafyGreen repositories",
5-
"main": "index.js",
5+
"main": "dist/index.js",
66
"license": "Apache-2.0",
77
"bin": {
88
"lg-lint": "./bin/lint.js"
@@ -11,7 +11,8 @@
1111
"access": "public"
1212
},
1313
"scripts": {
14-
"build": "rollup -c rollup.config.mjs"
14+
"build": "rollup -c rollup.config.mjs",
15+
"tsc": "tsc --build tsconfig.json"
1516
},
1617
"dependencies": {
1718
"@babel/core": "^7.22.5",

tools/lint/src/eslint.ts

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { spawn } from 'child_process';
2+
import path from 'path';
3+
import chalk from 'chalk';
4+
import { LintCommandOptions } from './lint.types';
5+
6+
const rootDir = process.cwd();
7+
const eslintConfigPath = path.resolve(__dirname, '../config/eslint.config.js');
8+
export const esLintExtensions = ['js', 'ts', 'tsx'];
9+
10+
/** Spawns an eslint job */
11+
export function eslint({
12+
fix,
13+
verbose,
14+
}: Pick<LintCommandOptions, 'fix' | 'verbose'>) {
15+
return new Promise<void>(resolve => {
16+
console.log(chalk.blue('Running ESLint...'));
17+
spawn(
18+
'eslint',
19+
[
20+
'--config',
21+
eslintConfigPath,
22+
`${rootDir}/**/*.{${esLintExtensions.join(',')}}`,
23+
fix ? '--fix' : '--no-fix',
24+
verbose ? '' : '--quiet',
25+
],
26+
{
27+
stdio: 'inherit',
28+
},
29+
).on('close', resolve);
30+
});
31+
}

tools/lint/src/index.ts

+22-88
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,30 @@
11
/* eslint-disable no-console */
2-
import chalk from 'chalk';
3-
import { spawn } from 'child_process';
4-
import { Command } from 'commander';
5-
import path from 'path';
6-
72
import { npmPkgJsonLint } from './npmPkgJsonLint';
83

9-
const rootDir = process.cwd();
10-
const eslintConfigPath = path.resolve(__dirname, '../config/eslint.config.js');
11-
const prettierConfigPath = path.resolve(
12-
__dirname,
13-
'../config/prettier.config.js',
14-
);
15-
16-
const esLintExtensions = ['js', 'ts', 'tsx'];
17-
const prettierExtensions = [...esLintExtensions, 'mjs', 'json', 'md', 'yml'];
18-
19-
interface LintFlags {
20-
fix: boolean;
21-
eslintOnly: boolean;
22-
prettierOnly: boolean;
23-
pkgJsonOnly: boolean;
24-
verbose: boolean;
25-
}
26-
27-
const cli = new Command()
28-
.option('-f, --fix', 'fix linting errors', false)
29-
.option('-e, --eslintOnly', 'run eslint only', false)
30-
.option('-p, --prettierOnly', 'run prettier only', false)
31-
.option('--pkgJsonOnly', 'run npmPackageJsonLint only', false)
32-
.option('--verbose', 'verbose mode', false)
33-
.parse(process.argv);
4+
import { eslint } from './eslint';
5+
import { LintCommandOptions } from './lint.types';
6+
import { prettier } from './prettier';
347

35-
const { fix, prettierOnly, eslintOnly, pkgJsonOnly, verbose } =
36-
cli.opts() as LintFlags;
8+
export const lint = (options: LintCommandOptions) => {
9+
const { fix, prettierOnly, eslintOnly, pkgJsonOnly, verbose } = options;
3710

38-
// If prettierOnly or eslintOnly is true, run only that linter
39-
if (prettierOnly || eslintOnly || pkgJsonOnly) {
40-
let lintPromise: Promise<unknown>;
11+
const linters: Array<Promise<unknown>> = [];
4112

42-
if (eslintOnly) {
43-
lintPromise = eslint();
44-
} else if (prettierOnly) {
45-
lintPromise = prettier();
46-
} else {
47-
lintPromise = npmPkgJsonLint(fix);
13+
if (!prettierOnly && !pkgJsonOnly) {
14+
linters.push(eslint({ fix, verbose }));
15+
}
16+
if (!eslintOnly && !pkgJsonOnly) {
17+
linters.push(prettier({ fix, verbose }));
18+
}
19+
if (!prettierOnly && !eslintOnly) {
20+
linters.push(npmPkgJsonLint({ fix, verbose }));
4821
}
49-
lintPromise.then(() => process.exit(0));
50-
} else {
51-
// Otherwise, run all linters
52-
(async () => {
53-
await eslint();
54-
await prettier();
55-
await npmPkgJsonLint(fix);
56-
})();
57-
}
58-
59-
/** Spawns an eslint job */
60-
function eslint() {
61-
return new Promise<void>(resolve => {
62-
console.log(chalk.blue('Running ESLint...'));
63-
spawn(
64-
'eslint',
65-
[
66-
'--config',
67-
eslintConfigPath,
68-
`${rootDir}/**/*.{${esLintExtensions.join(',')}}`,
69-
fix ? '--fix' : '--no-fix',
70-
verbose ? '' : '--quiet',
71-
],
72-
{
73-
stdio: 'inherit',
74-
},
75-
).on('close', resolve);
76-
});
77-
}
7822

79-
/** Spawns a prettier job */
80-
function prettier() {
81-
return new Promise<void>(resolve => {
82-
console.log(chalk.magenta('Running Prettier...'));
83-
spawn(
84-
'prettier',
85-
[
86-
fix ? '--write' : '--check',
87-
'--config',
88-
prettierConfigPath,
89-
`${rootDir}/**/*.{${prettierExtensions.join(',')}}`,
90-
],
91-
{
92-
stdio: 'inherit',
93-
},
94-
).on('close', resolve);
95-
});
96-
}
23+
Promise.all(linters)
24+
.then(() => {
25+
process.exit(0);
26+
})
27+
.catch(() => {
28+
process.exit(1);
29+
});
30+
};

tools/lint/src/lint.types.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export interface LintCommandOptions {
2+
fix: boolean;
3+
eslintOnly: boolean;
4+
prettierOnly: boolean;
5+
pkgJsonOnly: boolean;
6+
verbose: boolean;
7+
}

tools/lint/src/npmPkgJsonLint.ts

+22-13
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,37 @@
1-
/* eslint-disable no-console */
1+
import { spawn } from 'child_process';
22
import chalk from 'chalk';
3-
import fs from 'fs';
4-
import {
5-
NpmPackageJsonLint,
6-
PackageJsonFileLintingResult,
7-
} from 'npm-package-json-lint';
83
import path from 'path';
9-
4+
import { LintCommandOptions } from './lint.types';
5+
// import { NpmPackageJsonLint } from 'npm-package-json-lint';
106
const rootDir = process.cwd();
117
const npmPkgLintConfigPath = path.resolve(
128
__dirname,
139
'../config/npmpackagejsonlintrc.config.js',
1410
);
1511

16-
const npmPackageJsonLinter = new NpmPackageJsonLint({
17-
cwd: rootDir,
18-
patterns: ['**/package.json'],
19-
configFile: npmPkgLintConfigPath,
20-
});
12+
// const npmPackageJsonLinter = new NpmPackageJsonLint({
13+
// cwd: rootDir,
14+
// patterns: ['**/package.json'],
15+
// configFile: npmPkgLintConfigPath,
16+
// });
2117

2218
/** Spawns a npmPkgJsonLint job */
23-
export function npmPkgJsonLint(fix: boolean) {
19+
export function npmPkgJsonLint({
20+
fix,
21+
verbose,
22+
}: Pick<LintCommandOptions, 'fix' | 'verbose'>) {
2423
return new Promise<void>((resolve, reject) => {
2524
console.log(chalk.yellow('Running npmPkgJsonLint...'));
2625

26+
spawn('npmPkgJsonLint', [rootDir, '--configFile', npmPkgLintConfigPath], {
27+
cwd: rootDir,
28+
stdio: 'inherit',
29+
})
30+
.on('close', resolve)
31+
.on('error', reject);
32+
33+
/*
34+
TODO: use the JS API
2735
const { results, errorCount } = npmPackageJsonLinter.lint();
2836
2937
results.forEach(result => {
@@ -41,5 +49,6 @@ export function npmPkgJsonLint(fix: boolean) {
4149
} else {
4250
resolve();
4351
}
52+
*/
4453
});
4554
}

tools/lint/src/prettier.ts

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { spawn } from 'child_process';
2+
import path from 'path';
3+
import chalk from 'chalk';
4+
import { esLintExtensions } from './eslint';
5+
import { LintCommandOptions } from './lint.types';
6+
7+
const rootDir = process.cwd();
8+
const prettierConfigPath = path.resolve(
9+
__dirname,
10+
'../config/prettier.config.js',
11+
);
12+
const prettierExtensions = [...esLintExtensions, 'mjs', 'json', 'md', 'yml'];
13+
14+
/** Spawns a prettier job */
15+
export function prettier({
16+
fix,
17+
verbose,
18+
}: Pick<LintCommandOptions, 'fix' | 'verbose'>) {
19+
return new Promise<void>(resolve => {
20+
console.log(chalk.magenta('Running Prettier...'));
21+
spawn(
22+
'prettier',
23+
[
24+
fix ? '--write' : '--check',
25+
'--config',
26+
prettierConfigPath,
27+
`${rootDir}/**/*.{${prettierExtensions.join(',')}}`,
28+
],
29+
{
30+
stdio: 'inherit',
31+
},
32+
).on('close', resolve);
33+
});
34+
}

tools/lint/tsconfig.json

+10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
11
{
22
"extends": "@lg-tools/build/config/package.tsconfig.json",
3+
"compilerOptions": {
4+
"declarationDir": "dist",
5+
"outDir": "dist",
6+
"rootDir": "src",
7+
"baseUrl": "."
8+
},
9+
"include": [
10+
"src/**/*"
11+
],
12+
"exclude": ["../../node_modules/**/*"]
313
}

yarn.lock

+6-6
Original file line numberDiff line numberDiff line change
@@ -13701,9 +13701,9 @@ semver@^7.3.8:
1370113701
lru-cache "^6.0.0"
1370213702

1370313703
semver@^7.5.3:
13704-
version "7.5.3"
13705-
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e"
13706-
integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==
13704+
version "7.5.4"
13705+
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
13706+
integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
1370713707
dependencies:
1370813708
lru-cache "^6.0.0"
1370913709

@@ -14851,9 +14851,9 @@ type-fest@^3.1.0, type-fest@^3.9.0:
1485114851
integrity sha512-Gur3yQGM9qiLNs0KPP7LPgeRbio2QTt4xXouobMCarR0/wyW3F+F/+OWwshg3NG0Adon7uQfSZBpB46NfhoF1A==
1485214852

1485314853
type-fest@^3.12.0:
14854-
version "3.12.0"
14855-
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-3.12.0.tgz#4ce26edc1ccc59fc171e495887ef391fe1f5280e"
14856-
integrity sha512-qj9wWsnFvVEMUDbESiilKeXeHL7FwwiFcogfhfyjmvT968RXSvnl23f1JOClTHYItsi7o501C/7qVllscUP3oA==
14854+
version "3.13.0"
14855+
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-3.13.0.tgz#b088347ae73779a750c461694b264340c4c8c0d7"
14856+
integrity sha512-Gur3yQGM9qiLNs0KPP7LPgeRbio2QTt4xXouobMCarR0/wyW3F+F/+OWwshg3NG0Adon7uQfSZBpB46NfhoF1A==
1485714857

1485814858
type-is@~1.6.18:
1485914859
version "1.6.18"

0 commit comments

Comments
 (0)