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

fix: lazily evaluate options.repository for options.usage #1827

Merged
merged 2 commits into from
Jan 1, 2025
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
15 changes: 10 additions & 5 deletions src/next/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,14 @@ export const base = createBase({

const version = lazyValue(async () => (await packageData()).version);

const repository = lazyValue(
async () =>
options.repository ??
(await gitDefaults())?.name ??
(await packageData()).name ??
options.directory,
);

return {
access: "public" as const,
author,
Expand All @@ -222,11 +230,8 @@ export const base = createBase({
scripts: original.scripts,
};
},
repository: async () =>
options.repository ??
(await gitDefaults())?.name ??
(await packageData()).name,
...readDefaultsFromReadme(readme, options.repository),
repository,
...readDefaultsFromReadme(readme, repository),
version,
};
},
Expand Down
12 changes: 11 additions & 1 deletion src/shared/options/createOptionDefaults/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,13 +196,23 @@ describe("createOptionDefaults", () => {
expect(actual).toBe(name);
});

it("returns the package name when it exists and promptedOptions.repository a Git name don't", async () => {
it("returns the package name when it exists and promptedOptions.repository and Git name don't", async () => {
const name = "test-package-name";
mockReadPackageData.mockResolvedValueOnce({ name });

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

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

it("returns the directory when it exists and promptedOptions.repository, Git name, and package name don't", async () => {
mockReadPackageData.mockResolvedValueOnce({});
const directory = "test-prompted-directory";
const promptedOptions = { directory };

const actual = await createOptionDefaults(promptedOptions).repository();

expect(actual).toBe(directory);
});
});
});
7 changes: 5 additions & 2 deletions src/shared/options/createOptionDefaults/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ export function createOptionDefaults(promptedOptions?: PromptedOptions) {
repository: async () =>
promptedOptions?.repository ??
(await gitDefaults())?.name ??
(await packageData()).name,
...readDefaultsFromReadme(readme, promptedOptions?.repository),
(await packageData()).name ??
promptedOptions?.directory,
...readDefaultsFromReadme(readme, () =>
Promise.resolve(promptedOptions?.repository),
),
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,20 @@ vi.mock("../readLogoSizing.js", () => ({
},
}));

const mockGetUsageFromReadme = vi.fn().mockResolvedValue({});

vi.mock("./getUsageFromReadme.js", () => ({
get getUsageFromReadme() {
return mockGetUsageFromReadme;
},
}));

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

expect(logo).toBeUndefined();
Expand All @@ -26,7 +34,7 @@ describe("readDefaultsFromReadme", () => {
() =>
Promise.resolve(`
<img src=abc/def.jpg/>`),
undefined,
() => Promise.resolve(undefined),
).logo();

expect(logo).toEqual({
Expand All @@ -40,7 +48,7 @@ describe("readDefaultsFromReadme", () => {
() =>
Promise.resolve(`
<img src='abc/def.jpg'/>`),
undefined,
() => Promise.resolve(undefined),
).logo();

expect(logo).toEqual({
Expand All @@ -54,7 +62,7 @@ describe("readDefaultsFromReadme", () => {
() =>
Promise.resolve(`
<img src="abc/def.jpg"/>`),
undefined,
() => Promise.resolve(undefined),
).logo();

expect(logo).toEqual({
Expand All @@ -68,7 +76,7 @@ describe("readDefaultsFromReadme", () => {
() =>
Promise.resolve(`
<img alt="Project logo: a fancy circle" src="abc/def.jpg"/>`),
undefined,
() => Promise.resolve(undefined),
).logo();

expect(logo).toEqual({
Expand All @@ -82,7 +90,7 @@ describe("readDefaultsFromReadme", () => {
() =>
Promise.resolve(`
<img alt='Project logo: a fancy circle' src='abc/def.jpg'/>`),
undefined,
() => Promise.resolve(undefined),
).logo();

expect(logo).toEqual({
Expand All @@ -100,7 +108,7 @@ describe("readDefaultsFromReadme", () => {
() =>
Promise.resolve(`
<img alt='Project logo: a fancy circle' src='abc/def.jpg'/>`),
undefined,
() => Promise.resolve(undefined),
).logo();

expect(logo).toEqual({
Expand All @@ -117,7 +125,7 @@ describe("readDefaultsFromReadme", () => {
<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,
() => Promise.resolve(undefined),
).logo();

expect(logo).toEqual({
Expand Down Expand Up @@ -149,7 +157,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,
() => Promise.resolve(undefined),
).logo();

expect(logo).toEqual({
Expand All @@ -163,7 +171,7 @@ describe("readDefaultsFromReadme", () => {
it("defaults to undefined when it cannot be found", async () => {
const title = await readDefaultsFromReadme(
() => Promise.resolve(`nothing`),
undefined,
() => Promise.resolve(undefined),
).title();

expect(title).toBeUndefined();
Expand All @@ -172,7 +180,7 @@ describe("readDefaultsFromReadme", () => {
it('reads title as markdown from "README.md" when it exists', async () => {
const title = await readDefaultsFromReadme(
() => Promise.resolve(`# My Awesome Package`),
undefined,
() => Promise.resolve(undefined),
).title();

expect(title).toBe("My Awesome Package");
Expand All @@ -181,7 +189,7 @@ describe("readDefaultsFromReadme", () => {
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>'),
undefined,
() => Promise.resolve(undefined),
).title();

expect(title).toBe("My Awesome Package");
Expand All @@ -190,10 +198,43 @@ describe("readDefaultsFromReadme", () => {
it("returns undefined when title does not exist", async () => {
const title = await readDefaultsFromReadme(
() => Promise.resolve(`Other text.`),
undefined,
() => Promise.resolve(undefined),
).title();

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

describe("usage", () => {
it("returns the existing usage when getUsageFromReadme provides one", async () => {
const existing = "Use it.";

mockGetUsageFromReadme.mockReturnValueOnce(existing);

const usage = await readDefaultsFromReadme(
() => Promise.resolve(""),
() => Promise.resolve(undefined),
).usage();

expect(usage).toBe(existing);
});

it("returns sample usage when getUsageFromReadme doesn't provide usage", async () => {
mockGetUsageFromReadme.mockReturnValueOnce(undefined);

const usage = await readDefaultsFromReadme(
() => Promise.resolve(""),
() => Promise.resolve("test-repository"),
).usage();

expect(usage).toBe(`\`\`\`shell
npm i test-repository
\`\`\`
\`\`\`ts
import { greet } from "test-repository";

greet("Hello, world! 💖");
\`\`\``);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { getUsageFromReadme } from "./getUsageFromReadme.js";

export function readDefaultsFromReadme(
readme: () => Promise<string>,
repository: string | undefined,
repository: () => Promise<string | undefined>,
) {
const imageTag = lazyValue(
async () => /\n<img.+src=.+>/.exec(await readme())?.[0],
Expand Down Expand Up @@ -43,10 +43,10 @@ export function readDefaultsFromReadme(
return (
getUsageFromReadme(await readme()) ??
`\`\`\`shell
npm i ${repository}
npm i ${await repository()}
\`\`\`
\`\`\`ts
import { greet } from "${repository}";
import { greet } from "${await repository()}";

greet("Hello, world! 💖");
\`\`\``
Expand Down
Loading