forked from github/docs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
update-readme.js
executable file
·90 lines (72 loc) · 2.57 KB
/
update-readme.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/usr/bin/env node
import { fileURLToPath } from 'url'
import path from 'path'
import fs from 'fs'
import walk from 'walk-sync'
import dedent from 'dedent'
import { difference } from 'lodash-es'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const readme = path.join(__dirname, 'README.md')
// [start-readme]
//
// This script crawls the script directory, hooks on special comment markers
// in each script, and adds the comment to `script/README.md`.
//
// [end-readme]
const startComment = 'start-readme'
const endComment = 'end-readme'
const startCommentRegex = new RegExp(startComment)
const endCommentRegex = new RegExp(endComment)
const ignoreList = ['README.md']
const scriptsToRuleThemAll = ['bootstrap', 'server', 'test']
const allScripts = walk(__dirname, { directories: false }).filter((script) =>
ignoreList.every((ignoredPath) => !script.includes(ignoredPath))
)
const otherScripts = difference(allScripts, scriptsToRuleThemAll)
// build an object with script name as key and readme comment as value
const allComments = {}
allScripts.forEach((script) => {
const fullPath = path.join(__dirname, script)
let addToReadme = false
const readmeComment = fs
.readFileSync(fullPath, 'utf8')
.split('\n')
.filter((cmt) => {
if (startCommentRegex.test(cmt)) addToReadme = true
if (endCommentRegex.test(cmt)) addToReadme = false
if (addToReadme && !cmt.includes(startComment) && !cmt.includes(endComment)) return cmt
return false
})
// remove comment markers and clean up newlines
.map((cmt) => cmt.replace(/^(\/\/|#) ?/m, ''))
.join('\n')
.trim()
allComments[script] = readmeComment
// preserve double newlines as multiline list items
.replace(/\n\n/g, '\n\n\n ')
// remove single newlines
.replace(/\n(?!\n)/g, ' ')
})
// turn the script names/comments into itemized lists in the README
const template = `# Scripts
## Scripts to rule them all
This directory follows the [Scripts to Rule Them All](https://githubengineering.com/scripts-to-rule-them-all/) pattern:
${createTemplate(scriptsToRuleThemAll)}
## Additional scripts
${createTemplate(otherScripts)}
`
// update the readme
if (template === fs.readFileSync(readme, 'utf8')) {
console.log('The README is up-to-date!')
} else {
fs.writeFileSync(readme, template)
console.log('The README.md has been updated!')
}
function createTemplate(arrayOfScripts) {
return arrayOfScripts
.map((script) => {
const comment = allComments[script]
return dedent`### [\`${script}\`](${script})\n\n${comment}\n\n---\n\n`
})
.join('\n')
}