travis-web/app/utils/helpers.js
2016-01-04 13:15:14 +01:00

271 lines
7.3 KiB
JavaScript

import emojiDictionary from 'travis/utils/emoji-dictionary';
import { githubCommit as githubCommitUrl } from 'travis/utils/urls';
import configKeysMap from 'travis/utils/keys-map';
import config from 'travis/config/environment';
import Ember from 'ember';
var _emojize, _escape, _githubCommitReferenceLink, _githubCommitReferenceRegexp,
_githubReferenceLink, _githubReferenceRegexp, _githubUserLink, _githubUserRegexp,
_normalizeDateString, _nowUtc, _toUtc, colorForState, colors, compact, configKeys,
durationFrom, formatCommit, formatConfig, formatMessage, formatSha, githubify,
intersect, mapObject, only, pathFrom, safe, timeAgoInWords, timeInWords, timeago;
timeago = $.timeago;
mapObject = $.map;
colors = {
"default": 'yellow',
passed: 'green',
failed: 'red',
errored: 'red',
canceled: 'gray'
};
mapObject = function(elems, callback, arg) {
var i, key, ret, value;
value = void 0;
key = void 0;
ret = [];
i = 0;
for (key in elems) {
value = callback(elems[key], key, arg);
if (value != null) {
ret[ret.length] = value;
}
}
return ret.concat.apply([], ret);
};
only = function(object) {
var key, keys, result;
keys = Array.prototype.slice.apply(arguments);
object = (typeof keys[0] === 'object' ? keys.shift() : this);
result = {};
for (key in object) {
if (keys.indexOf(key) !== -1) {
result[key] = object[key];
}
}
return result;
};
intersect = function(array, other) {
return array.filter(function(element) {
return other.indexOf(element) !== -1;
});
};
compact = function(object) {
var key, ref, result, value;
result = {};
ref = object || {};
for (key in ref) {
value = ref[key];
if (!Ember.isEmpty(value)) {
result[key] = value;
}
}
return result;
};
safe = function(string) {
return new Ember.Handlebars.SafeString(string);
};
colorForState = function(state) {
return colors[state] || colors['default'];
};
formatCommit = function(sha, branch) {
return formatSha(sha) + (branch ? " (" + branch + ")" : '');
};
formatSha = function(sha) {
return (sha || '').substr(0, 7);
};
formatConfig = function(config) {
var values;
config = only(config, Object.keys(configKeysMap));
values = mapObject(config, function(value, key) {
value = (value && value.join ? value.join(', ') : value) || '';
if (key === 'rvm' && ("" + value).match(/^\d+$/)) {
value = value + ".0";
}
return '%@: %@'.fmt(configKeysMap[key], value);
});
if (values.length === 0) {
return '-';
} else {
return values.join(', ');
}
};
formatMessage = function(message, options) {
message = message || '';
if (options.short) {
message = message.split(/\n/)[0];
}
message = _emojize(_escape(message));
if (options.repo) {
message = githubify(message, Ember.get(options.repo, 'owner'), Ember.get(options.repo, 'name'));
}
if (options.pre) {
message = message.replace(/\n/g, '<br/>');
}
return message;
};
timeAgoInWords = function(date) {
if (date) {
return timeago(date);
}
};
durationFrom = function(started, finished) {
started = started && _toUtc(new Date(_normalizeDateString(started)));
finished = finished ? _toUtc(new Date(_normalizeDateString(finished))) : _nowUtc();
if (started && finished) {
return Math.round((finished - started) / 1000);
} else {
return 0;
}
};
timeInWords = function(duration) {
var days, hours, minutes, result, seconds;
days = Math.floor(duration / 86400);
hours = Math.floor(duration % 86400 / 3600);
minutes = Math.floor(duration % 3600 / 60);
seconds = duration % 60;
if (days > 0) {
return 'more than 24 hrs';
} else {
result = [];
if (hours === 1) {
result.push(hours + ' hr');
}
if (hours > 1) {
result.push(hours + ' hrs');
}
if (minutes > 0) {
result.push(minutes + ' min');
}
if (seconds > 0) {
result.push(seconds + ' sec');
}
if (result.length > 0) {
return result.join(' ');
} else {
return '-';
}
}
};
githubify = function(text, owner, repo) {
text = text.replace(_githubReferenceRegexp, function(reference, matchedOwner, matchedRepo, matchedNumber) {
return _githubReferenceLink(reference, {
owner: owner,
repo: repo
}, {
owner: matchedOwner,
repo: matchedRepo,
number: matchedNumber
});
});
text = text.replace(_githubUserRegexp, function(reference, username) {
return _githubUserLink(reference, username);
});
text = text.replace(_githubCommitReferenceRegexp, function(reference, matchedOwner, matchedRepo, matchedSHA) {
return _githubCommitReferenceLink(reference, {
owner: owner,
repo: repo
}, {
owner: matchedOwner,
repo: matchedRepo,
sha: matchedSHA
});
});
return text;
};
_githubReferenceRegexp = new RegExp("([\\w-]+)?\\/?([\\w-]+)?(?:#|gh-)(\\d+)", 'g');
_githubReferenceLink = function(reference, current, matched) {
var owner, repo;
owner = matched.owner || current.owner;
repo = matched.repo || current.repo;
return "<a href=\"" + config.sourceEndpoint + "/" + owner + "/" + repo + "/issues/" + matched.number + "\">" + reference + "</a>";
};
_githubUserRegexp = new RegExp("\\B@([\\w-]+)", 'g');
_githubUserLink = function(reference, username) {
return "<a href=\"" + config.sourceEndpoint + "/" + username + "\">" + reference + "</a>";
};
_githubCommitReferenceRegexp = new RegExp("([\\w-]+)?\\/([\\w-]+)?@([0-9A-Fa-f]+)", 'g');
_githubCommitReferenceLink = function(reference, current, matched) {
var owner, repo, url;
owner = matched.owner || current.owner;
repo = matched.repo || current.repo;
url = "" + (githubCommitUrl(owner + "/" + repo, matched.sha));
return "<a href=\"" + url + "\">" + reference + "</a>";
};
_normalizeDateString = function(string) {
if (window.JHW) {
string = string.replace('T', ' ').replace(/-/g, '/');
string = string.replace('Z', '').replace(/\..*$/, '');
}
return string;
};
_nowUtc = function() {
// TODO: we overwrite Travis.currentDate in tests, so we need to leave this
// global usage as it is for now, but it should be removed at some point
return _toUtc(Travis.currentDate());
};
_toUtc = function(date) {
return Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds());
};
_emojize = function(text) {
var emojis;
emojis = text.match(/:\S+?:/g);
if (emojis !== null) {
emojis.uniq().forEach(function(emoji, ix) {
var image, strippedEmoji;
strippedEmoji = emoji.substring(1, emoji.length - 1);
if (emojiDictionary.indexOf(strippedEmoji) !== -1) {
image = '<img class=\'emoji\' title=\'' + emoji + '\' alt=\'' + emoji + '\' src=\'' + '/images/emoji/' + strippedEmoji + '.png\'/>';
return text = text.replace(new RegExp(emoji, 'g'), image);
}
});
}
return text;
};
_escape = function(text) {
return text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
};
configKeys = function(config) {
if (!config) {
return [];
}
return intersect(Object.keys(config), Object.keys(configKeysMap));
};
pathFrom = function(url) {
return (url || '').split('/').pop();
};
export {
configKeys, githubify, timeInWords, durationFrom, timeAgoInWords, formatMessage, formatConfig,
formatSha, formatCommit, colorForState, safe, compact, pathFrom
};