Skip to content

Commit 149fdce

Browse files
committed
feat: able to exit only on CI when checker failed
1 parent fa44f88 commit 149fdce

File tree

7 files changed

+50
-17
lines changed

7 files changed

+50
-17
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"commander": "9.4.0",
4444
"find-up": "5.0.0",
4545
"fs-extra": "10.1.0",
46+
"is-ci": "^3.0.1",
4647
"minimatch": "5.1.0"
4748
},
4849
"devDependencies": {
@@ -52,6 +53,7 @@
5253
"@swc/cli": "0.1.57",
5354
"@swc/core": "1.2.244",
5455
"@types/fs-extra": "9.0.13",
56+
"@types/is-ci": "^3.0.0",
5557
"@types/jest": "28.1.3",
5658
"@types/minimatch": "5.1.1",
5759
"@types/node": "18.7.14",

pnpm-lock.yaml

Lines changed: 17 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/command/checkDeps.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { readWantedLockfile } from '@pnpm/lockfile-file'
22
import { Logger } from '../util/logger'
3+
import isCI from 'is-ci'
34
import { check } from '../checker'
45
import { parseOptions } from '../parser-option/parse-option'
56
import { findProjectRoot } from '../parser-option/find-project-root'
@@ -9,17 +10,19 @@ export const checkDeps = async () => {
910
try {
1011
const projectRoot = await findProjectRoot()
1112
const options = await parseOptions(projectRoot)
12-
1313
const lockfile = await readWantedLockfile(projectRoot, { ignoreIncompatible: false })
1414
if (!lockfile) {
1515
Logger.message(
1616
`Cannot find ${chalk.blueBright('pnpm-lock.yaml')}, try to run ${chalk.blueBright(
1717
'$ pnpm install'
1818
)} first`
1919
)
20-
return
20+
process.exit(1)
21+
}
22+
const haveError = check(lockfile, options, Logger)
23+
if (haveError && options.failOnCI && isCI) {
24+
process.exit(1)
2125
}
22-
check(lockfile, options, Logger)
2326
} catch (error) {
2427
if (error instanceof Error) {
2528
Logger.error(error)

src/error.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ export class OptionNotFoundError extends Error {
2727
}
2828

2929
export class OptionSyntaxError extends Error {
30-
constructor() {
31-
super(`Invalid option, please make sure you have included single version dependencies.`)
30+
constructor(message: string) {
31+
super(`Invalid option: ${message}`)
3232
this.name = 'OptionSyntaxError'
3333
}
3434
}

src/parser-option/parse-option.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,18 @@ import { OptionNotFoundError, OptionSyntaxError } from '../error'
66
import type { CheckerOptions } from '../type'
77

88
const validateOptions = (options: any): CheckerOptions => {
9-
if (!options) {
9+
if (!options || typeof options !== 'object') {
1010
throw new OptionNotFoundError()
1111
}
1212

13-
if (!Array.isArray(options?.includes) && !Array.isArray(options?.include)) {
14-
throw new OptionSyntaxError()
13+
const o = options as Partial<CheckerOptions>
14+
15+
if (!Array.isArray(o?.includes)) {
16+
throw new OptionSyntaxError('Please make sure you have included single version dependencies in option.')
1517
}
1618

17-
if (options.include) {
18-
options.includes = options.include
19+
if (o?.failOnCI !== undefined && typeof o.failOnCI !== 'boolean') {
20+
throw new OptionSyntaxError('Please use boolean for failedOnCI option')
1921
}
2022

2123
return options as CheckerOptions
@@ -25,5 +27,12 @@ export const parseOptions = async (projectRoot: string): Promise<CheckerOptions>
2527
const packageJsonfile = await fs.readFile(path.join(projectRoot, 'package.json'))
2628
// @see https://github.dev/sindresorhus/load-json-file
2729
const packageJSON = JSON.parse(new TextDecoder().decode(packageJsonfile))
28-
return validateOptions((packageJSON as any)?.[PACKAGE_JSON_OPTIONS_KEY])
30+
31+
const options = validateOptions((packageJSON as any)?.[PACKAGE_JSON_OPTIONS_KEY])
32+
33+
if (options.failOnCI === undefined) {
34+
options.failOnCI = true
35+
}
36+
37+
return options
2938
}

src/type.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ import { nameVerFromPkgSnapshot } from '@pnpm/lockfile-utils'
22

33
export interface CheckerOptions {
44
includes: string[]
5+
/**
6+
* default: true
7+
* In CI env, exit with status code 1 when checker found multiple version on specified dependencies.
8+
*/
9+
failOnCI?: boolean
510
}
611

712
export interface LoggerType {

src/util/logger.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
11
import chalk from 'chalk'
22
import { APP_NAME } from '../constant'
33

4-
const log = console.log
5-
64
export function createCheckerMessage(message: string): string {
75
return chalk.magenta(APP_NAME + ': ') + message
86
}
97

108
function debug(object: Object) {
11-
log(object)
9+
console.log(object)
1210
}
1311

1412
function message(value: string) {
15-
log(createCheckerMessage(value))
13+
console.log(createCheckerMessage(value))
1614
}
1715

1816
function error(error: Error) {
19-
log(createCheckerMessage(`${chalk.bgRed(' ERROR ')} ${error.message}`))
17+
console.log(createCheckerMessage(`${chalk.bgRed(' ERROR ')} ${error.message}`))
2018
}
2119

2220
export const Logger = Object.freeze({

0 commit comments

Comments
 (0)