Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Outputs a log of updated features #947

Merged
merged 6 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ secrets.json
tests.json
tests.old.json
.testtmp
feature-list.json
1 change: 1 addition & 0 deletions scripts/add-new-bcd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ const main = async (): Promise<void> => {
{addNewFeatures: true},
bcd.browsers,
overrides,
"",
ChrisC marked this conversation as resolved.
Show resolved Hide resolved
);

console.log("Injecting BCD...");
Expand Down
64 changes: 55 additions & 9 deletions scripts/update-bcd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,12 @@ interface UpdateLog {
reason: Reason;
}

interface FeatureListLog {
browser: BrowserName;
path: string;
statements: SimpleSupportStatement[];
}

/** Values available in operations. */
interface UpdateState extends UpdateLog {
shared: UpdateShared;
Expand Down Expand Up @@ -1008,6 +1014,27 @@ const pickLog = <T extends UpdateLog>({
};
};

/**
* Picks specific properties from an object of type T and returns a new object of type FeatureListLog.
* @template T - The type of the input object.
* @param obj - The input object.
* @param obj.browser - The browser property of the input object.
* @param obj.path - The path property of the input object.
* @param obj.statements - The statements property of the input object.
* @returns - The new object of type FeatureListLog.
*/
const pickFeatureList = <T extends UpdateLog>({
browser,
path,
statements,
}: T): FeatureListLog => {
return {
browser,
path,
statements,
};
};

/**
* Generates a sequence of key-value pairs representing the entries in an object tree.
* The keys are generated by concatenating the prefix with each nested key.
Expand Down Expand Up @@ -1035,14 +1062,14 @@ export const walkEntries = function* (
* @param bcd - The BCD identifier.
* @param supportMatrix - The support matrix.
* @param options - Additional options for the update.
* @returns A boolean indicating whether any changes were made during the update.
* @returns An array of objects representing BCD paths that have been updated.
*/
export const update = (
bcd: Identifier,
supportMatrix: SupportMatrix,
options: any,
): boolean => {
const changes: UpdateLog[] = [];
): FeatureListLog[] => {
const results: UpdateLog[] = [];
for (const state of compose(
expand("entry", function* () {
for (const [path, entry] of walkEntries("", bcd)) {
Expand Down Expand Up @@ -1136,7 +1163,7 @@ export const update = (
}
}),
)()) {
changes.push(pickLog(state));
results.push(pickLog(state));
if (state.statements) {
state.shared.support[state.browser] =
state.statements.length === 1 ? state.statements[0] : state.statements;
Expand All @@ -1145,8 +1172,11 @@ export const update = (
logger.warn(state.reason.message);
}
}
// TODO: Serialize changes to a file
return changes.some(({statements}) => Boolean(statements));

const updates = results
.filter(({statements}) => Boolean(statements))
.map((result) => pickFeatureList(result));
return updates;
};

/* c8 ignore start */
Expand Down Expand Up @@ -1191,13 +1221,15 @@ export const loadJsonFiles = async (
* @param filter - An object containing filter options.
* @param browsers - An object representing the browsers to include in the update.
* @param overrides - An object containing override options.
* @param outputPath - An string specifying filename and path for feature list output. Defaults to `feature-list.json`.
* @returns A Promise that resolves when the update is complete.
*/
export const main = async (
reportPaths: string[],
filter: any,
browsers: Browsers,
overrides: Overrides,
outputPath: string,
): Promise<void> => {
// Replace filter.path with a minimatch object.
if (filter.path && filter.path.includes("*")) {
Expand Down Expand Up @@ -1232,18 +1264,25 @@ export const main = async (
browsers,
overrides.filter(Array.isArray as (item: unknown) => item is OverrideTuple),
);
let featureList: FeatureListLog[] = [];

// Should match https://github.com/mdn/browser-compat-data/blob/f10bf2cc7d1b001a390e70b7854cab9435ffb443/test/linter/test-style.js#L63
// TODO: https://github.com/mdn/browser-compat-data/issues/3617
for (const [file, data] of Object.entries(bcdFiles)) {
const modified = update(data, supportMatrix, filter);
if (!modified) {
const updates = update(data, supportMatrix, filter);
if (!updates.length) {
continue;
}
featureList = featureList.concat(updates);
logger.info(`Updating ${path.relative(BCD_DIR, file)}`);
const json = JSON.stringify(data, null, " ") + "\n";
await fs.writeFile(file, json);
}

if (featureList.length) {
const featureListJSON = JSON.stringify(featureList, null, " ") + "\n";
await fs.writeFile(outputPath, featureListJSON);
}
};

if (esMain(import.meta)) {
Expand Down Expand Up @@ -1292,10 +1331,17 @@ if (esMain(import.meta)) {
'Only update when versions are a specific number (or "false"), disallowing ranges',
type: "boolean",
default: false,
})
.option("output", {
alias: "o",
describe:
'Specify filename and output path for a json list of updated features. Defaults to "feature-list.json"',
type: "string",
default: "feature-list.json",
});
},
);

await main(argv.reports, argv, browsers, overrides);
await main(argv.reports, argv, browsers, overrides, argv.output);
}
/* c8 ignore stop */