7be421456cadd5fb30f3c3c2c570ce2ebda17271
[WebKit-https.git] / Websites / perf.webkit.org / public / v3 / models / commit-log.js
1 'use strict';
2
3 class CommitLog extends DataModelObject {
4     constructor(id, rawData)
5     {
6         console.assert(parseInt(id) == id);
7         super(id);
8         this._repository = rawData.repository;
9         console.assert(this._repository instanceof Repository);
10         this._rawData = rawData;
11         this._remoteId = rawData.id;
12         if (this._remoteId)
13             this.ensureNamedStaticMap('remoteId')[this._remoteId] = this;
14         this._ownedCommits = null;
15     }
16
17     updateSingleton(rawData)
18     {
19         super.updateSingleton(rawData);
20
21         console.assert(+this._rawData['time'] == +rawData['time']);
22         console.assert(this._rawData['revision'] == rawData['revision']);
23
24         if (rawData.authorName)
25             this._rawData.authorName = rawData.authorName;
26         if (rawData.message)
27             this._rawData.message = rawData.message;
28         if (rawData.ownsCommits)
29             this._rawData.ownsCommits = rawData.ownsCommits;
30     }
31
32     repository() { return this._repository; }
33     time() { return new Date(this._rawData['time']); }
34     author() { return this._rawData['authorName']; }
35     revision() { return this._rawData['revision']; }
36     message() { return this._rawData['message']; }
37     url() { return this._repository.urlForRevision(this._rawData['revision']); }
38     ownsCommits() { return this._rawData['ownsCommits']; }
39
40     label()
41     {
42         var revision = this.revision();
43         if (parseInt(revision) == revision) // e.g. r12345
44             return 'r' + revision;
45         else if (revision.length == 40) // e.g. git hash
46             return revision.substring(0, 8);
47         return revision;
48     }
49     title() { return this._repository.name() + ' at ' + this.label(); }
50
51     diff(previousCommit)
52     {
53         if (this == previousCommit)
54             previousCommit = null;
55
56         const repository = this._repository;
57         if (!previousCommit)
58             return {repository: repository, label: this.label(), url: this.url()};
59
60         const to = this.revision();
61         const from = previousCommit.revision();
62         let fromRevisionForURL = from;
63         let label = null;
64         if (parseInt(from) == from) { // e.g. r12345.
65             fromRevisionForURL = (parseInt(from) + 1).toString;
66             label = `r${from}-r${this.revision()}`;
67         } else if (to.length == 40) // e.g. git hash
68             label = `${from.substring(0, 8)}..${to.substring(0, 8)}`;
69         else
70             label = `${from} - ${to}`;
71
72         return {repository: repository, label: label, url: repository.urlForRevisionRange(from, to)};
73     }
74
75     static fetchLatestCommitForPlatform(repository, platform)
76     {
77         console.assert(repository instanceof Repository);
78         console.assert(platform instanceof Platform);
79         return this.cachedFetch(`/api/commits/${repository.id()}/latest`, {platform: platform.id()}).then((data) => {
80             const commits = data['commits'];
81             if (!commits || !commits.length)
82                 return null;
83             const rawData = commits[0];
84             rawData.repository = repository;
85             return CommitLog.ensureSingleton(rawData.id, rawData);
86         });
87     }
88
89     fetchOwnedCommits()
90     {
91         if (!this.repository().ownedRepositories())
92             return Promise.reject();
93
94         if (!this.ownsCommits())
95             return Promise.reject();
96
97         if (this._ownedCommits)
98             return Promise.resolve(this._ownedCommits);
99
100         return CommitLog.cachedFetch(`../api/commits/${this.repository().id()}/owned-commits?owner-revision=${escape(this.revision())}`).then((data) => {
101             this._ownedCommits = CommitLog._constructFromRawData(data);
102             return this._ownedCommits;
103         });
104     }
105
106     _buildOwnedCommitMap()
107     {
108         const ownedCommitMap = new Map;
109         for (const commit of this._ownedCommits)
110             ownedCommitMap.set(commit.repository(), commit);
111         return ownedCommitMap;
112     }
113
114     static diffOwnedCommits(previousCommit, currentCommit)
115     {
116         console.assert(previousCommit);
117         console.assert(currentCommit);
118         console.assert(previousCommit._ownedCommits);
119         console.assert(currentCommit._ownedCommits);
120
121         const previousOwnedCommitMap = previousCommit._buildOwnedCommitMap();
122         const currentOwnedCommitMap = currentCommit._buildOwnedCommitMap();
123         const ownedCommitRepositories = new Set([...currentOwnedCommitMap.keys(), ...previousOwnedCommitMap.keys()]);
124         const difference = new Map;
125
126         ownedCommitRepositories.forEach((ownedCommitRepository) => {
127             const currentRevision = currentOwnedCommitMap.get(ownedCommitRepository);
128             const previousRevision = previousOwnedCommitMap.get(ownedCommitRepository);
129             if (currentRevision != previousRevision)
130                 difference.set(ownedCommitRepository, [previousRevision, currentRevision]);
131         });
132
133         return difference;
134     }
135
136     static fetchBetweenRevisions(repository, precedingRevision, lastRevision)
137     {
138         // FIXME: The cache should be smarter about fetching a range within an already fetched range, etc...
139         // FIXME: We should evict some entires from the cache in cachedFetch.
140         return this.cachedFetch(`/api/commits/${repository.id()}/`, {precedingRevision, lastRevision})
141             .then((data) => this._constructFromRawData(data));
142     }
143
144     static fetchForSingleRevision(repository, revision)
145     {
146         return this.cachedFetch(`/api/commits/${repository.id()}/${revision}`).then((data) => {
147             return this._constructFromRawData(data);
148         });
149     }
150
151     static _constructFromRawData(data)
152     {
153         return data['commits'].map((rawData) => {
154             rawData.repository = Repository.findById(rawData.repository);
155             return CommitLog.ensureSingleton(rawData.id, rawData);
156         });
157     }
158 }
159
160 if (typeof module != 'undefined')
161     module.exports.CommitLog = CommitLog;