forked from mdn/browser-compat-data
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bulk editor script for adding/removing tags (mdn#22515)
* Bulk editor script for adding tags * Fix support for --path * Run prettier * Use const when possible * Add license info at top of file * Change message * Add support for BCD_DIR, bcd tags remove & bcd tags show * Add support for npm run bcd * Restructure files * Remove unneeded "show" command * Restructure bulk editor for better extensibility * Fix ESLint reported issues * Walk file structure instead of attempting to guess it * Update scripts/bulk-editor/utils.ts Co-authored-by: Florian Scholz <[email protected]> * Add JSDoc * Allow for wildcards at the end of feature IDs * any => some * Add newlines to ends of files again --------- Co-authored-by: Queen Vinyl Da.i'gyu-Kazotetsu <[email protected]> Co-authored-by: Florian Scholz <[email protected]>
- Loading branch information
1 parent
dd678d2
commit cc46f48
Showing
8 changed files
with
194 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/* This file is a part of @mdn/browser-compat-data | ||
* See LICENSE file for more information. */ | ||
|
||
import yargs from 'yargs'; | ||
import { hideBin } from 'yargs/helpers'; | ||
|
||
import tags from './tags/index.js'; | ||
|
||
yargs(hideBin(process.argv)).command([tags]).demandCommand().help().parse(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* This file is a part of @mdn/browser-compat-data | ||
* See LICENSE file for more information. */ | ||
|
||
import { updateFeatures } from '../utils.js'; | ||
|
||
const command = { | ||
command: 'add <tag> <bcd-id..>', | ||
desc: 'Add the following tag to the BCD features', | ||
/** | ||
* handler - Action to perform for 'tags add' | ||
* @param argv Parameter list | ||
*/ | ||
handler: (argv) => { | ||
updateFeatures(argv['bcd-id'], (json) => { | ||
// If there is no tags entry, create one | ||
if (!json['tags']) { | ||
json['tags'] = []; | ||
} | ||
|
||
// Add the tag | ||
if (!json['tags'].includes(argv['tag'])) { | ||
json['tags'].push(argv['tag']); | ||
} | ||
|
||
return json; | ||
}); | ||
}, | ||
}; | ||
|
||
export default command; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/* This file is a part of @mdn/browser-compat-data | ||
* See LICENSE file for more information. */ | ||
|
||
import addCommand from './add.js'; | ||
import removeCommand from './remove.js'; | ||
|
||
const command = { | ||
command: 'tags', | ||
description: 'Modify tags', | ||
// eslint-disable-next-line @typescript-eslint/no-empty-function | ||
handler: () => {}, | ||
builder: (yargs) => | ||
yargs.command([addCommand, removeCommand]).demandCommand().help(), | ||
}; | ||
|
||
export default command; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* This file is a part of @mdn/browser-compat-data | ||
* See LICENSE file for more information. */ | ||
|
||
import { updateFeatures } from '../utils.js'; | ||
|
||
const command = { | ||
command: 'remove <tag> <bcd-id..>', | ||
desc: 'Remove the following tag from the BCD features', | ||
/** | ||
* handler - Action to perform for 'tags remove' | ||
* @param argv Parameter list | ||
*/ | ||
handler: (argv) => { | ||
updateFeatures(argv['bcd-id'], (json) => { | ||
// If there is no tags entry, create one | ||
if (json['tags']) { | ||
const index = json['tags'].indexOf(argv['tag']); | ||
// Actually remove it if found | ||
if (index !== -1) { | ||
json['tags'].splice(index, 1); | ||
} | ||
|
||
// Remove the tags array if empty | ||
if (json['tags'].length === 0) { | ||
delete json.tags; | ||
} | ||
} | ||
|
||
return json; | ||
}); | ||
}, | ||
}; | ||
|
||
export default command; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/* This file is a part of @mdn/browser-compat-data | ||
* See LICENSE file for more information. */ | ||
|
||
import path from 'node:path'; | ||
import { fileURLToPath } from 'node:url'; | ||
import fs from 'node:fs'; | ||
|
||
import chalk from 'chalk-template'; | ||
import { fdir } from 'fdir'; | ||
|
||
import { dataFolders } from '../../index.js'; | ||
import walk from '../../utils/walk.js'; | ||
import stringifyAndOrderProperties from '../lib/stringify-and-order-properties.js'; | ||
|
||
const dirname = fileURLToPath(new URL('.', import.meta.url)); | ||
|
||
/** | ||
* Updates the specified key in the given JSON object using the provided updater function. | ||
* | ||
* @param key The key to update in dot notation (e.g., 'api.foobar'). | ||
* @param json The JSON object to update. | ||
* @param updater The function to apply to the '__compat' property of the value corresponding to the key. | ||
* @returns The updated JSON object. | ||
*/ | ||
const performUpdate = (key, json, updater) => { | ||
const parts = key.split('.'); | ||
if (!(parts[0] in json)) { | ||
console.warn('Key not found in file!'); | ||
return json; | ||
} | ||
if (parts.length === 1) { | ||
json[parts[0]]['__compat'] = updater(json[parts[0]]['__compat']); | ||
} else { | ||
json[parts[0]] = performUpdate( | ||
parts.slice(1).join('.'), | ||
json[parts[0]], | ||
updater, | ||
); | ||
} | ||
return json; | ||
}; | ||
|
||
/** | ||
* Updates features in multiple JSON files based on the provided feature IDs and updater function. | ||
* | ||
* @param {string[]} featureIDs An array of feature IDs to update. | ||
* @param {Function} updater The updater function to apply to each matching feature. | ||
*/ | ||
export const updateFeatures = (featureIDs, updater) => { | ||
for (const dir of dataFolders) { | ||
const paths = new fdir() | ||
.withBasePath() | ||
.filter((fp) => fp.endsWith('.json')) | ||
.crawl(path.join(dirname, '..', '..', dir)) | ||
.sync() as string[]; | ||
|
||
for (const fp of paths) { | ||
const rawcontents = fs.readFileSync(fp); | ||
const contents = JSON.parse(rawcontents.toString('utf8')); | ||
let changed = false; | ||
|
||
const walker = walk(undefined, contents); | ||
for (const { path: featureID } of walker) { | ||
if ( | ||
featureIDs.some( | ||
(fid) => | ||
fid === featureID || | ||
(fid.endsWith('*') && featureID.startsWith(fid.slice(0, -1))), | ||
) | ||
) { | ||
console.log(chalk`{yellow Updating ${featureID}...}`); | ||
performUpdate(featureID, contents, updater); | ||
changed = true; | ||
} | ||
} | ||
|
||
if (changed) { | ||
fs.writeFileSync( | ||
fp, | ||
stringifyAndOrderProperties(contents) + '\n', | ||
'utf-8', | ||
); | ||
} | ||
} | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters