diff --git a/.github/DEVELOPMENT.md b/.github/DEVELOPMENT.md index 55e6aab5b..48da423e3 100644 --- a/.github/DEVELOPMENT.md +++ b/.github/DEVELOPMENT.md @@ -13,7 +13,7 @@ pnpm install ## Building -Run [[**tsup**](https://tsup.egoist.dev) locally to build source files from `src/` into output files in `lib/`: +Run [**tsup**](https://tsup.egoist.dev) locally to build source files from `src/` into output files in `lib/`: ```shell pnpm build @@ -87,47 +87,81 @@ Add `--watch` to keep the type checker running in a watch mode that updates the pnpm tsc --watch ``` -## The Hydration Script +## Setup Scripts -This template's "hydration" script is located in `src/hydrate/`. -It needs to be [built](#building) before it can be run. +As described in the `README.md` file and `docs/`, this template repository comes with two scripts that can set up an existing or new repository. -Be warned that running the hydration script in a repository -including this one- will modify that repository. -To test out the script, you may want to create a new test repository to run on: +> **Warning** +> Both setup scripts override many files in the directory they're run in. +> Make sure to save any changes you want to preserve before running them. + +### The Initialization Script + +This template's "initialization" script is located in `src/initialize/`. +You can run it locally with `pnpm run initialize`. +It uses [`tsx`](https://github.com/esbuild-kit/tsx) so you don't need to build files before running. ```shell -cd .. -mkdir temp -cd temp -echo node_modules > .gitignore -git init -npm init --yes +pnpm run initialize ``` -Then, in that directory, you can directly call the hydration script: +> 💡 Consider running `git add -A` to stage all local changes before running. + +#### Testing the Initialization Script + +You can run the end-to-end test for initializing locally on the command-line. +Note that files need to be built with `pnpm run build` beforehand. ```shell -node ../template-typescript-node-package/lib/hydrate/index.js -- description "Hooray, trying things out locally." +pnpm run initialize:test ``` -Along with the hydration script itself, end-to-end tests are removed on package setup. +That end-to-end test executes `script/initialize-test-e2e.js`, which: -## The Setup Script +1. Runs the initialization script using `--skip-github-api` and other skip flags +2. Checks that the local repository's files were changed correctly (e.g. removed initialization-only files) +3. Runs `pnpm run lint:knip` to make sure no excess dependencies or files were left over +4. Resets everything +5. Runs initialization a second time, capturing test coverage -This template's "setup" script is located in `script/`. +The `pnpm run initialize:test` script is run in CI to ensure that templating changes are in sync with the template's actual files. +See `.github/workflows/test-initialize.yml`. -### Testing the Setup Script +### The Migration Script -This template source includes an "end-to-end" test for `script/setup.js`. -You can run it locally on the command-line: +This template's "migration" script is located in `src/migrate/`. +Note that files need to be built with `pnpm run build` beforehand. + +To test out the script locally, run it from a different repository's directory: + +```shell +cd ../other-repo +node ../template-typescript-node-package/bin/migrate.js +``` + +The migration script will work on any directory. +You can try it out in a blank directory with scripts like: + +```shell +cd .. +mkdir temp +cd temp +node ../template-typescript-node-package/bin/migrate.js +``` + +#### Testing the Migration Script + +You can run the end-to-end test for migrating locally on the command-line: ```shell -pnpm run setup:test +pnpm run initiamigratelize:test ``` -That end-to-end test executes `script/setup-test-e2e.js`, which: +That end-to-end test executes `script/migrate-test-e2e.js`, which: -1. Runs the setup script using `--skip-api` -2. Checks that the local repository's files were changed correctly (e.g. removed setup-only files) +1. Runs the migration script using `--skip-github-api` and other skip flags +2. Checks that only a small list of allowed files were changed +3. Checks that the local repository's files were changed correctly (e.g. removed initialization-only files) -Along with the setup script itself, end-to-end tests are removed on package setup. +The `pnpm run migrate:test` script is run in CI to ensure that templating changes are in sync with the template's actual files. +See `.github/workflows/test-migrate.yml`. diff --git a/.github/workflows/setup.yml b/.github/workflows/test-initialize.yml similarity index 67% rename from .github/workflows/setup.yml rename to .github/workflows/test-initialize.yml index 27f18c6a5..495a949d9 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/test-initialize.yml @@ -1,23 +1,23 @@ jobs: - setup: + initialize: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: ./.github/actions/prepare - run: pnpm run build - - run: pnpm run setup:test + - run: pnpm run initialize:test - name: Codecov uses: codecov/codecov-action@v3 with: - files: coverage-setup/lcov.info - flags: setup + files: coverage-initialize/lcov.info + flags: initialize - if: always() name: Archive code coverage results uses: actions/upload-artifact@v3 with: - path: coverage-setup + path: coverage-initialize -name: Test Setup Script +name: Test Initialization Script on: pull_request: ~ diff --git a/.github/workflows/hydrate.yml b/.github/workflows/test-migrate.yml similarity index 69% rename from .github/workflows/hydrate.yml rename to .github/workflows/test-migrate.yml index 6e700c8c7..9735590c0 100644 --- a/.github/workflows/hydrate.yml +++ b/.github/workflows/test-migrate.yml @@ -1,23 +1,23 @@ jobs: - hydrate: + migrate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: ./.github/actions/prepare - run: pnpm run build - - run: pnpm run hydrate:test + - run: pnpm run migrate:test - name: Codecov uses: codecov/codecov-action@v3 with: - files: coverage-hydrate/lcov.info - flags: hydrate + files: coverage-migrate/lcov.info + flags: migrate - if: always() name: Archive code coverage results uses: actions/upload-artifact@v3 with: - path: coverage-hydrate + path: coverage-migrate -name: Test Hydrate Script +name: Test Migration Script on: pull_request: ~ diff --git a/README.md b/README.md index 38c12b09f..64b68ca41 100644 --- a/README.md +++ b/README.md @@ -26,9 +26,23 @@ TypeScript: Strict 💪

