Skip to content

Commit

Permalink
feat: add --bin option (#1068)
Browse files Browse the repository at this point in the history
## PR Checklist

- [x] Addresses an existing open issue: fixes #938
- [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

Adds the `--bin` option with auto-detection from existing `package.json`
contents.

Doesn't do anything about investigating whether to adjust `pnpm build`
before `pnpm lint` & similar. That can be a followup.
  • Loading branch information
JoshuaKGoldberg committed Dec 1, 2023
1 parent c980e54 commit 21c8529
Show file tree
Hide file tree
Showing 10 changed files with 37 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/Options.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ The setup scripts also allow for optional overrides of the following inputs whos

- `--access` _(`"public" | "restricted"`)_: Which [`npm publish --access`](https://docs.npmjs.com/cli/commands/npm-publish#access) to release npm packages with (by default, `"public"`)
- `--author` _(`string`)_: Username on npm to publish packages under (by default, an existing npm author, or the currently logged in npm user, or `owner.toLowerCase()`)
- `--bin` _(`string`)_: `package.json` bin value to include for npx-style running.
- `--directory` _(`string`)_: Directory to create the repository in (by default, the same name as the repository)
- `--email` _(`string`)_: Email address to be listed as the point of contact in docs and packages (e.g. `example@joshuakgoldberg.com`)
- Optionally, `--email-github` _(`string`)_ and/or `--email-npm` _(`string`)_ may be provided to use different emails in `.md` files and `package.json`, respectively
Expand Down
4 changes: 4 additions & 0 deletions src/bin/help.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ describe("logHelpText", () => {
"
--auto: Whether to infer all options from files on disk.",
],
[
"
--bin (string): package.json bin value to include for npx-style running.",
],
[
"
--directory (string): Directory to create the repository in (by default, the same
Expand Down
5 changes: 5 additions & 0 deletions src/shared/options/args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ export const allArgOptions = {
docsSection: "core",
type: "string",
},
bin: {
description: `package.json bin value to include for npx-style running.`,
docsSection: "optional",
type: "string",
},
"create-repository": {
description: `Whether to create a corresponding repository on github.com
(if it doesn't yet exist)`,
Expand Down
20 changes: 20 additions & 0 deletions src/shared/options/createOptionDefaults/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,26 @@ vi.mock("../../packages.js", () => ({
}));

describe("createOptionDefaults", () => {
describe("bin", () => {
it("returns undefined when package data does not have a bin", async () => {
mockReadPackageData.mockResolvedValue({});

const actual = await createOptionDefaults().bin();

expect(actual).toBeUndefined();
});

it("returns the bin when package data has a bin", async () => {
const bin = "./lib/index.js";

mockReadPackageData.mockResolvedValue({ bin });

const actual = await createOptionDefaults().bin();

expect(actual).toBe(bin);
});
});

describe("email", () => {
it("returns the npm whoami email from npm when only an npm exists", async () => {
mock$.mockImplementation(([command]: string[]) =>
Expand Down
1 change: 1 addition & 0 deletions src/shared/options/createOptionDefaults/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export function createOptionDefaults(promptedOptions?: PromptedOptions) {

return {
author: async () => (await packageAuthor()).author ?? npmDefaults.name,
bin: async () => (await packageData()).bin,
description: async () => (await packageData()).description,
email: async () => {
const gitEmail = await tryCatchAsync(
Expand Down
1 change: 1 addition & 0 deletions src/shared/options/optionsSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const optionsSchemaShape = {
z.literal("prompt"),
])
.optional(),
bin: z.string().optional(),
description: z.string().optional(),
directory: z.string().optional(),
email: z
Expand Down
1 change: 1 addition & 0 deletions src/shared/options/readOptions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const emptyOptions = {
author: undefined,
auto: false,
base: undefined,
bin: undefined,
description: undefined,
directory: undefined,
email: undefined,
Expand Down
1 change: 1 addition & 0 deletions src/shared/options/readOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export async function readOptions(
author: values.author,
auto: !!values.auto,
base: values.base,
bin: values.bin,
description: values.description,
directory: values.directory,
email:
Expand Down
2 changes: 2 additions & 0 deletions src/shared/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface AllContributorsData {

export interface PartialPackageData {
author?: { email: string; name: string } | string;
bin?: string;
dependencies?: Record<string, string>;
description?: string;
devDependencies?: Record<string, string>;
Expand Down Expand Up @@ -48,6 +49,7 @@ export interface Options {
access: OptionsAccess;
author?: string;
base?: OptionsBase;
bin?: string;
description: string;
directory: string;
email: OptionsEmail;
Expand Down
1 change: 1 addition & 0 deletions src/steps/writing/creation/writePackageJson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export async function writePackageJson(options: Options) {
...existingPackageJson,

author: { email: options.email.npm, name: options.author },
bin: options.bin,
description: options.description,
keywords: options.keywords?.length
? options.keywords.flatMap((keyword) => keyword.split(/ /))
Expand Down

0 comments on commit 21c8529

Please sign in to comment.