From fd7bfa396ad1b435226cd21c2b9262c8bffcd347 Mon Sep 17 00:00:00 2001 From: Joram van den Boezem Date: Sun, 11 Dec 2022 00:22:10 +0100 Subject: [PATCH] feat: reload option for use command --- TODO.md | 2 +- packages/cli/package.json | 2 +- packages/cli/src/commands/add.ts | 2 +- packages/cli/src/commands/list.ts | 13 ++++++++++--- packages/cli/src/commands/reload.ts | 2 +- packages/cli/src/commands/use.ts | 17 +++++++++++++---- packages/core/package.json | 2 +- packages/core/src/json.ts | 5 ++--- packages/core/src/plugin.ts | 6 ++---- packages/core/src/utils/index.ts | 1 + packages/core/src/utils/merge.ts | 11 +++++++++++ packages/core/src/yarn.ts | 13 +++++++++++++ packages/plugins/package.json | 2 +- packages/templates/package.json | 2 +- 14 files changed, 59 insertions(+), 21 deletions(-) create mode 100644 packages/core/src/utils/merge.ts diff --git a/TODO.md b/TODO.md index de101bbc..9a2b9a10 100644 --- a/TODO.md +++ b/TODO.md @@ -3,5 +3,5 @@ | Filename | line # | TODO | | :------------------------------------------------------------------------- | :----: | :------------------------------------------------------------ | | [packages/core/src/yarnrc.ts](packages/core/src/yarnrc.ts#L23) | 23 | etc, fix later | -| [packages/cli/src/commands/list.ts](packages/cli/src/commands/list.ts#L15) | 15 | list workspaces using https://yarnpkg.com/cli/workspaces/list | +| [packages/cli/src/commands/list.ts](packages/cli/src/commands/list.ts#L19) | 19 | list workspaces using https://yarnpkg.com/cli/workspaces/list | | [packages/plugins/src/jest/jest.ts](packages/plugins/src/jest/jest.ts#L31) | 31 | install jest without ts-jest | diff --git a/packages/cli/package.json b/packages/cli/package.json index 3103dda4..9a6949d3 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -18,7 +18,7 @@ "prepublish": "yarn clean && yarn build && cp ../../README.md .", "clean": "rm -rf dist && rm -rf types", "build": "yarn clean && tsc", - "build:watch": "yarn build && tsc --watch" + "build:watch": "tsc --watch" }, "dependencies": { "@mokr/core": "workspace:*", diff --git a/packages/cli/src/commands/add.ts b/packages/cli/src/commands/add.ts index 9ca21b5f..8b950732 100644 --- a/packages/cli/src/commands/add.ts +++ b/packages/cli/src/commands/add.ts @@ -10,7 +10,7 @@ import { import { command } from "bandersnatch"; export const add = command("add") - .description("Add a workspace to the monorepo") + .description("Add a workspace to a monorepo") .argument("name", { description: "Name of the workspace", prompt: true, diff --git a/packages/cli/src/commands/list.ts b/packages/cli/src/commands/list.ts index dde3fb70..4a1c5700 100644 --- a/packages/cli/src/commands/list.ts +++ b/packages/cli/src/commands/list.ts @@ -1,4 +1,4 @@ -import { getPlugins } from "@mokr/core"; +import { getPlugins, listWorkspaces } from "@mokr/core"; import { command } from "bandersnatch"; export const list = command("list") @@ -9,9 +9,16 @@ export const list = command("list") }) .action(async ({ cwd }) => { const plugins = await getPlugins({ directory: cwd }); + const workspaces = await listWorkspaces({ directory: cwd }); - console.log(`Plugins: ${plugins.join(", ")}`); + console.log( + `Plugins: +${plugins.map((plugin) => `- ${plugin}\n`).join("")}` + ); // @todo: list workspaces using https://yarnpkg.com/cli/workspaces/list - console.log(`Workspaces: ...`); + console.log( + `Workspaces: +${workspaces.map(({ location, name }) => `- ${name} (${location})\n`).join("")}` + ); }); diff --git a/packages/cli/src/commands/reload.ts b/packages/cli/src/commands/reload.ts index b2528266..48f9b19c 100644 --- a/packages/cli/src/commands/reload.ts +++ b/packages/cli/src/commands/reload.ts @@ -3,7 +3,7 @@ import { command } from "bandersnatch"; export const reload = command("reload") .hidden() - .description("Reload plugins in monorepo or workspace") + .description("Reload plugins in repo or workspace") .option("cwd", { description: "Directory to use as the current working directory", default: process.cwd(), diff --git a/packages/cli/src/commands/use.ts b/packages/cli/src/commands/use.ts index 190e6469..c4aa5566 100644 --- a/packages/cli/src/commands/use.ts +++ b/packages/cli/src/commands/use.ts @@ -1,4 +1,5 @@ import { + hasPlugin, installPlugin, loadAllPlugins, runDependencyQueues, @@ -12,15 +13,23 @@ export const use = command("use") description: "Plugin name", variadic: true, }) + .option("reinstall", { + type: "boolean", + description: "Re-install plugin even if it is already installed", + }) .option("cwd", { description: "Directory to use as the current working directory", default: process.cwd(), }) - .action(async ({ plugin, cwd }) => { + .action(async ({ plugin, reinstall, cwd }) => { for (const name of plugin) { - await task(`Add plugin ${name}`, () => - installPlugin({ directory: cwd, name }) - ); + await task(`Add plugin ${name}`, async () => { + if (!reinstall && (await hasPlugin({ directory: cwd, name }))) { + throw new Error(`Plugin ${name} is already installed`); + } + + await installPlugin({ directory: cwd, name }); + }); } await task(`Load plugins`, () => loadAllPlugins({ directory: cwd })); diff --git a/packages/core/package.json b/packages/core/package.json index 2e0d3b08..c350790b 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -19,7 +19,7 @@ "prepublish": "yarn build", "clean": "rm -rf dist && rm -rf types", "build": "yarn clean && tsc", - "build:watch": "yarn build && tsc --watch", + "build:watch": "tsc --watch", "test": "jest", "test:watch": "jest --watch" }, diff --git a/packages/core/src/json.ts b/packages/core/src/json.ts index 40785e9f..e42850d4 100644 --- a/packages/core/src/json.ts +++ b/packages/core/src/json.ts @@ -1,11 +1,10 @@ -import deepmerge from "deepmerge"; - import { isReadableAndWritableFile, readFile, writeFile } from "./file.js"; import { + deepmerge, isPlainObject, JSONValue, StringableJSONValue, -} from "./utils/types.js"; +} from "./utils/index.js"; export async function readJson({ path, diff --git a/packages/core/src/plugin.ts b/packages/core/src/plugin.ts index 8679b881..c09b3b67 100644 --- a/packages/core/src/plugin.ts +++ b/packages/core/src/plugin.ts @@ -113,13 +113,10 @@ export async function validateType({ } export async function installPlugin({ directory, name }: PluginOptions) { - if (await hasPlugin({ directory, name })) { - throw new Error(`Plugin ${name} is already installed`); - } - const plugin = await importPlugin({ directory, name }); await plugin.install({ directory }); + await writePackage({ directory, data: { @@ -138,6 +135,7 @@ export async function removePlugin({ directory, name }: PluginOptions) { const plugin = await importPlugin({ directory, name }); await plugin.remove({ directory }); + await updatePackage({ directory, merge: (existingData) => ({ diff --git a/packages/core/src/utils/index.ts b/packages/core/src/utils/index.ts index 1fa15856..2604c053 100644 --- a/packages/core/src/utils/index.ts +++ b/packages/core/src/utils/index.ts @@ -1,4 +1,5 @@ export * from "./assertions.js"; export * from "./exec.js"; +export * from "./merge.js"; export * from "./string.js"; export * from "./types.js"; diff --git a/packages/core/src/utils/merge.ts b/packages/core/src/utils/merge.ts new file mode 100644 index 00000000..6dfc3fd3 --- /dev/null +++ b/packages/core/src/utils/merge.ts @@ -0,0 +1,11 @@ +import ogDeepmerge from "deepmerge"; + +export function deepmerge(source1: Partial, source2: Partial) { + return ogDeepmerge(source1, source2, { + arrayMerge, + }); +} + +function arrayMerge(source1: T[], source2: T[]) { + return [...new Set([...source1, ...source2])]; +} diff --git a/packages/core/src/yarn.ts b/packages/core/src/yarn.ts index 972c0ef6..5da50d86 100644 --- a/packages/core/src/yarn.ts +++ b/packages/core/src/yarn.ts @@ -175,3 +175,16 @@ export async function runDependencyQueues({ directory }: DirOption) { queues.remove.set(directory, new Set()); } } + +export async function listWorkspaces({ directory }: DirOption) { + const { stdout } = await exec("yarn", ["workspaces", "list", "--json"], { + cwd: directory, + }); + const workspaces: { location: string; name: string }[] = []; + + for (const line of stdout.split("\n").filter((item) => item)) { + workspaces.push(JSON.parse(line.trim())); + } + + return workspaces; +} diff --git a/packages/plugins/package.json b/packages/plugins/package.json index 6c3234b4..a56c87cd 100644 --- a/packages/plugins/package.json +++ b/packages/plugins/package.json @@ -20,7 +20,7 @@ "prepublish": "yarn build", "clean": "rm -rf dist && rm -rf types", "build": "yarn clean && tsc", - "build:watch": "yarn build && tsc --watch" + "build:watch": "tsc --watch" }, "dependencies": { "@mokr/core": "workspace:*" diff --git a/packages/templates/package.json b/packages/templates/package.json index 8b342650..28feb8fe 100644 --- a/packages/templates/package.json +++ b/packages/templates/package.json @@ -19,7 +19,7 @@ "prepublish": "yarn build", "clean": "rm -rf dist && rm -rf types", "build": "yarn clean && tsc", - "build:watch": "yarn build && tsc --watch" + "build:watch": "tsc --watch" }, "dependencies": { "@mokr/core": "workspace:*"