Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support package.json keywords #886

Merged
merged 7 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/Options.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ The setup scripts also allow for optional overrides of the following inputs whos
- `--email` _(`string`)_: Email address to be listed as the point of contact in docs and packages (e.g. `[email protected]`)
- Optionally, `--email-github` _(`string`)_ and/or `--email-npm` _(`string`)_ may be provided to use different emails in `.md` files and `package.json`, respectively
- `--funding` _(`string`)_: GitHub organization or username to mention in `funding.yml` (by default, `owner`)
- `--keywords` _(`string[]`)_: Any number of keywords to include in `package.json` (by default, none)
- This can be specified any number of times, like `--keywords apple --keywords "banana cherry"`
- `--logo` _(`string`)_: Local image file in the repository to display near the top of the README.md as a logo
- `--logo-alt` _(`string`)_: If `--logo` is provided or detected from an existing README.md, alt text that describes the image will be prompted for if not provided

Expand Down
7 changes: 4 additions & 3 deletions src/create/createRerunSuggestion.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const options = {
excludeRenovate: undefined,
excludeTests: undefined,
funding: undefined,
keywords: ["abc", "def ghi", "jkl mno pqr"],
logo: undefined,
mode: "create",
owner: "TestOwner",
Expand All @@ -45,7 +46,7 @@ describe("createRerunSuggestion", () => {
const actual = createRerunSuggestion(options);

expect(actual).toMatchInlineSnapshot(
'"npx create-typescript-app --mode create --base everything --access public --author TestAuthor --create-repository true --description \\"Test description.\\" --email-github [email protected] --email-npm [email protected] --exclude-all-contributors true --exclude-compliance true --exclude-lint-jsdoc true --exclude-lint-json true --exclude-lint-knip true --exclude-lint-package-json true --exclude-lint-perfectionist true --mode create --owner TestOwner --repository test-repository --skip-github-api true --skip-install true --skip-removal true --title \\"Test Title\\""',
'"npx create-typescript-app --mode create --base everything --access public --author TestAuthor --create-repository true --description \\"Test description.\\" --email-github [email protected] --email-npm [email protected] --exclude-all-contributors true --exclude-compliance true --exclude-lint-jsdoc true --exclude-lint-json true --exclude-lint-knip true --exclude-lint-package-json true --exclude-lint-perfectionist true --keywords \\"abc def ghi jkl mno pqr\\" --mode create --owner TestOwner --repository test-repository --skip-github-api true --skip-install true --skip-removal true --title \\"Test Title\\""',
);
});

Expand All @@ -60,7 +61,7 @@ describe("createRerunSuggestion", () => {
});

expect(actual).toMatchInlineSnapshot(
'"npx create-typescript-app --mode initialize --base everything --access public --author TestAuthor --create-repository true --description \\"Test description.\\" --email-github [email protected] --email-npm [email protected] --exclude-all-contributors true --exclude-compliance true --exclude-lint-jsdoc true --exclude-lint-json true --exclude-lint-knip true --exclude-lint-package-json true --exclude-lint-perfectionist true --logo test/src.png --logo-alt \\"Test alt.\\" --mode initialize --owner TestOwner --repository test-repository --skip-github-api true --skip-install true --skip-removal true --title \\"Test Title\\""',
'"npx create-typescript-app --mode initialize --base everything --access public --author TestAuthor --create-repository true --description \\"Test description.\\" --email-github [email protected] --email-npm [email protected] --exclude-all-contributors true --exclude-compliance true --exclude-lint-jsdoc true --exclude-lint-json true --exclude-lint-knip true --exclude-lint-package-json true --exclude-lint-perfectionist true --keywords \\"abc def ghi jkl mno pqr\\" --logo test/src.png --logo-alt \\"Test alt.\\" --mode initialize --owner TestOwner --repository test-repository --skip-github-api true --skip-install true --skip-removal true --title \\"Test Title\\""',
);
});

Expand All @@ -74,7 +75,7 @@ describe("createRerunSuggestion", () => {
});

expect(actual).toMatchInlineSnapshot(
'"npx create-typescript-app --mode initialize --base everything --access public --author TestAuthor --create-repository true --description \\"Test description.\\" --email-github [email protected] --email-npm [email protected] --exclude-all-contributors true --exclude-compliance true --exclude-lint-jsdoc true --exclude-lint-json true --exclude-lint-knip true --exclude-lint-md true --exclude-lint-package-json true --exclude-lint-perfectionist true --exclude-lint-spelling true --mode initialize --owner TestOwner --repository test-repository --skip-github-api true --skip-install true --skip-removal true --title \\"Test Title\\""',
'"npx create-typescript-app --mode initialize --base everything --access public --author TestAuthor --create-repository true --description \\"Test description.\\" --email-github [email protected] --email-npm [email protected] --exclude-all-contributors true --exclude-compliance true --exclude-lint-jsdoc true --exclude-lint-json true --exclude-lint-knip true --exclude-lint-md true --exclude-lint-package-json true --exclude-lint-perfectionist true --exclude-lint-spelling true --keywords \\"abc def ghi jkl mno pqr\\" --mode initialize --owner TestOwner --repository test-repository --skip-github-api true --skip-install true --skip-removal true --title \\"Test Title\\""',
);
});
});
19 changes: 15 additions & 4 deletions src/create/createRerunSuggestion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,23 @@ export function createRerunSuggestion(options: Partial<Options>): string {
)
.filter(([, value]) => !!value)
.map(([key, value]) => {
const valueStringified = `${value}`;
return `--${getFirstMatchingArg(key)} ${
valueStringified.includes(" ") ? `"${value}"` : value
}`;
return `--${getFirstMatchingArg(key)} ${stringifyValue(value)}`;
})
.join(" ");

return `npx create-typescript-app --mode ${options.mode} ${args}`;
}

function stringifyValue(
value: boolean | string | string[] | undefined,
): string {
if (Array.isArray(value)) {
return stringifyValue(value.join(" "));
}

const valueStringified = `${value}`;

return valueStringified.includes(" ")
? `"${valueStringified}"`
: valueStringified;
}
5 changes: 4 additions & 1 deletion src/shared/options/args.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { ParseArgsConfig } from "node:util";

export const allArgOptions = {
access: { type: "string" },
author: { type: "string" },
Expand Down Expand Up @@ -27,6 +29,7 @@ export const allArgOptions = {
"exclude-renovate": { type: "boolean" },
"exclude-tests": { type: "boolean" },
funding: { type: "string" },
keywords: { multiple: true, type: "string" },
logo: { type: "string" },
"logo-alt": { type: "string" },
mode: { type: "string" },
Expand All @@ -40,4 +43,4 @@ export const allArgOptions = {
"skip-restore": { type: "boolean" },
"skip-uninstall": { type: "boolean" },
title: { type: "string" },
} as const;
} as const satisfies ParseArgsConfig["options"];
1 change: 1 addition & 0 deletions src/shared/options/optionsSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const optionsSchemaShape = {
excludeRenovate: z.boolean().optional(),
excludeTests: z.boolean().optional(),
funding: z.string().optional(),
keywords: z.array(z.string()).optional(),
logo: z.string().optional(),
logoAlt: z.string().optional(),
mode: z
Expand Down
1 change: 1 addition & 0 deletions src/shared/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export interface Options {
excludeRenovate?: boolean;
excludeTests?: boolean;
funding?: string;
keywords?: string[];
logo: OptionsLogo | undefined;
mode: Mode;
offline?: boolean;
Expand Down
13 changes: 13 additions & 0 deletions src/steps/writing/creation/writePackageJson.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,19 @@ describe("writePackageJson", () => {
);
});

it("includes flattened keywords when they're specified", async () => {
mockReadFileSafeAsJson.mockResolvedValue({});

const keywords = ["abc", "def ghi", "jkl mno pqr"];
const packageJson = await writePackageJson({ ...options, keywords });

expect(JSON.parse(packageJson)).toEqual(
expect.objectContaining({
keywords: ["abc", "def", "ghi", "jkl", "mno", "pqr"],
}),
);
});

it("includes all optional portions when no exclusions are enabled", async () => {
mockReadFileSafeAsJson.mockResolvedValue({});

Expand Down
3 changes: 3 additions & 0 deletions src/steps/writing/creation/writePackageJson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ export async function writePackageJson(options: Options) {

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

// We copy all existing dev dependencies except those we know are not used anymore
devDependencies: copyDevDependencies(existingPackageJson),
Expand Down