Skip to content

Commit

Permalink
chore: add usage option for create engine (#1822)
Browse files Browse the repository at this point in the history
## PR Checklist

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

Marking as `chore:` because this is only for the new `create` Blocks
engine.

💖
  • Loading branch information
JoshuaKGoldberg authored Dec 31, 2024
1 parent f109519 commit c8c7591
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 73 deletions.
6 changes: 5 additions & 1 deletion src/next/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ export const base = createBase({
.string()
.describe("'Sentence case.' description of the repository"),
title: z.string().describe("'Title Case' title for the repository"),
usage: z
.string()
.optional()
.describe("markdown docs to put in README.md under the ## Usage heading"),
version: z
.string()
.optional()
Expand Down Expand Up @@ -223,7 +227,7 @@ export const base = createBase({
options.repository ??
(await gitDefaults())?.name ??
(await packageData()).name,
...readDefaultsFromReadme(readme),
...readDefaultsFromReadme(readme, options.repository),
version,
};
},
Expand Down
49 changes: 13 additions & 36 deletions src/next/blocks/blockREADME.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@ import { describe, expect, test } from "vitest";
import { blockREADME } from "./blockREADME.js";
import { optionsBase } from "./options.fakes.js";

const options = {
...optionsBase,
usage: "Use it.",
};

describe("blockREADME", () => {
test("options.logo without sizing", () => {
const creation = testBlock(blockREADME, {
options: {
...optionsBase,
...options,
logo: {
alt: "My logo",
src: "img.jpg",
Expand Down Expand Up @@ -39,14 +44,7 @@ describe("blockREADME", () => {
## Usage
\`\`\`shell
npm i test-repository
\`\`\`
\`\`\`ts
import { greet } from "test-repository";
greet("Hello, world! 💖");
\`\`\`
Use it.
## Development
Expand All @@ -68,7 +66,7 @@ describe("blockREADME", () => {
test("options.logo with sizing", () => {
const creation = testBlock(blockREADME, {
options: {
...optionsBase,
...options,
logo: {
alt: "My logo",
height: 100,
Expand Down Expand Up @@ -101,14 +99,7 @@ describe("blockREADME", () => {
## Usage
\`\`\`shell
npm i test-repository
\`\`\`
\`\`\`ts
import { greet } from "test-repository";
greet("Hello, world! 💖");
\`\`\`
Use it.
## Development
Expand All @@ -129,7 +120,7 @@ describe("blockREADME", () => {

test("without addons", () => {
const creation = testBlock(blockREADME, {
options: optionsBase,
options,
});

expect(creation).toMatchInlineSnapshot(`
Expand All @@ -155,14 +146,7 @@ describe("blockREADME", () => {
## Usage
\`\`\`shell
npm i test-repository
\`\`\`
\`\`\`ts
import { greet } from "test-repository";
greet("Hello, world! 💖");
\`\`\`
Use it.
## Development
Expand All @@ -186,7 +170,7 @@ describe("blockREADME", () => {
addons: {
notices: ["> Hello, world! 💖"],
},
options: optionsBase,
options,
});

expect(creation).toMatchInlineSnapshot(`
Expand All @@ -212,14 +196,7 @@ describe("blockREADME", () => {
## Usage
\`\`\`shell
npm i test-repository
\`\`\`
\`\`\`ts
import { greet } from "test-repository";
greet("Hello, world! 💖");
\`\`\`
Use it.
## Development
Expand Down
9 changes: 1 addition & 8 deletions src/next/blocks/blockREADME.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,7 @@ ${logo}
## Usage
\`\`\`shell
npm i ${options.repository}
\`\`\`
\`\`\`ts
import { greet } from "${options.repository}";
greet("Hello, world! 💖");
\`\`\`
${options.usage}
## Development
Expand Down
29 changes: 29 additions & 0 deletions src/shared/options/createOptionDefaults/getUsageFromReadme.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { describe, expect, it } from "vitest";

import { getUsageFromReadme } from "./getUsageFromReadme.js";

describe("getUsageFromReadme", () => {
it("returns undefined when ## Usage is not found", () => {
const usage = getUsageFromReadme("## Other");

expect(usage).toBeUndefined();
});

it("returns undefined when ## Usage found and ## Development is not found", () => {
const usage = getUsageFromReadme("## Usage\n\nContents.");

expect(usage).toBeUndefined();
});

it("returns undefined when there is no content between ## Usage and ## Development", () => {
const usage = getUsageFromReadme("## Usage\n\n \n## Development");

expect(usage).toBeUndefined();
});

it("returns the content when content exists between ## Usage and ## Development", () => {
const usage = getUsageFromReadme("## Usage\n\n Content.\n## Development");

expect(usage).toBe("Content.");
});
});
23 changes: 23 additions & 0 deletions src/shared/options/createOptionDefaults/getUsageFromReadme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const startDevelopment = "## Development";
const startUsage = "## Usage";

export function getUsageFromReadme(readme: string) {
const indexOfUsage = readme.indexOf(startUsage);
if (indexOfUsage === -1) {
return undefined;
}

const indexOfDevelopment = readme.indexOf(
startDevelopment,
indexOfUsage + startUsage.length,
);
if (indexOfDevelopment === -1) {
return undefined;
}

const usage = readme
.slice(indexOfUsage + startUsage.length, indexOfDevelopment)
.trim();

return usage ? usage : undefined;
}
2 changes: 1 addition & 1 deletion src/shared/options/createOptionDefaults/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@ export function createOptionDefaults(promptedOptions?: PromptedOptions) {
promptedOptions?.repository ??
(await gitDefaults())?.name ??
(await packageData()).name,
...readDefaultsFromReadme(readme),
...readDefaultsFromReadme(readme, promptedOptions?.repository),
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,20 @@ vi.mock("../readLogoSizing.js", () => ({
describe("readDefaultsFromReadme", () => {
describe("logo", () => {
it("defaults to undefined when it cannot be found", async () => {
const logo = await readDefaultsFromReadme(() =>
Promise.resolve(`nothing.`),
const logo = await readDefaultsFromReadme(
() => Promise.resolve(`nothing.`),
undefined,
).logo();

expect(logo).toBeUndefined();
});

it("parses when found in an unquoted string", async () => {
const logo = await readDefaultsFromReadme(() =>
Promise.resolve(`
const logo = await readDefaultsFromReadme(
() =>
Promise.resolve(`
<img src=abc/def.jpg/>`),
undefined,
).logo();

expect(logo).toEqual({
Expand All @@ -33,9 +36,11 @@ describe("readDefaultsFromReadme", () => {
});

it("parses when found in a single quoted string", async () => {
const logo = await readDefaultsFromReadme(() =>
Promise.resolve(`
const logo = await readDefaultsFromReadme(
() =>
Promise.resolve(`
<img src='abc/def.jpg'/>`),
undefined,
).logo();

expect(logo).toEqual({
Expand All @@ -45,9 +50,11 @@ describe("readDefaultsFromReadme", () => {
});

it("parses when found in a double quoted string", async () => {
const logo = await readDefaultsFromReadme(() =>
Promise.resolve(`
const logo = await readDefaultsFromReadme(
() =>
Promise.resolve(`
<img src="abc/def.jpg"/>`),
undefined,
).logo();

expect(logo).toEqual({
Expand All @@ -57,9 +64,11 @@ describe("readDefaultsFromReadme", () => {
});

it("includes alt text when it exists in double quotes", async () => {
const logo = await readDefaultsFromReadme(() =>
Promise.resolve(`
const logo = await readDefaultsFromReadme(
() =>
Promise.resolve(`
<img alt="Project logo: a fancy circle" src="abc/def.jpg"/>`),
undefined,
).logo();

expect(logo).toEqual({
Expand All @@ -69,9 +78,11 @@ describe("readDefaultsFromReadme", () => {
});

it("includes alt text when it exists in single quotes", async () => {
const logo = await readDefaultsFromReadme(() =>
Promise.resolve(`
const logo = await readDefaultsFromReadme(
() =>
Promise.resolve(`
<img alt='Project logo: a fancy circle' src='abc/def.jpg'/>`),
undefined,
).logo();

expect(logo).toEqual({
Expand All @@ -85,9 +96,11 @@ describe("readDefaultsFromReadme", () => {

mockReadLogoSizing.mockReturnValueOnce(sizing);

const logo = await readDefaultsFromReadme(() =>
Promise.resolve(`
const logo = await readDefaultsFromReadme(
() =>
Promise.resolve(`
<img alt='Project logo: a fancy circle' src='abc/def.jpg'/>`),
undefined,
).logo();

expect(logo).toEqual({
Expand All @@ -98,11 +111,13 @@ describe("readDefaultsFromReadme", () => {
});

it("parses when found after a badge image", async () => {
const logo = await readDefaultsFromReadme(() =>
Promise.resolve(`
const logo = await readDefaultsFromReadme(
() =>
Promise.resolve(`
<a href="#contributors" target="_blank"><img alt="👪 All Contributors: 48" src="https://img.shields.io/badge/%F0%9F%91%AA_all_contributors-48-21bb42.svg" /></a>
<img src=abc/def.jpg/>
`),
undefined,
).logo();

expect(logo).toEqual({
Expand All @@ -112,8 +127,9 @@ describe("readDefaultsFromReadme", () => {
});

it("parses when found after an h1 and many badge images", async () => {
const logo = await readDefaultsFromReadme(() =>
Promise.resolve(`
const logo = await readDefaultsFromReadme(
() =>
Promise.resolve(`
<h1 align="center">Create TypeScript App</h1>
<p align="center">Quickstart-friendly TypeScript template with comprehensive, configurable, opinionated tooling. ❤️‍🔥</p>
Expand All @@ -133,6 +149,7 @@ describe("readDefaultsFromReadme", () => {
<img align="right" alt="Project logo: the TypeScript blue square with rounded corners, but a plus sign instead of 'TS'" src="./docs/create-typescript-app.png">
`),
undefined,
).logo();

expect(logo).toEqual({
Expand All @@ -144,32 +161,36 @@ describe("readDefaultsFromReadme", () => {

describe("title", () => {
it("defaults to undefined when it cannot be found", async () => {
const title = await readDefaultsFromReadme(() =>
Promise.resolve(`nothing`),
const title = await readDefaultsFromReadme(
() => Promise.resolve(`nothing`),
undefined,
).title();

expect(title).toBeUndefined();
});

it('reads title as markdown from "README.md" when it exists', async () => {
const title = await readDefaultsFromReadme(() =>
Promise.resolve(`# My Awesome Package`),
const title = await readDefaultsFromReadme(
() => Promise.resolve(`# My Awesome Package`),
undefined,
).title();

expect(title).toBe("My Awesome Package");
});

it('reads title as HTML from "README.md" when it exists', async () => {
const title = await readDefaultsFromReadme(() =>
Promise.resolve('<h1 align="center">My Awesome Package</h1>'),
const title = await readDefaultsFromReadme(
() => Promise.resolve('<h1 align="center">My Awesome Package</h1>'),
undefined,
).title();

expect(title).toBe("My Awesome Package");
});

it("returns undefined when title does not exist", async () => {
const title = await readDefaultsFromReadme(() =>
Promise.resolve(`Other text.`),
const title = await readDefaultsFromReadme(
() => Promise.resolve(`Other text.`),
undefined,
).title();

expect(title).toBeUndefined();
Expand Down
Loading

0 comments on commit c8c7591

Please sign in to comment.