+## Getting Started + +First make sure you have the following installed: + +- [GitHub CLI](https://cli.github.com) _(you'll need to be logged in)_ +- [Node.js](https://nodejs.org) +- [pnpm](https://pnpm.io) + +This repository comes with two scripts to set up an existing or new repository with tooling. +Use the corresponding docs page to get started: + +- [Initializing from the template](./docs/Initialization.md): creating a new repository with the [_Use this template_](https://github.com/JoshuaKGoldberg/template-typescript-node-package/generate) button on GitHub +- [Migrating an existing repository](./docs/Migration.md): adding this template's tooling on top of an existing repository + ## Explainer -This template is available for anybody who wants to set up a basic Node application using TypeScript. +This template is available for anybody who wants to set up a Node application using TypeScript. It sets up the following tooling for you: - [**All Contributors**](https://allcontributors.org): Tracks various kinds of contributions and displays them in a nicely formatted table in the README.md. @@ -44,112 +58,6 @@ It sets up the following tooling for you: - [**TypeScript**](https://typescriptlang.org): A typed superset of JavaScript, configured with strict compiler options. - [**Vitest**](https://vitest.dev): Fast unit tests, configured with coverage tracking and [console-fail-test](https://github.com/JoshuaKGoldberg/console-fail-test). -## Setup - -This package comes with a bootstrap/initialization setup script that fills out your repository's details, installs necessary packages, then removes itself and uninstalls setup dependencies. - -First make sure you have the following installed: - -- [GitHub CLI](https://cli.github.com) _(you'll need to be logged in)_ -- [Node.js](https://nodejs.org) -- [pnpm](https://pnpm.io) - -To use this template: - -1. Click the [_Use this template_](https://github.com/JoshuaKGoldberg/template-typescript-node-package/generate) button to create a new repository with the same Git history -2. Open that repository, such as by [cloning it locally](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) or [developing in a codespace](https://docs.github.com/en/codespaces/developing-in-codespaces/developing-in-a-codespace) -3. Create two tokens in [repository secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets): - - `ACCESS_TOKEN`: A [GitHub PAT](https://github.com/settings/tokens/new) with _repo_ and _workflow_ permissions - - `NPM_TOKEN`: An [npm access token](https://docs.npmjs.com/creating-and-viewing-access-tokens/) with _Automation_ permissions -4. `pnpm install` -5. `pnpm run setup` to run the setup script -6. Install the [Codecov GitHub App](https://github.com/marketplace/codecov) and [Renovate GitHub App](https://github.com/marketplace/renovate) - -> The setup script removes the `## Explainer`, `## Setup`, and `## Repository Hydration` sections from this README.md. - -### Setup Options - -The setup script requires four options to fill out repository details. -It will interactively prompt for any that are not provided as a string CLI flag: - -1. `repository`: The kebab-case name of the repository (e.g. `template-typescript-node-package`) -2. `title`: Title Case title for the repository to be used in documentation (e.g. `Template TypeScript Node Package`) -3. `owner`: GitHub organization or user the repository is underneath (e.g. `JoshuaKGoldberg`) -4. `description`: Sentence case description of the repository (e.g. `A quickstart-friendly TypeScript package with lots of great repository tooling. ✨`) - -Additionally, a `--skip-api` boolean CLI flag may be specified to prevent the setup script from calling to GitHub APIs for repository hydration. -The script normally posts to GitHub APIs to set information such as repository description and branch protections on github.com. -Specifying `--skip-api` prevents those API calls, effectively limiting setup changes to local files in Git. -Doing so can be useful to preview what running setup does. - -For example, pre-populating all values and skipping API calls: - -```shell -pnpm run setup --repository "testing-repository" --title "Testing Title" --owner "TestingOwner" --description "Test Description" --skip-api -``` - -> Tip: after running `pnpm run setup` with `--skip-api`, you can always `git add -A; git reset --hard HEAD` to completely reset all changes. - -## Repository Hydration - -> **Warning** -> Hydration will override many files in your repository. -> You'll want to review each of the changes and make sure nothing important is removed. - -Alternately, if you have an existing repository that you'd like to give the files from this repository, you can run `template-typescript-node-package` in a repository to "hydrate" it. - -```shell -npx template-typescript-node-package -``` - -Repository settings will be auto-filled from the repository's files if possible, but can be provided manually as well: - -- `author` _(`string`)_: e.g. `"Josh Goldberg"` -- `description` _(`string`)_: e.g. `"A quickstart-friendly TypeScript template with comprehensive formatting, linting, releases, testing, and other great tooling built-in. ✨"` -- `email` _(`string`)_: e.g. `"git@joshuakgoldberg.com"` -- `funding` _(`string`, optional)_: e.g. `"JoshuaKGoldberg"` -- `owner` _(`string`)_: e.g. `"JoshuaKGoldberg"` -- `repository` _(`string`)_: e.g. `"template-typescript-node-package"` -- `title` _(`string`)_: e.g. `"Template TypeScript Node Package"` - -For example, providing a `funding` value different from the `author`: - -```shell -npx template-typescript-node-package --funding MyOrganization -``` - -The hydration script by default will include all the features in this template. -You can disable some of them on the command-line: - -- `releases` _(`boolean`)_: Whether to include automated package publishing -- `unitTests` _(`boolean`)_: Whether to include unit tests with code coverage tracking - -```shell -npx template-typescript-node-package --releases false --unitTests false -``` - -You can prevent the hydration script from making network-based changes using either or both of the following CLI flags: - -- `--skip-contributors` _(`boolean`)_: Skips detecting existing contributors with [`all-contributors-for-repository`](https://github.com/JoshuaKGoldberg/all-contributors-for-repository) -- `--skip-install` _(`boolean`)_: Skips installing all the new template packages with `pnpm` -- `--skip-setup` _(`boolean`)_: Skips running the setup script at the end of hydration - -```shell -npx template-typescript-node-package --skip-install --skip-setup -``` - -## Usage - -```shell -npm i template-typescript-node-package -``` - -```ts -import { greet } from "template-typescript-node-package"; - -greet("Hello, world!"); -``` - ## Development See [`.github/CONTRIBUTING.md`](./.github/CONTRIBUTING.md), then [`.github/DEVELOPMENT.md`](./.github/DEVELOPMENT.md). diff --git a/bin/hydrate.js b/bin/hydrate.js deleted file mode 100644 index 7331e50d2..000000000 --- a/bin/hydrate.js +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env node -import { hydrate } from "../lib/hydrate/index.js"; - -process.exitCode = await hydrate(process.argv.slice(2)); diff --git a/bin/migrate.js b/bin/migrate.js new file mode 100755 index 000000000..4b4ec80b9 --- /dev/null +++ b/bin/migrate.js @@ -0,0 +1,4 @@ +#!/usr/bin/env node +import { migrate } from "../lib/migrate/index.js"; + +process.exitCode = await migrate(process.argv.slice(2)); diff --git a/docs/FAQs.md b/docs/FAQs.md new file mode 100644 index 000000000..ddfa62ea2 --- /dev/null +++ b/docs/FAQs.md @@ -0,0 +1,22 @@ +# FAQs + +## Can I use <insert tool here> with this template? + +Yes! +After you set up a repository, you can substitute in any tools you'd like. + +If you think the tool would be broadly useful to most consumers of this template, feel free to [file a feature request](https://github.com/JoshuaKGoldberg/template-typescript-node-package/issues/new?assignees=&labels=type%3A+feature&projects=&template=03-feature.yml&title=%F0%9F%9A%80+Feature%3A+%3Cshort+description+of+the+feature%3E) to add it in. + +## Is there a way to pull in template updates to previously created repositories? + +Not yet. +You can always copy & paste them in manually. + +See [🚀 Feature: Add a script to sync the tooling updates from forked template repo #498](https://github.com/JoshuaKGoldberg/template-typescript-node-package/issues/498): it will likely eventually be possible. + +## Why does this package include so many tools? + +This repository is meant to serve as a starter that includes all the general tooling a modern TypeScript/Node repository could possibly need. +Each of the included tools exists for a good reason and provides real value. + +If you don't want to use any particular tool, you can always remove it manually. diff --git a/docs/Initialization.md b/docs/Initialization.md new file mode 100644 index 000000000..a8a2d839a --- /dev/null +++ b/docs/Initialization.md @@ -0,0 +1,58 @@ +# Initializing from the Template + +The [_Use this template_](https://github.com/JoshuaKGoldberg/template-typescript-node-package/generate) button on GitHub can be used to quickly create a new repository. +After creating the new repository, you can set it up locally by cloning it and installing packages: + +```shell +git clone https://github.com/YourUsername/YourRepositoryName +cd YourRepositoryName +pnpm i +``` + +> 💡 If you don't want to `git clone` it locally, you can always [develop in a codespace](https://docs.github.com/en/codespaces/developing-in-codespaces/developing-in-a-codespace) instead. + +## The Initialization Script + +Once the repository's packages are installed, you can run `pnpm run initialize` to fill out your repository's details and install necessary packages. +It will then remove itself and uninstall dependencies only used for initialization. + +```shell +pnpm run initialize +``` + +The initialization script will interactively prompt for values to be used in creating the new repository. +Each may provided as a string CLI flag as well: + +- `--description`: Sentence case description of the repository (e.g. `A quickstart-friendly TypeScript package with lots of great repository tooling. ✨`) +- `--owner`: GitHub organization or user the repository is underneath (e.g. `JoshuaKGoldberg`) +- `--repository`: The kebab-case name of the repository (e.g. `template-typescript-node-package`) +- `--title`: Title Case title for the repository to be used in documentation (e.g. `Template TypeScript Node Package`) + +For example, pre-populating all values: + +```shell +pnpm run initialize --repository "testing-repository" --title "Testing Title" --owner "TestingOwner" --description "Test Description" +``` + +Then, go through the following two steps to set up required repository tooling on GitHub: + +1. Create two tokens in [repository secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets): + - `ACCESS_TOKEN`: A [GitHub PAT](https://github.com/settings/tokens/new) with _repo_ and _workflow_ permissions + - `NPM_TOKEN`: An [npm access token](https://docs.npmjs.com/creating-and-viewing-access-tokens/) with _Automation_ permissions +2. Install the [Codecov GitHub App](https://github.com/marketplace/codecov) and [Renovate GitHub App](https://github.com/marketplace/renovate) + +At this point, your new repository should be ready for development! 🥳 + +### Skipping API Calls + +The initialization script normally posts to GitHub APIs to set repository information such as repository description and branch protections on github.com. +You can skip those API calls by specifying `--skip-github-api`. + +For example, pre-populating all values and skipping API calls: + +```shell +pnpm run initialize --repository "testing-repository" --title "Testing Title" --owner "TestingOwner" --description "Test Description" --skip-github-api +``` + +> Tip: the `--skip-github-api` flag will cause all changes to be limited to your local repository. +> That means you can test out the script with `pnpm run initialize --skip-github-api`, then `git add -A; git reset --hard HEAD` to completely reset all changes. diff --git a/docs/Migration.md b/docs/Migration.md new file mode 100644 index 000000000..8d7628de4 --- /dev/null +++ b/docs/Migration.md @@ -0,0 +1,59 @@ +# Migrating an Existing Repository + +If you have an existing repository that you'd like to give the files from this repository, you can run `npx template-typescript-node-package` in it to "hydrate" its tooling with this template's. + +```shell +npx template-typescript-node-package +``` + +> **Warning** +> Migration will override many files in your repository. +> You'll want to review each of the changes. +> There will almost certainly be some incorrect changes you'll need to fix. + +## Values + +Repository settings will be auto-filled from the repository's files if possible, but can be provided manually as well: + +- `--author` _(`string`)_: e.g. `"Josh Goldberg"` +- `--description` _(`string`)_: e.g. `"A quickstart-friendly TypeScript template with comprehensive formatting, linting, releases, testing, and other great tooling built-in. ✨"` +- `--email` _(`string`)_: e.g. `"git@joshuakgoldberg.com"` +- `--funding` _(`string`, optional)_: e.g. `"JoshuaKGoldberg"` +- `--owner` _(`string`)_: e.g. `"JoshuaKGoldberg"` +- `--repository` _(`string`)_: e.g. `"template-typescript-node-package"` +- `--title` _(`string`)_: e.g. `"Template TypeScript Node Package"` + +For example, providing a `funding` value different from the `author`: + +```shell +npx template-typescript-node-package --funding MyOrganization +``` + +The migration script by default will include all the features in this template. +You can disable some of them on the command-line: + +- `releases` _(`boolean`)_: Whether to include automated package publishing +- `unitTests` _(`boolean`)_: Whether to include unit tests with code coverage tracking + +```shell +npx template-typescript-node-package --releases false --unitTests false +``` + +After the migration script finishes aligning your repository's contents to the templates, it will call the [Initialization](./Initialization.md) script as well. +It will forward any values you provided or it inferred from the repository. + +### Skipping API Calls + +You can prevent the migration script from making some network-based changes using any or all of the following CLI flags: + +- `--skip-contributors` _(`boolean`)_: Skips detecting existing contributors with [`all-contributors-for-repository`](https://github.com/JoshuaKGoldberg/all-contributors-for-repository) +- `--skip-github-api` _(`boolean`)_: Skips calling to GitHub APIs +- `--skip-install` _(`boolean`)_: Skips installing all the new template packages with `pnpm` +- `--skip-initialize` _(`boolean`)_: Skips running the initialize script at the end of migration + +```shell +npx template-typescript-node-package --skip-github-api --skip-initialize --skip-install +``` + +> Tip: the `--skip-github-api` flag will cause all changes to be limited to your local repository. +> That means you can test out the script with `npx template-typescript-node-package --skip-github-api`, then `git add -A; git reset --hard HEAD` to completely reset all changes. diff --git a/knip.jsonc b/knip.jsonc index 5a6ffc7db..6cae45405 100644 --- a/knip.jsonc +++ b/knip.jsonc @@ -2,8 +2,8 @@ "$schema": "https://unpkg.com/knip@latest/schema.json", "entry": [ "src/index.ts!", - "src/hydrate/index.ts", - "src/setup/index.ts", + "src/initialize/index.ts", + "src/migrate/index.ts", "script/*e2e.js" ], "ignoreBinaries": ["gh"], diff --git a/package.json b/package.json index c45871cc7..135648c58 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ }, "type": "module", "main": "./lib/index.js", - "bin": "./bin/hydrate.js", + "bin": "./bin/migrate.js", "files": [ "bin/", "lib/", @@ -25,16 +25,16 @@ "build": "tsup", "format": "prettier \"**/*\" --ignore-unknown", "format:write": "pnpm format --write", - "hydrate:test": "node script/hydrate-test-e2e.js", + "initialize": "tsx src/initialize/index.ts", + "initialize:test": "node script/initialize-test-e2e.js", "lint": "eslint . .*js --max-warnings 0 --report-unused-disable-directives", "lint:knip": "knip", "lint:md": "markdownlint \"**/*.md\" \".github/**/*.md\" --rules sentences-per-line", "lint:package": "npmPkgJsonLint .", "lint:packages": "pnpm dedupe --check", "lint:spelling": "cspell \"**\" \".github/**/*\"", + "migrate:test": "node script/migrate-test-e2e.js", "prepare": "husky install", - "setup": "tsx src/setup/index.ts", - "setup:test": "node script/setup-test-e2e.js", "should-semantic-release": "should-semantic-release --verbose", "test": "vitest" }, diff --git a/script/setup-test-e2e.js b/script/initialize-test-e2e.js similarity index 69% rename from script/setup-test-e2e.js rename to script/initialize-test-e2e.js index ecc83663f..ba252e336 100644 --- a/script/setup-test-e2e.js +++ b/script/initialize-test-e2e.js @@ -8,10 +8,10 @@ const owner = "RNR1"; const title = "New Title Test"; const repository = "new-repository-test"; -// First we run setup to modifies the local repo, so we can test the changes +// First we run initialize to modifies the local repo, so we can test the changes await $({ stdio: "inherit", -})`node ./lib/setup/index.js --description ${description} --owner ${owner} --title ${title} --repository ${repository} --skip-api --skip-restore`; +})`node ./lib/initialize/index.js --description ${description} --owner ${owner} --title ${title} --repository ${repository} --skip-github-api --skip-restore`; const newPackageJson = JSON.parse( (await fs.readFile("./package.json")).toString(), @@ -23,7 +23,7 @@ assert.equal(newPackageJson.name, repository); const files = await globby(["*.*", "**/*.*"], { gitignore: true, - ignoreFiles: ["script/setup.js", "script/setup-test-e2e.js"], + ignoreFiles: ["script/initialize-test-e2e.js"], }); for (const search of [ @@ -44,7 +44,7 @@ try { process.exitCode = 1; } -// Now that setup has passed normal steps, we reset everything, +// Now that initialize has passed normal steps, we reset everything, // then run again without removing files - so we can capture test coverage await $`git add -A`; await $`git reset --hard HEAD`; @@ -52,4 +52,4 @@ await $`pnpm i`; await $`pnpm run build`; await $({ stdio: "inherit", -})`c8 -o ./coverage-setup -r html -r lcov node ./lib/setup/index.js --description ${description} --owner ${owner} --title ${title} --repository ${repository} --skip-api --skip-removal --skip-restore`; +})`c8 -o ./coverage-initialize -r html -r lcov node ./lib/initialize/index.js --description ${description} --owner ${owner} --title ${title} --repository ${repository} --skip-github-api --skip-removal --skip-restore`; diff --git a/script/hydrate-test-e2e.js b/script/migrate-test-e2e.js similarity index 82% rename from script/hydrate-test-e2e.js rename to script/migrate-test-e2e.js index 6d1484057..5056cc2a4 100644 --- a/script/hydrate-test-e2e.js +++ b/script/migrate-test-e2e.js @@ -9,7 +9,7 @@ const title = "Template TypeScript Node Package"; await $({ stdio: "inherit", -})`c8 -o ./coverage-hydrate -r html -r lcov node ./bin/hydrate.js --description ${description} --owner ${owner} --title ${title} --repository ${repository} --skip-api --skip-contributors --skip-install --skip-setup`; +})`c8 -o ./coverage-migrate -r html -r lcov node ./bin/migrate.js --description ${description} --owner ${owner} --title ${title} --repository ${repository} --skip-github-api --skip-contributors --skip-initialize --skip-install`; const { stdout: gitStatus } = await $`git status`; console.log(`Stdout from running \`git status\`:\n${gitStatus}`); @@ -19,7 +19,7 @@ const indexOfUnstagedFilesMessage = gitStatus.indexOf( ); if (indexOfUnstagedFilesMessage === -1) { throw new Error( - `Looks like hydrate didn't cause any file changes? That's ...probably incorrect? 😬`, + `Looks like migrate didn't cause any file changes? That's ...probably incorrect? 😬`, ); } @@ -60,13 +60,13 @@ if (unstagedModifiedFiles.length) { console.error( [ "", - "Oh no! Running the hydrate script modified some files:", + "Oh no! Running the migrate script modified some files:", ...unstagedModifiedFiles.map((filePath) => ` - ${filePath}`), "", "That likely indicates changes made to the repository without", - "corresponding updates to templates in src/hydrate/creation.", + "corresponding updates to templates in src/migrate/creation.", "", - "Please search for those file(s)' name(s) under src/hydrate for", + "Please search for those file(s)' name(s) under src/migrate for", "the corresponding template and update those as well.", ] .map((line) => chalk.red(line)) diff --git a/src/initialize/index.ts b/src/initialize/index.ts new file mode 100644 index 000000000..4bad0282f --- /dev/null +++ b/src/initialize/index.ts @@ -0,0 +1,3 @@ +import { initialize } from "./initialize.js"; + +process.exitCode = await initialize(process.argv.slice(2)); diff --git a/src/initialize/initialize.ts b/src/initialize/initialize.ts new file mode 100644 index 000000000..67f25c3e1 --- /dev/null +++ b/src/initialize/initialize.ts @@ -0,0 +1,10 @@ +import { runOrRestore } from "../shared/runOrRestore.js"; +import { initializeWithInformation } from "./initializeWithInformation.js"; + +export async function initialize(args: string[]) { + return await runOrRestore({ + args, + label: "initialization", + run: initializeWithInformation, + }); +} diff --git a/src/setup/setupWithInformation.ts b/src/initialize/initializeWithInformation.ts similarity index 73% rename from src/setup/setupWithInformation.ts rename to src/initialize/initializeWithInformation.ts index e843df7fe..0a94ca016 100644 --- a/src/setup/setupWithInformation.ts +++ b/src/initialize/initializeWithInformation.ts @@ -7,9 +7,9 @@ import { getNpmAuthor } from "../shared/getNpmAuthor.js"; import { InputValuesAndOctokit } from "../shared/inputs.js"; import { addOwnerAsAllContributor } from "./settings/addOwnerAsAllContributor.js"; import { clearChangelog } from "./steps/clearChangelog.js"; -import { hydrateBranchProtectionSettings } from "./steps/hydrateBranchProtectionSettings.js"; -import { hydrateRepositorySettings } from "./steps/hydrateRepositorySettings.js"; -import { hydrateRepositoryLabels } from "./steps/labels/hydrateRepositoryLabels.js"; +import { migrateRepositoryLabels } from "./steps/labels/migrateRepositoryLabels.js"; +import { migrateBranchProtectionSettings } from "./steps/migrateBranchProtectionSettings.js"; +import { migrateRepositorySettings } from "./steps/migrateRepositorySettings.js"; import { removeSetupScripts } from "./steps/removeSetupScripts.js"; import { resetGitTags } from "./steps/resetGitTags.js"; import { uninstallPackages } from "./steps/uninstallPackages.js"; @@ -17,11 +17,11 @@ import { updateAllContributorsTable } from "./steps/updateAllContributorsTable.j import { updateLocalFiles } from "./steps/updateLocalFiles.js"; import { updateReadme } from "./steps/updateReadme.js"; -export async function setupWithInformation({ +export async function initializeWithInformation({ octokit, values, }: InputValuesAndOctokit) { - successSpinnerBlock("Started hydrating package metadata locally."); + successSpinnerBlock("Started migrating package metadata locally."); await withSpinner(async () => { await addOwnerAsAllContributor(values.owner); @@ -38,7 +38,7 @@ export async function setupWithInformation({ "Appending template-typescript-node-package notice to 'README.md'", ); - successSpinnerBlock(`Finished hydrating package metadata locally.`); + successSpinnerBlock(`Finished migrating package metadata locally.`); await withSpinner(clearChangelog, "clearing CHANGELOG.md"); @@ -49,23 +49,23 @@ export async function setupWithInformation({ await withSpinner(resetGitTags, "deleting local git tags..."); if (!octokit) { - skipSpinnerBlock(`Skipping API hydration.`); + skipSpinnerBlock(`Skipping API migration.`); } else { - successSpinnerBlock(`Starting API hydration.`); + successSpinnerBlock(`Starting API migration.`); - await withSpinner(hydrateRepositoryLabels, "hydrating repository labels"); + await withSpinner(migrateRepositoryLabels, "migrating repository labels"); await withSpinner(async () => { - await hydrateRepositorySettings(octokit, values); - }, "hydrating initial repository settings"); + await migrateRepositorySettings(octokit, values); + }, "migrating initial repository settings"); await withSpinner( - () => hydrateBranchProtectionSettings(octokit, values), - "hydrating branch protection settings", + () => migrateBranchProtectionSettings(octokit, values), + "migrating branch protection settings", "private repositories require GitHub Pro for that API.", ); - successSpinnerBlock(`Finished API hydration.`); + successSpinnerBlock(`Finished API migration.`); } if (values.skipRemoval) { diff --git a/src/setup/settings/addOwnerAsAllContributor.ts b/src/initialize/settings/addOwnerAsAllContributor.ts similarity index 100% rename from src/setup/settings/addOwnerAsAllContributor.ts rename to src/initialize/settings/addOwnerAsAllContributor.ts diff --git a/src/setup/steps/clearChangelog.ts b/src/initialize/steps/clearChangelog.ts similarity index 100% rename from src/setup/steps/clearChangelog.ts rename to src/initialize/steps/clearChangelog.ts diff --git a/src/setup/steps/labels/getExistingEquivalentLabel.test.ts b/src/initialize/steps/labels/getExistingEquivalentLabel.test.ts similarity index 100% rename from src/setup/steps/labels/getExistingEquivalentLabel.test.ts rename to src/initialize/steps/labels/getExistingEquivalentLabel.test.ts diff --git a/src/setup/steps/labels/getExistingEquivalentLabel.ts b/src/initialize/steps/labels/getExistingEquivalentLabel.ts similarity index 100% rename from src/setup/steps/labels/getExistingEquivalentLabel.ts rename to src/initialize/steps/labels/getExistingEquivalentLabel.ts diff --git a/src/setup/steps/labels/hydrateRepositoryLabels.test.ts b/src/initialize/steps/labels/migrateRepositoryLabels.test.ts similarity index 87% rename from src/setup/steps/labels/hydrateRepositoryLabels.test.ts rename to src/initialize/steps/labels/migrateRepositoryLabels.test.ts index b7d2e2ad8..ba3190bb0 100644 --- a/src/setup/steps/labels/hydrateRepositoryLabels.test.ts +++ b/src/initialize/steps/labels/migrateRepositoryLabels.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from "vitest"; -import { hydrateRepositoryLabels } from "./hydrateRepositoryLabels.js"; +import { migrateRepositoryLabels } from "./migrateRepositoryLabels.js"; const mock$ = vi.fn(); @@ -20,7 +20,7 @@ vi.mock("./outcomeLabels.js", () => ({ ], })); -describe("hydrateRepositoryLabels", () => { +describe("migrateRepositoryLabels", () => { it("creates a setup label when it doesn't already exist", async () => { mock$.mockResolvedValue({ stdout: JSON.stringify([ @@ -32,7 +32,7 @@ describe("hydrateRepositoryLabels", () => { ]), }); - await hydrateRepositoryLabels(); + await migrateRepositoryLabels(); expect(mock$).toHaveBeenCalledWith( ["gh label ", " ", " --color ", " --description ", ""], @@ -54,7 +54,7 @@ describe("hydrateRepositoryLabels", () => { ]), }); - await hydrateRepositoryLabels(); + await migrateRepositoryLabels(); expect(mock$).toHaveBeenCalledWith( ["gh label ", " ", " --color ", " --description ", ""], @@ -76,7 +76,7 @@ describe("hydrateRepositoryLabels", () => { ]), }); - await hydrateRepositoryLabels(); + await migrateRepositoryLabels(); expect(mock$).toHaveBeenCalledWith( ["gh label delete ", " --yes"], @@ -96,7 +96,7 @@ describe("hydrateRepositoryLabels", () => { ]), }); - await hydrateRepositoryLabels(); + await migrateRepositoryLabels(); expect(mock$).not.toHaveBeenCalledWith( ["gh label delete ", " --yes"], diff --git a/src/setup/steps/labels/hydrateRepositoryLabels.ts b/src/initialize/steps/labels/migrateRepositoryLabels.ts similarity index 95% rename from src/setup/steps/labels/hydrateRepositoryLabels.ts rename to src/initialize/steps/labels/migrateRepositoryLabels.ts index 80ae535ad..ec2991b08 100644 --- a/src/setup/steps/labels/hydrateRepositoryLabels.ts +++ b/src/initialize/steps/labels/migrateRepositoryLabels.ts @@ -7,7 +7,7 @@ interface GhLabelData { name: string; } -export async function hydrateRepositoryLabels() { +export async function migrateRepositoryLabels() { const getLabelName = (label: { name: string }) => label.name; const existingLabels = ( diff --git a/src/setup/steps/labels/outcomeLabels.ts b/src/initialize/steps/labels/outcomeLabels.ts similarity index 100% rename from src/setup/steps/labels/outcomeLabels.ts rename to src/initialize/steps/labels/outcomeLabels.ts diff --git a/src/setup/steps/hydrateBranchProtectionSettings.test.ts b/src/initialize/steps/migrateBranchProtectionSettings.test.ts similarity index 79% rename from src/setup/steps/hydrateBranchProtectionSettings.test.ts rename to src/initialize/steps/migrateBranchProtectionSettings.test.ts index 08f8b1bee..c3dea9c74 100644 --- a/src/setup/steps/hydrateBranchProtectionSettings.test.ts +++ b/src/initialize/steps/migrateBranchProtectionSettings.test.ts @@ -1,7 +1,7 @@ import { Octokit } from "octokit"; import { SpyInstance, describe, expect, it, vi } from "vitest"; -import { hydrateBranchProtectionSettings } from "./hydrateBranchProtectionSettings.js"; +import { migrateBranchProtectionSettings } from "./migrateBranchProtectionSettings.js"; const createMockOctokit = (request: SpyInstance) => ({ @@ -10,11 +10,11 @@ const createMockOctokit = (request: SpyInstance) => const stubValues = { owner: "", repository: "" }; -describe("hydrateBranchProtectionSettings", () => { +describe("migrateBranchProtectionSettings", () => { it("returns false when the request receives a 403 response", async () => { const mockRequest = vi.fn().mockRejectedValue({ status: 403 }); - const actual = await hydrateBranchProtectionSettings( + const actual = await migrateBranchProtectionSettings( createMockOctokit(mockRequest), stubValues, ); @@ -27,7 +27,7 @@ describe("hydrateBranchProtectionSettings", () => { const mockRequest = vi.fn().mockRejectedValue(error); await expect(() => - hydrateBranchProtectionSettings( + migrateBranchProtectionSettings( createMockOctokit(mockRequest), stubValues, ), diff --git a/src/setup/steps/hydrateBranchProtectionSettings.ts b/src/initialize/steps/migrateBranchProtectionSettings.ts similarity index 95% rename from src/setup/steps/hydrateBranchProtectionSettings.ts rename to src/initialize/steps/migrateBranchProtectionSettings.ts index 0798a5c13..13a62e8c6 100644 --- a/src/setup/steps/hydrateBranchProtectionSettings.ts +++ b/src/initialize/steps/migrateBranchProtectionSettings.ts @@ -3,7 +3,7 @@ import { Octokit } from "octokit"; import { InputValues } from "../../shared/inputs.js"; -export async function hydrateBranchProtectionSettings( +export async function migrateBranchProtectionSettings( octokit: Octokit, { owner, repository }: Pick, ) { diff --git a/src/setup/steps/hydrateRepositorySettings.ts b/src/initialize/steps/migrateRepositorySettings.ts similarity index 81% rename from src/setup/steps/hydrateRepositorySettings.ts rename to src/initialize/steps/migrateRepositorySettings.ts index 6c9545658..1eebfe887 100644 --- a/src/setup/steps/hydrateRepositorySettings.ts +++ b/src/initialize/steps/migrateRepositorySettings.ts @@ -2,14 +2,14 @@ import { Octokit } from "octokit"; import { InputValues } from "../../shared/inputs.js"; -type HydrateRepositoryValues = Pick< +type MigrateRepositoryValues = Pick< InputValues, "description" | "owner" | "repository" >; -export async function hydrateRepositorySettings( +export async function migrateRepositorySettings( octokit: Octokit, - { description, owner, repository }: HydrateRepositoryValues, + { description, owner, repository }: MigrateRepositoryValues, ) { await octokit.rest.repos.update({ allow_auto_merge: true, diff --git a/src/setup/steps/removeSetupScripts.ts b/src/initialize/steps/removeSetupScripts.ts similarity index 65% rename from src/setup/steps/removeSetupScripts.ts rename to src/initialize/steps/removeSetupScripts.ts index 71847d1ff..ec5cf62fe 100644 --- a/src/setup/steps/removeSetupScripts.ts +++ b/src/initialize/steps/removeSetupScripts.ts @@ -2,12 +2,13 @@ import fs from "node:fs/promises"; const globPaths = [ "./bin", + "./docs", "./script", - "./src/hydrate", - "./src/setup", + "./src/initialize", + "./src/migrate", "./src/shared", - ".github/workflows/hydrate.yml", - ".github/workflows/setup.yml", + ".github/workflows/test-initialize.yml", + ".github/workflows/test-migrate.yml", ]; export async function removeSetupScripts() { diff --git a/src/setup/steps/resetGitTags.ts b/src/initialize/steps/resetGitTags.ts similarity index 100% rename from src/setup/steps/resetGitTags.ts rename to src/initialize/steps/resetGitTags.ts diff --git a/src/setup/steps/uninstallPackages.ts b/src/initialize/steps/uninstallPackages.ts similarity index 100% rename from src/setup/steps/uninstallPackages.ts rename to src/initialize/steps/uninstallPackages.ts diff --git a/src/setup/steps/updateAllContributorsTable.ts b/src/initialize/steps/updateAllContributorsTable.ts similarity index 100% rename from src/setup/steps/updateAllContributorsTable.ts rename to src/initialize/steps/updateAllContributorsTable.ts diff --git a/src/setup/steps/updateLocalFiles.ts b/src/initialize/steps/updateLocalFiles.ts similarity index 76% rename from src/setup/steps/updateLocalFiles.ts rename to src/initialize/steps/updateLocalFiles.ts index 1bf0a20c8..d38381a61 100644 --- a/src/setup/steps/updateLocalFiles.ts +++ b/src/initialize/steps/updateLocalFiles.ts @@ -33,18 +33,15 @@ export async function updateLocalFiles({ [/\/\*\n.+\*\/\n\n/gs, ``, ".eslintrc.cjs"], [/"author": ".+"/g, `"author": "${npmAuthor}"`, "./package.json"], [/"bin": ".+\n/g, ``, "./package.json"], - [/"hydrate:test": ".+\n/g, ``, "./package.json"], - [/"setup:test": ".*/g, ``, "./package.json"], - [/"setup": ".*/g, ``, "./package.json"], - - [/## Explainer.*## Usage/gs, `## Usage`, "./README.md"], - [/\n## The .+ Script.*$/gs, "", "./.github/DEVELOPMENT.md"], - [`,\n\t\t["src/setup/*.json"`, ``, "./cspell.json"], - [`\t\t"src/hydrate/index.ts",\n`, ``, "./knip.jsonc"], - [`\t\t"src/setup/index.ts",\n`, ``, "./knip.jsonc"], - [`\t\t"ignoreDependencies": ["c8"],\n`, ``, "./knip.jsonc"], + [/"initialize:test": ".*/g, ``, "./package.json"], + [/"initialize": ".*/g, ``, "./package.json"], + [/"migrate:test": ".+\n/g, ``, "./package.json"], + [/## Getting Started.*## Development/gs, `## Development`, "./README.md"], + [/\n## Setup Scripts.*$/gs, "", "./.github/DEVELOPMENT.md"], + [`\t\t"src/initialize/index.ts",\n`, ``, "./knip.jsonc"], + [`\t\t"src/migrate/index.ts",\n`, ``, "./knip.jsonc"], [ - `["src/index.ts!", "script/setup*.js"]`, + `["src/index.ts!", "script/initialize*.js"]`, `"src/index.ts!"`, "./knip.jsonc", ], diff --git a/src/setup/steps/updateReadme.ts b/src/initialize/steps/updateReadme.ts similarity index 100% rename from src/setup/steps/updateReadme.ts rename to src/initialize/steps/updateReadme.ts diff --git a/src/hydrate/index.ts b/src/migrate/index.ts similarity index 61% rename from src/hydrate/index.ts rename to src/migrate/index.ts index 603356bbd..98f7afb82 100644 --- a/src/hydrate/index.ts +++ b/src/migrate/index.ts @@ -1,6 +1,6 @@ import { parseArgs } from "node:util"; -import { setupWithInformation } from "../setup/setupWithInformation.js"; +import { initializeWithInformation } from "../initialize/initializeWithInformation.js"; import { skipSpinnerBlock, successSpinnerBlock, @@ -13,14 +13,15 @@ import { finalizeDependencies } from "./steps/finalizeDependencies.js"; import { runCommand } from "./steps/runCommand.js"; import { writeReadme } from "./steps/writeReadme.js"; import { writeStructure } from "./steps/writing/writeStructure.js"; -import { getHydrationDefaults } from "./values/getHydrationDefaults.js"; -import { augmentWithHydrationValues } from "./values/hydrationInputValues.js"; +import { getMigrationDefaults } from "./values/getMigrationDefaults.js"; +import { augmentWithMigrationValues } from "./values/migrationInputValues.js"; -export async function hydrate(args: string[]) { - const { values: hydrationSkips } = parseArgs({ +export async function migrate(args: string[]) { + const { values: migrationSkips } = parseArgs({ args, options: { "skip-contributors": { type: "boolean" }, + "skip-github-api": { type: "boolean" }, "skip-install": { type: "boolean" }, "skip-setup": { type: "boolean" }, }, @@ -30,24 +31,27 @@ export async function hydrate(args: string[]) { return await runOrRestore({ args, - defaults: await getHydrationDefaults(), - label: "hydration", + defaults: await getMigrationDefaults(), + label: "migration", run: async ({ octokit, values }) => { - const hydrationValues = await augmentWithHydrationValues(values); + const migrationValues = await augmentWithMigrationValues(values); await withSpinner(clearUnnecessaryFiles, "clearing unnecessary files"); await withSpinner( - () => writeStructure(hydrationValues), + () => writeStructure(migrationValues), "writing new repository structure", ); await withSpinner( - () => writeReadme(hydrationValues), + () => writeReadme(migrationValues), "writing README.md", ); - if (hydrationSkips["skip-contributors"]) { + if ( + migrationSkips["skip-github-api"] ?? + migrationSkips["skip-contributors"] + ) { skipSpinnerBlock(`Skipping detecting existing contributors.`); } else { await withSpinner( @@ -56,11 +60,11 @@ export async function hydrate(args: string[]) { ); } - if (hydrationSkips["skip-install"]) { + if (migrationSkips["skip-github-api"] ?? migrationSkips["skip-install"]) { skipSpinnerBlock(`Skipping package installations.`); } else { await withSpinner( - () => finalizeDependencies(hydrationValues), + () => finalizeDependencies(migrationValues), "finalizing dependencies", ); } @@ -68,15 +72,15 @@ export async function hydrate(args: string[]) { await runCommand("pnpm lint --fix", "auto-fixing lint rules"); await runCommand("pnpm format --write", "formatting files"); - if (hydrationSkips["skip-setup"]) { - skipSpinnerBlock(`Done hydrating, and skipping setup command.`); + if (migrationSkips["skip-initialize"]) { + skipSpinnerBlock(`Done migrating, and skipping initialize command.`); } else { - successSpinnerBlock("Done hydrating. Starting setup command..."); + successSpinnerBlock("Done migrating. Starting initialize command..."); - await setupWithInformation({ + await initializeWithInformation({ octokit, values: { - ...hydrationValues, + ...migrationValues, skipUninstalls: true, }, }); diff --git a/src/hydrate/steps/clearUnnecessaryFiles.ts b/src/migrate/steps/clearUnnecessaryFiles.ts similarity index 100% rename from src/hydrate/steps/clearUnnecessaryFiles.ts rename to src/migrate/steps/clearUnnecessaryFiles.ts diff --git a/src/hydrate/steps/detectExistingContributors.ts b/src/migrate/steps/detectExistingContributors.ts similarity index 100% rename from src/hydrate/steps/detectExistingContributors.ts rename to src/migrate/steps/detectExistingContributors.ts diff --git a/src/hydrate/steps/finalizeDependencies.test.ts b/src/migrate/steps/finalizeDependencies.test.ts similarity index 100% rename from src/hydrate/steps/finalizeDependencies.test.ts rename to src/migrate/steps/finalizeDependencies.test.ts diff --git a/src/hydrate/steps/finalizeDependencies.ts b/src/migrate/steps/finalizeDependencies.ts similarity index 92% rename from src/hydrate/steps/finalizeDependencies.ts rename to src/migrate/steps/finalizeDependencies.ts index 82e066326..7b0b2e0df 100644 --- a/src/hydrate/steps/finalizeDependencies.ts +++ b/src/migrate/steps/finalizeDependencies.ts @@ -1,11 +1,11 @@ import { execaCommand } from "execa"; -import { HydrationInputValues } from "../values/types.js"; +import { MigrationInputValues } from "../values/types.js"; export async function finalizeDependencies({ releases, unitTests, -}: Pick) { +}: Pick) { const devDependencies = [ "@types/eslint", "@typescript-eslint/eslint-plugin", diff --git a/src/hydrate/steps/runCommand.test.ts b/src/migrate/steps/runCommand.test.ts similarity index 100% rename from src/hydrate/steps/runCommand.test.ts rename to src/migrate/steps/runCommand.test.ts diff --git a/src/hydrate/steps/runCommand.ts b/src/migrate/steps/runCommand.ts similarity index 100% rename from src/hydrate/steps/runCommand.ts rename to src/migrate/steps/runCommand.ts diff --git a/src/hydrate/steps/writeReadme.test.ts b/src/migrate/steps/writeReadme.test.ts similarity index 100% rename from src/hydrate/steps/writeReadme.test.ts rename to src/migrate/steps/writeReadme.test.ts diff --git a/src/hydrate/steps/writeReadme.ts b/src/migrate/steps/writeReadme.ts similarity index 94% rename from src/hydrate/steps/writeReadme.ts rename to src/migrate/steps/writeReadme.ts index d1f351ff6..2227a1664 100644 --- a/src/hydrate/steps/writeReadme.ts +++ b/src/migrate/steps/writeReadme.ts @@ -1,7 +1,7 @@ import fs from "node:fs/promises"; import { readFileSafe } from "../../shared/readFileSafe.js"; -import { HydrationInputValues } from "../values/types.js"; +import { MigrationInputValues } from "../values/types.js"; const contributorsIndicator = ``; @@ -23,7 +23,7 @@ ${contributorsIndicator} `; -export async function writeReadme(values: HydrationInputValues) { +export async function writeReadme(values: MigrationInputValues) { let contents = await readFileSafe("README.md", ""); if (!contents) { await fs.writeFile( @@ -58,7 +58,7 @@ function findH1Close(contents: string) { return contents.indexOf("") + "".length; } -function generateTopContent(values: HydrationInputValues) { +function generateTopContent(values: MigrationInputValues) { return `

