Skip to content

Instantly share code, notes, and snippets.

@cvan
Last active April 8, 2019 10:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cvan/d37e7d78ce114ba15e3736af18acfdac to your computer and use it in GitHub Desktop.
Save cvan/d37e7d78ce114ba15e3736af18acfdac to your computer and use it in GitHub Desktop.
GitHub Releases: Get list of URLs to download (w/ grouping and filtering by filename patterns + platform/architecture)
// Source: https://gist.github.com/cvan/d37e7d78ce114ba15e3736af18acfdac
// Author: CVAN <https://cvan.io>
const fs = require('fs');
const os = require('os');
const path = require('path');
// Source: https://gist.github.com/cvan/ef28f73b88b991d4a9705314b2af2e78#file-system-js
// Author: CVAN <https://cvan.io>
// Useful helper snippet for understanding the capabilities of a user's system from Node.js' built-in `process.arch` and `process.platform`.
const system = {
_arch: process.arch,
_platform: process.platform
};
system.win = system._platform === 'win32' || process.env.OSTYPE === 'cygwin' || process.env.OSTYPE === 'msys';
system.mac = system._platform === 'darwin';
system.linux = !system.win && !system.mac;
system.arch32 = system._arch === 'arm' || system._arch === 'ia32' || system._arch === 'mips' || system._arch === 'ppc' || system._arch === 's390' || system._arch === 'x32';
system.arch64 = system._arch === 'arm64' || system._arch === 'mipsel' || system._arch === 'ppc64' || system._arch === '390x' || system._arch === 'x64';
system.intel = system._arch === 'ia32' || system._arch === 'x32' || system._arch === 'x64';
system.arm = system._arch === 'arm' || system._arch === 'arm64';
const utils = {
argv: process.argv.slice(2),
system, // TODO: Use this later for grouping by platform/architecture.
};
utils.findArgvFlag = values => utils.argv.find(value => {
const valueLower = (value || '').toLowerCase().replace(/^-+/g, '').trim();
return values.includes(valueLower);
});
utils.debugMode = (process.env.DEBUG && process.env.DEBUG !== '0' && process.env.DEBUG !== 'off') || utils.findArgvFlag(['d', 'debug', 'verbose']);
utils.helpFlag = utils.findArgvFlag(['h', 'help']);
class GitHubLatestReleases {
constructor ({org = '', repo = '', orgRepo = '', groups, rules, debugMode}) {
this.org = org.toLowerCase().trim();
this.repo = repo.toLowerCase().trim();
this.orgRepo = orgRepo.toLowerCase().trim();
this.debugMode = typeof debugMode === 'undefined' ? utils.debugMode : debugMode;
if (orgRepo && orgRepo.includes('/')) {
const orgRepoChunks = orgRepo.toLowerCase().split('/');
this.org = orgRepoChunks[0];
this.repo = orgRepoChunks[1];
this.orgRepo = this.orgRepo;
} else {
this.orgRepo = `${this.org}/${this.repo}`;
}
if (!this.orgRepo) {
throw new Error('Invalid {org}/{repo} pair (example: cvan/hotcops)')
}
this.groups = groups || {};
this.rules = rules || [
name => {
if (this.orgRepo !== 'mozilla/deepspeech') {
return false;
}
if (name.startsWith('deepspeech-') && name.includes('-models.')) {
return `${this.repo}-models`;
}
if (name.startsWith('deepspeech-') && name.endsWith('.whl') && name.includes('-macosx_') || name.includes('-macos_') || name.includes('-mac_')) {
return `${this.repo}-whl-mac`;
}
if (name.startsWith('deepspeech-') && name.endsWith('.whl') && name.includes('-linux_') || name.includes('linux_')) {
return `${this.repo}-whl-linux-aarch64`;
}
if (name.startsWith('deepspeech-') && name.includes('gpu') && name.includes('linux')) {
return `${this.repo}-gpu-linux`;
}
if (name.startsWith('deepspeech-') && name.includes('gpu')) {
return `${this.repo}-gpu`;
}
if (name.startsWith('native') && name.includes('client') && name.includes('osx.') || name.includes('mac.') || name.includes('macos.') || name.includes('macosx.')) {
return `${this.repo}-native-client-mac-osx`;
}
}
];
if (this.org && this.repo) {
this.run();
}
}
run () {
// Open https://api.github.com/repos/mozilla/DeepSpeech/releases/latest from your web browser,
// save the file in this working directory to `mozilla-deepspeech-latest-releases.json`.
//
// curl 'https://api.github.com/repos/mozilla/DeepSpeech/releases/latest' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36' > mozilla-deepspeech-latest-releases.json
//
// TODO: Fetch the file using Node.js' `https` request library.
fs.readFile(path.join(__dirname, `${this.org}-${this.repo}-latest-releases.json`), (err, data) => {
if (err) {
throw new Error(err);
}
data = JSON.parse(data);
(data.assets || []).forEach(asset => {
const name = asset.name;
const url = asset.browser_download_url;
if (!name || !url) {
return;
}
if (this.debugMode) {
console.log(`Asset:\n${JSON.stringify({
name,
url
}, null, 2)}`);
}
const nameLower = name.toLowerCase();
this.rules.forEach(rule => {
const matchedGroup = rule(nameLower);
if (matchedGroup) {
this.groups[matchedGroup] = {
name,
url
};
}
});
});
const groupsStr = JSON.stringify(this.groups, null, 2);
if (this.debugMode) {
console.log(`\n\nGroups:\n${groupsStr}`);
}
fs.writeFile(path.join(__dirname, `${this.org}-${this.repo}-latest-releases-groups.json`), groupsStr, (err, data) => {
if (err) {
throw new Error(err);
}
});
});
}
}
const argv = process.argv.slice(2);
const orgRepo = (argv[0] || process.env.GITHUB_REPO || process.env.GH_REPO || process.env.REPO || '').trim();
if (!orgRepo || utils.helpFlag) {
console.log(`
Usage:
node gh-latest-releases.js {org}/{repo}
Example:
node gh-latest-releases.js 30-seconds/30-seconds-of-code
·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•
·•·Made by CVAN <https://cvan.io>·•
•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•
`.trim() + '\n');
process.exit(1);
}
if (!module.parent) {
new GitHubLatestReleases({orgRepo, debugMode: true});
}
module.exports = GitHubLatestReleases;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment