Skip to content

Commit

Permalink
feat(react-query): add cli error handling (#1388)
Browse files Browse the repository at this point in the history
# Overview

related:
#1383 (comment)

- add error handler in commander.js
- add logger utils (for consistency)

ref:
https://github.com/tj/commander.js?tab=readme-ov-file#override-exit-and-output-handling

## PR Checklist

- [x] I did below actions if need

1. I read the [Contributing
Guide](https://github.com/toss/suspensive/blob/main/CONTRIBUTING.md)
2. I added documents and tests.

---------

Co-authored-by: Jonghyeon Ko <[email protected]>
  • Loading branch information
gwansikk and manudeli authored Dec 11, 2024
1 parent 7af2803 commit a9bff19
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 20 deletions.
5 changes: 5 additions & 0 deletions .changeset/few-news-push.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@suspensive/react-query": patch
---

feat(react-query): add cli error handling
15 changes: 12 additions & 3 deletions packages/react-query/src/bin/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

import { Command } from '@commander-js/extra-typings'
import { fixAction, statusAction, switchAction } from './utils/commands'
import { logger } from './utils/logger'
import { getPackageJson } from './utils/package'

const packageJson = getPackageJson()
const program = new Command(packageJson.name)
const program = new Command(packageJson.name).configureOutput({
writeErr: (str) => logger.error(str.replace('error: ', '')),
})

program
.description(packageJson.description)
Expand All @@ -25,7 +28,7 @@ program
`@tanstack/react-query's version`,
"Switch @suspensive/react-query's exports to use compatible Suspensive interfaces for @tanstack/react-query@<version>"
)
.action((version) => switchAction(version))
.action(switchAction)

program
.command('fix')
Expand All @@ -34,4 +37,10 @@ program
)
.action(fixAction)

program.parse(process.argv)
try {
program.parse(process.argv)
} catch (error) {
if (error instanceof Error) {
logger.error(error.message)
}
}
8 changes: 4 additions & 4 deletions packages/react-query/src/bin/postinstall.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ vi.mock('./utils/package')
vi.mock('./utils/switchVersion')

