Pre-process PRs when publishing the database

This moves some processing from the frontend
to the server, which should speed things up a bit,
but costs slightly more in downloading.

We'll make more use of this data with further
improvements, so it makes sense to prepare the
data on the server.
This commit is contained in:
Yuri Sizov
2023-11-26 23:11:40 +01:00
parent 3a2c4debd7
commit f8097af283
3 changed files with 41 additions and 32 deletions

View File

@@ -7,8 +7,11 @@ const VERSION_PREFIX_REGEX = /^[\(\[][34]\.[0-9x][\)\]]/;
const VERSION_SUFFIX_REGEX = /[\(\[][34]\.[0-9x][\)\]]$/;
const AREA_PREFIX_REGEX = /^[\[`']([a-zA-Z0-9]+)[\]`']/;
export default class ReleaseNotesFormatter {
static determineGroup(allLabels) {
class PullClassifier {
determineGroup(pull) {
// Simplify the array.
const allLabels = pull.labels.map(item => item.name);
// We use labels to deduce which category does the change
// fall under. We consider more specific groups before more
// general ones. When in doubt, pick any group.
@@ -54,12 +57,11 @@ export default class ReleaseNotesFormatter {
}
// If no group was detected, we just stay on "core".
return groupName;
}
static humanizeGroupName(name) {
switch (name) {
humanizeGroup(groupName) {
switch (groupName) {
case "2d":
return "2D";
case "3d":
@@ -78,11 +80,11 @@ export default class ReleaseNotesFormatter {
return "XR";
}
return name.charAt(0).toUpperCase() + name.substring(1);
return groupName.charAt(0).toUpperCase() + groupName.substring(1);
}
static cleanupChangeMessage(groupName, message) {
let cleanMessage = message.trim();
cleanupTitle(pull) {
let cleanMessage = pull.title.trim();
// Sometimes there are periods at the end.
if (cleanMessage.endsWith(".")) {
cleanMessage = cleanMessage.substring(0, cleanMessage.length - 1);
@@ -113,8 +115,8 @@ export default class ReleaseNotesFormatter {
// Some PR titles contain the same group prefix already,
// so we're going to remove it for a cleaner look.
if (cleanMessage.startsWith(`${groupName}:`)) {
cleanMessage = cleanMessage.substring(groupName.length + 1).trim();
if (cleanMessage.startsWith(`${pull.group_name}:`)) {
cleanMessage = cleanMessage.substring(pull.group_name.length + 1).trim();
}
// There are also some special cases where the prefix may
@@ -135,10 +137,6 @@ export default class ReleaseNotesFormatter {
return cleanMessage;
}
static sortGroupNames(a, b) {
if (a.toLowerCase() > b.toLowerCase()) return 1;
if (a.toLowerCase() < b.toLowerCase()) return -1;
return 0;
}
}
module.exports = PullClassifier;

View File

@@ -2,8 +2,11 @@ const fs = require('fs').promises;
const fsConstants = require('fs').constants;
const buildCommon = require('./build/utils/build-common.js');
const PullClassifier = require('./build/utils/publish-classifier.js')
async function publishData() {
const classifier = new PullClassifier();
try {
console.log("[*] Copying pre-generated data files.");
const sourcePath = "./data";
@@ -29,14 +32,26 @@ async function publishData() {
continue;
}
// Resaving the data entry without extra spaces as a way to compress it a bit.
// Resave the data entry without extra spaces as a way to compress it a bit.
// We also do some pre-processing to speed up processing on the front end at
// a cost of a slightly bigger download.
await fs.access(entryPath, fsConstants.R_OK);
const entryContent = await fs.readFile(entryPath, { encoding: 'utf-8' });
const entry = JSON.parse(entryContent);
// Classify and clean-up pull requests.
Object.keys(entry.pulls).forEach((pullKey) => {
const pull = entry.pulls[pullKey];
pull.group_key = classifier.determineGroup(pull);
pull.group_name = classifier.humanizeGroup(pull.group_key);
pull.title = classifier.cleanupTitle(pull);
});
const copyPath = `${targetPath}/${sourceName}`;
await fs.writeFile(copyPath, JSON.stringify(entry), { encoding: 'utf-8' });
console.log(` Published data from ${sourceName}.`);
file_count++;
}

View File

@@ -1,7 +1,5 @@
import { LitElement, html, css, customElement, property } from 'lit-element';
import ReleaseNotesFormatter from "../../helpers/ReleaseNotesFormatter"
@customElement('gr-release-notes')
export default class ReleaseNotesItem extends LitElement {
static get styles() {
@@ -196,20 +194,19 @@ export default class ReleaseNotesItem extends LitElement {
let groupedNotes = {};
this.pulls.forEach((pull) => {
// Simplify the array.
const allLabels = pull.labels.map(item => item.name);
let groupName = ReleaseNotesFormatter.determineGroup(allLabels);
// Store under the determined group.
const humanizedName = ReleaseNotesFormatter.humanizeGroupName(groupName);
if (typeof groupedNotes[humanizedName] === "undefined") {
groupedNotes[humanizedName] = [];
if (typeof groupedNotes[pull.group_name] === "undefined") {
groupedNotes[pull.group_name] = [];
}
groupedNotes[humanizedName].push(pull);
groupedNotes[pull.group_name].push(pull);
});
const groupNames = Object.keys(groupedNotes);
groupNames.sort(ReleaseNotesFormatter.sortGroupNames);
groupNames.sort((a, b) => {
if (a.toLowerCase() > b.toLowerCase()) return 1;
if (a.toLowerCase() < b.toLowerCase()) return -1;
return 0;
});
groupNames.forEach((group) => {
const pulls = groupedNotes[group];
@@ -226,18 +223,17 @@ export default class ReleaseNotesItem extends LitElement {
let groupItems = [];
pulls.forEach((pull) => {
const cleanTitle = ReleaseNotesFormatter.cleanupChangeMessage(group, pull.title);
const item = {
"group": group,
"title": cleanTitle,
"title": pull.title,
"public_id": pull.public_id,
};
this._sortedNotes.push(item);
groupItems.push(item);
this._copiableUnifiedText += `- ${group}: ${cleanTitle} ([GH-${pull.public_id}](https://github.com/${this.repository}/pull/${pull.public_id})).\n`;
this._copiableGroupedText += `- ${cleanTitle} ([GH-${pull.public_id}](https://github.com/${this.repository}/pull/${pull.public_id})).\n`;
this._copiableUnifiedText += `- ${group}: ${pull.title} ([GH-${pull.public_id}](https://github.com/${this.repository}/pull/${pull.public_id})).\n`;
this._copiableGroupedText += `- ${pull.title} ([GH-${pull.public_id}](https://github.com/${this.repository}/pull/${pull.public_id})).\n`;
});
this._groupedNotes.push({