Skip to content

Commit edd4d8f

Browse files
feat: add create flow and unify bin with --mode (#681)
<!-- 👋 Hi, thanks for sending a PR to template-typescript-node-package! 💖. Please fill out all fields below and make sure each item is true and [x] checked. Otherwise we may not be able to review your PR. --> ## PR Checklist - [x] Addresses an existing open issue: fixes #670 - [x] That issue was marked as [`status: accepting prs`](https://github.com/JoshuaKGoldberg/template-typescript-node-package/issues?q=is%3Aopen+is%3Aissue+label%3A%22status%3A+accepting+prs%22) - [x] Steps in [CONTRIBUTING.md](https://github.com/JoshuaKGoldberg/template-typescript-node-package/blob/main/.github/CONTRIBUTING.md) were taken ## Overview Changes the bin script to be the main launching point for the app. It can take in or prompt for a `--mode` set to either `"create"`, `"initialize"`, or `"migrate"`. This comes with a few cleanups: * Simplified `runOrRestore` so that it just runs or logs - leaving parsing logic to the functions that call it * Removed a lot of the terminal logs so that the remaining output is cleaner * Cleaned up input parsing to have fewer different code paths / types Tracking my todo items: - [x] Add a new `create` flow alongside `initialize` and `migrate` - [x] Manually test a bunch - [x] Refactor their code to streamline the flow of logic - [x] Fix unit tests - [x] Fix existing end-to-end tests - [x] Overhaul documentation - [x] Add a new end-to-end test - [x] Manually test some more
1 parent c688e98 commit edd4d8f

File tree

114 files changed

+1841
-948
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

114 files changed

+1841
-948
lines changed

Diff for: .github/DEVELOPMENT.md

+23-3
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ pnpm format:write
4141
This package includes several forms of linting to enforce consistent code quality and styling.
4242
Each should be shown in VS Code, and can be run manually on the command-line:
4343

44+
- `pnpm lint` ([ESLint](https://eslint.org) with [typescript-eslint](https://typescript-eslint.io)): Lints JavaScript and TypeScript source files
4445
- `pnpm lint:knip` ([knip](https://github.com/webpro/knip)): Detects unused files, dependencies, and code exports
4546
- `pnpm lint:md` ([Markdownlint](https://github.com/DavidAnson/markdownlint)): Checks Markdown source files
4647
- `pnpm lint:package` ([npm-package-json-lint](https://npmpackagejsonlint.org/)): Lints the `package.json` file
4748
- `pnpm lint:packages` ([pnpm dedupe --check](https://pnpm.io/cli/dedupe)): Checks for unnecessarily duplicated packages in the `pnpm-lock.yml` file
4849
- `pnpm lint:spelling` ([cspell](https://cspell.org)): Spell checks across all source files
49-
- `pnpm lint` ([ESLint](https://eslint.org) with [typescript-eslint](https://typescript-eslint.io)): Lints JavaScript and TypeScript source files
5050

5151
## Testing
5252

@@ -89,12 +89,32 @@ pnpm tsc --watch
8989

9090
## Setup Scripts
9191

92-
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.
92+
As described in the `README.md` file and `docs/`, this template repository comes with three scripts that can set up an existing or new repository.
9393

9494
> **Warning**
95-
> Both setup scripts override many files in the directory they're run in.
95+
> Each setup script overrides many files in the directory they're run in.
9696
> Make sure to save any changes you want to preserve before running them.
9797
98+
### The Creation Script
99+
100+
This template's "creation" script is located in `src/create/`.
101+
You can run it locally with `node bin/index.js --mode create`.
102+
Note that files need to be built with `pnpm run build` beforehand.
103+
104+
#### Testing the Creation Script
105+
106+
You can run the end-to-end test for creation locally on the command-line.
107+
Note that the files need to be built with `pnpm run build` beforehand.
108+
109+
```shell
110+
pnpm run create:test
111+
```
112+
113+
That end-to-end test executes `script/create-test-e2e.js`, which:
114+
115+
1. Runs the creation script to create a new `test-repository` child directory and repository
116+
2. Asserts that commands such as `build` and `lint` each pass
117+
98118
### The Initialization Script
99119

100120
This template's "initialization" script is located in `src/initialize/`.

Diff for: .github/workflows/test-create.yml

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
jobs:
2+
create:
3+
runs-on: ubuntu-latest
4+
steps:
5+
- uses: actions/checkout@v3
6+
- uses: ./.github/actions/prepare
7+
- run: pnpm run build
8+
- run: pnpm run create:test
9+
- if: always()
10+
name: Codecov
11+
uses: codecov/codecov-action@v3
12+
with:
13+
files: coverage-create/lcov.info
14+
flags: create
15+
- if: always()
16+
name: Archive code coverage results
17+
uses: actions/upload-artifact@v3
18+
with:
19+
path: coverage-create
20+
21+
name: Test Creation Script
22+
23+
on:
24+
pull_request: ~
25+
26+
push:
27+
branches:
28+
- main

Diff for: .github/workflows/test-initialize.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ jobs:
66
- uses: ./.github/actions/prepare
77
- run: pnpm run build
88
- run: pnpm run initialize:test
9-
- name: Codecov
9+
- if: always()
10+
name: Codecov
1011
uses: codecov/codecov-action@v3
1112
with:
1213
files: coverage-initialize/lcov.info

Diff for: .github/workflows/test-migrate.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ jobs:
66
- uses: ./.github/actions/prepare
77
- run: pnpm run build
88
- run: pnpm run migrate:test
9-
- name: Codecov
9+
- if: always()
10+
name: Codecov
1011
uses: codecov/codecov-action@v3
1112
with:
1213
files: coverage-migrate/lcov.info

Diff for: README.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@
2626
<img alt="TypeScript: Strict 💪" src="https://img.shields.io/badge/typescript-strict_💪-21bb42.svg" />
2727
</p>
2828

29+
Note that this template is early stage, opinionated, and not endorsed by the TypeScript team.
30+
It sets up a _lot_ of tooling out of the box.
31+
Each of the included tools exists for a good reason and provides real value.
32+
33+
If you don't want to use any particular tool, you can always remove it manually.
34+
2935
## Getting Started
3036

3137
First make sure you have the following installed:
@@ -37,7 +43,8 @@ First make sure you have the following installed:
3743
This repository comes with two scripts to set up an existing or new repository with tooling.
3844
Use the corresponding docs page to get started:
3945

40-
- [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
46+
- [Initializing from the template](./docs/InitializationFromTemplate.md): creating a new repository with the [_Use this template_](https://github.com/JoshuaKGoldberg/template-typescript-node-package/generate) button on GitHub _(recommended)_
47+
- [Initializing from the terminal](./docs/InitializationFromTerminal.md): creating a new repository locally on the command-line
4148
- [Migrating an existing repository](./docs/Migration.md): adding this template's tooling on top of an existing repository
4249

4350
## Explainer

Diff for: bin/index.js

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env node
2+
import { bin } from "../lib/bin/index.js";
3+
4+
process.exitCode = await bin(process.argv.slice(2));

Diff for: bin/migrate.js

-4
This file was deleted.

Diff for: codecov.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
codecov:
22
notify:
3-
after_n_builds: 3
3+
after_n_builds: 4
44
comment:
5-
after_n_builds: 3
5+
after_n_builds: 4
File renamed without changes.

Diff for: docs/InitializationFromTerminal.md

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Initializing from the Terminal
2+
3+
As a local alternative to [initialization from the template](./InitializationFromTemplate.md), you can run `npx template-typescript-node-package` in your terminal:
4+
5+
```shell
6+
npx template-typescript-node-package
7+
```
8+
9+
The prompt by default will ask you which mode you'd like to run in.
10+
Pass `--mode create` to tell it to create a new repository in a child directory:
11+
12+
```shell
13+
npx template-typescript-node-package --mode create
14+
```
15+
16+
Upon completion, the prompt will suggest commands to get started working in the repository and create a corresponding GitHub repository.
17+
Those commands will roughly run the [The Initialization Script](./InitializationFromTemplate.md#the-initialization-script), but with `npm template-typescript-node-package --mode initialize` instead of `pnpm run initialize`:
18+
19+
```shell
20+
cd repository-name
21+
gh repo create repository-name --public --source=. --remote=origin
22+
npx template-typescript-node-package --mode initialize
23+
git add -A
24+
git commit -m "chore: initial commit ✨"
25+
git push -u origin main
26+
```
27+
28+
## The Creation Script
29+
30+
The creation script will interactively prompt for values to be used in creating the new repository.
31+
Each may provided as a string CLI flag as well:
32+
33+
- `--description`: Sentence case description of the repository (e.g. `A quickstart-friendly TypeScript package with lots of great repository tooling. ✨`)
34+
- `--owner`: GitHub organization or user the repository is underneath (e.g. `JoshuaKGoldberg`)
35+
- `--repository`: The kebab-case name of the repository (e.g. `template-typescript-node-package`)
36+
- `--title`: Title Case title for the repository to be used in documentation (e.g. `Template TypeScript Node Package`)
37+
38+
For example, pre-populating all values:
39+
40+
```shell
41+
npx template-typescript-node-package --mode create --repository "testing-repository" --title "Testing Title" --owner "TestingOwner" --description "Test Description"
42+
```
43+
44+
Then, go through the following two steps to set up required repository tooling on GitHub:
45+
46+
1. Create two tokens in [repository secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets):
47+
- `ACCESS_TOKEN`: A [GitHub PAT](https://github.com/settings/tokens/new) with _repo_ and _workflow_ permissions
48+
- `NPM_TOKEN`: An [npm access token](https://docs.npmjs.com/creating-and-viewing-access-tokens/) with _Automation_ permissions
49+
2. Install the [Codecov GitHub App](https://github.com/marketplace/codecov) and [Renovate GitHub App](https://github.com/marketplace/renovate)
50+
51+
At this point, your new repository should be ready for development! 🥳

Diff for: docs/Migration.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,9 @@ You can prevent the migration script from making some network-based changes usin
4949
- `--skip-contributors` _(`boolean`)_: Skips detecting existing contributors with [`all-contributors-for-repository`](https://github.com/JoshuaKGoldberg/all-contributors-for-repository)
5050
- `--skip-github-api` _(`boolean`)_: Skips calling to GitHub APIs
5151
- `--skip-install` _(`boolean`)_: Skips installing all the new template packages with `pnpm`
52-
- `--skip-initialize` _(`boolean`)_: Skips running the initialize script at the end of migration
5352

5453
```shell
55-
npx template-typescript-node-package --skip-github-api --skip-initialize --skip-install
54+
npx template-typescript-node-package --skip-github-api --skip-install
5655
```
5756

5857
> Tip: the `--skip-github-api` flag will cause all changes to be limited to your local repository.

Diff for: knip.jsonc

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"$schema": "https://unpkg.com/knip@latest/schema.json",
33
"entry": [
44
"src/index.ts!",
5+
"src/guide/index.ts",
56
"src/initialize/index.ts",
67
"src/migrate/index.ts",
78
"script/*e2e.js"

Diff for: package.json

+5-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
},
1414
"type": "module",
1515
"main": "./lib/index.js",
16-
"bin": "./bin/migrate.js",
16+
"bin": "./bin/index.js",
1717
"files": [
1818
"bin/",
1919
"lib/",
@@ -23,9 +23,10 @@
2323
],
2424
"scripts": {
2525
"build": "tsup",
26+
"create:test": "node script/create-test-e2e.js",
2627
"format": "prettier \"**/*\" --ignore-unknown",
2728
"format:write": "pnpm format --write",
28-
"initialize": "tsx src/initialize/index.ts",
29+
"initialize": "tsx ./src/bin/index.js --mode initialize",
2930
"initialize:test": "node script/initialize-test-e2e.js",
3031
"lint": "eslint . .*js --max-warnings 0 --report-unused-disable-directives",
3132
"lint:knip": "knip",
@@ -36,7 +37,8 @@
3637
"migrate:test": "node script/migrate-test-e2e.js",
3738
"prepare": "husky install",
3839
"should-semantic-release": "should-semantic-release --verbose",
39-
"test": "vitest"
40+
"test": "vitest",
41+
"tsc": "tsc"
4042
},
4143
"lint-staged": {
4244
"*": "prettier --ignore-unknown --write"

Diff for: script/create-test-e2e.js

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { $, execaCommand } from "execa";
2+
import { strict as assert } from "node:assert";
3+
4+
const author = "Test Author";
5+
const description = "Test description.";
6+
const email = "[email protected]";
7+
const repository = "test-repository";
8+
const owner = "TestOwner";
9+
const title = "Test Title";
10+
11+
await $`rm -rf ${repository}`;
12+
13+
await $({
14+
stdio: "inherit",
15+
})`c8 -o ./coverage-create -r html -r lcov node ./bin/index.js --mode create --author ${author} --email ${email} --description ${description} --owner ${owner} --title ${title} --repository ${repository} --skip-contributors --skip-github-api`;
16+
17+
process.chdir(repository);
18+
19+
const failures = [];
20+
21+
for (const command of [
22+
`pnpm i`,
23+
`pnpm run build`,
24+
`pnpm run format --list-different`,
25+
`pnpm run lint`,
26+
`pnpm run lint:md`,
27+
`pnpm run lint:package`,
28+
`pnpm run lint:packages`,
29+
`pnpm run lint:spelling`,
30+
`pnpm run lint:knip`,
31+
`pnpm run test run`,
32+
`pnpm run tsc`,
33+
]) {
34+
const result = await execaCommand(command, { stdio: "inherit" });
35+
36+
if (result.exitCode) {
37+
failures.push({ command, result });
38+
}
39+
}
40+
41+
assert.deepEqual(failures, []);

Diff for: script/initialize-test-e2e.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const repository = "new-repository-test";
1111
// First we run initialize to modifies the local repo, so we can test the changes
1212
await $({
1313
stdio: "inherit",
14-
})`node ./lib/initialize/index.js --description ${description} --owner ${owner} --title ${title} --repository ${repository} --skip-github-api --skip-restore`;
14+
})`node ./bin/index.js --description ${description} --mode initialize --owner ${owner} --title ${title} --repository ${repository} --skip-github-api --skip-restore`;
1515

1616
const newPackageJson = JSON.parse(
1717
(await fs.readFile("./package.json")).toString(),
@@ -52,4 +52,4 @@ await $`pnpm i`;
5252
await $`pnpm run build`;
5353
await $({
5454
stdio: "inherit",
55-
})`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`;
55+
})`c8 -o ./coverage-initialize -r html -r lcov node ./bin/index.js --description ${description} --mode initialize --owner ${owner} --title ${title} --repository ${repository} --skip-github-api --skip-removal --skip-restore`;

Diff for: script/migrate-test-e2e.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const title = "Template TypeScript Node Package";
99

1010
await $({
1111
stdio: "inherit",
12-
})`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`;
12+
})`c8 -o ./coverage-migrate -r html -r lcov node ./bin/index.js --mode migrate --description ${description} --owner ${owner} --title ${title} --repository ${repository} --skip-github-api --skip-contributors --skip-install`;
1313

1414
const { stdout: gitStatus } = await $`git status`;
1515
console.log(`Stdout from running \`git status\`:\n${gitStatus}`);
@@ -25,6 +25,7 @@ if (indexOfUnstagedFilesMessage === -1) {
2525

2626
const filesExpectedToBeChanged = new Set([
2727
".all-contributorsrc",
28+
"bin/index.js",
2829
"README.md",
2930
"knip.jsonc",
3031
"package.json",

0 commit comments

Comments
 (0)