UNPKG

github-describe

Version:

Run 'git describe' on a GitHub repository, in the browser. Useful for GitHub pages sites!

92 lines (64 loc) 3.1 kB
// wrap-start /*! github-describe | © Nick Freear | MIT license. */ if (!('fetch' in window)) throw new Error('github-describe requires the "fetch" API.'); const fetch = window.fetch; const ELEM = document.querySelector('#github-describe'); const REPO = document.querySelector('[ data-github-describe-repo ]').getAttribute('data-github-describe-repo'); const GITHUB_URL = 'https://github.com/{repo}/commit/{sha}'.replace('{repo}', REPO); const TAG_URL = 'https://api.github.com/repos/{repo}/tags'.replace('{repo}', REPO); const COMP_URL = 'https://api.github.com/repos/{repo}/compare/{tag}...HEAD'.replace('{repo}', REPO); console.warn('github-describe:', REPO, TAG_URL, ELEM); var lastTag; fetch(TAG_URL) .then(function (resp) { console.warn('Fetch tag:', resp, resp.headers.get('x-ratelimit-remaining')); console.assert(resp.status === 200, 'HTTP status'); console.assert(resp.ok, 'Ok?'); console.assert(resp.type === 'cors', 'CORS?'); console.assert(resp.bodyUsed, 'body?'); // console.assert(typeof resp.body === 'ReadableStream', 'body?'); console.assert(resp.headers.get('x-ratelimit-remaining') > 4, 'x-ratelimit-remaining'); if (!resp.ok) return Promise.reject(resp); return resp.json(); }) .then(function (body) { console.assert(body.length > 0, 'tag count'); if (!body.length) return Promise.reject(new Error({ statusText: 'No git tags found', url: TAG_URL })); const LAST_TAG = body[ 0 ].name; const COMPARE_URL = COMP_URL.replace('{tag}', LAST_TAG); console.warn('GD tag:', LAST_TAG, COMPARE_URL); lastTag = LAST_TAG; return fetch(COMPARE_URL); }) .then(function (resp) { console.warn('Fetch compare:', resp); console.assert(resp.status === 200, 'HTTP status'); console.assert(resp.ok, 'Ok?'); console.assert(resp.type === 'cors', 'CORS?'); // console.assert(resp.bodyUsed, 'body?'); if (!resp.ok) return Promise.reject(resp); return resp.json(); }) .then(function (body) { console.assert(body.status === 'ahead', 'Ahead'); // console.assert(body.behind_by === 0); console.assert(lastTag); const LAST_TAG = lastTag; const AHEAD_BY = body.ahead_by; const COMMIT = body.commits[ 0 ]; // TODO: check !! const DESCRIBE = replaceObj('{tag}-{num}-g{sha}', { '{tag}': LAST_TAG, '{num}': AHEAD_BY, '{sha}': COMMIT.sha.substr(0, 7) }); const TITLE = replaceObj('{tag} - {msg}, by {by}, on {dt}', { '{tag}': LAST_TAG, '{msg}': COMMIT.commit.message, '{by}': COMMIT.author.login, '{dt}': COMMIT.commit.author.date }); ELEM.setAttribute('href', GITHUB_URL.replace('{sha}', COMMIT.sha)); ELEM.setAttribute('title', TITLE); ELEM.innerHTML = replaceObj('<b>{repo}</b> @ <i>{desc}</i>', { '{repo}': REPO, '{desc}': DESCRIBE }); }) .catch(errResp => console.error('Fetch error:', errResp.statusText, errResp)); function replaceObj (str, mapObj) { const RE = new RegExp(Object.keys(mapObj).join('|'), 'g'); // Was: "gi". return str.replace(RE, function (matched) { return mapObj[ matched ]; }); } // wrap-end