diff --git a/package.json b/package.json index 13b30e7c..78f4b4e7 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "@types/tar": "^6.1.2", "byline": "^5.0.0", "cross-env": "^5.2.0", - "find-git-exec": "0.0.1-alpha.2", + "find-git-exec": "^0.0.4", "jest": "^28.1.3", "prettier": "^2.7.1", "rimraf": "^2.5.4", diff --git a/test/external/git-process-external-test.ts b/test/external/git-process-external-test.ts index 26a24ce6..e5c46036 100644 --- a/test/external/git-process-external-test.ts +++ b/test/external/git-process-external-test.ts @@ -1,46 +1,31 @@ -import { dirname } from 'path' -import { default as findGit, Git } from 'find-git-exec' +import { resolve } from 'path' +import findGit from 'find-git-exec' import { GitProcess } from '../../lib' import { verify } from '../helpers' const temp = require('temp').track() -async function setupGitEnvironment(): Promise { - let git: Git | undefined = undefined - - try { - git = await findGit() - } catch { - return null - } - if (!git || !git.path || !git.execPath) { - return null - } else { - const { path, execPath } = git - // Set the environment variable to be able to use an external Git. - process.env.GIT_EXEC_PATH = execPath - process.env.LOCAL_GIT_DIRECTORY = dirname(dirname(path)) - return git - } -} +const getExternalGitEnvironment = () => + findGit().then(({ path, execPath }) => ({ + GIT_EXEC_PATH: execPath, + LOCAL_GIT_DIRECTORY: resolve(path, '../../'), + })) describe('git-process [with external Git executable]', () => { - describe('clone', () => { + describe('--exec-path', () => { it('returns exit code when successful', async () => { - const git = await setupGitEnvironment() - if (git == null) { - throw new Error('External Git was not found on the host system.') - } + const env = await getExternalGitEnvironment() const testRepoPath = temp.mkdirSync('desktop-git-clone-valid-external') - const result = await GitProcess.exec( - ['clone', '--', 'https://github.com/TypeFox/find-git-exec.git', '.'], - testRepoPath - ) - verify(result, r => { - expect(r.exitCode).toEqual(0) + const result = await GitProcess.exec(['--exec-path'], testRepoPath, { + env, }) + + verify(result, r => expect(r.exitCode).toEqual(0)) + verify(result, r => + expect(resolve(r.stdout.trim())).toEqual(resolve(env.GIT_EXEC_PATH)) + ) }) }) }) diff --git a/test/fast/git-process-test.ts b/test/fast/git-process-test.ts index dc792abc..dcbaac99 100644 --- a/test/fast/git-process-test.ts +++ b/test/fast/git-process-test.ts @@ -18,18 +18,27 @@ import { import { gitVersion } from '../helpers' import { setupNoAuth } from '../slow/auth' +import { pathToFileURL } from 'url' const temp = require('temp').track() describe('git-process', () => { it('can cancel in-progress git command', async () => { - const testRepoPath = temp.mkdirSync('desktop-git-clone-valid') + const sourceRepoPath = temp.mkdirSync('desktop-git-clone-source') + const destinationRepoPath = temp.mkdirSync('desktop-git-clone-destination') const options = { env: setupNoAuth(), } + + await GitProcess.exec(['init'], sourceRepoPath) + await GitProcess.exec( + ['commit', '--allow-empty', '-m', 'Init'], + sourceRepoPath + ) + const task = GitProcess.execTask( - ['clone', '--', 'https://github.com/shiftkey/friendly-bassoon.git', '.'], - testRepoPath, + ['clone', '--', pathToFileURL(sourceRepoPath).toString(), '.'], + destinationRepoPath, options ) diff --git a/test/slow/git-process-test.ts b/test/slow/git-process-test.ts index 58a66e84..a55182c5 100644 --- a/test/slow/git-process-test.ts +++ b/test/slow/git-process-test.ts @@ -4,6 +4,9 @@ import * as Path from 'path' import { GitProcess, GitError } from '../../lib' import { initialize, verify } from '../helpers' import { setupAskPass, setupNoAuth } from './auth' +import { pathToFileURL } from 'url' +import { resolve } from 'path' +import { createServer } from 'http' const temp = require('temp').track() @@ -15,18 +18,11 @@ describe('git-process', () => { env: setupNoAuth(), } - // GitHub will prompt for (and validate) credentials for non-public - // repositories, to prevent leakage of information. - // Bitbucket will not prompt for credentials, and will immediately - // return whether this non-public repository exists. - // - // This is an easier to way to test for the specific error than to - // pass live account credentials to Git. const result = await GitProcess.exec( [ 'clone', '--', - 'https://bitbucket.org/shiftkey/testing-non-existent.git', + pathToFileURL(resolve('i-for-sure-donut-exist')).toString(), '.', ], testRepoPath, @@ -43,41 +39,40 @@ describe('git-process', () => { const options = { env: setupAskPass('error', 'error'), } - const result = await GitProcess.exec( - [ - 'clone', - '--', - 'https://github.com/shiftkey/repository-private.git', - '.', - ], - testRepoPath, - options - ) - verify(result, r => { - expect(r.exitCode).toBe(128) + + const server = createServer((req, res) => { + res.writeHead(401, { + 'Content-Type': 'text/plain', + 'WWW-Authenticate': 'Basic realm="foo"', + }) + res.end() }) - const error = GitProcess.parseError(result.stderr) - expect(error).toBe(GitError.HTTPSAuthenticationFailed) - }) - it('returns exit code when successful', async () => { - const testRepoPath = temp.mkdirSync('desktop-git-clone-valid') - const options = { - env: setupNoAuth(), - } - const result = await GitProcess.exec( - [ - 'clone', - '--', - 'https://github.com/shiftkey/friendly-bassoon.git', - '.', - ], - testRepoPath, - options - ) - verify(result, r => { - expect(r.exitCode).toBe(0) + const port = await new Promise((resolve, reject) => { + server.listen(0, () => { + const addr = server.address() + if (addr === null || typeof addr === 'string') { + reject(new Error('invalid server address')) + } else { + resolve(addr.port) + } + }) }) + + try { + const result = await GitProcess.exec( + ['clone', '--', `http://127.0.0.1:${port}/`, '.'], + testRepoPath, + options + ) + verify(result, r => { + expect(r.exitCode).toBe(128) + }) + const error = GitProcess.parseError(result.stderr) + expect(error).toBe(GitError.HTTPSAuthenticationFailed) + } finally { + server.close() + } }) }) @@ -85,19 +80,12 @@ describe('git-process', () => { it("returns exit code when repository doesn't exist", async () => { const testRepoPath = await initialize('desktop-git-fetch-failure') - // GitHub will prompt for (and validate) credentials for non-public - // repositories, to prevent leakage of information. - // Bitbucket will not prompt for credentials, and will immediately - // return whether this non-public repository exists. - // - // This is an easier to way to test for the specific error than to - // pass live account credentials to Git. const addRemote = await GitProcess.exec( [ 'remote', 'add', 'origin', - 'https://bitbucket.org/shiftkey/testing-non-existent.git', + pathToFileURL(resolve('i-for-sure-donut-exist')).toString(), ], testRepoPath ) @@ -117,64 +105,6 @@ describe('git-process', () => { expect(r.exitCode).toBe(128) }) }) - - it('returns exit code and error when repository requires credentials', async () => { - const testRepoPath = await initialize('desktop-git-fetch-failure') - const addRemote = await GitProcess.exec( - [ - 'remote', - 'add', - 'origin', - 'https://github.com/shiftkey/repository-private.git', - ], - testRepoPath - ) - verify(addRemote, r => { - expect(r.exitCode).toBe(0) - }) - - const options = { - env: setupAskPass('error', 'error'), - } - const result = await GitProcess.exec( - ['fetch', 'origin'], - testRepoPath, - options - ) - verify(result, r => { - expect(r.exitCode).toBe(128) - }) - const error = GitProcess.parseError(result.stderr) - expect(error).toBe(GitError.HTTPSAuthenticationFailed) - }) - - it('returns exit code when successful', async () => { - const testRepoPath = await initialize('desktop-git-fetch-valid') - const addRemote = await GitProcess.exec( - [ - 'remote', - 'add', - 'origin', - 'https://github.com/shiftkey/friendly-bassoon.git', - ], - testRepoPath - ) - verify(addRemote, r => { - expect(r.exitCode).toBe(0) - }) - - const options = { - env: setupNoAuth(), - } - const result = await GitProcess.exec( - ['fetch', 'origin'], - testRepoPath, - options - ) - verify(result, r => { - expect(r.exitCode).toBe(0) - }) - }) }) describe('checkout', () => { diff --git a/yarn.lock b/yarn.lock index 9026e11a..2b088227 100644 --- a/yarn.lock +++ b/yarn.lock @@ -650,16 +650,16 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.6.tgz#31743bc5772b6ac223845e18c3fc26f042713c83" integrity sha512-EdxgKRXgYsNITy5mjjXjVE/CS8YENSdhiagGrLqjG0pvA2owgJ6i4l7wy/PFZGC0B1/H20lWKN7ONVDNYDZm7A== +"@types/node@^10.14.22": + version "10.17.60" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b" + integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== + "@types/node@^11.9.0": version "11.15.54" resolved "https://registry.yarnpkg.com/@types/node/-/node-11.15.54.tgz#59ed60e7b0d56905a654292e8d73275034eb6283" integrity sha512-1RWYiq+5UfozGsU6MwJyFX6BtktcT10XRjvcAQmskCtMcW3tPske88lM/nHv7BQG1w9KBXI1zPGuu5PnNCX14g== -"@types/node@^8.0.26": - version "8.10.66" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.66.tgz#dd035d409df322acc83dff62a602f12a5783bbb3" - integrity sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw== - "@types/prettier@^2.1.5": version "2.7.0" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.0.tgz#ea03e9f0376a4446f44797ca19d9c46c36e352dc" @@ -693,6 +693,11 @@ "@types/node" "*" minipass "^3.3.5" +"@types/which@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/which/-/which-1.3.2.tgz#9c246fc0c93ded311c8512df2891fb41f6227fdf" + integrity sha512-8oDqyLC7eD4HM307boe2QWKyuzdzWBj56xI/imSl2cpL+U3tCMaTAkMJ4ee5JBZ/FsOJlvRGeIShiZDAl1qERA== + "@types/yargs-parser@*": version "21.0.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" @@ -1123,12 +1128,14 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -find-git-exec@0.0.1-alpha.2: - version "0.0.1-alpha.2" - resolved "https://registry.yarnpkg.com/find-git-exec/-/find-git-exec-0.0.1-alpha.2.tgz#02c266b3be6e411c19aa5fd6f813c96a73286fac" - integrity sha512-Vr4UEPeqQQmTv8EPHff1VyRpT/xIB8VdJ+JdKol0TpbdBg5fNBowdd6La8aBtkdYYWLg6BfpCqezwddmB0gZkA== +find-git-exec@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/find-git-exec/-/find-git-exec-0.0.4.tgz#f1d0d35f93ad99bc81aacd357388d00ae902bc92" + integrity sha512-klzQwno+dpdeahtHhvZZ5Yn6K+zme1Aj+YJ4ZD+DywSLrQoyCywTrsubUZa1hHRehmfwBThoeKjS7fsaxhpfNA== dependencies: - "@types/node" "^8.0.26" + "@types/node" "^10.14.22" + "@types/which" "^1.3.2" + which "^2.0.1" find-up@^4.0.0, find-up@^4.1.0: version "4.1.0"