${values.title}

${values.description}

diff --git a/src/hydrate/steps/writing/creation/dotGitHub/actions.test.ts b/src/migrate/steps/writing/creation/dotGitHub/actions.test.ts similarity index 100% rename from src/hydrate/steps/writing/creation/dotGitHub/actions.test.ts rename to src/migrate/steps/writing/creation/dotGitHub/actions.test.ts diff --git a/src/hydrate/steps/writing/creation/dotGitHub/actions.ts b/src/migrate/steps/writing/creation/dotGitHub/actions.ts similarity index 100% rename from src/hydrate/steps/writing/creation/dotGitHub/actions.ts rename to src/migrate/steps/writing/creation/dotGitHub/actions.ts diff --git a/src/hydrate/steps/writing/creation/dotGitHub/createWorkflowFile.test.ts b/src/migrate/steps/writing/creation/dotGitHub/createWorkflowFile.test.ts similarity index 100% rename from src/hydrate/steps/writing/creation/dotGitHub/createWorkflowFile.test.ts rename to src/migrate/steps/writing/creation/dotGitHub/createWorkflowFile.test.ts diff --git a/src/hydrate/steps/writing/creation/dotGitHub/createWorkflowFile.ts b/src/migrate/steps/writing/creation/dotGitHub/createWorkflowFile.ts similarity index 100% rename from src/hydrate/steps/writing/creation/dotGitHub/createWorkflowFile.ts rename to src/migrate/steps/writing/creation/dotGitHub/createWorkflowFile.ts diff --git a/src/hydrate/steps/writing/creation/dotGitHub/index.ts b/src/migrate/steps/writing/creation/dotGitHub/index.ts similarity index 76% rename from src/hydrate/steps/writing/creation/dotGitHub/index.ts rename to src/migrate/steps/writing/creation/dotGitHub/index.ts index b1d6b0763..f057fbc51 100644 --- a/src/hydrate/steps/writing/creation/dotGitHub/index.ts +++ b/src/migrate/steps/writing/creation/dotGitHub/index.ts @@ -1,10 +1,10 @@ -import { HydrationInputValues } from "../../../../values/types.js"; +import { MigrationInputValues } from "../../../../values/types.js"; import { createDotGitHubActions } from "./actions.js"; import { createDotGitHubIssueTemplate } from "./issueTemplate.js"; import { createDotGitHubFiles } from "./rootFiles.js"; import { createWorkflows } from "./workflows.js"; -export function createDotGitHub(values: HydrationInputValues) { +export function createDotGitHub(values: MigrationInputValues) { return { ISSUE_TEMPLATE: createDotGitHubIssueTemplate(values), actions: createDotGitHubActions(), diff --git a/src/hydrate/steps/writing/creation/dotGitHub/issueTemplate.ts b/src/migrate/steps/writing/creation/dotGitHub/issueTemplate.ts similarity index 97% rename from src/hydrate/steps/writing/creation/dotGitHub/issueTemplate.ts rename to src/migrate/steps/writing/creation/dotGitHub/issueTemplate.ts index 50ab41c8f..387ab74e5 100644 --- a/src/hydrate/steps/writing/creation/dotGitHub/issueTemplate.ts +++ b/src/migrate/steps/writing/creation/dotGitHub/issueTemplate.ts @@ -1,10 +1,10 @@ -import { HydrationInputValues } from "../../../../values/types.js"; +import { MigrationInputValues } from "../../../../values/types.js"; import { formatYaml } from "../formatters/formatYaml.js"; export function createDotGitHubIssueTemplate({ owner, repository, -}: Pick) { +}: Pick) { return { "01-bug.yml": formatYaml({ body: [ diff --git a/src/hydrate/steps/writing/creation/dotGitHub/rootFiles.ts b/src/migrate/steps/writing/creation/dotGitHub/rootFiles.ts similarity index 96% rename from src/hydrate/steps/writing/creation/dotGitHub/rootFiles.ts rename to src/migrate/steps/writing/creation/dotGitHub/rootFiles.ts index 5f4ce1578..94b723b23 100644 --- a/src/hydrate/steps/writing/creation/dotGitHub/rootFiles.ts +++ b/src/migrate/steps/writing/creation/dotGitHub/rootFiles.ts @@ -1,5 +1,5 @@ /* spellchecker: disable */ -import { HydrationInputValues } from "../../../../values/types.js"; +import { MigrationInputValues } from "../../../../values/types.js"; import { formatYaml } from "../formatters/formatYaml.js"; export function createDotGitHubFiles({ @@ -7,7 +7,7 @@ export function createDotGitHubFiles({ funding, owner, repository, -}: Pick) { +}: Pick) { return { "CODE_OF_CONDUCT.md": `# Contributor Covenant Code of Conduct @@ -300,23 +300,7 @@ Calls to \`console.log\`, \`console.warn\`, and other console methods will cause This repository includes a [VS Code launch configuration](https://code.visualstudio.com/docs/editor/debugging) for debugging unit tests. To launch it, open a test file, then run _Debug Current Test File_ from the VS Code Debug panel (or press F5). - -### Testing the Setup Script - -In addition to unit tests, this template also includes an "end-to-end" test for \`script/setup.js\`. -You can run it locally on the command-line: - -\`\`\`shell -pnpm run setup:test -\`\`\` - -That end-to-end test executes \`script/setup-test-e2e.js\`, which: - -1. Runs the setup script using \`--skip-api\` -2. Checks that the local repository's files were changed correctly (e.g. removed setup-only files) - -As with the setup script itself, end-to-end tests are removed on package setup. - `, +`, ...(funding && { "FUNDING.yml": formatYaml({ github: funding }) }), "ISSUE_TEMPLATE.md": ` diff --git a/src/hydrate/steps/writing/creation/dotGitHub/workflows.ts b/src/migrate/steps/writing/creation/dotGitHub/workflows.ts similarity index 98% rename from src/hydrate/steps/writing/creation/dotGitHub/workflows.ts rename to src/migrate/steps/writing/creation/dotGitHub/workflows.ts index 6319a9345..eeb88f9e7 100644 --- a/src/hydrate/steps/writing/creation/dotGitHub/workflows.ts +++ b/src/migrate/steps/writing/creation/dotGitHub/workflows.ts @@ -1,11 +1,11 @@ /* spellchecker: disable */ -import { HydrationInputValues } from "../../../../values/types.js"; +import { MigrationInputValues } from "../../../../values/types.js"; import { createWorkflowFile } from "./createWorkflowFile.js"; export function createWorkflows({ owner, repository, -}: Pick) { +}: Pick) { return { "build.yml": createWorkflowFile({ name: "Build", diff --git a/src/hydrate/steps/writing/creation/dotHusky.ts b/src/migrate/steps/writing/creation/dotHusky.ts similarity index 100% rename from src/hydrate/steps/writing/creation/dotHusky.ts rename to src/migrate/steps/writing/creation/dotHusky.ts diff --git a/src/hydrate/steps/writing/creation/dotVSCode.ts b/src/migrate/steps/writing/creation/dotVSCode.ts similarity index 100% rename from src/hydrate/steps/writing/creation/dotVSCode.ts rename to src/migrate/steps/writing/creation/dotVSCode.ts diff --git a/src/hydrate/steps/writing/creation/formatters/formatIgnoreFile.ts b/src/migrate/steps/writing/creation/formatters/formatIgnoreFile.ts similarity index 100% rename from src/hydrate/steps/writing/creation/formatters/formatIgnoreFile.ts rename to src/migrate/steps/writing/creation/formatters/formatIgnoreFile.ts diff --git a/src/hydrate/steps/writing/creation/formatters/formatJson.ts b/src/migrate/steps/writing/creation/formatters/formatJson.ts similarity index 100% rename from src/hydrate/steps/writing/creation/formatters/formatJson.ts rename to src/migrate/steps/writing/creation/formatters/formatJson.ts diff --git a/src/hydrate/steps/writing/creation/formatters/formatYaml.ts b/src/migrate/steps/writing/creation/formatters/formatYaml.ts similarity index 100% rename from src/hydrate/steps/writing/creation/formatters/formatYaml.ts rename to src/migrate/steps/writing/creation/formatters/formatYaml.ts diff --git a/src/hydrate/steps/writing/creation/index.ts b/src/migrate/steps/writing/creation/index.ts similarity index 83% rename from src/hydrate/steps/writing/creation/index.ts rename to src/migrate/steps/writing/creation/index.ts index 1686effa9..3067f6041 100644 --- a/src/hydrate/steps/writing/creation/index.ts +++ b/src/migrate/steps/writing/creation/index.ts @@ -1,4 +1,4 @@ -import { HydrationInputValues } from "../../../values/types.js"; +import { MigrationInputValues } from "../../../values/types.js"; import { Structure } from "../types.js"; import { createDotGitHub } from "./dotGitHub/index.js"; import { createDotHusky } from "./dotHusky.js"; @@ -6,7 +6,7 @@ import { createDotVSCode } from "./dotVSCode.js"; import { createRootFiles } from "./rootFiles.js"; export async function createStructure( - values: HydrationInputValues, + values: MigrationInputValues, ): Promise { return { ".github": createDotGitHub(values), diff --git a/src/hydrate/steps/writing/creation/rootFiles.ts b/src/migrate/steps/writing/creation/rootFiles.ts similarity index 98% rename from src/hydrate/steps/writing/creation/rootFiles.ts rename to src/migrate/steps/writing/creation/rootFiles.ts index 93deedb79..cf7831138 100644 --- a/src/hydrate/steps/writing/creation/rootFiles.ts +++ b/src/migrate/steps/writing/creation/rootFiles.ts @@ -1,10 +1,10 @@ -import { HydrationInputValues } from "../../../values/types.js"; +import { MigrationInputValues } from "../../../values/types.js"; import { formatIgnoreFile } from "./formatters/formatIgnoreFile.js"; import { formatJson } from "./formatters/formatJson.js"; import { writeAllContributorsRC } from "./writeAllContributorsRC.js"; import { writePackageJson } from "./writePackageJson.js"; -export async function createRootFiles(values: HydrationInputValues) { +export async function createRootFiles(values: MigrationInputValues) { return { ".all-contributorsrc": await writeAllContributorsRC(values), ".eslintignore": formatIgnoreFile([ diff --git a/src/hydrate/steps/writing/creation/writeAllContributorsRC.ts b/src/migrate/steps/writing/creation/writeAllContributorsRC.ts similarity index 86% rename from src/hydrate/steps/writing/creation/writeAllContributorsRC.ts rename to src/migrate/steps/writing/creation/writeAllContributorsRC.ts index 9ff1a2c76..fbba3a44f 100644 --- a/src/hydrate/steps/writing/creation/writeAllContributorsRC.ts +++ b/src/migrate/steps/writing/creation/writeAllContributorsRC.ts @@ -1,9 +1,9 @@ import { readFileSafeAsJson } from "../../../../shared/readFileSafeAsJson.js"; import { AllContributorsData } from "../../../../shared/types.js"; -import { HydrationInputValues } from "../../../values/types.js"; +import { MigrationInputValues } from "../../../values/types.js"; import { formatJson } from "./formatters/formatJson.js"; -export async function writeAllContributorsRC(values: HydrationInputValues) { +export async function writeAllContributorsRC(values: MigrationInputValues) { const existing = (await readFileSafeAsJson( ".all-contributorsrc", )) as AllContributorsData | null; diff --git a/src/hydrate/steps/writing/creation/writePackageJson.test.ts b/src/migrate/steps/writing/creation/writePackageJson.test.ts similarity index 100% rename from src/hydrate/steps/writing/creation/writePackageJson.test.ts rename to src/migrate/steps/writing/creation/writePackageJson.test.ts diff --git a/src/hydrate/steps/writing/creation/writePackageJson.ts b/src/migrate/steps/writing/creation/writePackageJson.ts similarity index 97% rename from src/hydrate/steps/writing/creation/writePackageJson.ts rename to src/migrate/steps/writing/creation/writePackageJson.ts index eaef89da9..486381a15 100644 --- a/src/hydrate/steps/writing/creation/writePackageJson.ts +++ b/src/migrate/steps/writing/creation/writePackageJson.ts @@ -1,5 +1,5 @@ import { readFileSafeAsJson } from "../../../../shared/readFileSafeAsJson.js"; -import { HydrationInputValues } from "../../../values/types.js"; +import { MigrationInputValues } from "../../../values/types.js"; import { formatJson } from "./formatters/formatJson.js"; const devDependenciesToRemove = [ @@ -32,7 +32,7 @@ export async function writePackageJson({ repository, unitTests, }: Pick< - HydrationInputValues, + MigrationInputValues, | "author" | "description" | "email" diff --git a/src/hydrate/steps/writing/types.ts b/src/migrate/steps/writing/types.ts similarity index 100% rename from src/hydrate/steps/writing/types.ts rename to src/migrate/steps/writing/types.ts diff --git a/src/hydrate/steps/writing/writeStructure.ts b/src/migrate/steps/writing/writeStructure.ts similarity index 60% rename from src/hydrate/steps/writing/writeStructure.ts rename to src/migrate/steps/writing/writeStructure.ts index fe2dd4f14..554871b25 100644 --- a/src/hydrate/steps/writing/writeStructure.ts +++ b/src/migrate/steps/writing/writeStructure.ts @@ -1,7 +1,7 @@ -import { HydrationInputValues } from "../../values/types.js"; +import { MigrationInputValues } from "../../values/types.js"; import { createStructure } from "./creation/index.js"; import { writeStructureWorker } from "./writeStructureWorker.js"; -export async function writeStructure(values: HydrationInputValues) { +export async function writeStructure(values: MigrationInputValues) { await writeStructureWorker(await createStructure(values), "."); } diff --git a/src/hydrate/steps/writing/writeStructureWorker.test.ts b/src/migrate/steps/writing/writeStructureWorker.test.ts similarity index 100% rename from src/hydrate/steps/writing/writeStructureWorker.test.ts rename to src/migrate/steps/writing/writeStructureWorker.test.ts diff --git a/src/hydrate/steps/writing/writeStructureWorker.ts b/src/migrate/steps/writing/writeStructureWorker.ts similarity index 100% rename from src/hydrate/steps/writing/writeStructureWorker.ts rename to src/migrate/steps/writing/writeStructureWorker.ts diff --git a/src/hydrate/values/getHydrationDefaults.test.ts b/src/migrate/values/getMigrationDefaults.test.ts similarity index 86% rename from src/hydrate/values/getHydrationDefaults.test.ts rename to src/migrate/values/getMigrationDefaults.test.ts index 01043b5ae..0ffe962b2 100644 --- a/src/hydrate/values/getHydrationDefaults.test.ts +++ b/src/migrate/values/getMigrationDefaults.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from "vitest"; -import { getHydrationDefaults } from "./getHydrationDefaults.js"; +import { getMigrationDefaults } from "./getMigrationDefaults.js"; const mockReadFileSafe = vi.fn(); @@ -34,8 +34,8 @@ vi.mock("./readTitleFromReadme.js", () => ({ }, })); -describe("getHydrationDefaults", () => { - it("reads hydration defaults from existing readme and package json when exists", async () => { +describe("getMigrationDefaults", () => { + it("reads migration defaults from existing readme and package json when exists", async () => { mockReadTitleFromReadme.mockResolvedValue("My Awesome Package"); mockReadFileSafe.mockResolvedValueOnce( '{"author":"Someone "}', @@ -43,7 +43,7 @@ describe("getHydrationDefaults", () => { mockReadFundingIfExists.mockResolvedValue("Someone"); mockReadOwnerFromGitRemote.mockResolvedValue("SUM1"); - const result = await getHydrationDefaults(); + const result = await getMigrationDefaults(); expect(await result.author()).toBe("Someone"); expect(await result.email()).toBe("someone@test.com"); expect(await result.funding()).toBe("Someone"); diff --git a/src/hydrate/values/getHydrationDefaults.ts b/src/migrate/values/getMigrationDefaults.ts similarity index 94% rename from src/hydrate/values/getHydrationDefaults.ts rename to src/migrate/values/getMigrationDefaults.ts index 20952715f..0f2b2cfd8 100644 --- a/src/hydrate/values/getHydrationDefaults.ts +++ b/src/migrate/values/getMigrationDefaults.ts @@ -7,7 +7,7 @@ import { readFundingIfExists } from "./readFundingIfExists.js"; import { readOwnerFromGitRemote } from "./readOwnerFromGitRemote.js"; import { readTitleFromReadme } from "./readTitleFromReadme.js"; -export async function getHydrationDefaults() { +export async function getMigrationDefaults() { const existingPackage = JSON.parse( await readFileSafe("./package.json", "{}"), ) as PartialPackageData; diff --git a/src/hydrate/values/hydrationInputValues.ts b/src/migrate/values/migrationInputValues.ts similarity index 77% rename from src/hydrate/values/hydrationInputValues.ts rename to src/migrate/values/migrationInputValues.ts index f3a30e8e9..a33bc4b80 100644 --- a/src/hydrate/values/hydrationInputValues.ts +++ b/src/migrate/values/migrationInputValues.ts @@ -1,10 +1,10 @@ import { PrefillPrompter } from "../../shared/PrefillPrompter.js"; import { InputValues } from "../../shared/inputs.js"; -import { HydrationInputValues } from "./types.js"; +import { MigrationInputValues } from "./types.js"; -export async function augmentWithHydrationValues( +export async function augmentWithMigrationValues( values: InputValues, -): Promise { +): Promise { const prompter = new PrefillPrompter(); return { diff --git a/src/hydrate/values/readAuthorIfExists.test.ts b/src/migrate/values/readAuthorIfExists.test.ts similarity index 100% rename from src/hydrate/values/readAuthorIfExists.test.ts rename to src/migrate/values/readAuthorIfExists.test.ts diff --git a/src/hydrate/values/readAuthorIfExists.ts b/src/migrate/values/readAuthorIfExists.ts similarity index 100% rename from src/hydrate/values/readAuthorIfExists.ts rename to src/migrate/values/readAuthorIfExists.ts diff --git a/src/hydrate/values/readEmailIfExists.test.ts b/src/migrate/values/readEmailIfExists.test.ts similarity index 100% rename from src/hydrate/values/readEmailIfExists.test.ts rename to src/migrate/values/readEmailIfExists.test.ts diff --git a/src/hydrate/values/readEmailIfExists.ts b/src/migrate/values/readEmailIfExists.ts similarity index 100% rename from src/hydrate/values/readEmailIfExists.ts rename to src/migrate/values/readEmailIfExists.ts diff --git a/src/hydrate/values/readFundingIfExists.test.ts b/src/migrate/values/readFundingIfExists.test.ts similarity index 100% rename from src/hydrate/values/readFundingIfExists.test.ts rename to src/migrate/values/readFundingIfExists.test.ts diff --git a/src/hydrate/values/readFundingIfExists.ts b/src/migrate/values/readFundingIfExists.ts similarity index 100% rename from src/hydrate/values/readFundingIfExists.ts rename to src/migrate/values/readFundingIfExists.ts diff --git a/src/hydrate/values/readOwnerFromGitRemote.test.ts b/src/migrate/values/readOwnerFromGitRemote.test.ts similarity index 100% rename from src/hydrate/values/readOwnerFromGitRemote.test.ts rename to src/migrate/values/readOwnerFromGitRemote.test.ts diff --git a/src/hydrate/values/readOwnerFromGitRemote.ts b/src/migrate/values/readOwnerFromGitRemote.ts similarity index 100% rename from src/hydrate/values/readOwnerFromGitRemote.ts rename to src/migrate/values/readOwnerFromGitRemote.ts diff --git a/src/hydrate/values/readTitleFromReadme.test.ts b/src/migrate/values/readTitleFromReadme.test.ts similarity index 100% rename from src/hydrate/values/readTitleFromReadme.test.ts rename to src/migrate/values/readTitleFromReadme.test.ts diff --git a/src/hydrate/values/readTitleFromReadme.ts b/src/migrate/values/readTitleFromReadme.ts similarity index 100% rename from src/hydrate/values/readTitleFromReadme.ts rename to src/migrate/values/readTitleFromReadme.ts diff --git a/src/hydrate/values/types.ts b/src/migrate/values/types.ts similarity index 81% rename from src/hydrate/values/types.ts rename to src/migrate/values/types.ts index 6a9b7131b..eee00f794 100644 --- a/src/hydrate/values/types.ts +++ b/src/migrate/values/types.ts @@ -1,6 +1,6 @@ import { InputValues } from "../../shared/inputs.js"; -export interface HydrationInputValues extends InputValues { +export interface MigrationInputValues extends InputValues { author: string; email: string; } diff --git a/src/setup/index.ts b/src/setup/index.ts deleted file mode 100644 index caec91aa1..000000000 --- a/src/setup/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { setup } from "./setup.js"; - -process.exitCode = await setup(process.argv.slice(2)); diff --git a/src/setup/setup.ts b/src/setup/setup.ts deleted file mode 100644 index c3c1a5195..000000000 --- a/src/setup/setup.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { runOrRestore } from "../shared/runOrRestore.js"; -import { setupWithInformation } from "./setupWithInformation.js"; - -export async function setup(args: string[]) { - return await runOrRestore({ - args, - label: "setup", - run: setupWithInformation, - }); -} diff --git a/src/shared/inputs.ts b/src/shared/inputs.ts index c4a12a47e..73f1416c0 100644 --- a/src/shared/inputs.ts +++ b/src/shared/inputs.ts @@ -54,7 +54,7 @@ export async function getInputValuesAndOctokit( owner: { type: "string" }, releases: { type: "boolean" }, repository: { type: "string" }, - "skip-api": { type: "boolean" }, + "skip-github-api": { type: "boolean" }, "skip-removal": { type: "boolean" }, "skip-restore": { type: "boolean" }, "skip-uninstall": { type: "boolean" }, @@ -73,7 +73,7 @@ export async function getInputValuesAndOctokit( defaultOwner, ); - const octokit = await getOctokit(!!values["skip-api"]); + const octokit = await getOctokit(!!values["skip-github-api"]); prompter.reset(); @@ -124,7 +124,7 @@ export async function getInputValuesAndOctokit( defaults.releases, ), repository, - skipApi: !!values["skip-api"], + skipApi: !!values["skip-github-api"], skipRemoval: !!values["skip-removal"], skipRestore: !!values["skip-restore"], skipUninstalls: !!values["skip-uninstalls"],