Skip to content
Permalink
Browse files
[build.webkit.org] Support identifiers in popover
https://bugs.webkit.org/show_bug.cgi?id=239773
<rdar://problem/92339575>

Rubber-stamped by Aakash Jain.

* Tools/CISupport/build-webkit-org/public_html/dashboard/Scripts/Commits.js:
(Commits): Keep track of all fetched commits.
(Commits.prototype._update): Save fetched commits.
(Commits.prototype.lastNIdentifiers): Return a list of the last n identifiers
on a branch.
(Commits.prototype.fetch): Load information for last N commits.
(Commits.prototype.urlFor): Return a url for a commit ref.
* Tools/CISupport/build-webkit-org/public_html/dashboard/Scripts/Main.js: Remove
trac auto-updater.
* Tools/CISupport/build-webkit-org/public_html/dashboard/Scripts/QueueView.js:
(QueueView.prototype._appendPendingRevisionCount): After we determine the
number of commits behind, fetch that many commits.
(QueueView.prototype._popoverLinesForCommitRange): Support commits with identifiers.
(QueueView.prototype._presentPopoverForPendingCommits):
* Tools/CISupport/build-webkit-org/public_html/dashboard/Scripts/tests/resources/MockCommits.js:
* Tools/CISupport/build-webkit-org/public_html/dashboard/Scripts/tests/resources/tests.js:

Canonical link: https://commits.webkit.org/250011@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@293475 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
JonWBedard committed Apr 26, 2022
1 parent 6a219ec commit 0975a44109764e822959c8935dc753764e637b90
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 108 deletions.
@@ -30,6 +30,7 @@ Commits = function(url)
console.assert(url);
this.url = url;
this.heads = {'main': null};
this.commits = {}
};

BaseObject.addConstructorFunctions(Commits);
@@ -45,6 +46,7 @@ Commits.prototype = {
Object.entries(self.heads).forEach(function(branch){
JSON.load(self.url + '/' + branch[0] + '/json', function(data) {
self.heads[branch[0]] = data;
self.commits[data.identifier] = data;
});
});
},
@@ -60,4 +62,36 @@ Commits.prototype = {
return parseFloat(split[1]);
return null
},
lastNIdentifiers(branch, count) {
if (!this.heads[branch])
return [];

var split = this.heads[branch].identifier.split(/\.|@/);
var result = [];
for(; count--;) {
var identifier = '';
if (split.length === 2)
identifier = `${parseFloat(split[0]) - count}@${branch}`;
else if (split.length === 3)
identifier = `${split[0]}.${parseFloat(split[1]) - count}@${branch}`;

result.push(identifier);
}
return result.reverse();
},
fetch: function(branch, count) {
var self = this;
this.lastNIdentifiers(branch, count).forEach((identifier) => {
if (self.commits[identifier] !== undefined)
return;
self.commits[identifier] = null;

JSON.load(self.url + '/' + identifier + '/json', function(data) {
self.commits[data.identifier] = data;
});
});
},
urlFor: function(identifier) {
return `${this.url}/${identifier}`;
}
};
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
* Copyright (C) 2013-2022 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -331,9 +331,6 @@ function documentReady()

