const fetch = require('node-fetch'); const fs = require('fs-extra'); const toolUtils = {}; toolUtils.execCommand = function(command) { const exec = require('child_process').exec; return new Promise((resolve, reject) => { exec(command, (error, stdout) => { if (error) { if (error.signal == 'SIGTERM') { resolve('Process was killed'); } else { reject(error); } } else { resolve(stdout.trim()); } }); }); }; toolUtils.execCommandWithPipes = function(executable, args) { var spawn = require('child_process').spawn; return new Promise((resolve, reject) => { const child = spawn(executable, args, { stdio: 'inherit'}); child.on('error', (error) => { reject(error); }); child.on('close', (code) => { if (code !== 0) { reject(`Ended with code ${code}`); } else { resolve(); } }); }); }; toolUtils.downloadFile = function(url, targetPath) { const https = require('https'); const fs = require('fs'); return new Promise((resolve, reject) => { const file = fs.createWriteStream(targetPath); https.get(url, function(response) { if (response.statusCode !== 200) reject(new Error(`HTTP error ${response.statusCode}`)); response.pipe(file); file.on('finish', function() { // file.close(); resolve(); }); }).on('error', (error) => { reject(error); }); }); }; toolUtils.fileSha256 = function(filePath) { return new Promise((resolve, reject) => { const crypto = require('crypto'); const fs = require('fs'); const algo = 'sha256'; const shasum = crypto.createHash(algo); const s = fs.ReadStream(filePath); s.on('data', function(d) { shasum.update(d); }); s.on('end', function() { const d = shasum.digest('hex'); resolve(d); }); s.on('error', function(error) { reject(error); }); }); }; toolUtils.unlinkForce = async function(filePath) { const fs = require('fs-extra'); try { await fs.unlink(filePath); } catch (error) { if (error.code === 'ENOENT') return; throw error; } }; toolUtils.fileExists = async function(filePath) { const fs = require('fs-extra'); return new Promise((resolve, reject) => { fs.stat(filePath, function(err) { if (err == null) { resolve(true); } else if (err.code == 'ENOENT') { resolve(false); } else { reject(err); } }); }); }; async function loadGitHubUsernameCache() { const path = `${__dirname}/github_username_cache.json`; if (await fs.exists(path)) { const jsonString = await fs.readFile(path); return JSON.parse(jsonString); } return {}; } async function saveGitHubUsernameCache(cache) { const path = `${__dirname}/github_username_cache.json`; await fs.writeFile(path, JSON.stringify(cache)); } toolUtils.githubUsername = async function(email) { const cache = await loadGitHubUsernameCache(); if (email in cache) return cache[email]; let output = null; const oauthToken = await toolUtils.githubOauthToken(); const response = await fetch(`https://api.github.com/search/users?q=${encodeURI(email)}+in:email`, { method: 'GET', headers: { 'Content-Type': 'application/json', 'Authorization': `token ${oauthToken}`, }, }); const responseText = await response.text(); if (response.ok) { const responseJson = JSON.parse(responseText); if (!responseJson || !responseJson.items || responseJson.items.length !== 1) { output = null; } else { output = responseJson.items[0].login; } } cache[email] = output; await saveGitHubUsernameCache(cache); return output; }; toolUtils.githubOauthToken = async function() { const fs = require('fs-extra'); const r = await fs.readFile(`${__dirname}/github_oauth_token.txt`); return r.toString(); }; toolUtils.githubRelease = async function(project, tagName, options = null) { options = Object.assign({}, { isDraft: false, isPreRelease: false, }, options); const oauthToken = await toolUtils.githubOauthToken(); const response = await fetch(`https://api.github.com/repos/laurent22/${project}/releases`, { method: 'POST', body: JSON.stringify({ tag_name: tagName, name: tagName, draft: options.isDraft, prerelease: options.isPreRelease, }), headers: { 'Content-Type': 'application/json', 'Authorization': `token ${oauthToken}`, }, }); const responseText = await response.text(); if (!response.ok) throw new Error(`Cannot create GitHub release: ${responseText}`); const responseJson = JSON.parse(responseText); if (!responseJson.url) throw new Error(`No URL for release: ${responseText}`); return responseJson; }; toolUtils.readline = question => { return new Promise((resolve) => { const readline = require('readline'); const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); rl.question(`${question} `, answer => { resolve(answer); rl.close(); }); }); }; toolUtils.isLinux = () => { return process && process.platform === 'linux'; }; toolUtils.isWindows = () => { return process && process.platform === 'win32'; }; toolUtils.isMac = () => { return process && process.platform === 'darwin'; }; toolUtils.insertContentIntoFile = async function(filePath, markerOpen, markerClose, contentToInsert) { const fs = require('fs-extra'); let content = await fs.readFile(filePath, 'utf-8'); // [^]* matches any character including new lines const regex = new RegExp(`${markerOpen}[^]*?${markerClose}`); content = content.replace(regex, markerOpen + contentToInsert + markerClose); await fs.writeFile(filePath, content); }; module.exports = toolUtils;