From a9e9ddf883052f5693f022b7cdd34bd28e79f829 Mon Sep 17 00:00:00 2001 From: Stefan Guggisberg Date: Sat, 16 Feb 2019 19:23:28 +0100 Subject: [PATCH] replacing git cli calls with isomorphic-git #523 --- src/config/config-utils.js | 2 +- src/deploy.cmd.js | 8 +-- src/git-utils.js | 100 +++++++++++----------------------- src/publish.cmd.js | 2 +- test/testBlankRemoteDeploy.js | 6 +- test/testDeployCmd.js | 2 +- test/testGitUtils.js | 50 +++++------------ 7 files changed, 56 insertions(+), 114 deletions(-) diff --git a/src/config/config-utils.js b/src/config/config-utils.js index 1c2f48f5a..4751c8cf9 100644 --- a/src/config/config-utils.js +++ b/src/config/config-utils.js @@ -23,7 +23,7 @@ class ConfigUtils { */ static async createDefaultConfig(dir) { const source = await fs.readFile(DEFAULT_CONFIG, 'utf8'); - const origin = new GitUrl(GitUtils.getOrigin(dir) || 'http://localhost/local/default.git'); + const origin = new GitUrl(await GitUtils.getOrigin(dir || process.cwd()) || 'http://localhost/local/default.git'); return source.replace(/"\$CURRENT_ORIGIN"/g, `"${origin.toString()}"`); } } diff --git a/src/deploy.cmd.js b/src/deploy.cmd.js index 33d801af6..92cae0f0d 100644 --- a/src/deploy.cmd.js +++ b/src/deploy.cmd.js @@ -180,7 +180,7 @@ class DeployCommand extends AbstractCommand { throw new Error(`Cannot automate deployment without ${path.resolve(process.cwd(), '.circleci', 'config.yaml')}`); } - const { owner, repo, ref } = GitUtils.getOriginURL(); + const { owner, repo, ref } = await GitUtils.getOriginURL(this.directory); const auth = { username: this._circleciAuth, @@ -260,7 +260,7 @@ class DeployCommand extends AbstractCommand { async run() { await this.init(); - const origin = GitUtils.getOrigin(this.directory); + const origin = await GitUtils.getOrigin(this.directory); if (!origin) { throw Error('hlx cannot deploy without a remote git repository. Add one with\n$ git remote add origin .git'); } @@ -273,7 +273,7 @@ class DeployCommand extends AbstractCommand { } // get git coordinates and list affected strains - const ref = GitUtils.getBranch(this.directory); + const ref = await GitUtils.getBranch(this.directory); const giturl = new GitUrl(`${origin}#${ref}`); const affected = this.config.strains.filterByCode(giturl); if (affected.length === 0) { @@ -318,7 +318,7 @@ Alternatively you can auto-add one using the {grey --add } option.`); if (dirty) { this._prefix = `${giturl.host.replace(/[\W]/g, '-')}--${giturl.owner.replace(/[\W]/g, '-')}--${giturl.repo.replace(/[\W]/g, '-')}--${giturl.ref.replace(/[\W]/g, '-')}-dirty`; } else { - this._prefix = GitUtils.getCurrentRevision(this.directory); + this._prefix = await GitUtils.getCurrentRevision(this.directory); } const owoptions = { diff --git a/src/git-utils.js b/src/git-utils.js index 0f660c1ef..ca58b49c8 100644 --- a/src/git-utils.js +++ b/src/git-utils.js @@ -12,26 +12,11 @@ /* eslint no-console: off */ -const $ = require('shelljs'); const path = require('path'); const { GitUrl } = require('@adobe/helix-shared'); const git = require('isomorphic-git'); git.plugins.set('fs', require('fs')); -function runIn(dir, fn) { - const pwd = $.pwd(); - try { - if (dir) { - $.cd(dir); - } - return fn(); - } finally { - if (dir) { - $.cd(pwd); - } - } -} - class GitUtils { static async isDirty(dir) { // see https://isomorphic-git.org/docs/en/statusMatrix @@ -44,73 +29,50 @@ class GitUtils { .length !== 0; } - static getBranch(dir) { - return runIn(dir, () => { - const rev = $ - .exec('git rev-parse HEAD', { - silent: true, - }) - .stdout.replace(/\n/g, ''); - - const tag = $ - .exec(`git name-rev --tags --name-only ${rev}`, { - silent: true, - }) - .stdout.replace(/\n/g, ''); - - const branchname = $ - .exec('git rev-parse --abbrev-ref HEAD', { - silent: true, - }) - .stdout.replace(/\n/g, ''); + static async getBranch(dir) { + // current branch name + const currentBranch = await git.currentBranch({ dir, fullname: false }); + // current commit sha + const rev = await git.resolveRef({ dir, ref: 'HEAD' }); + // reverse-lookup tag from commit sha + const allTags = await git.listTags({ dir }); - return tag !== 'undefined' ? tag : branchname; - }); + const tagCommitShas = await Promise.all(allTags.map(async (tag) => { + const oid = await git.resolveRef({ dir, ref: tag }); + const obj = await git.readObject({ dir, oid }); + // annotated or lightweight tag? + return obj.type === 'tag' ? { + tag, + sha: await git.resolveRef({ dir, ref: obj.object.object }), + } : { tag, sha: oid }; + })); + const tag = tagCommitShas.find(entry => entry.sha === rev); + return typeof tag === 'object' ? tag.tag : currentBranch; } static async getBranchFlag(dir) { const dirty = await GitUtils.isDirty(dir); - return dirty ? 'dirty' : GitUtils.getBranch(dir).replace(/[\W]/g, '-'); + const branch = await GitUtils.getBranch(dir); + return dirty ? 'dirty' : branch.replace(/[\W]/g, '-'); } - static getRepository(dir) { - return runIn(dir, () => { - const repo = GitUtils.getOrigin() - .replace(/[\W]/g, '-'); - if (repo !== '') { - return repo; - } - return `local--${path.basename(process.cwd())}`; - }); + static async getRepository(dir) { + const repo = (await GitUtils.getOrigin(dir)) + .replace(/[\W]/g, '-'); + return repo !== '' ? repo : `local--${path.basename(process.cwd())}`; } - static getOrigin(dir) { - return runIn(dir, () => { - try { - const origin = $.exec('git config --get remote.origin.url', { - silent: true, - }).stdout.replace(/\n/g, ''); - return origin; - } catch (e) { - return ''; - } - }); + static async getOrigin(dir) { + const rmt = (await git.listRemotes({ dir })).find(entry => entry.remote === 'origin'); + return typeof rmt === 'object' ? rmt.url : ''; } - static getOriginURL(dir) { - return new GitUrl(GitUtils.getOrigin(dir)); + static async getOriginURL(dir) { + return new GitUrl(await GitUtils.getOrigin(dir)); } - static getCurrentRevision(dir) { - return runIn(dir, () => { - const rev = $ - .exec('git rev-parse HEAD', { - silent: true, - }) - .stdout.replace(/\n/g, '') - .replace(/[\W]/g, '-'); - return rev; - }); + static async getCurrentRevision(dir) { + return git.resolveRef({ dir, ref: 'HEAD' }); } } diff --git a/src/publish.cmd.js b/src/publish.cmd.js index 15fee57a1..7385f055f 100644 --- a/src/publish.cmd.js +++ b/src/publish.cmd.js @@ -527,7 +527,7 @@ ${PublishCommand.makeParamWhitelist(params, ' ')} async getVersionVCLSection() { const configVersion = await this.getCurrentVersion(); const cliVersion = cli.getVersion(); - const revision = GitUtils.getCurrentRevision(); + const revision = await GitUtils.getCurrentRevision(this.directory); return PublishCommand.getXVersionExtensionVCL(configVersion, cliVersion, revision); } diff --git a/test/testBlankRemoteDeploy.js b/test/testBlankRemoteDeploy.js index acb79c54d..aecb8ab7e 100644 --- a/test/testBlankRemoteDeploy.js +++ b/test/testBlankRemoteDeploy.js @@ -43,10 +43,10 @@ describe('Test Deployment in Empty Project', () => { }); }); - it('Get function name', () => { + it('Get function name', async () => { // eslint-disable-next-line global-require - assert.notEqual('', GitUtils.getRepository()); - assert.equal('local--pulvillar-pantograph', GitUtils.getRepository()); + assert.notEqual('', await GitUtils.getRepository(process.cwd())); + assert.equal('local--pulvillar-pantograph', await GitUtils.getRepository(process.cwd())); }); afterEach('Reset working directory', function after() { diff --git a/test/testDeployCmd.js b/test/testDeployCmd.js index 0a1bf9e71..58895f033 100644 --- a/test/testDeployCmd.js +++ b/test/testDeployCmd.js @@ -326,7 +326,7 @@ describe('hlx deploy (Integration)', () => { .withTarget(buildDir) .run(); - const ref = GitUtils.getCurrentRevision(testRoot); + const ref = await GitUtils.getCurrentRevision(testRoot); assert.equal(cmd.config.strains.get('default').package, ''); assert.equal(cmd.config.strains.get('dev').package, `hlx/${ref}`); // todo: can't test writeback of helix-config.yaml, since it's disabled during dry-run diff --git a/test/testGitUtils.js b/test/testGitUtils.js index 329096608..a7bd2de16 100644 --- a/test/testGitUtils.js +++ b/test/testGitUtils.js @@ -17,6 +17,10 @@ const path = require('path'); const fse = require('fs-extra'); const crypto = require('crypto'); const shell = require('shelljs'); + +const git = require('isomorphic-git'); +git.plugins.set('fs', require('fs')); + const GitUtils = require('../src/git-utils'); if (!shell.which('git')) { @@ -53,69 +57,45 @@ describe('Testing GitUtils', () => { await fse.remove(testRoot); }); - it('getOrigin #unit', () => { + it('getOrigin #unit', async () => { shell.exec('git remote add origin http://github.com/adobe/dummy.git'); - assert.ok(GitUtils.getOrigin()); - assert.ok(/dummy/.test(GitUtils.getOrigin())); - - shell.cd(pwd); - assert.ok(/dummy/.test(GitUtils.getOrigin(testRoot))); + assert.ok(await GitUtils.getOrigin(testRoot)); + assert.ok(/dummy/.test(await GitUtils.getOrigin(testRoot))); }); - it('getOriginURL #unit', () => { + it('getOriginURL #unit', async () => { shell.exec('git remote add origin http://github.com/adobe/dummy.git'); - assert.ok(GitUtils.getOriginURL()); - assert.equal(GitUtils.getOriginURL().toString(), 'http://github.com/adobe/dummy.git'); - - shell.cd(pwd); - assert.equal(GitUtils.getOriginURL(testRoot).toString(), 'http://github.com/adobe/dummy.git'); + assert.ok(await GitUtils.getOriginURL(testRoot)); + assert.equal((await GitUtils.getOriginURL(testRoot)).toString(), 'http://github.com/adobe/dummy.git'); }); - it('getBranch #unit', () => { + it('getBranch #unit', async () => { shell.exec('git checkout -b newbranch'); - assert.equal(GitUtils.getBranch(), 'newbranch'); - - shell.cd(pwd); - assert.equal(GitUtils.getBranch(testRoot), 'newbranch'); + assert.equal(await GitUtils.getBranch(testRoot), 'newbranch'); }); it('isDirty #unit', async () => { assert.equal(await GitUtils.isDirty(testRoot), false); await fse.writeFile(path.resolve(testRoot, 'README.md'), 'Hello, world.\n', 'utf-8'); assert.equal(await GitUtils.isDirty(testRoot), true); - - shell.cd(pwd); - assert.equal(await GitUtils.isDirty(testRoot), true); }); it('getBranchFlag #unit', async () => { assert.equal(await GitUtils.getBranchFlag(testRoot), 'master'); await fse.writeFile(path.resolve(testRoot, 'README.md'), 'Hello, world.\n', 'utf-8'); assert.equal(await GitUtils.getBranchFlag(testRoot), 'dirty'); - - shell.cd(pwd); - assert.equal(await GitUtils.getBranchFlag(testRoot), 'dirty'); }); it('getRepository #unit', async () => { shell.exec('git remote add origin http://github.com/adobe/dummy.git'); - assert.equal(GitUtils.getRepository(), 'http---github.aaakk.us.kg-adobe-dummy-git'); - - shell.cd(pwd); - assert.equal(GitUtils.getRepository(testRoot), 'http---github.aaakk.us.kg-adobe-dummy-git'); + assert.equal(await GitUtils.getRepository(testRoot), 'http---github.aaakk.us.kg-adobe-dummy-git'); }); it('getRepository (local) #unit', async () => { - assert.equal(GitUtils.getRepository(), `local--${path.basename(testRoot)}`); - - shell.cd(pwd); - assert.equal(GitUtils.getRepository(testRoot), `local--${path.basename(testRoot)}`); + assert.equal(await GitUtils.getRepository(testRoot), `local--${path.basename(testRoot)}`); }); it('getCurrentRevision #unit', async () => { - assert.ok(/[0-9a-fA-F]+/.test(GitUtils.getCurrentRevision())); - - shell.cd(pwd); - assert.ok(/[0-9a-fA-F]+/.test(GitUtils.getCurrentRevision(testRoot))); + assert.ok(/[0-9a-fA-F]+/.test(await GitUtils.getCurrentRevision(testRoot))); }); });