var sortedRepositories = Dashboard.sortedRepositories;
for (var i = 0; i < sortedRepositories.length; ++i) {
var trac = sortedRepositories[i].trac;
if (typeof trac !== "undefined")
trac.startPeriodicUpdates();
var commits = sortedRepositories[i].commits;
if (typeof commits !== "undefined")
commits.startPeriodicUpdates();
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013 Apple Inc. All rights reserved.
* Copyright (C) 2013-2022 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -40,6 +40,7 @@ BaseObject.addConstructorFunctions(QueueView);

QueueView.UpdateInterval = 45000; // 45 seconds
QueueView.UpdateSoonTimeout = 1000; // 1 second
QueueView.MAX_POPOVER = 20;

QueueView.prototype = {
constructor: QueueView,
@@ -139,6 +140,7 @@ QueueView.prototype = {
if (!totalRevisionsBehind)
return;

commits.fetch(branch.name, Math.min(totalRevisionsBehind, QueueView.MAX_POPOVER));
var messageElement = document.createElement("span"); // We can't just pass text to StatusLineView here, because we need an element that perfectly fits the text for popover positioning.
messageElement.textContent = totalRevisionsBehind + " " + (totalRevisionsBehind === 1 ? "commit behind" : "commits behind");
var status = new StatusLineView(messageElement, StatusLineView.Status.NoBubble);
@@ -147,41 +149,36 @@ QueueView.prototype = {
new PopoverTracker(messageElement, this._presentPopoverForPendingCommits.bind(this, latestIterationGetter), queue);
},

_popoverLinesForCommitRange: function(trac, branch, firstRevisionNumber, lastRevisionNumber)
_popoverLinesForCommitRange: function(commits, branch, commitList)
{
function lineForCommit(trac, commit)
function lineForCommit(commits, commit)
{
var result = document.createElement("div");
result.className = "pending-commit";

var linkElement = document.createElement("a");
linkElement.className = "revision";
linkElement.href = trac.revisionURL(commit.revisionNumber);
linkElement.href = commits.urlFor(commit.identifier);
linkElement.target = "_blank";
linkElement.textContent = this._formatRevisionForDisplay(commit.revisionNumber, branch.repository);
linkElement.textContent = this._formatRevisionForDisplay(commit.identifier, branch.repository);
result.appendChild(linkElement);

var authorElement = document.createElement("span");
authorElement.className = "author";
authorElement.textContent = commit.author;
authorElement.textContent = commit.author ? commit.author.name : '';
result.appendChild(authorElement);

var titleElement = document.createElement("span");
titleElement.className = "title";
titleElement.innerHTML = commit.title.innerHTML;
titleElement.innerHTML = commit.message ? commit.message.split('\n')[0] : '';
result.appendChild(titleElement);

return result;
}

console.assert(trac.indexOfRevision(trac.oldestRecordedRevisionNumber) <= trac.indexOfRevision(firstRevisionNumber));

// FIXME: To be 100% correct, we should also filter out changes that are ignored by
// the queue, see _should_file_trigger_build in wkbuild.py.
var commits = trac.commitsOnBranchInRevisionRange(branch.name, firstRevisionNumber, lastRevisionNumber);
return commits.map(function(commit) {
return lineForCommit.call(this, trac, commit);
}, this).reverse();
return commitList.map(function(commit) {
return lineForCommit.call(this, commits, commit);
}, this);
},

_presentPopoverForPendingCommits: function(latestIterationGetter, element, popover, queue)
@@ -199,14 +196,21 @@ QueueView.prototype = {
var branch = branches[i];
var repository = branch.repository;
var repositoryName = repository.name;
var trac = repository.trac;
var latestProductiveRevisionNumber = latestProductiveIteration.revision[repositoryName];
if (!latestProductiveRevisionNumber || !trac.latestRecordedRevisionNumber)
continue;
var nextRevision = trac.nextRevision(branch.name, latestProductiveRevisionNumber);
if (nextRevision === Trac.NO_MORE_REVISIONS)
var commits = repository.commits;
if (!commits.heads[branch.name])
continue;
var lines = this._popoverLinesForCommitRange(trac, branch, nextRevision, trac.latestRecordedRevisionNumber);

var commitList = [];
var latestProductiveIdentifier = latestProductiveIteration.revision[repositoryName];
for (const identifier of commits.lastNIdentifiers(branch.name, QueueView.MAX_POPOVER)) {
if (identifier == latestProductiveIdentifier)
break;
if (commits.commits[identifier])
commitList.push(commits.commits[identifier]);
}
if (!commitList.length)
continue
var lines = this._popoverLinesForCommitRange(commits, branch, commitList);
var length = lines.length;
if (length && shouldAddDivider)
this._addDividerToPopover(content);
@@ -27,6 +27,10 @@ MockCommits = function(url)
{
BaseObject.call(this);
this.heads = {'main': {'identifier': '33022@main'}};
this.commits = {
'33021@main': {'identifier': '33021@main'},
'33022@main': this.heads['main'],
}
};

BaseObject.addConstructorFunctions(MockCommits);
@@ -47,4 +51,25 @@ MockCommits.prototype = {
return parseFloat(split[1]);
return null
},
lastNIdentifiers(branch, count) {
if (!this.heads[branch])
return [];

var split = this.heads[branch].identifier.split(/\.|@/);
var result = [];
for(; count--;) {
var identifier = '';
if (split.length === 2)
identifier = `${parseFloat(split[0]) - count}@${branch}`;
else if (split.length === 3)
identifier = `${split[0]}.${parseFloat(split[1]) - count}@${branch}`;

result.push(identifier);
}
return result.reverse();
},
fetch: function(branch, count) {},
urlFor: function(identifier) {
return `${this.url}/${identifier}`;
}
};
@@ -46,42 +46,6 @@ module("Trac", {
}
});

test("_loaded", function()
{
this.trac.recordedCommits = MockTrac.EXAMPLE_TRAC_COMMITS;
var client = new XMLHttpRequest();
client.open("GET", "resources/test-fixture-trac-rss.xml", false);
client.onload = function () {
this.trac._loaded(client.responseXML);
}.bind(this);
client.send();
var commits = this.trac.recordedCommits;
strictEqual(commits.length, 8, "should have 8 commits");
for (var i = 1; i < commits.length; i++) {
var firstRevision = commits[i - 1].revisionNumber;
var secondRevision = commits[i].revisionNumber;
strictEqual(secondRevision - firstRevision, 1, "commits should be in order " + firstRevision + ", " + secondRevision);
}
});

test("parse gitBranches", function()
{
var client = new XMLHttpRequest();
client.open("GET", "resources/test-fixture-git-trac-rss.xml", false);
client.onload = function () {
this.trac._loaded(client.responseXML);
}.bind(this);
client.send();
var commits = this.trac.recordedCommits;
strictEqual(commits.length, 3, "should have 3 commits");
strictEqual(commits[0].branches.length, 0, "should have no branches");
strictEqual(commits[1].branches.length, 1, "should have one branch");
strictEqual(commits[1].branches.includes("master"), true, "should contain branch master");
strictEqual(commits[2].branches.length, 2, "should have two branches");
strictEqual(commits[2].branches.includes("master"), true, "should contain branch master");
strictEqual(commits[2].branches.includes("someOtherBranch"), true, "should contain branch someOtherBranch");
});

test("_parseRevisionFromURL", function()
{
strictEqual(this.trac._parseRevisionFromURL("https://trac.webkit.org/changeset/190497"), "190497", "Subversion");
@@ -174,7 +138,16 @@ module("BuildBotQueueView", {
isSVN: true,
}
};
this.queue.branches = [this.trunkBranch];
this.mainBranch = {
name: "main",
repository: {
name: "openSource",
trac: this.trac,
commits: this.commits,
isGit: true,
}
};
this.queue.branches = [this.mainBranch];
this.view = new MockBuildbotQueueView([this.queue]);
this.view._latestProductiveIteration = function(queue)
{
@@ -196,7 +169,10 @@ test("_appendPendingRevisionCount", function()

test("_popoverLinesForCommitRange", function()
{
var lines = this.view._popoverLinesForCommitRange(this.trac, this.trunkBranch, "33018", "33020");
var lines = this.view._popoverLinesForCommitRange(this.commits, this.mainBranch, [
{identifier: '26210@main'},
{identifier: '26208@main'},
]);
strictEqual(lines.length, 2, "has 2 lines");
});

@@ -228,66 +204,29 @@ test("_presentPopoverForPendingCommits no pending commits", function()
strictEqual(nodeList.length, 0, "has 0 pending commits");
});

test("_presentPopoverForRevisionRange", function()
{
var element = document.createElement("div");
var popover = new Dashboard.Popover();
var context = {
trac: this.trac,
commits: this.commits,
branch: this.trunkBranch,
firstRevision: "33018",
lastRevision: "33020"
};
this.view._presentPopoverForRevisionRange(element, popover, context);
var nodeList = popover._element.getElementsByClassName("pending-commit");
strictEqual(nodeList.length, 2, "has 2 commits");
});

test("_presentPopoverForRevisionRange no commits", function()
{
var element = document.createElement("div");
var popover = new Dashboard.Popover();
var context = {
trac: this.trac,
commits: this.commits,
branch: this.trunkBranch,
firstRevision: "33020",
lastRevision: "33018"
};
this.view._presentPopoverForRevisionRange(element, popover, context);
var nodeList = popover._element.getElementsByClassName("pending-commit");
strictEqual(nodeList.length, 0, "has 0 commits");
});

test("_revisionContentWithPopoverForIteration", function()
{
var finished = false;
var iteration = new BuildbotIteration(this.queue, 1, finished);
iteration.revision = { "openSource": "33018" };
iteration.revision = { "openSource": "33018@main" };
var previousIteration = null;
var content = this.view._revisionContentWithPopoverForIteration(iteration, previousIteration, this.trunkBranch);
strictEqual(content.innerHTML, "r33018", "should have correct revision number.");
var content = this.view._revisionContentWithPopoverForIteration(iteration, previousIteration, this.mainBranch);
strictEqual(content.innerHTML, "33018@main", "should have correct revision number.");
strictEqual(content.classList.contains("revision-number"), true, "should have class 'revision-number'.");
strictEqual(content.classList.contains("popover-tracking"), false, "should not have class 'popover-tracking'.");
});

test("_revisionContentWithPopoverForIteration has previousIteration", function()
{
var finished = false;
var iteration = new BuildbotIteration(this.queue, 2, finished);
iteration.revision = { "openSource": "33022" };
iteration.revision = { "openSource": "33022@main" };
var previousIteration = new BuildbotIteration(this.queue, 1, finished);
previousIteration.revision = { "openSource": "33018" };
var content = this.view._revisionContentWithPopoverForIteration(iteration, previousIteration, this.trunkBranch);
strictEqual(content.innerHTML, "r33022", "should have correct revision number.");
previousIteration.revision = { "openSource": "33018@main" };
var content = this.view._revisionContentWithPopoverForIteration(iteration, previousIteration, this.mainBranch);
strictEqual(content.innerHTML, "33022@main", "should have correct revision number.");
strictEqual(content.classList.contains("revision-number"), true, "should have class 'revision-number'.");
strictEqual(content.classList.contains("popover-tracking"), true, "should have class 'popover-tracking'.");
var element = document.createElement("div");
var popover = new Dashboard.Popover();
this.view._presentPopoverForRevisionRange(element, popover, content.popoverTracker._context);
var nodeList = popover._element.getElementsByClassName("pending-commit");
strictEqual(nodeList.length, 2, "has 2 commits");
});

test("_formatRevisionForDisplay Subversion", function()
@@ -1,3 +1,28 @@
2022-04-26 Jonathan Bedard <jbedard@apple.com>

[build.webkit.org] Support identifiers in popover
https://bugs.webkit.org/show_bug.cgi?id=239773
<rdar://problem/92339575>

Rubber-stamped by Aakash Jain.

* CISupport/build-webkit-org/public_html/dashboard/Scripts/Commits.js:
(Commits): Keep track of all fetched commits.
(Commits.prototype._update): Save fetched commits.
(Commits.prototype.lastNIdentifiers): Return a list of the last n identifiers
on a branch.
(Commits.prototype.fetch): Load information for last N commits.
(Commits.prototype.urlFor): Return a url for a commit ref.
* CISupport/build-webkit-org/public_html/dashboard/Scripts/Main.js: Remove
trac auto-updater.
* CISupport/build-webkit-org/public_html/dashboard/Scripts/QueueView.js:
(QueueView.prototype._appendPendingRevisionCount): After we determine the
number of commits behind, fetch that many commits.
(QueueView.prototype._popoverLinesForCommitRange): Support commits with identifiers.
(QueueView.prototype._presentPopoverForPendingCommits):
* CISupport/build-webkit-org/public_html/dashboard/Scripts/tests/resources/MockCommits.js:
* CISupport/build-webkit-org/public_html/dashboard/Scripts/tests/resources/tests.js:

2022-04-26 Yusuke Suzuki <ysuzuki@apple.com>

[JSC] Add forceUnlinkedDFG option

0 comments on commit 0975a44

Please sign in to comment.