Home | History | Annotate | Download | only in static
      1 /**
      2  * Copyright (c) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you
      5  * may not use this file except in compliance with the License. You may
      6  * obtain a copy of the License at
      7  *
      8  *   http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
     13  * implied. See the License for the specific language governing
     14  * permissions and limitations under the License.
     15  */
     16 
     17 'use strict';
     18 
     19 const REPO_URL = 'https://android.googlesource.com/platform/external/perfetto/';
     20 const GERRIT_REVIEW_URL = 'https://android-review.googlesource.com/c/platform/external/perfetto';
     21 const CHANGES_URL = '/changes/?q=project:platform/external/perfetto+-age:7days+-is:abandoned&o=DETAILED_ACCOUNTS';
     22 const REPO = 'catapult-project/perfetto';
     23 
     24 let botIndex = {};
     25 
     26 // Builds a map of bot name -> column index, e.g.:
     27 // {'linux-clang-x86_64-relese' -> 1, 'android-clang-arm-debug' -> 2}.
     28 function GetColumnIndexes() {
     29   const cols = document.getElementById('cls_header').children;
     30   for (let i = 0; i < cols.length; i++) {
     31     const id = cols[i].id;
     32     if (id)
     33       botIndex[id] = i + 4 /* 4 = subject...updated columns */;
     34   }
     35 }
     36 
     37 function GetTravisStatusForJob(jobId, div) {
     38   fetch('https://api.travis-ci.org/jobs/' + jobId)
     39     .then(response => {
     40       if (response.status != 200)
     41         throw 'Unable to make request to Travis';
     42       return response.json();
     43     })
     44     .then(resp => {
     45       let jobName = resp.config.env.split(' ')[0];
     46       if (jobName.startsWith('CFG='))
     47         jobName = jobName.substring(4);
     48       if (!(jobName in botIndex))
     49         return;
     50       let link = document.createElement('a');
     51       link.href = 'https://travis-ci.org/' + REPO + '/jobs/' + jobId;
     52       link.title = resp.state + ' [' + jobName + ']';
     53       let jobState = resp.state;
     54       if (resp.state == 'finished' && resp.result !== 0)
     55         jobState = 'errored';
     56       link.classList.add(jobState);
     57       if (jobState == 'finished')
     58         link.innerHTML = '<i class="material-icons">check_circle</i>';
     59       else if (jobState == 'created')
     60         link.innerHTML = '<i class="material-icons">autorenew</i>';
     61       else if (jobState == 'errored' || jobState == 'cancelled')
     62         link.innerHTML = '<i class="material-icons">bug_report</i>';
     63       else
     64         link.innerHTML = '<i class="material-icons">hourglass_full</i>';
     65       let td = div.children[botIndex[jobName]];
     66       td.innerHTML = '';
     67       td.appendChild(link);
     68     });
     69 }
     70 
     71 function GetTravisStatusForBranch(branch, div) {
     72   fetch('https://api.travis-ci.org/repos/' + REPO + '/branches/' + branch)
     73     .then(response => {
     74       if (response.status != 200)
     75         throw 'Unable to make request to Travis';
     76       return response.json()
     77     })
     78     .then(resp => {
     79       for (const jobId of resp.branch.job_ids)
     80         GetTravisStatusForJob(jobId, div);
     81     });
     82 }
     83 
     84 function CreateRowForBranch(branch, href, subject, status, author, updated) {
     85   let table = document.getElementById('cls');
     86   let tr = document.createElement('tr');
     87   tr.classList.add(status);
     88 
     89   let link = document.createElement('a');
     90   link.href = href;
     91   link.innerText = subject;
     92   let td = document.createElement('td');
     93   td.appendChild(link);
     94   tr.appendChild(td);
     95 
     96   td = document.createElement('td');
     97   td.innerText = status;
     98   tr.appendChild(td);
     99 
    100   td = document.createElement('td');
    101   td.innerText = author;
    102   tr.appendChild(td);
    103 
    104   td = document.createElement('td');
    105   td.innerText = updated;
    106   tr.appendChild(td);
    107 
    108   for (let _ in botIndex) {
    109     td = document.createElement('td');
    110     td.classList.add('job');
    111     tr.appendChild(td);
    112   }
    113   table.appendChild(tr);
    114   GetTravisStatusForBranch(branch, tr);
    115 }
    116 
    117 function LoadGerritCLs() {
    118   fetch(CHANGES_URL)
    119     .then(response => {
    120       if (response.status != 200)
    121         throw 'Unable to make request to Travis';
    122       return response.text();
    123     })
    124     .then(text => {
    125       let json;
    126       if (text.startsWith(')]}\''))
    127         json = text.substring(4);
    128       else
    129         json = text;
    130       let resp = JSON.parse(json);
    131       for (const cl of resp) {
    132         const branch = 'changes/' + cl._number;
    133         const href = GERRIT_REVIEW_URL + '/+/' + cl._number;;
    134         const lastUpdate = new Date(cl.updated + ' UTC');
    135         const lastUpdateMins = Math.ceil((Date.now() - lastUpdate) / 60000);
    136         let lastUpdateText = '';
    137         if (lastUpdateMins < 60)
    138           lastUpdateText = lastUpdateMins + ' mins ago';
    139         else if (lastUpdateMins < 60 * 24)
    140           lastUpdateText = Math.ceil(lastUpdateMins / 60) + ' hours ago';
    141         else
    142           lastUpdateText = lastUpdate.toLocaleDateString();
    143         CreateRowForBranch(branch, href, cl.subject, cl.status,
    144             cl.owner.email.replace('@google.com', '@'), lastUpdateText);
    145       }
    146     });
    147 }
    148 
    149 // Register the service worker to cache job requests.
    150 if ('serviceWorker' in navigator) {
    151   navigator.serviceWorker.register('/service_worker.js', { scope: '/' });
    152 }
    153 
    154 // Fetch the CLs and the corresponding status for the Travis jobs.
    155 GetColumnIndexes();
    156 CreateRowForBranch('master', REPO_URL, '*** master branch ***', 'MASTER', '', '');
    157 LoadGerritCLs();
    158