Skip to content

Commit

Permalink
update logic to only overwrite when git config is also not set
Browse files Browse the repository at this point in the history
  • Loading branch information
pacotedev committed Jun 27, 2024
1 parent 6061bd4 commit 5f58104
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 8 deletions.
65 changes: 57 additions & 8 deletions lib/opts.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,57 @@
// Values we want to set if they're not already defined by the end user
const defaultEnv = {}
module.exports = (opts = {}) => ({
stdioString: true,
...opts,
shell: false,
env: opts.env || { ...defaultEnv, ...process.env },
})
const fs = require('fs')
const os = require('os')
const path = require('path')
const ini = require('ini')

const gitConfigPath = path.join(os.homedir(), '.gitconfig')

// Function to check if sshCommand is set in the git config
const isGitSshCommandSetInConfig = () => {
try {
if (fs.existsSync(gitConfigPath)) {
const config = ini.parse(fs.readFileSync(gitConfigPath, 'utf-8'))
return config.core && config.core.sshCommand !== undefined
}
} catch (error) {
return false
}
return false
}

// Function to check if askpass is set in the git config
const isGitAskPassSetInConfig = () => {
try {
if (fs.existsSync(gitConfigPath)) {
const config = ini.parse(fs.readFileSync(gitConfigPath, 'utf-8'))
return config.core && config.core.askpass !== undefined
}
} catch (error) {
return false
}
return false
}

module.exports = (opts = {}) => {
const sshCommandSetInEnv = process.env.GIT_SSH_COMMAND !== undefined
const sshCommandSetInConfig = isGitSshCommandSetInConfig()
const askPassSetInEnv = process.env.GIT_ASKPASS !== undefined
const askPassSetInConfig = isGitAskPassSetInConfig()

// Values we want to set if they're not already defined by the end user
// This defaults to accepting new ssh host key fingerprints
const finalGitEnv = {
...(askPassSetInEnv || askPassSetInConfig ? {} : {
GIT_ASKPASS: 'echo',
}),
...(sshCommandSetInEnv || sshCommandSetInConfig ? {} : {
GIT_SSH_COMMAND: 'ssh -oStrictHostKeyChecking=accept-new',
}),
}

return {
stdioString: true,
...opts,
shell: false,
env: opts.env || { ...finalGitEnv, ...process.env },
}
}
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,13 @@
},
"dependencies": {
"@npmcli/promise-spawn": "^7.0.0",
"ini": "^4.1.3",
"lru-cache": "^10.0.1",
"npm-pick-manifest": "^9.0.0",
"proc-log": "^4.0.0",
"promise-inflight": "^1.0.1",
"promise-retry": "^2.0.1",
"proxyquire": "^2.1.3",
"semver": "^7.3.5",
"which": "^4.0.0"
},
Expand Down
144 changes: 144 additions & 0 deletions test/opts.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,125 @@
const t = require('tap')
const proxyquire = require('proxyquire')
const gitOpts = require('../lib/opts.js')
const fs = require('fs')
const os = require('os')
const path = require('path')

const gitConfigPath = path.join(os.homedir(), '.gitconfig')

const mockFs = {
existsSync: () => false,
readFileSync: () => '',
}

// Utility function to backup and restore gitconfig
const backupGitConfig = () => {
const backupPath = `${gitConfigPath}.backup`
if (fs.existsSync(gitConfigPath)) {
fs.copyFileSync(gitConfigPath, backupPath)
fs.unlinkSync(gitConfigPath)
}
return backupPath
}

const restoreGitConfig = (backupPath) => {
if (fs.existsSync(backupPath)) {
fs.copyFileSync(backupPath, gitConfigPath)
fs.unlinkSync(backupPath)
} else if (fs.existsSync(gitConfigPath)) {
fs.unlinkSync(gitConfigPath)
}
}

const writeGitConfig = (content) => {
fs.writeFileSync(gitConfigPath, content)
}

t.test('handle case when fs.existsSync throws an error', t => {
const { GIT_ASKPASS, GIT_SSH_COMMAND } = process.env
t.teardown(() => {
process.env.GIT_ASKPASS = GIT_ASKPASS
process.env.GIT_SSH_COMMAND = GIT_SSH_COMMAND
})

// Mocking fs.existsSync to throw an error
const gitOptsWithMockFs = proxyquire('../lib/opts.js', {
fs: {
...mockFs,
existsSync: () => {
throw new Error('Mocked error')
},
},
})

t.match(gitOptsWithMockFs(), {
env: {
GIT_ASKPASS: 'echo',
GIT_SSH_COMMAND: 'ssh -oStrictHostKeyChecking=accept-new',
},
shell: false,
}, 'should apply defaults when fs.existsSync throws an error')

t.end()
})

t.test('defaults', t => {
const backupPath = backupGitConfig()
const { GIT_ASKPASS, GIT_SSH_COMMAND } = process.env
t.teardown(() => {
restoreGitConfig(backupPath)
process.env.GIT_ASKPASS = GIT_ASKPASS
process.env.GIT_SSH_COMMAND = GIT_SSH_COMMAND
})

delete process.env.GIT_ASKPASS
delete process.env.GIT_SSH_COMMAND

t.match(gitOpts(), {
env: {
GIT_ASKPASS: 'echo',
GIT_SSH_COMMAND: 'ssh -oStrictHostKeyChecking=accept-new',
},
shell: false,
}, 'got the git defaults we want')

t.end()
})

t.test('does not override when sshCommand is set in env', t => {
const backupPath = backupGitConfig()
const { GIT_ASKPASS, GIT_SSH_COMMAND } = process.env
t.teardown(() => {
restoreGitConfig(backupPath)
process.env.GIT_ASKPASS = GIT_ASKPASS
process.env.GIT_SSH_COMMAND = GIT_SSH_COMMAND
})

process.env.GIT_ASKPASS = 'test_askpass'
process.env.GIT_SSH_COMMAND = 'test_ssh_command'

t.match(gitOpts(), {
env: {
GIT_ASKPASS: 'test_askpass',
GIT_SSH_COMMAND: 'test_ssh_command',
},
shell: false,
}, 'values already in process.env remain')

t.end()
})

t.test('as non-root', t => {
const backupPath = backupGitConfig()
const { GIT_ASKPASS, GIT_SSH_COMMAND } = process.env
t.teardown(() => {
restoreGitConfig(backupPath)
process.env.GIT_ASKPASS = GIT_ASKPASS
process.env.GIT_SSH_COMMAND = GIT_SSH_COMMAND
})

process.getuid = () => 999

t.match(gitOpts({
foo: 'bar',
env: { override: 'for some reason' },
Expand All @@ -17,5 +134,32 @@ t.test('as non-root', t => {
gid: undefined,
abc: undefined,
}, 'do not set uid/gid as non-root')

t.end()
})

t.test('does not override when sshCommand is set in git config', t => {
const backupPath = backupGitConfig()
const { GIT_ASKPASS, GIT_SSH_COMMAND } = process.env
t.teardown(() => {
restoreGitConfig(backupPath)
process.env.GIT_ASKPASS = GIT_ASKPASS
process.env.GIT_SSH_COMMAND = GIT_SSH_COMMAND
})

writeGitConfig(`
[core]
askpass = echo
sshCommand = custom_ssh_command
`)

t.match(gitOpts(), {
env: {
GIT_ASKPASS: 'undefined',
GIT_SSH_COMMAND: 'undefined',
},
shell: false,
}, 'sshCommand in git config remains')

t.end()
})

0 comments on commit 5f58104

Please sign in to comment.