Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Ahmad Nassri 2015-04-16 20:18:08 -04:00
commit 8dab4bb170
5 changed files with 312 additions and 3 deletions

View File

@ -42,8 +42,7 @@ As you can see below, without increasing the footprint of these badges, I've tri
![Badge design](spec/proportions.png)
We have an effort to produce similar-looking SVGs through a web service at
<http://img.shields.io>. That ensures that we are retina-ready.
This badge design corresponds to an old and now deprecated version which has since been replaced by beautiful and scalable SVG versions that can be found on [shields.io](http://shields.io).
## Examples

View File

@ -153,6 +153,10 @@ Pixel-perfect &nbsp; Retina-ready &nbsp; Fast &nbsp; Consistent &nbsp; Hackable
<td><img src='https://img.shields.io/codecov/c/github/codecov/example-python.svg' alt=''/></td>
<td><code>https://img.shields.io/codecov/c/github/codecov/example-python.svg</code></td>
</tr>
<tr><th> Coverity Scan: </th>
<td><img src='https://img.shields.io/coverity/scan/3997.svg' alt=''/></td>
<td><code>https://img.shields.io/coverity/scan/3997.svg</code></td>
</tr>
<tr><th> HHVM: </th>
<td><img src='https://img.shields.io/hhvm/symfony/symfony.svg' alt=''/></td>
<td><code>https://img.shields.io/hhvm/symfony/symfony.svg</code></td>
@ -284,6 +288,22 @@ Pixel-perfect &nbsp; Retina-ready &nbsp; Fast &nbsp; Consistent &nbsp; Hackable
<td><img src='https://img.shields.io/puppetforge/dt/camptocamp/openldap.svg' alt=''/></td>
<td><code>https://img.shields.io/puppetforge/dt/camptocamp/openldap.svg</code></td>
</tr>
<tr><th data-keywords='dub'> DUB: </th>
<td><img src='https://img.shields.io/dub/dd/vibe-d.svg' alt=''/></td>
<td><code>https://img.shields.io/dub/dd/vibe-d.svg</code></td>
</tr>
<tr><th data-keywords='dub'> DUB: </th>
<td><img src='https://img.shields.io/dub/dw/vibe-d.svg' alt=''/></td>
<td><code>https://img.shields.io/dub/dw/vibe-d.svg</code></td>
</tr>
<tr><th data-keywords='dub'> DUB: </th>
<td><img src='https://img.shields.io/dub/dm/vibe-d/latest.svg' alt=''/></td>
<td><code>https://img.shields.io/dub/dm/vibe-d/latest.svg</code></td>
</tr>
<tr><th data-keywords='dub'> DUB: </th>
<td><img src='https://img.shields.io/dub/dt/vibe-d/0.7.23.svg' alt=''/></td>
<td><code>https://img.shields.io/dub/dt/vibe-d/0.7.23.svg</code></td>
</tr>
</tbody></table>
<h3 id="version"> Version </h3>
<table class='badge'><tbody>
@ -395,6 +415,10 @@ Pixel-perfect &nbsp; Retina-ready &nbsp; Fast &nbsp; Consistent &nbsp; Hackable
<td><img src='https://img.shields.io/ctan/v/tex.svg' alt=''/></td>
<td><code>https://img.shields.io/ctan/v/tex.svg</code></td>
</tr>
<tr><th data-keywords='dub'> DUB: </th>
<td><img src='https://img.shields.io/dub/v/vibe-d.svg' alt=''/></td>
<td><code>https://img.shields.io/dub/v/vibe-d.svg</code></td>
</tr>
</tbody></table>
<h3 id="miscellaneous"> Miscellaneous </h3>
@ -542,6 +566,10 @@ Pixel-perfect &nbsp; Retina-ready &nbsp; Fast &nbsp; Consistent &nbsp; Hackable
<td><img src='https://img.shields.io/gem/u/raphink.svg' alt=''/></td>
<td><code>https://img.shields.io/gem/u/raphink.svg</code></td>
</tr>
<tr><th data-keywords='dub'> DUB: </th>
<td><img src='https://img.shields.io/dub/l/vibe-d.svg' alt=''/></td>
<td><code>https://img.shields.io/dub/l/vibe-d.svg</code></td>
</tr>
</tbody></table>
<h2 id="your-badge"> Your Badge </h2>

233
server.js
View File

@ -578,6 +578,41 @@ camp.route(/^\/sonar\/(http|https)\/(.*)\/(.*)\/coverage\.(svg|png|gif|jpg|json)
});
}));
// Coverity integration
camp.route(/^\/coverity\/scan\/(.+)\.(svg|png|gif|jpg|json)$/,
cache(function(data, match, sendBadge, request) {
var projectId = match[1]; // eg, `3997`
var format = match[2];
var url = 'https://scan.coverity.com/projects/' + projectId + '/badge.json';
var badgeData = getBadgeData('coverity', data);
request(url, function(err, res, buffer) {
if (err != null) {
badgeData.text[1] = 'inaccessible';
sendBadge(format, badgeData);
return;
}
try {
var data = JSON.parse(buffer);
badgeData.text[1] = data.message;
if (data.message === 'passed') {
badgeData.colorscheme = 'brightgreen'
} else if (/^passed .* new defects$/.test(data.message)) {
badgeData.colorscheme = 'yellow';
} else if (data.message === 'pending') {
badgeData.colorscheme = 'orange';
} else if (data.message === 'failed') {
badgeData.colorscheme = 'red';
}
sendBadge(format, badgeData);
} catch(e) {
badgeData.text[1] = 'invalid';
sendBadge(format, badgeData);
}
});
}));
// Gratipay integration.
camp.route(/^\/(gittip|gratipay)\/(.*)\.(svg|png|gif|jpg|json)$/,
cache(function(data, match, sendBadge, request) {
@ -1570,6 +1605,53 @@ cache(function(data, match, sendBadge, request) {
});
}));
// Scrutinizer build integration.
camp.route(/^\/scrutinizer\/build\/(.*)\.(svg|png|gif|jpg|json)$/,
cache(function(data, match, sendBadge, request) {
var repo = match[1]; // eg, g/phpmyadmin/phpmyadmin
var format = match[2];
// The repo may contain a branch, which would be unsuitable.
var repoParts = repo.split('/');
var branch = null;
// Normally, there are 2 slashes in `repo` when the branch isn't specified.
var slashesInRepo = 2;
if (repoParts[0] === 'gp') { slashesInRepo = 1; }
if ((repoParts.length - 1) > slashesInRepo) {
branch = repoParts[repoParts.length - 1];
repo = repoParts.slice(0, -1).join('/');
}
var apiUrl = 'https://scrutinizer-ci.com/api/repositories/' + repo;
var badgeData = getBadgeData('build', data);
request(apiUrl, {}, function(err, res, buffer) {
if (err !== null) {
badgeData.text[1] = 'inaccessible';
sendBadge(format, badgeData);
return;
}
try {
var data = JSON.parse(buffer);
// Which branch are we dealing with?
if (branch === null) { branch = data.default_branch; }
var res = data.applications[branch].build_status.status;
badgeData.text[1] = res;
if (res === 'passed') {
badgeData.colorscheme = 'brightgreen';
} else if (res === 'failed' || res === 'error') {
badgeData.colorscheme = 'red';
} else if (res === 'pending') {
badgeData.colorscheme = 'orange';
} else if (res === 'unknown') {
badgeData.colorscheme = 'gray';
}
sendBadge(format, badgeData);
} catch(e) {
badgeData.text[1] = 'invalid';
sendBadge(format, badgeData);
}
});
}));
// Scrutinizer integration.
camp.route(/^\/scrutinizer\/(.*)\.(svg|png|gif|jpg|json)$/,
cache(function(data, match, sendBadge, request) {
@ -1652,6 +1734,8 @@ cache(function(data, match, sendBadge, request) {
} else if (status === 'uptodate') {
badgeData.colorscheme = 'brightgreen';
status = 'up-to-date';
} else if (status === 'none') {
badgeData.colorscheme = 'brightgreen';
}
badgeData.text[1] = status;
sendBadge(format, badgeData);
@ -1915,7 +1999,8 @@ cache(function(data, match, sendBadge, request) {
return; // Hope for the best in the cache.
}
var data = JSON.parse(buffer);
var tag = data[0].name;
var versions = data.map(function(e) { return e.name; });
var tag = latestVersion(versions);
var vdata = versionColor(tag);
badgeData.text[1] = vdata.version;
badgeData.colorscheme = vdata.color;
@ -2162,6 +2247,57 @@ cache(function(data, match, sendBadge, request) {
});
}));
// GitHub license integration.
camp.route(/^\/github\/license\/([^\/]+)\/([^\/]+)\.(svg|png|gif|jpg|json)$/,
cache(function(data, match, sendBadge, request) {
var user = match[1]; // eg, mashape
var repo = match[2]; // eg, apistatus
var format = match[3];
var apiUrl = 'https://api.github.com/repos/' + user + '/' + repo;
var badgeData = getBadgeData('license', data);
// Using our OAuth App secret grants us 5000 req/hour
// instead of the standard 60 req/hour.
if (serverSecrets) {
apiUrl += '?client_id=' + serverSecrets.gh_client_id
+ '&client_secret=' + serverSecrets.gh_client_secret;
}
// Custom user-agent and accept headers are required
// http://developer.github.com/v3/#user-agent-required
// https://developer.github.com/v3/licenses/
var customHeaders = {
'User-Agent': 'Shields.io',
'Accept': 'application/vnd.github.drax-preview+json'
};
request(apiUrl, { headers: customHeaders }, function(err, res, buffer) {
if (err != null) {
badgeData.text[1] = 'inaccessible';
sendBadge(format, badgeData);
return;
}
try {
if ((+res.headers['x-ratelimit-remaining']) === 0) {
return; // Hope for the best in the cache.
} else if (res.statusCode === 404) {
badgeData.text[1] = 'repo not found';
sendBadge(format, badgeData);
return;
}
var body = JSON.parse(buffer);
if (body.license != null) {
badgeData.text[1] = body.license.name;
badgeData.colorscheme = 'blue';
sendBadge(format, badgeData);
} else {
badgeData.text[1] = 'unknown license';
sendBadge(format, badgeData);
}
} catch(e) {
badgeData.text[1] = 'invalid';
sendBadge(format, badgeData);
}
});
}));
// Chef cookbook integration.
camp.route(/^\/cookbook\/v\/(.*)\.(svg|png|gif|jpg|json)$/,
cache(function(data, match, sendBadge, request) {
@ -3156,6 +3292,101 @@ cache(function(data, match, sendBadge, request) {
})}
));
// DUB download integration
camp.route(/^\/dub\/(dd|dw|dm|dt)\/([^\/]+)(?:\/([^\/]+))?\.(svg|png|gif|jpg|json)$/,
cache(function (data, match, sendBadge, request) {
var info = match[1]; // downloads (dd - daily, dw - weekly, dm - monthly, dt - total)
var pkg = match[2]; // package name, e.g. vibe-d
var version = match[3]; // version (1.2.3 or latest)
var format = match[4];
var apiUrl = 'http://code.dlang.org/api/packages/'+pkg;
if (version)
apiUrl += '/' + version;
apiUrl += '/stats';
var badgeData = getBadgeData('dub', data);
request(apiUrl, function(err, res, buffer) {
if (err != null) {
badgeData.text[1] = 'inaccessible';
sendBadge(format, badgeData);
}
try {
var data = JSON.parse(buffer);
if (info.charAt(0) === 'd') {
badgeData.text[0] = getLabel('downloads', data);
var downloads;
switch (info.charAt(1)) {
case 'm':
downloads = data.downloads.monthly;
badgeData.text[1] = metric(downloads) + '/month';
break;
case 'w':
downloads = data.downloads.weekly;
badgeData.text[1] = metric(downloads) + '/week';
break;
case 'd':
downloads = data.downloads.daily;
badgeData.text[1] = metric(downloads) + '/day';
break;
case 't':
downloads = data.downloads.total;
badgeData.text[1] = metric(downloads);
break;
}
if (version) {
badgeData.text[1] += ' ' + versionColor(version).version;
}
badgeData.colorscheme = downloadCountColor(downloads);
sendBadge(format, badgeData);
}
} catch(e) {
badgeData.text[1] = 'invalid';
sendBadge(format, badgeData);
}
});
}));
// DUB license and version integration
camp.route(/^\/dub\/(v|l)\/([^\/]+)\.(svg|png|gif|jpg|json)$/,
cache(function (data, match, sendBadge, request) {
var info = match[1]; // (v - version, l - license)
var pkg = match[2]; // package name, e.g. vibe-d
var format = match[3];
var apiUrl = 'http://code.dlang.org/api/packages/'+pkg;
if (info === 'v')
apiUrl += '/latest';
else if (info === 'l')
apiUrl += '/latest/info';
var badgeData = getBadgeData('dub', data);
request(apiUrl, function(err, res, buffer) {
if (err != null) {
badgeData.text[1] = 'inaccessible';
sendBadge(format, badgeData);
}
try {
var data = JSON.parse(buffer);
if (info === 'v') {
var vdata = versionColor(data);
badgeData.text[1] = vdata.version;
badgeData.colorscheme = vdata.color;
sendBadge(format, badgeData);
} else if (info == 'l') {
var license = data.info.license;
badgeData.text[0] = 'license';
if (license == null) {
badgeData.text[1] = 'Unknown';
} else {
badgeData.text[1] = license;
badgeData.colorscheme = 'blue';
}
sendBadge(format, badgeData);
}
} catch(e) {
badgeData.text[1] = 'invalid';
sendBadge(format, badgeData);
}
});
}));
// Any badge.
camp.route(/^\/(:|badge\/)(([^-]|--)+)-(([^-]|--)+)-(([^-]|--)+)\.(svg|png|gif|jpg)$/,
function(data, match, end, ask) {

View File

@ -9,6 +9,18 @@ This document specifies the visual design of Shields badges.
- **concise**: one descriptive word on the left (the key), one piece of data on the right (the value)
- **hyperlinked**: badges can link to a third-party website providing more information, either related to the metadata provided by the badge or about the project the badge was used for (e.g. an open source library)
### Example
#### Bad
![bad example](https://img.shields.io/badge/MySuperSaaSisSoAwesome.com-1.1.1-orange.svg)
The key is shamelessly promoting the service provider instead of giving context to the value. If service providers want to promote themselves, they can simply encourage people to link back to them and let folks who are curious click on the button for more information.
#### Good
![good example](https://img.shields.io/badge/version-1.1.1-green.svg)
The key clearly explains what the value stands for (the version of the software provided). The platform or service hosting the version of the software is only relevant to people who decide to click on an eventual link added to the badge itself but the value stands on its own with the metadata value it provides to viewers.
## Aesthetics
The design of our badges has been carefully considered to provide sufficient padding between the container badge and the text within. Badges should never have a fixed width. The letter spacing (or kerning) is deliberate and focused on clarity, so is the use of the Open Sans font face. Contrary to widely available web-safe alternative sans-serif fonts like Arial (a sloppy Helvetica ripoff) and Verdana (a sloppy Futura ripoff), OpenSans remains highly legible at very small sizes which is why it was chosen.

View File

@ -148,10 +148,18 @@ Pixel-perfect &nbsp; Retina-ready &nbsp; Fast &nbsp; Consistent &nbsp; Hackable
<td><img src='/scrutinizer/coverage/g/phpmyadmin/phpmyadmin/master.svg' alt=''/></td>
<td><code>https://img.shields.io/scrutinizer/coverage/g/phpmyadmin/phpmyadmin/master.svg</code></td>
</tr>
<tr><th> Scrutinizer Build: </th>
<td><img src='/scrutinizer/build/g/filp/whoops.svg' alt=''/></td>
<td><code>https://img.shields.io/scrutinizer/build/g/filp/whoops.svg</code></td>
</tr>
<tr><th> Codecov: </th>
<td><img src='/codecov/c/github/codecov/example-python.svg' alt=''/></td>
<td><code>https://img.shields.io/codecov/c/github/codecov/example-python.svg</code></td>
</tr>
<tr><th> Coverity Scan: </th>
<td><img src='/coverity/scan/3997.svg' alt=''/></td>
<td><code>https://img.shields.io/coverity/scan/3997.svg</code></td>
</tr>
<tr><th> HHVM: </th>
<td><img src='/hhvm/symfony/symfony.svg' alt=''/></td>
<td><code>https://img.shields.io/hhvm/symfony/symfony.svg</code></td>
@ -283,6 +291,22 @@ Pixel-perfect &nbsp; Retina-ready &nbsp; Fast &nbsp; Consistent &nbsp; Hackable
<td><img src='/puppetforge/dt/camptocamp/openldap.svg' alt=''/></td>
<td><code>https://img.shields.io/puppetforge/dt/camptocamp/openldap.svg</code></td>
</tr>
<tr><th data-keywords='dub'> DUB: </th>
<td><img src='/dub/dd/vibe-d.svg' alt=''/></td>
<td><code>https://img.shields.io/dub/dd/vibe-d.svg</code></td>
</tr>
<tr><th data-keywords='dub'> DUB: </th>
<td><img src='/dub/dw/vibe-d.svg' alt=''/></td>
<td><code>https://img.shields.io/dub/dw/vibe-d.svg</code></td>
</tr>
<tr><th data-keywords='dub'> DUB: </th>
<td><img src='/dub/dm/vibe-d/latest.svg' alt=''/></td>
<td><code>https://img.shields.io/dub/dm/vibe-d/latest.svg</code></td>
</tr>
<tr><th data-keywords='dub'> DUB: </th>
<td><img src='/dub/dt/vibe-d/0.7.23.svg' alt=''/></td>
<td><code>https://img.shields.io/dub/dt/vibe-d/0.7.23.svg</code></td>
</tr>
</tbody></table>
<h3 id="version"> Version </h3>
<table class='badge'><tbody>
@ -394,6 +418,10 @@ Pixel-perfect &nbsp; Retina-ready &nbsp; Fast &nbsp; Consistent &nbsp; Hackable
<td><img src='/ctan/v/tex.svg' alt=''/></td>
<td><code>https://img.shields.io/ctan/v/tex.svg</code></td>
</tr>
<tr><th data-keywords='dub'> DUB: </th>
<td><img src='/dub/v/vibe-d.svg' alt=''/></td>
<td><code>https://img.shields.io/dub/v/vibe-d.svg</code></td>
</tr>
</tbody></table>
<h3 id="miscellaneous"> Miscellaneous </h3>
@ -506,6 +534,10 @@ Pixel-perfect &nbsp; Retina-ready &nbsp; Fast &nbsp; Consistent &nbsp; Hackable
<td><img src='/github/followers/espadrine.svg' alt=''/></td>
<td><code>https://img.shields.io/github/followers/espadrine.svg</code></td>
</tr>
<tr><th data-keywords='github license'> GitHub license: </th>
<td><img src='/github/license/mashape/apistatus.svg' alt=''/></td>
<td><code>https://img.shields.io/github/license/mashape/apistatus.svg</code></td>
</tr>
<tr><th> WordPress rating: </th>
<td><img src='/wordpress/plugin/r/akismet.svg' alt=''/></td>
<td><code>https://img.shields.io/wordpress/plugin/r/akismet.svg</code></td>
@ -541,6 +573,10 @@ Pixel-perfect &nbsp; Retina-ready &nbsp; Fast &nbsp; Consistent &nbsp; Hackable
<td><img src='/gem/u/raphink.svg' alt=''/></td>
<td><code>https://img.shields.io/gem/u/raphink.svg</code></td>
</tr>
<tr><th data-keywords='dub'> DUB: </th>
<td><img src='/dub/l/vibe-d.svg' alt=''/></td>
<td><code>https://img.shields.io/dub/l/vibe-d.svg</code></td>
</tr>
</tbody></table>
<h2 id="your-badge"> Your Badge </h2>
@ -741,6 +777,9 @@ is where the current server got started.
<a class='photo' href='https://github.com/raphink'>
<img alt='raphink' src='https://avatars.githubusercontent.com/u/650430?s=80'>
</a>
<a class='photo' href='https://github.com/montanaflynn'>
<img alt='montanaflynn' src='https://avatars.githubusercontent.com/u/24260?s=80'>
</a>
<p><small>:wq</small></p>
</main>