From 442b63a5cdbf17ef6ac46283c7433996fe5b161b Mon Sep 17 00:00:00 2001 From: shuheikikuchi Date: Wed, 14 Jun 2023 23:00:40 +0900 Subject: [PATCH] feat: Add clean command to remove workspaces --- src/commands/clean.ts | 34 +++++++++++++ src/db.ts | 6 +++ src/index.ts | 3 +- src/operations/clean-workspaces.ts | 10 ++++ test/operations/clean-workspaces.test.ts | 65 ++++++++++++++++++++++++ 5 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 src/commands/clean.ts create mode 100644 src/operations/clean-workspaces.ts create mode 100644 test/operations/clean-workspaces.test.ts diff --git a/src/commands/clean.ts b/src/commands/clean.ts new file mode 100644 index 0000000..172544a --- /dev/null +++ b/src/commands/clean.ts @@ -0,0 +1,34 @@ +import { cancel, confirm, isCancel, log, outro } from '@clack/prompts'; +import { command } from 'cleye'; +import colors from 'picocolors'; + +import { cleanWorkspaces } from '../operations/clean-workspaces'; + +export default command( + { + name: 'clean', + + help: { + description: 'Clean all workspaces codew stored', + }, + }, + async () => { + try { + const confirmed = await confirm({ + message: `Are you sure to clean all workspaces?`, + initialValue: false, + }); + if (!confirmed || isCancel(confirmed)) { + cancel(`Cancelled`); + process.exit(0); + } + + await cleanWorkspaces(); + + outro(colors.cyan('✔ Successfully cleaned.')); + process.exit(0); + } catch (e) { + log.error(`${e}`); + } + } +); diff --git a/src/db.ts b/src/db.ts index ba80383..1f9fc3a 100644 --- a/src/db.ts +++ b/src/db.ts @@ -27,3 +27,9 @@ export async function insertWorkspace(workspace: Workspace) { db.data.workspaces.push(workspace); await db.write(); } + +export async function dropWorkspaces() { + const db = await getDb(); + db.data.workspaces = []; + await db.write(); +} diff --git a/src/index.ts b/src/index.ts index f366fe1..bcb8e50 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,6 +4,7 @@ import { log } from '@clack/prompts'; import { cli } from 'cleye'; import * as pkg from '../package.json'; +import clean from './commands/clean'; import list from './commands/list'; import { checkDir } from './operations/check-dir'; import { createWorkspace } from './operations/create-workspace'; @@ -25,7 +26,7 @@ cli( examples: ['codew .'], }, - commands: [list], + commands: [list, clean], }, async (argv) => { const path = argv._.path; diff --git a/src/operations/clean-workspaces.ts b/src/operations/clean-workspaces.ts new file mode 100644 index 0000000..d409e67 --- /dev/null +++ b/src/operations/clean-workspaces.ts @@ -0,0 +1,10 @@ +import { rm } from 'node:fs/promises'; + +import { workspaceDir } from '../config'; +import { dropWorkspaces } from '../db'; + +export async function cleanWorkspaces() { + await rm(workspaceDir, { recursive: true, force: true }); + + await dropWorkspaces(); +} diff --git a/test/operations/clean-workspaces.test.ts b/test/operations/clean-workspaces.test.ts new file mode 100644 index 0000000..6f185c9 --- /dev/null +++ b/test/operations/clean-workspaces.test.ts @@ -0,0 +1,65 @@ +import { existsSync } from 'node:fs'; +import { mkdir, readFile, rm } from 'node:fs/promises'; +import { basename, resolve } from 'node:path'; + +import { afterEach, beforeEach, expect, test, vi } from 'vitest'; + +import { cleanWorkspaces } from '../../src/operations/clean-workspaces'; +import { createWorkspace } from '../../src/operations/create-workspace'; + +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('cleanWorkspaces', async () => { + await createWorkspace('dir-1'); + + expect( + existsSync( + resolve(mocks.testHomedir(), '.codew/workspaces/dir-1.code-workspace') + ) + ).toBe(true); + const dbContent = await readFile( + resolve(mocks.testHomedir(), '.codew/db.json'), + { + encoding: 'utf-8', + } + ); + const db = JSON.parse(dbContent); + expect(db.workspaces.length).toBe(1); + + await cleanWorkspaces(); + + expect( + existsSync( + resolve(mocks.testHomedir(), '.codew/workspaces/dir-1.code-workspace') + ) + ).toBe(false); + const dbContent2 = await readFile( + resolve(mocks.testHomedir(), '.codew/db.json'), + { + encoding: 'utf-8', + } + ); + const db2 = JSON.parse(dbContent2); + expect(db2.workspaces.length).toBe(0); +});