blob: 71771811426ce169edfd82cdcb6d2b9ce902fd6a [file] [log] [blame]
/*
* Copyright (C) 2020 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import replaceAll from "replaceall";
import {escapeForSlackText} from "./Utility.mjs";
function findAndRemove(change, regExp)
{
let matched = change.match(regExp);
if (matched) {
change = change.replace(regExp, "");
return [matched[1], change];
}
return [null, change];
}
function cleanUpChange(change, contributors)
{
for (let entry of contributors.entries) {
if (!entry.nicks)
continue;
let nameWithNicks = `${entry.name} (@${entry.nicks[0]})`;
if (change.includes(entry.name)) {
change = replaceAll(entry.name, nameWithNicks, change);
for (let email of entry.emails)
change = replaceAll(`<${email}>`, "", change);
} else {
for (let email of entry.emails)
change = replaceAll(` ${email} `, ` ${nameWithNicks} `, change);
}
}
return change;
}
export default class Commit {
constructor(feedItem, contributors)
{
let originalChange = feedItem.contentSnippet;
let change = cleanUpChange(originalChange, contributors);
[this._revision, change] = findAndRemove(change, /^git-svn-id: https:\/\/svn\.webkit\.org\/repository\/webkit\/trunk@(\d+) /im);
[this._patchBy, change] = findAndRemove(change, /^Patch\s+by\s+(.+?)\s+on(?:\s+\d{4}-\d{2}-\d{2})?\n?/im);
[this._revert, change] = findAndRemove(change, /(?:rolling out|reverting) (r?\d+(?:(?:,\s*|,?\s*and\s+)?r?\d+)*)\.?\s*/im);
[this._bugzilla, change] = findAndRemove(change, /https?:\/\/(?:bugs\.webkit\.org\/show_bug\.cgi\?id=|webkit\.org\/b\/)(\d+)/im);
[this._radar, change] = findAndRemove(change, /<rdar:\/\/(?:problem\/)?(\d+)>/im);
this._email = feedItem.author;
let lines = originalChange.split("\n");
this._title = feedItem.title;
if (lines.length)
this._title = lines[0];
if (this._patchBy)
this._author = this._patchBy;
if (!this._author) {
this._author = this._email;
if (this._email) {
let entry = contributors.queryWithEmail(this._email);
if (entry) {
if (entry.nicks && entry.nicks[0])
this._author = `${entry.name} (@${entry.nicks[0]})`;
if (entry.slackId)
this._authorSlackId = entry.slackId;
}
}
}
if (this._revert) {
let matched = change.match(/^"?(.+?)"? \(Requested\s+by\s+(.+?)\s+on\s+#webkit\)\./im);
if (matched) {
// FIXME: Implement more descriptive message when we detect that this commit is revert commit.
// let reason = matched[0];
// let author = matched[1];
}
}
if (!this._revision)
throw new Error("Cannot find revision");
this._revision = Number.parseInt(this._revision, 10);
this._bugzilla = this._bugzilla ? Number.parseInt(this._bugzilla, 10) : null;
this._radar = this._radar ? Number.parseInt(this._radar, 10) : null;
this._url = `https://trac.webkit.org/r${this._revision}`;
}
get revision() { return this._revision; }
get patchBy() { return this._patchBy; }
get revert() { return this._revert; }
get bugzilla() { return this._bugzilla; }
get email() { return this._email; }
get radar() { return this._radar; }
get title() { return this._title; }
get author() { return this._author; }
get authorSlackId() { return this._authorSlackId; }
get url() { return this._url; }
message()
{
let results = [];
results.push(escapeForSlackText(`${this._title}`));
if (!this._authorSlackId)
results.push(escapeForSlackText(`${this._url} by ${this._author}`));
else
results.push(`${escapeForSlackText(this._url)} by <@${this._authorSlackId}>`);
let urls = [];
if (this._bugzilla !== null)
urls.push(escapeForSlackText(`https://webkit.org/b/${this._bugzilla}`));
if (this._radar !== null) {
// Link it in Slack format `<>`.
urls.push(`<rdar://problem/${this._radar}>`);
}
if (urls.length !== 0)
results.push(urls.join(" "));
return results.join("\n");
}
}