Skip to content

Commit c71dbbf

Browse files
fix: correct readme templated-by parsing for multiple indicators (#2142)
## PR Checklist - [x] Addresses an existing open issue: fixes #2141 - [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 The two parts of README.md parsing for documentation that care about these notices are: * `additional`: which cares about the _first_ notice * `footnotes`: which cares about the _last_ notice I considered merging the two `read*` functions into a single one, but figured I could save that refactor for if this gets even more complicated / intertwined. 🎁
1 parent c0fa41b commit c71dbbf

4 files changed

+61
-11
lines changed

src/options/readReadmeAdditional.test.ts

+20
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,26 @@ Usage.
100100
101101
After.
102102
103+
> 💝 This package was templated with ...
104+
`);
105+
106+
const result = await readReadmeAdditional(getReadme);
107+
108+
expect(result).toBe("After.");
109+
});
110+
111+
it("excludes templated notices contributors when there are comment and quote template notices", async () => {
112+
const getReadme = () =>
113+
Promise.resolve(`# My Package
114+
115+
Usage.
116+
117+
<!-- spellchecker:enable -->
118+
119+
After.
120+
121+
<!-- You can remove this notice if you don't want it 🙂 no worries! -->
122+
103123
> 💝 This package was templated with ...
104124
`);
105125

src/options/readReadmeAdditional.ts

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { indicatorTemplatedBy } from "./readReadmeFootnotes.js";
1+
import { indicatorsTemplatedBy } from "./readReadmeFootnotes.js";
22

33
const indicatorAfterAllContributors = /<!--\s*ALL-CONTRIBUTORS-LIST:END\s*-->/;
44
const indicatorAfterAllContributorsSpellCheck =
@@ -17,12 +17,18 @@ export async function readReadmeAdditional(getReadme: () => Promise<string>) {
1717
return undefined;
1818
}
1919

20-
const templatedByMatch = indicatorTemplatedBy.exec(readme);
20+
const indexOfFirstTemplatedBy = indicatorsTemplatedBy.reduce(
21+
(smallest, indicator) => {
22+
const indexOf = indicator.exec(readme)?.index;
23+
return indexOf ? Math.min(smallest, indexOf) : smallest;
24+
},
25+
readme.length,
26+
);
2127

2228
return readme
2329
.slice(
2430
indexAfterContributors.index + indexAfterContributors[0].length,
25-
templatedByMatch?.index,
31+
indexOfFirstTemplatedBy,
2632
)
2733
.trim();
2834
}

src/options/readReadmeFootnotes.test.ts

+19-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ describe(readReadmeFootnotes, () => {
1919
expect(result).toBeUndefined();
2020
});
2121

22-
it("resolves undefined when there is no content after a templated by notice", async () => {
22+
it("resolves undefined when there is no content after a quote templated by notice", async () => {
2323
const getReadme = () =>
2424
Promise.resolve(`# My Package
2525
@@ -32,7 +32,7 @@ describe(readReadmeFootnotes, () => {
3232
expect(result).toBeUndefined();
3333
});
3434

35-
it("resolves the content when there plain text content after a templated by notice", async () => {
35+
it("resolves the content when there plain text content after a quote templated by notice", async () => {
3636
const getReadme = () =>
3737
Promise.resolve(`# My Package
3838
@@ -46,12 +46,28 @@ After.
4646
expect(result).toBe("After.");
4747
});
4848

49-
it("resolves the content when there are footnotes after a templated by notice", async () => {
49+
it("resolves the content when there are footnotes after a quote templated by notice", async () => {
5050
const getReadme = () =>
5151
Promise.resolve(`# My Package
5252
5353
> 💖 This package was templated with etc. etc.
5454
55+
[^1]: After.
56+
`);
57+
58+
const result = await readReadmeFootnotes(getReadme);
59+
60+
expect(result).toBe("[^1]: After.");
61+
});
62+
63+
it("resolves the content when there are footnotes after a comment and quote templated by notice", async () => {
64+
const getReadme = () =>
65+
Promise.resolve(`# My Package
66+
67+
<!-- You can remove this notice etc. etc. -->
68+
69+
> 💖 This package was templated with etc. etc.
70+
5571
[^1]: After.
5672
`);
5773

src/options/readReadmeFootnotes.ts

+13-5
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
1-
export const indicatorTemplatedBy =
2-
/> .* This package (?:is|was) (?:based|build|templated) (?:on|with) |<!-- You can remove this notice/;
1+
export const indicatorsTemplatedBy = [
2+
/> .* This package (?:is|was) (?:based|build|templated) (?:on|with)/,
3+
/<!-- You can remove this notice/,
4+
];
35

46
export async function readReadmeFootnotes(getReadme: () => Promise<string>) {
57
const readme = await getReadme();
68
if (!readme) {
79
return undefined;
810
}
911

10-
const indexOfTemplatedBy = indicatorTemplatedBy.exec(readme)?.index;
11-
if (!indexOfTemplatedBy) {
12+
const indexOfLastTemplatedBy = indicatorsTemplatedBy.reduce(
13+
(largest, indicator) => {
14+
const indexOf = indicator.exec(readme)?.index;
15+
return indexOf ? Math.max(largest, indexOf) : largest;
16+
},
17+
0,
18+
);
19+
if (!indexOfLastTemplatedBy) {
1220
return undefined;
1321
}
1422

15-
const indexOfNextLine = readme.indexOf("\n", indexOfTemplatedBy);
23+
const indexOfNextLine = readme.indexOf("\n", indexOfLastTemplatedBy);
1624

1725
return readme.slice(indexOfNextLine).trim() || undefined;
1826
}

0 commit comments

Comments
 (0)