forked from github/docs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
purge-fastly-by-url.js
executable file
·95 lines (79 loc) · 2.97 KB
/
purge-fastly-by-url.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
91
92
93
94
95
#!/usr/bin/env node
const fs = require('fs')
const path = require('path')
const program = require('commander')
const { execSync } = require('child_process')
const languageCodes = Object.keys(require('../lib/languages'))
const { getPathWithoutLanguage } = require('../lib/path-utils')
// [start-readme]
//
// Run this script to manually purge the [Fastly cache](https://github.com/github/docs-internal#fastly-cdn)
// for all language variants of a single URL or for a batch of URLs in a file. This script does
// not require authentication.
//
// [end-readme]
const requiredUrlPrefix = 'https://docs.github.com'
const purgeCommand = 'curl -s -X PURGE -H "Fastly-Soft-Purge:1"'
program
.description('Purge the Fastly cache for a single URL or a batch of URLs in a file, plus all language variants of the given URL(s).')
.option('-s, --single <URL>', `provide a single ${requiredUrlPrefix} URL`)
.option('-b, --batch <FILE>', `provide a path to a file containing a list of ${requiredUrlPrefix} URLs`)
.option('-d, --dry-run', 'print URLs to be purged without actually purging')
.parse(process.argv)
const singleUrl = program.single
const batchFile = program.batch
const dryRun = program.dryRun
// verify CLI options
if (!singleUrl && !batchFile) {
console.error('error: you must specify --single <URL> or --batch <FILE>.\n')
process.exit(1)
}
if (singleUrl && !singleUrl.startsWith(requiredUrlPrefix)) {
console.error(`error: cannot purge ${singleUrl} because URLs must start with ${requiredUrlPrefix}.\n`)
process.exit(1)
}
if (batchFile && !fs.existsSync(batchFile)) {
console.error('error: cannot find batch file.\n')
process.exit(1)
}
// do the purge
if (singleUrl) {
purge(singleUrl)
}
if (batchFile) {
fs.readFileSync(batchFile, 'utf8')
.split('\n')
.filter(line => line !== '')
.forEach(url => {
if (!url.startsWith(requiredUrlPrefix)) {
console.error(`error: cannot purge ${url} because URLs must start with ${requiredUrlPrefix}.\n`)
process.exit(1)
}
purge(url)
})
}
function purge (url) {
getLanguageVariants(url).forEach(localizedUrl => {
if (dryRun) {
console.log(`This is a dry run! Will purge cache for ${localizedUrl}`)
return
}
console.log(`Purging cache for ${localizedUrl}`)
const result = execSync(`${purgeCommand} ${localizedUrl}`).toString()
logStatus(result)
// purge twice to ensure referenced content on the page is updated too
const secondResult = execSync(`${purgeCommand} ${localizedUrl}`).toString()
logStatus(secondResult)
})
}
function getLanguageVariants (url) {
// for https://docs.github.com/en/foo, get https://docs.github.com/foo
const languagelessUrl = getPathWithoutLanguage(url.replace(requiredUrlPrefix, ''))
// then derive localized urls
return languageCodes.map(lc => path.join(requiredUrlPrefix, lc, languagelessUrl))
}
function logStatus (result) {
// only log status if it's not ok
if (JSON.parse(result).status === 'ok') return
console.log(result)
}