Files
shields/lib/color-formatters.js
Pyves 7039e68018 Consistent version formatting (#1246)
Provide greater consistency for badges related to versions. Fix #1181.

- the `version` function in `color-formatters` was previously returning the colour of the badge, but also its text with a leading _v_. It was broken down into two separate functions and the text formatting part was moved to `text-formatters`, where it really belongs.

- unit tests were added for these two functions in `color-formatters.spec` and `text-formatters.spec`, using Sazerac.

- as discussed in #1181, the leading _v_ was omitted  for _xxxx-yy-zz_ date patterns. Any future exceptions can easily be added to the `ignoredVersionPatterns` pattern.

- the badge colour was previously switched to orange if a hyphen was found in the version string. This didn't seem ideal, instead pattern matching is done to find keywords such as `beta`, `alpha` or `snapshot`. Of course, this list can easily be extended.

- all badges related to versions now use the `versionText` and `versionColor` functions. There are a few rare exceptions, for instance in cases where the data returned by the service's API allows to figure things out without relying on any parsing/pattern matching (eg. `badgeData.colorscheme = prerelease ? 'orange' : 'blue';`, where `prerelease` is determined from an API's response).
2017-11-11 17:54:38 -05:00

95 lines
2.3 KiB
JavaScript

/**
* Commonly-used functions for determining the colour to use for a badge,
* including colours based off download count, version number, etc.
*/
'use strict';
const moment = require('moment');
function version(version) {
let first = version[0];
if (first === 'v') {
first = version[1];
}
if (first === '0' || /alpha|beta|snapshot|dev|pre/.test(version.toLowerCase())) {
return 'orange';
} else {
return 'blue';
}
}
function downloadCount(downloads) {
return floorCount(downloads, 10, 100, 1000);
}
function coveragePercentage(percentage) {
return floorCount(percentage, 80, 90, 100);
}
function floorCount(value, yellow, yellowgreen, green) {
if (value <= 0) {
return 'red';
} else if (value < yellow) {
return 'yellow';
} else if (value < yellowgreen) {
return 'yellowgreen';
} else if (value < green) {
return 'green';
} else {
return 'brightgreen';
}
}
function colorScale(steps, colors, reversed) {
if (steps === undefined) {
throw Error('When invoking colorScale, steps should be provided.');
}
const defaultColors = {
1: ['red', 'brightgreen'],
2: ['red', 'yellow', 'brightgreen'],
3: ['red', 'yellow', 'green', 'brightgreen'],
4: ['red', 'yellow', 'yellowgreen', 'green', 'brightgreen'],
5: ['red', 'orange', 'yellow', 'yellowgreen', 'green', 'brightgreen'],
};
if (typeof colors === 'undefined') {
if (steps.length in defaultColors) {
colors = defaultColors[steps.length];
} else {
throw Error(`No default colors for ${steps.length} steps.`);
}
}
if (steps.length !== colors.length - 1) {
throw Error('When colors are provided, there should be n + 1 colors for n steps.');
}
if (reversed) {
colors = Array.from(colors).reverse();
}
return value => {
const stepIndex = steps.findIndex(step => value < step);
// For the final step, stepIndex is -1, so in all cases this expression
// works swimmingly.
return colors.slice(stepIndex)[0];
};
}
function age(date) {
const colorByAge = colorScale([7, 30, 180, 365, 730], undefined, true);
const daysElapsed = moment().diff(moment(date), 'days');
return colorByAge(daysElapsed);
}
module.exports = {
version,
downloadCount,
coveragePercentage,
floorCount,
colorScale,
age
};