const childProcess = require('child_process'); module.exports = { async remotes() { return git('remote', '-v'); }, async branches() { return git('branch', '-a'); }, async commitInfo() { const headSha = await getHeadSha(); const masterSha = await getMasterSha(); return { headSha, masterSha, tagName: await getTagName(), isMaster: headSha === masterSha }; }, async add(path) { return git('add', '-f', path); }, async commit(message) { return git('commit', '--message', message); }, git // visible for testing }; async function getHeadSha() { const stdout = await git('rev-parse', '--short', 'HEAD'); return stdout.trim(); } async function getMasterSha() { try { const stdout = await git('rev-parse', '--short', 'origin/master'); return stdout.trim(); } catch (error) { if (/Needed a single revision/.test(error.message)) { // Master was not checked out but in this case, so we know we are not master. We can ignore this return ''; } throw error; } } async function getTagName() { const stdout = await git('tag', '-l', '--points-at', 'HEAD'); const trimmedStdout = stdout.trim(); if (trimmedStdout === '') { return null; // there is no tag } const tags = trimmedStdout.split(/\n|\r\n/); const versionTags = tags.filter(tag => /^v/.test(tag)); if (versionTags[0] != null) { return versionTags[0]; } return tags[0]; } async function git(...args) { return new Promise((resolve, reject) => childProcess.execFile('git', args, (err, stdout) => { if (err != null) { return reject( new Error(`"git ${args.join(' ')}" caused error: ${err.message}`) ); } resolve(stdout); }) ); }