stab-crashes/buildid_changeset.js

198 строки
5.8 KiB
JavaScript

let onLoad = new Promise(function(resolve, reject) {
window.onload = resolve;
});
function parseBuildID(buildID) {
return {
year: Number(buildID.substring(0, 4)),
month: Number(buildID.substring(4, 6)),
day: Number(buildID.substring(6, 8)),
hour: Number(buildID.substring(8, 10)),
minute: Number(buildID.substring(10, 12)),
second: Number(buildID.substring(12, 14)),
};
}
function compareBuildIDs(buildID1, buildID2) {
let buildObj1 = parseBuildID(buildID1);
let buildObj2 = parseBuildID(buildID2);
if (buildObj1.year > buildObj2.year) {
return 1;
} else if (buildObj1.year < buildObj2.year) {
return -1;
}
if (buildObj1.month > buildObj2.month) {
return 1;
} else if (buildObj1.month < buildObj2.month) {
return -1;
}
if (buildObj1.day > buildObj2.day) {
return 1;
} else if (buildObj1.day < buildObj2.day) {
return -1;
}
if (buildObj1.hour > buildObj2.hour) {
return 1;
} else if (buildObj1.hour < buildObj2.hour) {
return -1;
}
if (buildObj1.minute > buildObj2.minute) {
return 1;
} else if (buildObj1.minute < buildObj2.minute) {
return -1;
}
if (buildObj1.second > buildObj2.second) {
return 1;
} else if (buildObj1.second < buildObj2.second) {
return -1;
}
return 0;
}
function toTwoDigits(num) {
if (num < 10) {
return '0' + num;
}
return num;
}
function fromBuildIDtoChangeset(buildID) {
let buildObj = parseBuildID(buildID);
let directory = 'https://ftp.mozilla.org/pub/firefox/nightly/' + buildObj.year + '/' + toTwoDigits(buildObj.month) + '/' + buildObj.year + '-' + toTwoDigits(buildObj.month) + '-' + toTwoDigits(buildObj.day) + '-' + toTwoDigits(buildObj.hour) + '-' + toTwoDigits(buildObj.minute) + '-' + toTwoDigits(buildObj.second) + '-mozilla-central/';
return fetch(directory)
.then(response => response.text())
.then(data => {
let file = data.match(/firefox-\d+.0a1.en-US.win32.txt/);
if (file.length == 1) {
return file[0];
} else {
throw new Error('Couldn\'t find win32.txt file.');
}
})
.then(file => fetch(directory + file))
.then(response => response.text())
.then(data => {
let lines = data.split('\n');
lines = lines.map(line => line.replace('\r', ''));
let buildIDfromFile = lines[0];
if (buildID != buildIDfromFile) {
throw new Error('Unexpected error: wrong build ID in directory.');
}
return lines[1];
});
}
function getRevFromChangeset(changeset) {
let re = /https:\/\/hg.mozilla.org\/mozilla-central\/rev\/([A-Za-z0-9]+)/;
let result = re.exec(changeset);
return result[1];
}
function getChangesetDate(changeset) {
return fetch('https://hg.mozilla.org/mozilla-central/json-rev/' + changeset)
.then(response => response.json())
.then(json_rev => new Date(json_rev['pushdate'][0] * 1000))
}
function findFirstBuildIDInSet(buildIDs, date, i=0) {
return fromBuildIDtoChangeset(buildIDs[i])
.then(buildChangeset => getChangesetDate(getRevFromChangeset(buildChangeset)))
.then(buildDate => {
if (buildDate >= date) {
return buildIDs[i];
} else {
return matchBuildID(buildIDs, date, i + 1);
}
});
}
function findFirstBuildID(date, year=null, month=null) {
// Who knows where Firefox is built, so give the build ID some slack.
let possibleDate = new Date(date.getTime());
possibleDate.setUTCHours(possibleDate.getUTCHours() - 9);
let possibleBuildID = '' + possibleDate.getUTCFullYear() + toTwoDigits((possibleDate.getUTCMonth() + 1)) + toTwoDigits(possibleDate.getUTCDate()) + toTwoDigits(possibleDate.getUTCHours()) + toTwoDigits(possibleDate.getUTCMinutes()) + toTwoDigits(possibleDate.getUTCSeconds());
if (year == null) {
year = possibleDate.getUTCFullYear();
month = possibleDate.getUTCMonth() + 1;
}
return fetch('https://ftp.mozilla.org/pub/firefox/nightly/' + year + '/' + toTwoDigits(month) + '/')
.then(response => response.text())
.then(data => {
let re = />(\d+)-(\d\d)-(\d\d)-(\d\d)-(\d\d)-(\d\d)-mozilla-central\/</g;
let results;
let buildIDs = [];
while ((results = re.exec(data)) !== null) {
let buildID = results[1] + results[2] + results[3] + results[4] + results[5] + results[6];
// Check if this build ID is 'newer' than date.
if (compareBuildIDs(possibleBuildID, buildID) != 1) {
buildIDs.push(buildID);
}
}
return buildIDs;
})
.then(buildIDs => {
if (buildIDs.length === 0) {
return null;
}
return findFirstBuildIDInSet(buildIDs, date);
})
.then(rev => {
if (!rev) {
let nextYear = (month + 1) == 13 ? year + 1 : year;
let nextMonth = month + 1;
if (nextMonth == 13) {
nextMonth = 1;
}
if (nextYear > new Date().getUTCFullYear() || (nextYear == new Date().getUTCFullYear() && nextMonth > (new Date().getUTCMonth() + 1))) {
return null;
}
return findFirstBuildID(date, nextYear, nextMonth);
}
return rev;
});
}
function getBuildID(changeset) {
return getChangesetDate(changeset)
.then(date => findFirstBuildID(date));
}
onLoad
.then(function() {
document.getElementById('getChangeset').onclick = function() {
// e.g. 20161001030430
fromBuildIDtoChangeset(document.getElementById('buildID').value)
.then(changeset => document.getElementById('getChangesetResult').textContent = changeset)
};
document.getElementById('getBuildID').onclick = function() {
// e.g. 87cd291d2db6
// 1: Find date of the changeset
// 2: Find first build ID that is greater than the date of the changeset
// 3: Get the changeset for the build ID found in (2), if it's older than changeset, go to the next build.
getBuildID(document.getElementById('changeset').value)
.then(buildID => document.getElementById('getBuildIDResult').textContent = buildID ? buildID : 'Not shipped yet.')
};
});