describe('postinstall', () => {
const mockConsoleWarn = vi.spyOn(console, 'warn')
const mockConsoleError = vi.spyOn(console, 'error')
const mockGetTanStackReactQueryPackageJson = vi.mocked(getTanStackReactQueryPackageJson)
const mockSwitchVersion = vi.mocked(switchVersion)

Expand All @@ -31,7 +31,7 @@ describe('postinstall', () => {
expect(mockGetTanStackReactQueryPackageJson).toHaveBeenCalledTimes(1)
expect(mockSwitchVersion).toHaveBeenCalledWith(4)
expect(mockSwitchVersion).toHaveBeenCalledTimes(1)
expect(mockConsoleWarn).not.toHaveBeenCalled()
expect(mockConsoleError).not.toHaveBeenCalled()
})

it('should switch to @suspensive/react-query-5 when @tanstack/react-query@^5 is installed', async () => {
Expand All @@ -40,14 +40,14 @@ describe('postinstall', () => {
expect(mockGetTanStackReactQueryPackageJson).toHaveBeenCalledTimes(1)
expect(mockSwitchVersion).toHaveBeenCalledWith(5)
expect(mockSwitchVersion).toHaveBeenCalledTimes(1)
expect(mockConsoleWarn).not.toHaveBeenCalled()
expect(mockConsoleError).not.toHaveBeenCalled()
})

it('should show warning when unsupported version is installed', async () => {
await runPostInstall('3.3.4')

expect(mockGetTanStackReactQueryPackageJson).toHaveBeenCalledTimes(1)
expect(mockSwitchVersion).not.toHaveBeenCalled()
expect(mockConsoleWarn).toHaveBeenCalledWith('[@suspensive/react-query]', 'version v3.3.4 is not supported.')
expect(mockConsoleError).toHaveBeenCalledWith('[@suspensive/react-query]', 'version v3.3.4 is not supported.')
})
})
3 changes: 2 additions & 1 deletion packages/react-query/src/bin/postinstall.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { logger } from './utils/logger'
import { getTanStackReactQueryPackageJson } from './utils/package'
import { switchVersion } from './utils/switchVersion'

Expand All @@ -8,5 +9,5 @@ if (version.startsWith('4.')) {
} else if (version.startsWith('5.')) {
switchVersion(5)
} else {
console.warn('[@suspensive/react-query]', `version v${version} is not supported.`)
logger.error(`version v${version} is not supported.`)
}
3 changes: 2 additions & 1 deletion packages/react-query/src/bin/utils/commands.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ vi.mock('./switchVersion')
describe('commands', () => {
const consoleLogSpy = vi.spyOn(console, 'log').mockClear()
const consoleWarnSpy = vi.spyOn(console, 'warn').mockClear()
const consoleErrorSpy = vi.spyOn(console, 'error').mockClear()

const mockGetPackageJson = vi.mocked(getPackageJson)
mockGetPackageJson.mockReturnValue(packageJson)
Expand Down Expand Up @@ -88,7 +89,7 @@ describe('commands', () => {

statusAction()

expect(consoleWarnSpy).toHaveBeenCalledWith('[@suspensive/react-query]', 'The version is not found.')
expect(consoleErrorSpy).toHaveBeenCalledWith('[@suspensive/react-query]', 'The version is not found.')
})
})

Expand Down
13 changes: 7 additions & 6 deletions packages/react-query/src/bin/utils/commands.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { logger } from './logger'
import { getTanStackReactQueryPackageJson, getTargetSuspensiveReactQueryVersion } from './package'
import { switchVersion } from './switchVersion'
import { getStatusTable } from './table'

export function statusAction() {
const targetSuspensiveReactQueryVersion = getTargetSuspensiveReactQueryVersion()

if (!targetSuspensiveReactQueryVersion) {
return console.warn('[@suspensive/react-query]', 'The version is not found.')
logger.error('The version is not found.')
return
}

console.log(getStatusTable(targetSuspensiveReactQueryVersion))
Expand All @@ -24,13 +25,13 @@ export function switchAction(version: string) {

export function fixAction() {
const tanStackReactQueryPackageJson = getTanStackReactQueryPackageJson()
const suspensiveReactQueryVersion = getTargetSuspensiveReactQueryVersion()
const targetSuspensiveReactQueryVersion = getTargetSuspensiveReactQueryVersion()

const tanStackReactQueryMajorVersion = tanStackReactQueryPackageJson.version.split('.')[0]
if (suspensiveReactQueryVersion === tanStackReactQueryMajorVersion) {
console.log('[@suspensive/react-query]', 'The versions are compatible.')
if (targetSuspensiveReactQueryVersion === tanStackReactQueryMajorVersion) {
logger.log('The versions are compatible.')
} else {
console.log('[@suspensive/react-query]', 'Switching to the compatible version...')
logger.log('Switching to the compatible version...')
switchVersion(Number(tanStackReactQueryMajorVersion))
}
}
26 changes: 26 additions & 0 deletions packages/react-query/src/bin/utils/logger.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { logger } from './logger'

describe('logger', () => {
const LOG_PREFIX = '[@suspensive/react-query]'
const consoleLogSpy = vi.spyOn(console, 'log').mockClear()
const consoleErrorSpy = vi.spyOn(console, 'error').mockClear()

beforeEach(() => {
vi.resetModules()
vi.clearAllMocks()
})

it('should log a message with console.log', () => {
const testMessage = 'test message'
logger.log(testMessage)

expect(consoleLogSpy).toHaveBeenCalledWith(LOG_PREFIX, testMessage)
})

it('should log a error with console.warn', () => {
const testMessage = 'error message'
logger.error(testMessage)

expect(consoleErrorSpy).toHaveBeenCalledWith(LOG_PREFIX, testMessage)
})
})
6 changes: 6 additions & 0 deletions packages/react-query/src/bin/utils/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const LOG_PREFIX = '[@suspensive/react-query]'

export const logger = {
log: (message: string) => console.log(LOG_PREFIX, message),
error: (message: string) => console.error(LOG_PREFIX, message),
}
6 changes: 3 additions & 3 deletions packages/react-query/src/bin/utils/switchVersion.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ vi.mock('./copy', () => ({

describe('switchVersion', () => {
const consoleLogSpy = vi.spyOn(console, 'log').mockClear()
const consoleWarnSpy = vi.spyOn(console, 'warn').mockClear()
const consoleErrorSpy = vi.spyOn(console, 'error').mockClear()

beforeEach(() => {
vi.resetModules()
Expand All @@ -20,15 +20,15 @@ describe('switchVersion', () => {
switchVersion(5)

expect(consoleLogSpy).toHaveBeenCalledWith('[@suspensive/react-query]', 'switched to version v5')
expect(consoleWarnSpy).not.toHaveBeenCalled()
expect(consoleErrorSpy).not.toHaveBeenCalled()
})

it('should log warning message when copy function returns false', () => {
vi.mocked(copy).mockReturnValue(false)

switchVersion(1)

expect(consoleWarnSpy).toHaveBeenCalledWith('[@suspensive/react-query]', 'not found version files.')
expect(consoleErrorSpy).toHaveBeenCalledWith('[@suspensive/react-query]', 'not found version files.')
expect(consoleLogSpy).not.toHaveBeenCalled()
})
})
5 changes: 3 additions & 2 deletions packages/react-query/src/bin/utils/switchVersion.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { copy } from './copy'
import { logger } from './logger'

export function switchVersion(version: number) {
const result = copy(version)

if (result) {
console.log('[@suspensive/react-query]', `switched to version v${version}`)
logger.log(`switched to version v${version}`)
} else {
console.warn('[@suspensive/react-query]', 'not found version files.')
logger.error('not found version files.')
}
}

0 comments on commit a9bff19

Please sign in to comment.