cdbrelease/index.js

136 lines
3.6 KiB
JavaScript
Raw Normal View History

2019-02-09 00:02:19 -05:00
const process = require('process');
const needle = require('needle');
const cheerio = require('cheerio');
const minimist = require('minimist');
const config = minimist(process.argv.slice(2), {default: {
root: 'https://content.minetest.net/',
user: false,
pass: false,
pkg: false,
version: false,
min: 'none',
max: 'none',
2019-03-29 06:17:05 -04:00
branch: 'master',
timeout: 60,
poll: 2
2019-02-09 00:02:19 -05:00
}});
const missing = [];
Object.keys(config).sort().forEach(k => {
if(k === '_') return;
const v = config[k];
2019-03-29 06:17:05 -04:00
if(!v || v === false)
2019-02-09 00:02:19 -05:00
missing.push(k);
});
if(missing.length)
throw 'missing/invalid options: ' + missing.join(', ');
config.root = config.root.replace(/\/+$/, '');
const cookiejar = {};
async function fetch(uri, meth, data, opts, ref, ...rest) {
meth = meth || 'get';
opts = opts || {};
opts.headers = opts.headers || {};
opts.headers.Referer = 'https://content.minetest.net';
opts.cookies = cookiejar;
const r = await needle(meth, uri, data, opts, ...rest);
if(r.cookies)
Object.keys(r.cookies).forEach(k => cookiejar[k] = r.cookies[k]);
const $ = cheerio.load(r.body.toString());
let err;
$('h1').each(function() {
const t = $(this).text();
if(/^\s*Oops!/.test(t))
err = t;
});
if(err) throw err;
return $;
}
function getfields($, sel) {
const fields = {};
$('input').each(function() {
const e = $(this);
const n = e.attr('name');
if(!n) return;
const v = e.attr('value');
if(v) fields[n] = v;
});
return fields;
}
async function login() {
const uri = config.root + '/user/sign-in';
2019-03-29 06:17:05 -04:00
console.log('fetching sign-in page...');
2019-02-09 00:02:19 -05:00
let $ = await fetch(uri);
const fields = getfields($);
fields.username = config.user;
fields.password = config.pass;
2019-03-29 06:17:05 -04:00
console.log('submitting sign-in form...');
2019-02-09 00:02:19 -05:00
$ = await fetch(uri, 'post', fields);
let success;
$('h1').each(function() {
success = success || /^\s*Redirecting\b/i.test($(this).text());
});
if(!success) throw $('body').text();
}
2019-03-29 06:17:05 -04:00
async function checkalready() {
2019-02-09 00:02:19 -05:00
const uri = config.root + '/packages/' + config.user + '/' + config.pkg + '/';
2019-03-29 06:17:05 -04:00
console.log('fetching release list...');
2019-02-09 00:02:19 -05:00
let $ = await fetch(uri);
2019-03-29 06:17:05 -04:00
let already;
2019-02-09 00:02:19 -05:00
$('a').each(function() {
2019-03-29 06:17:05 -04:00
if(already) return;
2019-02-09 00:02:19 -05:00
const a = $(this);
const h = a.attr('href');
if(!h || !/\/releases\/\d+\/download\//.test(h)) return;
2019-03-29 06:17:05 -04:00
if(a.text().trim() === config.version.trim())
already = true;
2019-02-09 00:02:19 -05:00
});
2019-03-29 06:17:05 -04:00
return already;
2019-02-09 00:02:19 -05:00
}
function findversion($, sel, name) {
let v;
$(sel).each(function() {
const o = $(this);
const t = o.text();
if(t.toLowerCase() === name.toLowerCase())
v = o.attr('value');
});
return v;
}
async function makerelease() {
const uri = config.root + '/packages/' + config.user + '/' + config.pkg + '/releases/new/';
2019-03-29 06:17:05 -04:00
console.log('fetching new release page...');
2019-02-09 00:02:19 -05:00
let $ = await fetch(uri);
const fields = getfields($);
fields.min_rel = findversion($, 'select#min_rel option', config.min);
fields.max_rel = findversion($, 'select#max_rel option', config.max);
fields.vcsLabel = config.branch;
fields.uploadOpt = 'vcs';
fields.title = config.version;
2019-03-29 06:17:05 -04:00
console.log('submitting new release...');
2019-02-09 00:02:19 -05:00
$ = await fetch(uri, 'post', fields, {follow_max: 10});
}
(async () => {
2019-03-29 06:17:05 -04:00
await login();
console.log('checking if new version is already released...');
if(await checkalready()) {
2019-02-09 00:02:19 -05:00
console.log('version ' + config.version + ' already released');
return;
}
await makerelease();
2019-03-29 06:17:05 -04:00
console.log('waiting for new submission to be listed...');
for(let i = 0; i < config.timeout; i += config.poll) {
if(await checkalready()) {
console.log('version ' + config.version + ' release successful');
return;
}
await new Promise(r => setTimeout(r, config.poll * 1000));
}
2019-02-09 00:02:19 -05:00
})();