Skip to content

Commit 983b8c2

Browse files
authored
Script to audit a top-level content dir (#56208)
1 parent 62ab1ee commit 983b8c2

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

src/metrics/scripts/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ See documentation below for:
66

77
Run this on any GitHub Docs URL to gather a set of metrics about it.
88

9+
* [docsaudit](#docsaudit)
10+
11+
Run this on a top-level content directory to gather info about its files and output to a CSV.
12+
913
Print usage info for any script in this directory:
1014

1115
```bash
@@ -70,6 +74,23 @@ To use `docstat` from any location in Terminal, set up a global alias:
7074
```
7175
Now you can run `docstat <url>` from any directory.
7276

77+
## docsaudit
78+
79+
Run `docsaudit` on a top-level content directory to gather data about its files—including title, path, versions, 30d views, and 30d users—and output it to a CSV file.
80+
81+
To see the available options:
82+
```
83+
tsx src/metrics/scripts/docsaudit.js --help
84+
```
85+
Run the script on any top-level content directory:
86+
```
87+
tsx src/metrics/scripts/docsaudit.js <content directory name>
88+
```
89+
For example:
90+
```
91+
tsx src/metrics/scripts/docsaudit.js actions
92+
```
93+
7394
## Future development
7495
7596
Applies to all scripts in this directory:

src/metrics/scripts/docsaudit.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#!/usr/bin/env node
2+
3+
import fs from 'fs'
4+
import path from 'path'
5+
import { fileURLToPath } from 'url'
6+
import { Command } from 'commander'
7+
import walkFiles from '#src/workflows/walk-files.ts'
8+
import readFrontmatter from '@/frame/lib/read-frontmatter.js'
9+
import { getKustoClient } from '#src/metrics/lib/kusto-client.js'
10+
import { getDates } from 'src/metrics/lib/dates.js'
11+
import { getViews } from '#src/metrics/queries/views.js'
12+
import { getUsers } from '#src/metrics/queries/users.js'
13+
14+
const __filename = fileURLToPath(import.meta.url)
15+
const __dirname = path.dirname(__filename)
16+
const ROOTDIR = process.cwd()
17+
18+
const program = new Command()
19+
20+
program
21+
.name('docsaudit')
22+
.description('Get data about a top-level docs product and output a CSV')
23+
.argument('<auditDir>', 'Name of the content directory you want to audit, e.g., actions')
24+
.option('-r, --range <days>', 'Number of days to look back', 30)
25+
.option('--verbose', 'Display Kusto queries being executed')
26+
.parse(process.argv)
27+
28+
const options = program.opts()
29+
const [auditDirName] = program.args
30+
const contentDir = path.join(ROOTDIR, 'content')
31+
const auditDir = path.join(contentDir, auditDirName)
32+
const outputFile = path.join(__dirname, `${auditDirName}-audit.csv`)
33+
34+
if (!fs.existsSync(auditDir)) {
35+
console.error(`${auditDirName} not found`)
36+
process.exit(1)
37+
}
38+
39+
// Get dates object in format { endDate, startDate, friendlyRange }
40+
const dates = getDates(options.range)
41+
42+
const files = walkFiles(auditDir, ['.md'])
43+
console.log(`Auditing the ${files.length} "${auditDirName}" files. This may take a while.\n`)
44+
45+
main()
46+
47+
async function main() {
48+
const client = getKustoClient()
49+
50+
let csvString = `title,path,versions,${options.range}d views,${options.range}d users\n`
51+
console.log(`Assembling data for these CSV columns: ${csvString}`)
52+
53+
// Get the title, path, and versions from the filesystem
54+
// Get the views and users from the Kusto API
55+
const results = []
56+
for (const file of files) {
57+
const contents = await fs.promises.readFile(file)
58+
const contentPath = path.relative(ROOTDIR, file)
59+
const { data } = readFrontmatter(contents)
60+
const versionString = JSON.stringify(data.versions).replaceAll('"', "'")
61+
const pathToQuery = getPathToQuery(file)
62+
// Pass null to get all versions (the default if no version is provided)
63+
const version = null
64+
// Only pass true for verbose on the first iteration
65+
const isFirst = results.length === 0
66+
const views = await getViews(pathToQuery, client, dates, version, options.verbose && isFirst)
67+
const users = await getUsers(pathToQuery, client, dates, version, options.verbose && isFirst)
68+
const csvEntry = `"${data.title}","${contentPath}","${versionString}","${views}","${users}"`
69+
console.log(csvEntry)
70+
results.push(csvEntry)
71+
}
72+
csvString += results.join('\n') + '\n'
73+
74+
fs.writeFileSync(outputFile, csvString.trim(), 'utf8')
75+
console.log(`Done! Wrote ${outputFile}`)
76+
}
77+
78+
function getPathToQuery(file) {
79+
return path.relative(contentDir, file).replace('/index.md', '').replace('.md', '')
80+
}

0 commit comments

Comments
 (0)