-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtraverse-yaml.js
59 lines (57 loc) · 1.42 KB
/
traverse-yaml.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
// # traverse-yaml.js
// Utility function for easily traversing and modifying yaml in bulk.
import path from 'node:path';
import fs from 'node:fs';
import { Glob } from 'glob';
import { Document, parseAllDocuments } from 'yaml';
import stylizeDoc from '../actions/fetch/stylize-doc.js';
const defaultToStringOptions = {
lineWidth: 0,
};
// # traverse(patterns, fn)
export default async function traverse(patterns, fn = () => {}, opts = {}) {
const {
stylize = true,
cwd = path.resolve(import.meta.dirname, '../src'),
...restOptions
} = opts;
const glob = new Glob(patterns, {
absolute: true,
nodir: true,
nocase: true,
cwd,
});
for await (let file of glob) {
let contents = String(await fs.promises.readFile(file));
let docs = [];
let changed;
for (let doc of parseAllDocuments(contents)) {
let raw = contents.slice(doc.range[0], doc.range[1]);
let json = doc.toJSON();
let result = await fn(json, doc, raw, file);
if (result) {
if (result instanceof Document) {
docs.push(result);
} else {
docs.push(new Document(result));
}
changed = true;
} else {
docs.push(doc);
}
}
if (changed) {
let buffer = docs.map((doc, i) => {
doc.directives.docStart = i > 0;
if (stylize) {
stylizeDoc(doc);
}
return doc.toString({
...defaultToStringOptions,
...restOptions,
});
}).join('\n');
await fs.promises.writeFile(file, buffer);
}
}
}