diff --git a/index.js b/index.js index ec51a29..f009010 100644 --- a/index.js +++ b/index.js @@ -83,11 +83,27 @@ function determineBuildId (id, inputDir) { if (id) return Promise.resolve(id) return new Promise((resolve, reject) => { const cp = require('child_process') - cp.execFile('git', [`--git-dir=${inputDir}/.git`, `--work-tree=${inputDir}`, 'rev-parse', 'HEAD'], (err, stdout, stderr) => { + + // inputDir may not be the project root so look for .git dir in parent dirs too + let dir = inputDir + const root = path.parse(dir).root + let attempts = 0 // protect against infinite tight loop if libs misbehave + while (dir !== root && attempts < 999) { + attempts++ + try { + fs.accessSync(path.join(dir, '.git'), (fs.constants || fs).R_OK) + break + } catch (_) { + dir = path.dirname(dir) + } + } + if (dir === root || attempts >= 999) dir = inputDir + + cp.execFile('git', [`--git-dir=${path.join(dir, '.git')}`, `--work-tree=${dir}`, 'rev-parse', 'HEAD'], (err, stdout, stderr) => { if (err) return reject(err) if (stderr) return reject(String(stderr).trim()) if (stdout) return resolve(String(stdout).trim()) - reject(`No output from command: git --git-dir=${inputDir}/.git --work-tree=${inputDir} rev-parse HEAD`) + reject(`No output from command: git --git-dir=${path.join(dir, '.git')} --work-tree=${dir} rev-parse HEAD`) }) }) } diff --git a/test/git b/test/git index b8a1fa1..61e90b6 100755 --- a/test/git +++ b/test/git @@ -1,4 +1,12 @@ #!/usr/bin/env node -if (!String(process.argv[3]).includes('fixture3')) { - console.log('0123456789abcdef0123456789abcdef01234567') -} + +// --git-dir=${inputDir}/.git --work-tree=${inputDir} +require('sywac') + .dir('--git-dir ', { mustExist: true }) + .outputSettings({ showHelpOnError: false }) + .parseAndExit() + .then(argv => { + if (!process.env.NBI_TEST_FIXTURE || !String(process.env.NBI_TEST_FIXTURE).includes('fixture3')) { + console.log('0123456789abcdef0123456789abcdef01234567') + } + }) diff --git a/test/test-fixture.js b/test/test-fixture.js index 6145f87..27ab5d4 100644 --- a/test/test-fixture.js +++ b/test/test-fixture.js @@ -88,7 +88,7 @@ tap.test('supports custom --id', t => { tap.test('does not need git with custom --id', t => { return exec('npm', 'run build', fixturePath).then(() => { - return cli('--id 123456', fixturePath, '/dne') + return cli('--id 123456', fixturePath, { PATH: '/dne' }) }).then(io => { t.notOk(io.err) t.notOk(io.stderr) diff --git a/test/test-others.js b/test/test-others.js index 368bbcb..ee61606 100644 --- a/test/test-others.js +++ b/test/test-others.js @@ -21,7 +21,7 @@ tap.test('errs on invalid json', t => { }) tap.test('errs on no git output', t => { - return cli('', path.resolve(__dirname, 'fixture3')).then(io => { + return cli('', path.resolve(__dirname, 'fixture3'), { NBI_TEST_FIXTURE: 'fixture3' }).then(io => { t.equal(io.err.code, 1) t.match(io.stderr, /No output from command: git/) t.notOk(io.stdout) @@ -29,7 +29,7 @@ tap.test('errs on no git output', t => { }) tap.test('errs without --id and without git', t => { - return cli('', path.resolve(__dirname, 'fixture3'), '/dne').then(io => { + return cli('', path.resolve(__dirname, 'fixture3'), { NBI_TEST_FIXTURE: 'fixture3', PATH: '/dne' }).then(io => { t.equal(io.err.code, 1) t.match(io.stderr, /Unexpected error/) t.notOk(io.stdout) diff --git a/test/utils.js b/test/utils.js index bb5453d..8addc82 100644 --- a/test/utils.js +++ b/test/utils.js @@ -21,14 +21,14 @@ function exec (file, args, cwd, env, alwaysResolve) { }) } -function mockedGitEnv (envPath) { - const env = Object.assign({}, process.env) - env.PATH = envPath || [__dirname].concat(env.PATH.split(path.delimiter)).join(path.delimiter) - return env +function mockedGitEnv (env) { + env = env || {} + if (!env.PATH) env.PATH = [__dirname].concat(process.env.PATH.split(path.delimiter)).join(path.delimiter) + return Object.assign({}, process.env, env) } -function cli (args, cwd, envPath) { - return exec(cliPath, args, cwd, mockedGitEnv(envPath), true) +function cli (args, cwd, env) { + return exec(cliPath, args, cwd, mockedGitEnv(env), true) } function readTextFile (file) {