Skip to content

Commit 36281e4

Browse files
committed
refactor: use Eleventy's collection API for article discovery
Replace duplicated globby + gray-matter + tag filtering in four scripts with a shared getArticles() utility that uses Eleventy's own collection API as the single source of truth for what constitutes an article.
1 parent a4d785c commit 36281e4

5 files changed

Lines changed: 63 additions & 59 deletions

File tree

11ty/get-articles.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import Eleventy, { type CollectionApi, type EleventyEntry } from '@11ty/eleventy'
2+
import matter from 'gray-matter'
3+
import { readFile } from 'node:fs/promises'
4+
5+
export interface ArticleInfo {
6+
filePath: string
7+
data: Record<string, any>
8+
content: string
9+
rawInput: string
10+
}
11+
12+
export async function getArticles(): Promise<ArticleInfo[]> {
13+
let captured: EleventyEntry[] = []
14+
15+
const elev = new Eleventy('www', 'dist/www', {
16+
quietMode: true,
17+
config(config) {
18+
config.addCollection('_getArticles', (api: CollectionApi) => {
19+
captured = api.getFilteredByTag('article')
20+
return captured
21+
})
22+
},
23+
})
24+
25+
await elev.toJSON()
26+
27+
return Promise.all(
28+
captured.map(async (entry) => {
29+
const filePath = entry.inputPath.replace(/^\.\//, '')
30+
const rawInput = await readFile(filePath, 'utf-8')
31+
const parsed = matter(rawInput)
32+
return {
33+
filePath,
34+
data: entry.data,
35+
content: parsed.content,
36+
rawInput,
37+
}
38+
})
39+
)
40+
}

11ty/update-revisions.ts

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
import { globby } from 'globby'
2-
import matter from 'gray-matter'
3-
import { readFile } from 'node:fs/promises'
4-
1+
import { getArticles } from './get-articles.ts'
52
import {
63
computeHash,
74
getCommitMessage,
@@ -14,19 +11,12 @@ async function main() {
1411
const revisions = await loadRevisions()
1512
const commit = getCurrentCommit()
1613

17-
const files = await globby('www/**/*.md')
14+
const articles = await getArticles()
1815
let revisionCount = 0
1916

20-
for (const filePath of files) {
21-
const fileContent = await readFile(filePath, 'utf-8')
22-
const parsed = matter(fileContent)
23-
24-
const tags: string[] = parsed.data.tags ?? []
25-
if (!tags.includes('article')) continue
26-
27-
const title = parsed.data.title as string
28-
const subhead = parsed.data.subhead as string | undefined
29-
const content = parsed.content
17+
for (const { filePath, data, content } of articles) {
18+
const title = data.title as string
19+
const subhead = data.subhead as string | undefined
3020

3121
const hash = computeHash(title, subhead, content)
3222

bin/backfill-revisions.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import { globby } from 'globby'
21
import matter from 'gray-matter'
32
import { execFileSync } from 'node:child_process'
4-
import { readFile } from 'node:fs/promises'
53

4+
import { getArticles } from '../11ty/get-articles.ts'
65
import {
76
type RevisionsFile,
87
REVISIONS_PATH,
@@ -46,7 +45,7 @@ function getFileAtCommit(sha: string, filePath: string): string | null {
4645
}
4746

4847
async function main() {
49-
const files = await globby('www/**/*.md')
48+
const articles = await getArticles()
5049
const revisions: RevisionsFile = {
5150
versions: {
5251
'1': {
@@ -62,13 +61,7 @@ async function main() {
6261
let totalFiles = 0
6362
let totalRevisions = 0
6463

65-
for (const filePath of files) {
66-
const fileContent = await readFile(filePath, 'utf-8')
67-
const parsed = matter(fileContent)
68-
69-
const tags: string[] = parsed.data.tags ?? []
70-
if (!tags.includes('article')) continue
71-
64+
for (const { filePath } of articles) {
7265
totalFiles++
7366
const logEntries = getGitLog(filePath)
7467

bin/evaluate-teasers.ts

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import Anthropic from '@anthropic-ai/sdk'
2-
import { globby } from 'globby'
3-
import matter from 'gray-matter'
4-
import { readFile } from 'node:fs/promises'
52

63
import { generateTeaser } from './generate-teasers.ts'
4+
import { getArticles } from '../11ty/get-articles.ts'
75

86
interface Article {
97
title: string
@@ -14,22 +12,12 @@ interface Article {
1412
async function main() {
1513
const count = parseInt(process.argv[2] ?? '5', 10)
1614
const anthropic = new Anthropic()
17-
const files = await globby('www/**/*.md')
18-
const articles: Article[] = []
19-
20-
for (const filePath of files) {
21-
const fileContent = await readFile(filePath, 'utf-8')
22-
const parsed = matter(fileContent)
23-
24-
const tags: string[] = parsed.data.tags ?? []
25-
if (!tags.includes('article')) continue
26-
27-
articles.push({
28-
title: parsed.data.title as string,
29-
date: new Date(parsed.data.date as string),
30-
content: parsed.content,
31-
})
32-
}
15+
const allArticles = await getArticles()
16+
const articles: Article[] = allArticles.map((a) => ({
17+
title: a.data.title as string,
18+
date: new Date(a.data.date as string),
19+
content: a.content,
20+
}))
3321

3422
articles.sort((a, b) => b.date.getTime() - a.date.getTime())
3523
const latest = articles.slice(0, count)

bin/generate-teasers.ts

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import Anthropic from '@anthropic-ai/sdk'
2-
import { globby } from 'globby'
32
import matter from 'gray-matter'
4-
import { readFile, writeFile } from 'node:fs/promises'
3+
import { writeFile } from 'node:fs/promises'
54
import { smartypantsu } from 'smartypants'
65

6+
import { getArticles } from '../11ty/get-articles.ts'
77
import {
88
computeHash,
99
computeTeaserHash,
@@ -151,21 +151,14 @@ async function main() {
151151
const revisions = await loadRevisions()
152152
const anthropic = process.env.ANTHROPIC_API_KEY ? new Anthropic() : null
153153

154-
const files = await globby('www/**/*.md')
154+
const articles = await getArticles()
155155
let generatedCount = 0
156156
let teaserHashChanged = false
157157

158-
for (const filePath of files) {
159-
const fileContent = await readFile(filePath, 'utf-8')
160-
const parsed = matter(fileContent)
161-
162-
const tags: string[] = parsed.data.tags ?? []
163-
if (!tags.includes('article')) continue
164-
165-
const title = parsed.data.title as string
166-
const subhead = parsed.data.subhead as string | undefined
167-
const teaser = parsed.data.teaser as string | undefined
168-
const content = parsed.content
158+
for (const { filePath, data, content, rawInput } of articles) {
159+
const title = data.title as string
160+
const subhead = data.subhead as string | undefined
161+
const teaser = data.teaser as string | undefined
169162

170163
const hash = computeHash(title, subhead, content)
171164

@@ -204,7 +197,7 @@ async function main() {
204197
console.log(`[${decision.action}] ${filePath}: ${decision.reason}`)
205198

206199
const newTeaser = await generateTeaser(anthropic, title, content)
207-
const updatedContent = insertTeaserIntoFrontmatter(fileContent, newTeaser)
200+
const updatedContent = insertTeaserIntoFrontmatter(rawInput, newTeaser)
208201
await writeFile(filePath, updatedContent)
209202

210203
revisions.entries[filePath] ??= { revisions: [] }

0 commit comments

Comments
 (0)