Skip to content

Commit cef1179

Browse files
feat: prune existing badges out of README.md during hydration (#637)
## PR Checklist - [x] Addresses an existing open issue: fixes #502 - [x] That issue was marked as [`status: accepting prs`](https://github.com/JoshuaKGoldberg/template-typescript-node-package/issues?q=is%3Aopen+is%3Aissue+label%3A%22status%3A+accepting+prs%22) - [x] Steps in [CONTRIBUTING.md](https://github.com/JoshuaKGoldberg/template-typescript-node-package/blob/main/.github/CONTRIBUTING.md) were taken ## Overview Adds some regexp fanciness to remove existing badges. They detect badges in the two formats referenced in the issue. Also adds a bit of snapshot unit testing.
1 parent 58fe984 commit cef1179

File tree

2 files changed

+103
-2
lines changed

2 files changed

+103
-2
lines changed

src/hydrate/steps/writeReadme.test.ts

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import { describe, expect, it, vi } from "vitest";
2+
3+
import { writeReadme } from "./writeReadme.js";
4+
5+
const mockWriteFile = vi.fn();
6+
7+
vi.mock("node:fs/promises", () => ({
8+
get default() {
9+
return {
10+
get writeFile() {
11+
return mockWriteFile;
12+
},
13+
};
14+
},
15+
}));
16+
17+
const mockReadFileSafe = vi.fn();
18+
19+
vi.mock("../readFileSafe.js", () => ({
20+
get readFileSafe() {
21+
return mockReadFileSafe;
22+
},
23+
}));
24+
25+
const stubValues = {
26+
author: "Test Author",
27+
description: "Test description.",
28+
29+
funding: undefined,
30+
owner: "TestOwner",
31+
releases: undefined,
32+
repository: "test-repository",
33+
skipApi: false,
34+
skipRemoval: false,
35+
skipRestore: false,
36+
skipUninstalls: false,
37+
title: "Test Title",
38+
unitTests: undefined,
39+
};
40+
41+
describe("writeReadme", () => {
42+
it("writes a new file when README.md does not yet exist", async () => {
43+
mockReadFileSafe.mockResolvedValue(undefined);
44+
45+
await writeReadme(stubValues);
46+
47+
expect(mockWriteFile.mock.calls).toMatchInlineSnapshot(`
48+
[
49+
[
50+
"README.md",
51+
"<h1 align=\\"center\\">Test Title</h1>
52+
53+
<p align=\\"center\\">Test description.</p>
54+
55+
<p align=\\"center\\">
56+
<a href=\\"#contributors\\" target=\\"_blank\\">
57+
<!-- prettier-ignore-start -->
58+
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
59+
<img alt=\\"All Contributors: 17\\" src=\\"https://img.shields.io/badge/all_contributors-17-21bb42.svg\\" />
60+
<!-- ALL-CONTRIBUTORS-BADGE:END -->
61+
<!-- prettier-ignore-end -->
62+
</a>
63+
<a href=\\"https://codecov.io/gh/TestOwner/test-repository\\" target=\\"_blank\\">
64+
</a>
65+
<a href=\\"https://github.com/TestOwner/test-repository/blob/main/.github/CODE_OF_CONDUCT.md\\" target=\\"_blank\\">
66+
<img alt=\\"Contributor Covenant\\" src=\\"https://img.shields.io/badge/code_of_conduct-enforced-21bb42\\" />
67+
</a>
68+
<a href=\\"https://github.com/TestOwner/test-repository/blob/main/LICENSE.md\\" target=\\"_blank\\">
69+
<img alt=\\"License: MIT\\" src=\\"https://img.shields.io/github/license/TestOwner/test-repository?color=21bb42\\">
70+
</a>
71+
<img alt=\\"Style: Prettier\\" src=\\"https://img.shields.io/badge/style-prettier-21bb42.svg\\" />
72+
<img alt=\\"TypeScript: Strict\\" src=\\"https://img.shields.io/badge/typescript-strict-21bb42.svg\\" />
73+
</p>
74+
75+
76+
## Contributors
77+
78+
<!-- spellchecker: disable -->
79+
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
80+
<!-- prettier-ignore-start -->
81+
<!-- markdownlint-disable -->
82+
<table>
83+
<!-- (this will be filled in by all-contributors) -->
84+
</table>
85+
86+
<!-- markdownlint-restore -->
87+
<!-- prettier-ignore-end -->
88+
89+
<!-- ALL-CONTRIBUTORS-LIST:END -->
90+
<!-- spellchecker: enable -->
91+
",
92+
],
93+
]
94+
`);
95+
});
96+
});

src/hydrate/steps/writeReadme.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as fs from "node:fs/promises";
1+
import fs from "node:fs/promises";
22

33
import { readFileSafe } from "../../shared/readFileSafe.js";
44
import { HydrationInputValues } from "../values/types.js";
@@ -35,7 +35,12 @@ export async function writeReadme(values: HydrationInputValues) {
3535

3636
const endOfH1 = findH1Close(contents);
3737

38-
contents = [generateTopContent(values), contents.slice(endOfH1)].join("");
38+
contents = [generateTopContent(values), contents.slice(endOfH1)]
39+
.join("")
40+
.replace(/\[!\[.+\]\(.+\)\]\(.+\)/g, "")
41+
.replace(/!\[.+\]\(.+\)/g, "")
42+
.replaceAll("\r", "")
43+
.replaceAll("\n\n\n", "\n\n");
3944

4045
if (!contents.includes(contributorsIndicator)) {
4146
contents = [contents, allContributorsContent].join("\n\n");

0 commit comments

Comments
 (0)