Skip to content

Commit 398e947

Browse files
feat: add logo.height and logo.width (#1806)
## PR Checklist - [x] Addresses an existing open issue: fixes #1203 - [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 Uses [`image-size`](https://github.com/image-size/image-size) to read from disk, if possible. Caps sizes to 128px. Doesn't bother adding a warning logo - I don't feel strongly about it, and have yet to have come across a situation where I would have been helped by that. 💖
1 parent 42c6ebd commit 398e947

18 files changed

+315
-3
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<img alt="💪 TypeScript: Strict" src="https://img.shields.io/badge/%F0%9F%92%AA_typescript-strict-21bb42.svg" />
1616
</p>
1717

18-
<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">
18+
<img align="right" alt="Project logo: the TypeScript blue square with rounded corners, but a plus sign instead of 'TS'" height="128" src="./docs/create-typescript-app.png" width="128">
1919

2020
`create-typescript-app` is a one-stop-shop solution to set up a new or existing repository with the latest and greatest TypeScript tooling.
2121
It includes options not just for building and testing but also GitHub repository templates, contributor recognition, automated release management, and more.

docs/Options.md

+2
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ The setup scripts also allow for optional overrides of the following inputs whos
6464
- This can be specified any number of times, like `--keywords apple --keywords "banana cherry"`
6565
- `--logo` _(`string`)_: Local image file in the repository to display near the top of the README.md
6666
- `--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)
67+
- `--logo-height` _(`number`)_: If `--logo` is provided or detected from an existing README.md, an explicit height style (by default, read from the image, capped to `128`)
68+
- `--logo-width` _(`number`)_: If `--logo` is provided or detected from an existing README.md, an explicit width style (by default, read from the image, capped to `128`)
6769
- `--preserve-generated-from` _(`boolean`)_: Whether to keep the GitHub repository _generated from_ notice (by default, `false`)
6870

6971
For example, customizing the ownership and users associated with a new repository:

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
"execa": "^9.5.2",
5050
"git-remote-origin-url": "^4.0.0",
5151
"git-url-parse": "^16.0.0",
52+
"image-size": "^1.2.0",
5253
"input-from-file": "0.1.0-alpha.4",
5354
"input-from-file-json": "0.1.0-alpha.4",
5455
"input-from-script": "0.1.0-alpha.4",

pnpm-lock.yaml

+19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/bin/help.test.ts

+10
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,16 @@ describe("logHelpText", () => {
176176
--logo-alt (string): If --logo is provided or detected from an existing README.md,
177177
alt text that describes the image will be prompted for if not provided",
178178
],
179+
[
180+
"
181+
--logo-height (string): If --logo is provided or detected from an existing README.md,
182+
an explicit height style",
183+
],
184+
[
185+
"
186+
--logo-width (string): If --logo is provided or detected from an existing README.md,
187+
an explicit width style",
188+
],
179189
[
180190
"
181191
--preserve-generated-from: Whether to keep the GitHub repository generated from

src/next/base.ts

+2
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ export const base = createBase({
9595
logo: z
9696
.object({
9797
alt: z.string(),
98+
height: z.number().optional(),
9899
src: z.string(),
100+
width: z.number().optional(),
99101
})
100102
.optional()
101103
.describe(

src/next/blocks/blockREADME.test.ts

+63-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { blockREADME } from "./blockREADME.js";
55
import { optionsBase } from "./options.fakes.js";
66

77
describe("blockREADME", () => {
8-
test("options.logo", () => {
8+
test("options.logo without sizing", () => {
99
const creation = testBlock(blockREADME, {
1010
options: {
1111
...optionsBase,
@@ -65,6 +65,68 @@ describe("blockREADME", () => {
6565
`);
6666
});
6767

