From d76c736d74083ee05f9c6c8ccbecff7bc8f77eb1 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Wed, 6 May 2020 17:17:18 -0600 Subject: [PATCH] add brew, mariadb --- _common/brew.js | 64 ++++++++++++++ mariadb/releases.js | 205 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 269 insertions(+) create mode 100644 _common/brew.js create mode 100644 mariadb/releases.js diff --git a/_common/brew.js b/_common/brew.js new file mode 100644 index 0000000..c0f7fd0 --- /dev/null +++ b/_common/brew.js @@ -0,0 +1,64 @@ +'use strict'; + +/** + * Gets a releases from 'brew'. + * + * @param request + * @param {string} formula + * @returns {PromiseLike | Promise} + */ +function getAllReleases(request, formula) { + if (!formula) { + return Promise.reject('missing formula for brew'); + } + return request({ + url: 'https://formulae.brew.sh/api/formula/' + formula + '.json', + fail: true, // https://git.coolaj86.com/coolaj86/request.js/issues/2 + json: true + }) + .then(failOnBadStatus) + .then(function (resp) { + var ver = resp.body.versions.stable; + var dl = ( + resp.body.bottle.stable.files.high_sierra || + resp.body.bottle.stable.files.catalina + ).url.replace(new RegExp(ver.replace(/\./g, '\\.'), 'g'), '{{ v }}'); + return [ + { + version: ver, + download: dl.replace(/{{ v }}/g, ver) + } + ].concat( + resp.body.versioned_formulae.map(function (f) { + var ver = f.replace(/.*@/, ''); + return { + version: ver, + download: dl + }; + }) + ); + }) + .catch(function (err) { + console.error('Error fetching MariaDB versions (brew)'); + console.error(err); + return []; + }); +} + +function failOnBadStatus(resp) { + if (resp.statusCode >= 400) { + var err = new Error('Non-successful status code: ' + resp.statusCode); + err.code = 'ESTATUS'; + err.response = resp; + throw err; + } + return resp; +} + +module.exports = getAllReleases; + +if (module === require.main) { + getAllReleases(require('@root/request'), 'mariadb').then(function (all) { + console.info(JSON.stringify(all, null, 2)); + }); +} diff --git a/mariadb/releases.js b/mariadb/releases.js new file mode 100644 index 0000000..0c3ca30 --- /dev/null +++ b/mariadb/releases.js @@ -0,0 +1,205 @@ +'use strict'; + +var brewReleases = require('../_common/brew.js'); + +module.exports = function (request) { + // So many places to get (incomplete) release info... + // + // MariaDB official + // - https://downloads.mariadb.org/mariadb/+releases/ + // - http://archive.mariadb.org/ + // Brew + // - https://formulae.brew.sh/api/formula/mariadb@10.3.json + // - https://formulae.brew.sh/docs/api/ + // - https://formulae.brew.sh/formula/mariadb@10.2#default + // + // Note: This could be very fragile due to using the html + // as an API. It's pretty rather than minified, but that + // doesn't guarantee that it's meant as a consumable API. + // + + var promises = [mariaReleases(), brewReleases(request, 'mariadb')]; + return Promise.all(promises).then(function (many) { + var versions = many[0]; + var brews = many[1]; + + var all = { download: '', releases: [] }; + + // linux x86 + // linux x64 + // windows x86 + // windows x64 + // (and mac, wedged-in from Homebrew) + versions.forEach(function (ver) { + all.releases.push({ + version: ver.version, + lts: false, + channel: ver.channel, + date: ver.date, + os: 'linux', + arch: 'amd64', + download: 'http://archive.mariadb.org/mariadb-{{ v }}/bintar-linux-x86_64/mariadb-{{ v }}-linux-x86_64.tar.gz'.replace( + /{{ v }}/g, + ver.version + ) + }); + all.releases.push({ + version: ver.version, + lts: false, + channel: ver.channel, + date: ver.date, + os: 'linux', + arch: 'amd64', + download: 'http://archive.mariadb.org/mariadb-{{ v }}/bintar-linux-x86/mariadb-{{ v }}-linux-x86.tar.gz'.replace( + /{{ v }}/g, + ver.version + ) + }); + + // windows + all.releases.push({ + version: ver.version, + lts: false, + channel: ver.channel, + date: ver.date, + os: 'windows', + arch: 'amd64', + download: 'http://archive.mariadb.org/mariadb-{{ v }}/winx64-packages/mariadb-{{ v }}-winx64.zip'.replace( + /{{ v }}/g, + ver.version + ) + }); + all.releases.push({ + version: ver.version, + lts: false, + channel: ver.channel, + date: ver.date, + os: 'windows', + arch: 'x86', + download: 'http://archive.mariadb.org/mariadb-{{ v }}/win32-packages/mariadb-{{ v }}-win32.zip'.replace( + /{{ v }}/g, + ver.version + ) + }); + + // Note: versions are sorted most-recent first. + // We just assume that the brew version is most recent stable + // ... but we can't really know for sure + + // TODO + brews.some(function (brew, i) { + // 10.3 => ^10.2(\b|\.) + var reBrewVer = new RegExp( + '^' + brew.version.replace(/\./, '\\.') + '(\\b|\\.)', + 'g' + ); + if (!ver.version.match(reBrewVer)) { + return; + } + all.releases.push({ + version: ver.version, + lts: false, + channel: ver.channel, + date: ver.date, + os: 'macos', + arch: 'amd64', + download: brew.download.replace(/{{ v }}/g, ver.version) + }); + brews.splice(i, 1); // remove + return true; + }); + }); + + return all; + }); + + function mariaReleases() { + return request({ + url: 'https://downloads.mariadb.org/mariadb/+releases/', + fail: true // https://git.coolaj86.com/coolaj86/request.js/issues/2 + }) + .then(failOnBadStatus) + .then(function (resp) { + // fragile, but simple + + // Make release info go from this: + var html = resp.body; + // + // + // 10.0.38 + // 2019-01-31 + // Stable + // + + // To this: + var reLine = /\s*(<(tr|td)[^>]*>)\s*/g; + // + // 10.0.382019-01-31Stable + // 10.0.372018-11-01Stable + // 10.0.362018-08-01Stable + // + // To this: + var reVer = /.*mariadb\/(10[^\/]+)\/">.*(20\d\d-\d\d-\d\d)<\/td>(\w+)<\/td>/; + // + // { "version": "10.0.36", "date": "2018-08-01", "channel": "stable" } + + return html + .replace(reLine, '$1') + .split(/\n/) + .map(function (line) { + var m = line.match(reVer); + if (!m) { + return; + } + return { + version: m[1], + channel: mapChannel(m[3].toLowerCase()), + date: m[2] + }; + }) + .filter(Boolean); + }) + .catch(function (err) { + console.error('Error fetching (official) MariaDB versions'); + console.error(err); + return []; + }); + } +}; + +function mapChannel(ch) { + if ('alpha' === ch) { + return 'dev'; + } + // stable,rc,beta + return ch; +} + +function failOnBadStatus(resp) { + if (resp.statusCode >= 400) { + var err = new Error('Non-successful status code: ' + resp.statusCode); + err.code = 'ESTATUS'; + err.response = resp; + throw err; + } + return resp; +} + +if (module === require.main) { + module.exports(require('@root/request')).then(function (all) { + console.info('official releases look like:'); + console.info(JSON.stringify(all.releases.slice(0, 2), null, 2)); + console.info('Homebrew releases look like:'); + console.info( + JSON.stringify( + all.releases + .filter(function (rel) { + return 'macos' === rel.os; + }) + .slice(0, 2), + null, + 2 + ) + ); + }); +} -- 2.25.1