Rewrite 'pull-os-versions' script in Javascript to add support for reporting os revis...
[WebKit-https.git] / Websites / perf.webkit.org / tools / js / os-build-fetcher.js
1 'use strict';
2
3 let assert = require('assert');
4
5 class OSBuildFetcher {
6
7     constructor(osConfig, remoteAPI, slaveAuth, subprocess, logger)
8     {
9         this._osConfig = osConfig;
10         this._reportedRevisions = new Set();
11         this._logger = logger;
12         this._slaveAuth = slaveAuth;
13         this._remoteAPI = remoteAPI;
14         this._subprocess = subprocess;
15     }
16
17     fetchAndReportNewBuilds()
18     {
19         return this._fetchAvailableBuilds().then((results) =>{
20             return this._submitCommits(results);
21         });
22     }
23
24     _fetchAvailableBuilds()
25     {
26         const config = this._osConfig;
27         const repositoryName = config['name'];
28         let customCommands = config['customCommands'];
29
30         return Promise.all(customCommands.map((command) => {
31             assert(command['minRevision']);
32             assert(command['maxRevision']);
33             const minRevisionOrder = this._computeOrder(command['minRevision']);
34             const maxRevisionOrder = this._computeOrder(command['maxRevision']);
35
36             let fetchCommitsPromise = this._remoteAPI.getJSONWithStatus(`/api/commits/${escape(repositoryName)}/last-reported?from=${minRevisionOrder}&to=${maxRevisionOrder}`).then((result) => {
37                 const minOrder = result['commits'].length == 1 ? parseInt(result['commits'][0]['order']) : 0;
38                 return this._commitsForAvailableBuilds(repositoryName, command['command'], command['linesToIgnore'], minOrder);
39             })
40
41             if ('subCommitCommand' in command)
42                 fetchCommitsPromise = fetchCommitsPromise.then((commits) => this._addSubCommitsForBuild(commits, command['subCommitCommand']));
43
44             return fetchCommitsPromise;
45         })).then(results => {
46             return Array.prototype.concat.apply([], results);
47         });
48     }
49
50     _computeOrder(revision)
51     {
52         const buildNameRegex = /(\d+)([a-zA-Z])(\d+)([a-zA-Z]*)$/;
53         const match = buildNameRegex.exec(revision);
54         assert(match);
55         const major = parseInt(match[1]);
56         const kind = match[2].toUpperCase().charCodeAt(0) - "A".charCodeAt(0);
57         const minor = parseInt(match[3]);
58         const variant = match[4] ? match[4].toUpperCase().charCodeAt(0) - "A".charCodeAt(0) + 1 : 0;
59         return ((major * 100 + kind) * 10000 + minor) * 100 + variant;
60     }
61
62     _commitsForAvailableBuilds(repository, command, linesToIgnore, minOrder)
63     {
64         return this._subprocess.execute(command).then((output) => {
65             let lines = output.split('\n');
66             if (linesToIgnore){
67                 const regex = new RegExp(linesToIgnore);
68                 lines = lines.filter(function(line) {return !regex.exec(line);});
69             }
70             return lines.map(revision => ({repository, revision, 'order': this._computeOrder(revision)}))
71                 .filter(commit => commit['order'] > minOrder);
72         });
73     }
74
75     _addSubCommitsForBuild(commits, command)
76     {
77         return commits.reduce((promise, commit) => {
78             return promise.then(() => {
79                 return this._subprocess.execute(command.concat(commit['revision']));
80             }).then((subCommitOutput) => {
81                 const subCommits = JSON.parse(subCommitOutput);
82                 for (let repositoryName in subCommits) {
83                     const subCommit = subCommits[repositoryName];
84                     assert(subCommit['revision']);
85                 }
86                 commit['subCommits'] = subCommits;
87             });
88         }, Promise.resolve()).then(() => commits);
89     }
90
91     _submitCommits(commits)
92     {
93         const commitsToReport = {"slaveName": this._slaveAuth['name'], "slavePassword": this._slaveAuth['password'], 'commits': commits};
94         return this._remoteAPI.postJSONWithStatus('/api/report-commits/', commitsToReport);
95     }
96 }
97 if (typeof module != 'undefined')
98     module.exports.OSBuildFetcher = OSBuildFetcher;