68+
test("options.logo with sizing", () => {
69+
const creation = testBlock(blockREADME, {
70+
options: {
71+
...optionsBase,
72+
logo: {
73+
alt: "My logo",
74+
height: 100,
75+
src: "img.jpg",
76+
width: 128,
77+
},
78+
},
79+
});
80+
81+
expect(creation).toMatchInlineSnapshot(`
82+
{
83+
"files": {
84+
"README.md": "<h1 align="center">Test Title</h1>
85+
86+
<p align="center">Test description</p>
87+
88+
<p align="center">
89+
<!-- prettier-ignore-start -->
90+
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
91+
<!-- ALL-CONTRIBUTORS-BADGE:END -->
92+
<!-- prettier-ignore-end -->
93+
<a href="https://github.com/test-owner/test-repository/blob/main/.github/CODE_OF_CONDUCT.md" target="_blank"><img alt="🤝 Code of Conduct: Kept" src="https://img.shields.io/badge/%F0%9F%A4%9D_code_of_conduct-kept-21bb42" /></a>
94+
<a href="https://codecov.io/gh/test-owner/test-repository" target="_blank"><img alt="🧪 Coverage" src="https://img.shields.io/codecov/c/github/test-owner/test-repository?label=%F0%9F%A7%AA%20coverage" /></a>
95+
<a href="https://github.com/test-owner/test-repository/blob/main/LICENSE.md" target="_blank"><img alt="📝 License: MIT" src="https://img.shields.io/badge/%F0%9F%93%9D_license-MIT-21bb42.svg"></a>
96+
<a href="http://npmjs.com/package/test-repository"><img alt="📦 npm version" src="https://img.shields.io/npm/v/test-repository?color=21bb42&label=%F0%9F%93%A6%20npm" /></a>
97+
<img alt="💪 TypeScript: Strict" src="https://img.shields.io/badge/%F0%9F%92%AA_typescript-strict-21bb42.svg" />
98+
</p>
99+
100+
<img align="right" alt="My logo" height="100" src="img.jpg" width="128">
101+
102+
## Usage
103+
104+
\`\`\`shell
105+
npm i test-repository
106+
\`\`\`
107+
\`\`\`ts
108+
import { greet } from "test-repository";
109+
110+
greet("Hello, world! 💖");
111+
\`\`\`
112+
113+
## Development
114+
115+
See [\`.github/CONTRIBUTING.md\`](./.github/CONTRIBUTING.md), then [\`.github/DEVELOPMENT.md\`](./.github/DEVELOPMENT.md).
116+
Thanks! 💖
117+
118+
## Contributors
119+
120+
<!-- spellchecker: disable -->
121+
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
122+
<!-- ALL-CONTRIBUTORS-LIST:END -->
123+
<!-- spellchecker: enable -->
124+
",
125+
},
126+
}
127+
`);
128+
});
129+
68130
test("without addons", () => {
69131
const creation = testBlock(blockREADME, {
70132
options: optionsBase,

src/next/blocks/blockREADME.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ import { z } from "zod";
22

33
import { base } from "../base.js";
44

5+
function printAttributes(attributes: Record<string, number | string>) {
6+
return Object.entries(attributes)
7+
.map(([key, value]) => `${key}="${value}"`)
8+
.join(" ");
9+
}
10+
511
export const blockREADME = base.createBlock({
612
about: {
713
name: "README.md",
@@ -12,6 +18,10 @@ export const blockREADME = base.createBlock({
1218
produce({ addons, options }) {
1319
const { notices } = addons;
1420

21+
const logo = options.logo
22+
? `<img ${printAttributes({ align: "right", ...options.logo })}>`
23+
: "";
24+
1525
return {
1626
files: {
1727
"README.md": `<h1 align="center">${options.title}</h1>
@@ -30,7 +40,7 @@ export const blockREADME = base.createBlock({
3040
<img alt="💪 TypeScript: Strict" src="https://img.shields.io/badge/%F0%9F%92%AA_typescript-strict-21bb42.svg" />
3141
</p>
3242
33-
${options.logo ? `<img align="right" alt="${options.logo.alt}" src="${options.logo.src}">` : ""}
43+
${logo}
3444
3545
## Usage
3646

src/shared/options/args.ts

+16
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,22 @@ export const allArgOptions = {
231231
docsSection: "optional",
232232
type: "string",
233233
},
234+
"logo-height": {
235+
description: `If ${chalk.cyanBright(
236+
"--logo",
237+
)} is provided or detected from an existing README.md,
238+
an explicit height style`,
239+
docsSection: "optional",
240+
type: "string",
241+
},
242+
"logo-width": {
243+
description: `If ${chalk.cyanBright(
244+
"--logo",
245+
)} is provided or detected from an existing README.md,
246+
an explicit width style`,
247+
docsSection: "optional",
248+
type: "string",
249+
},
234250
mode: {
235251
description: `Whether to:
236252
• create: a new repository in a child directory

src/shared/options/createOptionDefaults/readDefaultsFromReadme.test.ts

+26
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ vi.mock("../../readFileSafe.js", () => ({
1010
},
1111
}));
1212

13+
const mockReadLogoSizing = vi.fn().mockResolvedValue({});
14+
15+
vi.mock("../readLogoSizing.js", () => ({
16+
get readLogoSizing() {
17+
return mockReadLogoSizing;
18+
},
19+
}));
20+
1321
describe("readDefaultsFromReadme", () => {
1422
describe("logo", () => {
1523
it("defaults to undefined when it cannot be found", async () => {
@@ -87,6 +95,24 @@ nothing.
8795
});
8896
});
8997

98+
it("includes sizing when readLogoSizing returns sizing", async () => {
99+
const sizing = { height: 117, width: 128 };
100+
101+
mockReadFileSafe.mockResolvedValue(`
102+
<img alt='Project logo: a fancy circle' src='abc/def.jpg'/>,
103+
`);
104+
105+
mockReadLogoSizing.mockReturnValueOnce(sizing);
106+
107+
const logo = await readDefaultsFromReadme().logo();
108+
109+
expect(logo).toEqual({
110+
alt: "Project logo: a fancy circle",
111+
src: "abc/def.jpg",
112+
...sizing,
113+
});
114+
});
115+
90116
it("parses when found after a badge image", async () => {
91117
mockReadFileSafe.mockResolvedValue(`
92118
<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>

src/shared/options/createOptionDefaults/readDefaultsFromReadme.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import lazyValue from "lazy-value";
22

33
import { readFileSafe } from "../../readFileSafe.js";
4+
import { readLogoSizing } from "../readLogoSizing.js";
45

56
export function readDefaultsFromReadme() {
67
const readme = lazyValue(async () => await readFileSafe("README.md", ""));
@@ -28,6 +29,7 @@ export function readDefaultsFromReadme() {
2829
return {
2930
alt: /alt=['"](.+)['"]\s*src=/.exec(tag)?.[1] ?? "Project logo",
3031
src,
32+
...readLogoSizing(src),
3133
};
3234
},
3335
title: async () => {

src/shared/options/logInferredOptions.ts

+8
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ export function logInferredOptions(augmentedOptions: InferredOptions) {
2323
if (augmentedOptions.logo) {
2424
logLine(chalk.gray(`- logo: ${augmentedOptions.logo.src}`));
2525
logLine(chalk.gray(`- logo-alt: ${augmentedOptions.logo.alt}`));
26+
27+
if (augmentedOptions.logo.height) {
28+
logLine(chalk.gray(`- logo-height: ${augmentedOptions.logo.height}`));
29+
}
30+
31+
if (augmentedOptions.logo.width) {
32+
logLine(chalk.gray(`- logo-width: ${augmentedOptions.logo.width}`));
33+
}
2634
}
2735

2836
logLine(chalk.gray(`- owner: ${augmentedOptions.owner}`));

0 commit comments

Comments
 (0)