diff --git a/src/index.ts b/src/index.ts index 4fc3ea6..5af151e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,10 @@ #!/usr/bin/env node +import { log } from '@clack/prompts'; import { cli } from 'cleye'; import * as pkg from '../package.json'; +import { checkDir } from './operations/check-dir'; import { createWorkspace } from './operations/create-workspace'; import { getWorkspace } from './operations/get-workspace'; import { openWorkspace } from './operations/open-workspace'; @@ -24,10 +26,16 @@ const argv = cli({ const path = argv._.path; -const workspace = await getWorkspace(path); -if (workspace) { - await openWorkspace(workspace); -} else { - const workspace = await createWorkspace(path); - await openWorkspace(workspace); +try { + await checkDir(path); + + const workspace = await getWorkspace(path); + if (workspace) { + await openWorkspace(workspace); + } else { + const workspace = await createWorkspace(path); + await openWorkspace(workspace); + } +} catch (e) { + log.error(`${e}`); } diff --git a/src/operations/check-dir.ts b/src/operations/check-dir.ts new file mode 100644 index 0000000..0c881b1 --- /dev/null +++ b/src/operations/check-dir.ts @@ -0,0 +1,13 @@ +import { stat } from 'node:fs/promises'; + +export async function checkDir(path: string) { + const stats = await stat(path).catch(() => { + throw new Error('invalid path'); + }); + + if (!stats.isDirectory()) { + throw new Error('not a directory'); + } + + return true; +} diff --git a/test/operations/check-dir.test.ts b/test/operations/check-dir.test.ts new file mode 100644 index 0000000..362c9b2 --- /dev/null +++ b/test/operations/check-dir.test.ts @@ -0,0 +1,45 @@ +import { existsSync } from 'node:fs'; +import { mkdir, readFile, rm, writeFile } from 'node:fs/promises'; +import { basename, resolve } from 'node:path'; + +import { afterEach, beforeEach, expect, test, vi } from 'vitest'; + +import { checkDir } from '../../src/operations/check-dir'; + +const mocks = vi.hoisted(() => { + return { + testHomedir: () => resolve('test-tmp', basename(import.meta.url)), + }; +}); + +beforeEach(async () => { + if (existsSync(mocks.testHomedir())) { + await rm(mocks.testHomedir(), { recursive: true, force: true }); + } + await mkdir(mocks.testHomedir(), { recursive: true }); + + vi.mock('node:os', () => { + return { + homedir: () => mocks.testHomedir(), + }; + }); +}); + +afterEach(async () => { + vi.restoreAllMocks(); +}); + +test('checkDir', async () => { + await expect(() => + checkDir(resolve(mocks.testHomedir(), 'dir-1')) + ).rejects.toThrowError('invalid'); + + await mkdir(resolve(mocks.testHomedir(), 'dir-1'), { recursive: true }); + await writeFile(resolve(mocks.testHomedir(), 'file-1'), ''); + + expect(await checkDir(resolve(mocks.testHomedir(), 'dir-1'))).toBe(true); + + await expect(() => + checkDir(resolve(mocks.testHomedir(), 'file-1')) + ).rejects.toThrowError('not a directory'); +});