From c7a0881d339953c127f169ee90a4eed59d6d67af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josh=20Goldberg=20=E2=9C=A8?= Date: Sat, 21 Dec 2024 16:51:36 -0500 Subject: [PATCH] chore: use cspell-populate-words in CSpell block (#1794) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - [x] Addresses an existing open issue: fixes #381 - [x] That issue was marked as [`status: accepting prs`](https://github.com/JoshuaKGoldberg/create-typescript-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22status%3A+accepting+prs%22) - [x] Steps in [CONTRIBUTING.md](https://github.com/JoshuaKGoldberg/create-typescript-app/blob/main/.github/CONTRIBUTING.md) were taken ## Overview Applies only to the new `create` engine Block system, because it'd be a nontrivial change in the old system, and I want that old system to be gone within the next few weeks. 🚀 Uses: 1. [`object-strings-deep`](https://github.com/JoshuaKGoldberg/object-strings-deep) to collect all strings from options 2. [`cspell-populate-words`](https://github.com/JoshuaKGoldberg/cspell-populate-words) in a new `script` to add any reported words to the `cspell.json` file Scoping the PR as a `chore:` because the new system is not yet part of the public API. 💖 --- knip.json | 2 +- package.json | 2 ++ pnpm-lock.yaml | 21 +++++++++++++++++++++ src/next/blocks/blockCSpell.test.ts | 6 +++++- src/next/blocks/blockCSpell.ts | 19 +++++++++++++++++++ src/next/utils/resolveBin.ts | 3 +++ src/steps/uninstallPackages.ts | 2 ++ src/steps/writing/creation/index.test.ts | 8 +++++++- 8 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 src/next/utils/resolveBin.ts diff --git a/knip.json b/knip.json index 5ae2bbf6..15b40937 100644 --- a/knip.json +++ b/knip.json @@ -1,7 +1,7 @@ { "$schema": "https://unpkg.com/knip@5.41.0/schema.json", "entry": ["script/*e2e.js", "src/index.ts!", "src/**/*.test.*"], - "ignoreDependencies": ["all-contributors-cli"], + "ignoreDependencies": ["all-contributors-cli", "cspell-populate-words"], "ignoreExportsUsedInFile": { "interface": true, "type": true }, "project": ["src/**/*.ts!", "script/**/*.js"] } diff --git a/package.json b/package.json index 73abffdc..8c79f2fd 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "@prettier/sync": "^0.5.2", "chalk": "^5.3.0", "create": "0.1.0-alpha.7", + "cspell-populate-words": "^0.2.2", "execa": "^9.5.2", "git-remote-origin-url": "^4.0.0", "git-url-parse": "^16.0.0", @@ -53,6 +54,7 @@ "js-yaml": "^4.1.0", "lazy-value": "^3.0.0", "npm-user": "^6.1.1", + "object-strings-deep": "^0.1.1", "octokit": "^4.0.2", "octokit-from-auth": "^0.3.0", "parse-author": "^2.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 898b7851..49768661 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,9 @@ importers: create: specifier: 0.1.0-alpha.7 version: 0.1.0-alpha.7 + cspell-populate-words: + specifier: ^0.2.2 + version: 0.2.2 execa: specifier: ^9.5.2 version: 9.5.2 @@ -44,6 +47,9 @@ importers: npm-user: specifier: ^6.1.1 version: 6.1.1 + object-strings-deep: + specifier: ^0.1.1 + version: 0.1.1 octokit: specifier: ^4.0.2 version: 4.0.2 @@ -1965,6 +1971,11 @@ packages: resolution: {integrity: sha512-66n83Q7bK5tnvkDH7869/pBY/65AKmZVfCOAlsbhJn3YMDbNHFCHR0d1oNMlqG+n65Aco89VGwYfXxImZY+/mA==} engines: {node: '>=18'} + cspell-populate-words@0.2.2: + resolution: {integrity: sha512-F0RBfW96Ce/bWJiP2U6MpN31gOtDrUC4SGMJ52sV7UVbhz4WyPp6oqQEWN/ij7cAIfgMpYn9lvqcM/9iMNOWeg==} + engines: {node: '>=18.3.0'} + hasBin: true + cspell-trie-lib@8.17.1: resolution: {integrity: sha512-13WNa5s75VwOjlGzWprmfNbBFIfXyA7tYYrbV+LugKkznyNZJeJPojHouEudcLq3SYb2Q6tJ7qyWcuT5bR9qPA==} engines: {node: '>=18'} @@ -3278,6 +3289,10 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} + object-strings-deep@0.1.1: + resolution: {integrity: sha512-5ypgv3IIlt7v2pybSIcn1OcAQvJBtB2GrOXf1MAVNsMyQ/CYV9P5ZQPAsVrKTbZ0EMUHHMsSLbMc9SBHB57MxA==} + engines: {node: '>=18.3.0'} + octokit-from-auth@0.2.0: resolution: {integrity: sha512-UMo+WQkWi1PS/HZ15SMM1sgPhhXykqPJKCCAi6R0+JAhTbLBcfeKCJ3AwUVdJBJQKSQ37BUqPpME4iGAjZQtkw==} engines: {node: '>=18.3.0'} @@ -5980,6 +5995,10 @@ snapshots: vscode-uri: 3.0.8 xdg-basedir: 5.1.0 + cspell-populate-words@0.2.2: + dependencies: + cspell: 8.17.1 + cspell-trie-lib@8.17.1: dependencies: '@cspell/cspell-pipe': 8.17.1 @@ -7534,6 +7553,8 @@ snapshots: object-assign@4.1.1: {} + object-strings-deep@0.1.1: {} + octokit-from-auth@0.2.0: dependencies: get-github-auth-token: 0.1.0 diff --git a/src/next/blocks/blockCSpell.test.ts b/src/next/blocks/blockCSpell.test.ts index b8c885ae..6431025e 100644 --- a/src/next/blocks/blockCSpell.test.ts +++ b/src/next/blocks/blockCSpell.test.ts @@ -1,9 +1,13 @@ import { testBlock } from "create-testers"; -import { describe, expect, test } from "vitest"; +import { describe, expect, test, vi } from "vitest"; import { blockCSpell } from "./blockCSpell.js"; import { optionsBase } from "./options.fakes.js"; +vi.mock("../utils/resolveBin.js", () => ({ + resolveBin: (bin: string) => `path/to/${bin}`, +})); + describe("blockCSpell", () => { test("without addons", () => { const creation = testBlock(blockCSpell, { diff --git a/src/next/blocks/blockCSpell.ts b/src/next/blocks/blockCSpell.ts index f5274244..13099112 100644 --- a/src/next/blocks/blockCSpell.ts +++ b/src/next/blocks/blockCSpell.ts @@ -1,11 +1,14 @@ +import { getObjectStringsDeep } from "object-strings-deep"; import { z } from "zod"; import { base } from "../base.js"; +import { resolveBin } from "../utils/resolveBin.js"; import { blockDevelopmentDocs } from "./blockDevelopmentDocs.js"; import { blockGitHubActionsCI } from "./blockGitHubActionsCI.js"; import { blockPackageJson } from "./blockPackageJson.js"; import { blockVSCode } from "./blockVSCode.js"; import { getPackageDependencies } from "./packageData.js"; +import { CommandPhase } from "./phases.js"; const filesGlob = `"**" ".github/**/*"`; @@ -17,6 +20,22 @@ export const blockCSpell = base.createBlock({ ignores: z.array(z.string()).default([]), words: z.array(z.string()).default([]), }, + initialize({ options }) { + const wordArgs = getObjectStringsDeep(options) + .map((word) => `--words "${word.replaceAll(`"`, " ")}"`) + .join(" "); + + return { + scripts: [ + { + commands: [ + `node ${resolveBin("cspell-populate-words/bin/index.mjs")} ${wordArgs}`, + ], + phase: CommandPhase.Process, + }, + ], + }; + }, produce({ addons }) { const { ignores, words } = addons; diff --git a/src/next/utils/resolveBin.ts b/src/next/utils/resolveBin.ts new file mode 100644 index 00000000..c823553f --- /dev/null +++ b/src/next/utils/resolveBin.ts @@ -0,0 +1,3 @@ +export function resolveBin(bin: string) { + return import.meta.resolve(bin).replace(/^file:\/\//gu, ""); +} diff --git a/src/steps/uninstallPackages.ts b/src/steps/uninstallPackages.ts index 7e4386bf..ce5d5085 100644 --- a/src/steps/uninstallPackages.ts +++ b/src/steps/uninstallPackages.ts @@ -12,6 +12,7 @@ export async function uninstallPackages(offline: boolean | undefined) { "all-contributors-cli", "chalk", "create", + "cspell-populate-words", "execa", "git-remote-origin-url", "git-url-parse", @@ -20,6 +21,7 @@ export async function uninstallPackages(offline: boolean | undefined) { "js-yaml", "lazy-value", "npm-user", + "object-strings-deep", "octokit", "octokit-from-auth", "parse-author", diff --git a/src/steps/writing/creation/index.test.ts b/src/steps/writing/creation/index.test.ts index 90c5a768..c8e23a07 100644 --- a/src/steps/writing/creation/index.test.ts +++ b/src/steps/writing/creation/index.test.ts @@ -1,9 +1,13 @@ -import { describe, expect, it } from "vitest"; +import { describe, expect, it, vi } from "vitest"; import { getPackageDependencies } from "../../../next/blocks/packageData.js"; import { Options } from "../../../shared/types.js"; import { createStructure } from "./index.js"; +vi.mock("../../../next/utils/resolveBin.ts", () => ({ + resolveBin: (bin: string) => `path/to/${bin}`, +})); + /* eslint-disable @typescript-eslint/no-dynamic-delete */ const documentation = ` @@ -204,6 +208,7 @@ describe("createStructure", () => { "@prettier/sync", "chalk", "create", + "cspell-populate-words", "execa", "git-remote-origin-url", "git-url-parse", @@ -212,6 +217,7 @@ describe("createStructure", () => { "js-yaml", "lazy-value", "npm-user", + "object-strings-deep", "octokit", "octokit-from-auth", "parse-author",