Skip to content

Commit ba04fd0

Browse files
authored
Improvements to the update snippets script (#1276)
1 parent cf51a53 commit ba04fd0

File tree

4 files changed

+141
-51
lines changed

4 files changed

+141
-51
lines changed

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,9 @@
101101
},
102102
"scripts": {
103103
"build": "webpack --mode production",
104-
"postbuild": "npm run update:snippets",
104+
"postbuild": "npm run validate:es5 && npm run update:snippets:examples",
105105
"build:dev": "webpack --mode development",
106-
"postbuild:dev": "npm run update:snippets",
106+
"postbuild:dev": "npm run postbuild",
107107
"test": "./node_modules/.bin/grunt test",
108108
"test-browser": "./node_modules/.bin/grunt test-browser",
109109
"test-server": "mocha 'test/server.*.test.js' --reporter spec",
@@ -113,6 +113,6 @@
113113
"test-ci": "./node_modules/.bin/grunt test && npm run test-server",
114114
"lint": "./node_modules/.bin/eslint .",
115115
"validate:es5": "es-check es5 './dist/**/*.js' --verbose",
116-
"update:snippets": "node scripts/update-example-snippets.js"
116+
"update:snippets:examples": "node scripts/update-snippets.js examples"
117117
}
118118
}

scripts/update-example-snippets.js

Lines changed: 0 additions & 48 deletions
This file was deleted.

scripts/update-snippets.js

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* Updates the Rollbar snippet in js and html files under a specified base
5+
* directory from the project root.
6+
*
7+
* Usage:
8+
* update-snippets <baseDir>
9+
*
10+
* If <baseDir> is omitted, it defaults to '.' (current directory).
11+
*
12+
* Replaces content between "// Rollbar Snippet" and "// End Rollbar Snippet" markers.
13+
*/
14+
15+
import { readFile, writeFile } from 'node:fs/promises';
16+
import { fileURLToPath } from 'node:url';
17+
import path from 'node:path';
18+
import glob from 'glob';
19+
20+
import { findUp } from './util.js';
21+
22+
const verbose = ['--verbose', '-v'].some((f) => process.argv.includes(f));
23+
const baseDir = process.argv.at(verbose ? 3 : 2);
24+
25+
function replaceSnippet({ content, snippet, regex, file, root }) {
26+
let didMatch = false;
27+
let wasReplaced = false;
28+
29+
const updatedContent = content.replace(regex, (...args) => {
30+
const { indent, start, currentSnippet, end } = args.at(-1); // groups
31+
didMatch = true;
32+
wasReplaced = currentSnippet.trim() !== snippet;
33+
console.log(` ${wasReplaced ? '✓' : '-'} ${path.relative(root, file)}`);
34+
return `${indent}${start}${indent}${snippet}${end}`;
35+
});
36+
37+
if (verbose && !didMatch) {
38+
console.log(` ✗ ${path.relative(root, file)}`);
39+
}
40+
41+
return { updatedContent, wasReplaced };
42+
}
43+
44+
async function updateSnippets({ dir }) {
45+
if (!dir) {
46+
throw new Error('baseDir is required.');
47+
}
48+
49+
const cwd = path.dirname(fileURLToPath(import.meta.url));
50+
const root = await findUp({ fileName: 'package.json', dir: cwd });
51+
52+
console.log(`Updating Rollbar snippets in ${path.relative(root, cwd)}...`);
53+
54+
if (verbose) {
55+
console.log(`Found project root at ${root}`);
56+
}
57+
58+
const snippetPath = path.join(root, 'dist/rollbar.snippet.js');
59+
const snippet = await readFile(snippetPath, 'utf8');
60+
61+
const regex = new RegExp(
62+
'^' +
63+
'(?<indent>[ \t]*)' +
64+
'(?<start>// Rollbar Snippet\n)' +
65+
'(?<currentSnippet>.*?)' +
66+
'(?<end>\n[ \t]*// End Rollbar Snippet)' +
67+
'$',
68+
'ms',
69+
);
70+
71+
const files = glob.sync(`${dir}/**/*.{html,js}`, {
72+
cwd: root,
73+
absolute: true,
74+
ignore: ['**/.git/**', '**/node_modules/**'],
75+
});
76+
77+
if (files.length === 0) {
78+
throw new Error(`No files found in ${path.relative(root, dir)} to update.`);
79+
}
80+
81+
let snippetsUpdated = 0;
82+
83+
for (const file of files) {
84+
const content = await readFile(file, 'utf8');
85+
86+
const { updatedContent, wasReplaced } = replaceSnippet({
87+
content,
88+
snippet,
89+
regex,
90+
file,
91+
root,
92+
});
93+
94+
if (wasReplaced) {
95+
await writeFile(file, updatedContent);
96+
snippetsUpdated++;
97+
}
98+
}
99+
100+
console.log(`${snippetsUpdated} snippets updated.`);
101+
}
102+
103+
updateSnippets({ dir: baseDir }).catch((err) => {
104+
console.error('Error updating snippets:', err);
105+
console.error('\nUsage: update-snippets [--verbose|-v] <baseDir>');
106+
console.error('Example:');
107+
console.error(' update-snippets examples');
108+
process.exit(1);
109+
});

scripts/util.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { access } from 'node:fs/promises';
2+
import path from 'node:path';
3+
4+
/**
5+
* Walks up parent directories from the given start directory until it finds the specified file.
6+
*
7+
* @param {Object} options - The options object.
8+
* @param {string} options.fileName - Name of the file to search for, eg. 'package.json'.
9+
* @param {string} [options.dir=process.cwd()] - Directory to start from. Defaults to `process.cwd()`.
10+
* @returns {Promise<string>} The directory containing the file.
11+
* @throws {Error} If no such file is found in any ancestor.
12+
*/
13+
export async function findUp({ fileName, dir = process.cwd() }) {
14+
const origin = dir;
15+
let current = dir;
16+
17+
while (true) {
18+
try {
19+
await access(path.join(current, fileName));
20+
return current;
21+
} catch {
22+
const parent = path.dirname(current);
23+
if (parent === current) break;
24+
current = parent;
25+
}
26+
}
27+
28+
throw new Error(`No ${fileName} found in or above ${origin}`);
29+
}

0 commit comments

Comments
 (0)