From bd1f8bf30509f091e253be0f68a1960c48ac1a7d Mon Sep 17 00:00:00 2001 From: erezrokah Date: Sun, 14 Feb 2021 18:42:36 +0100 Subject: [PATCH 1/2] test(command-lm): add cleanup --- src/commands/lm/uninstall.js | 23 ++++++++++++ src/utils/lm/install.js | 72 ++++++++++++++++++++++++++++-------- tests/command.lm.test.js | 3 ++ 3 files changed, 82 insertions(+), 16 deletions(-) create mode 100644 src/commands/lm/uninstall.js diff --git a/src/commands/lm/uninstall.js b/src/commands/lm/uninstall.js new file mode 100644 index 00000000000..0e12c90d108 --- /dev/null +++ b/src/commands/lm/uninstall.js @@ -0,0 +1,23 @@ +const Command = require('../../utils/command') +const { uninstall } = require('../../utils/lm/install') + +class LmUninstallCommand extends Command { + async run() { + await this.config.runHook('analytics', { + eventName: 'command', + payload: { + command: 'lm:uninstall', + }, + }) + + await uninstall() + } +} + +LmUninstallCommand.aliases = ['lm:remove'] +LmUninstallCommand.hidden = true + +LmUninstallCommand.description = + 'Uninstalls Netlify git credentials helper and cleans up any related configuration changes made by the install command.' + +module.exports = LmUninstallCommand diff --git a/src/utils/lm/install.js b/src/utils/lm/install.js index 31644868c28..65817c84c53 100644 --- a/src/utils/lm/install.js +++ b/src/utils/lm/install.js @@ -9,12 +9,21 @@ const Listr = require('listr') const pathKey = require('path-key') const { shouldFetchLatestVersion, fetchLatestVersion } = require('../../lib/exec-fetcher') -const { fileExistsAsync, writeFileAsync, readFileAsync, appendFileAsync, copyFileAsync } = require('../../lib/fs') +const { + fileExistsAsync, + writeFileAsync, + readFileAsync, + appendFileAsync, + copyFileAsync, + rmdirRecursiveAsync, +} = require('../../lib/fs') const { getPathInHome, getLegacyPathInHome } = require('../../lib/settings') const PACKAGE_NAME = 'netlify-credential-helper' const EXEC_NAME = 'git-credential-netlify' +const GIT_CONFIG = '.gitconfig' + const { checkGitVersionStep, checkGitLFSVersionStep, checkLFSFiltersStep } = require('./steps') const SUPPORTED_PLATFORMS = { @@ -126,16 +135,18 @@ const setupWindowsPath = async function () { ) } +const getInitContent = (incFilePath) => ` +# The next line updates PATH for Netlify's Git Credential Helper. +if [ -f '${incFilePath}' ]; then source '${incFilePath}'; fi +` + const setupUnixPath = async () => { if (isBinInPath()) { return true } const { shell, incFilePath, configFile } = shellVariables() - const initContent = ` -# The next line updates PATH for Netlify's Git Credential Helper. -if [ -f '${incFilePath}' ]; then source '${incFilePath}'; fi -` + const initContent = getInitContent(incFilePath) switch (shell) { case 'bash': @@ -181,6 +192,13 @@ const getCurrentCredentials = async () => { } } +// Git expects the config path to always use / even on Windows +const getGitConfigContent = (gitConfigPath) => ` +# This next lines include Netlify's Git Credential Helper configuration in your Git configuration. +[include] + path = ${path.posix.normalize(gitConfigPath)} +` + const configureGitConfig = async function () { const currentCredentials = await getCurrentCredentials() @@ -211,17 +229,10 @@ const configureGitConfig = async function () { }) } - const helperPath = getHelperPath() - await writeFileAsync(path.join(helperPath, 'git-config'), helperConfig) + const gitConfigPath = getGitConfigPath() + await writeFileAsync(gitConfigPath, helperConfig) - // Git expects the config path to always use / even on Windows - const gitConfigPath = path.posix.normalize(`${helperPath}/git-config`) - const gitConfigContent = ` -# This next lines include Netlify's Git Credential Helper configuration in your Git configuration. -[include] - path = ${gitConfigPath} -` - return writeConfig('.gitconfig', gitConfigContent) + return writeConfig(GIT_CONFIG, getGitConfigContent(gitConfigPath)) } const getHelperPath = function () { @@ -232,6 +243,10 @@ const getBinPath = function () { return path.join(getHelperPath(), 'bin') } +const getGitConfigPath = function () { + return path.join(getHelperPath(), 'git-config') +} + const getLegacyBinPath = function () { return path.join(getLegacyPathInHome(['helper', 'bin'])) } @@ -255,4 +270,29 @@ const shellVariables = function () { } } -module.exports = { installPlatform, isBinInPath, shellVariables } +const uninstall = async function () { + await rmdirRecursiveAsync(getHelperPath()) + await removeConfig(GIT_CONFIG, getGitConfigContent(getGitConfigPath())) + + try { + const { configFile, incFilePath } = shellVariables() + if (configFile === undefined) { + return + } + + await removeConfig(configFile, getInitContent(incFilePath)) + } catch (_) {} +} + +const removeConfig = async function (name, toRemove) { + const configPath = path.join(os.homedir(), name) + + if (!(await fileExistsAsync(configPath))) { + return + } + + const content = await readFileAsync(configPath, 'utf8') + return await writeFileAsync(configPath, content.replace(toRemove, '')) +} + +module.exports = { installPlatform, isBinInPath, shellVariables, uninstall } diff --git a/tests/command.lm.test.js b/tests/command.lm.test.js index fa068ccc03b..0ebc63be544 100644 --- a/tests/command.lm.test.js +++ b/tests/command.lm.test.js @@ -35,6 +35,8 @@ if (process.env.IS_FORK !== 'true') { t.context.builder = builder t.context.mockApi = mockApi t.context.apiUrl = `http://localhost:${mockApi.address().port}/api/v1` + + await callCli(['lm:uninstall'], t.context.execOptions) }) test.serial('netlify lm:info', async (t) => { @@ -91,6 +93,7 @@ if (process.env.IS_FORK !== 'true') { test.after('cleanup', async (t) => { const { execOptions, builder, mockApi } = t.context console.log('Performing cleanup') + await callCli(['lm:uninstall'], t.context.execOptions) console.log(`deleting test site "${siteName}". ${execOptions.env.NETLIFY_SITE_ID}`) await callCli(['sites:delete', execOptions.env.NETLIFY_SITE_ID, '--force'], execOptions) From 9776b08d582a8cd88949b5d55bb32b06d205982a Mon Sep 17 00:00:00 2001 From: erezrokah Date: Sun, 14 Feb 2021 18:56:36 +0100 Subject: [PATCH 2/2] refactor: use promise.all --- src/utils/lm/install.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/utils/lm/install.js b/src/utils/lm/install.js index 65817c84c53..4893b4ee45a 100644 --- a/src/utils/lm/install.js +++ b/src/utils/lm/install.js @@ -270,10 +270,7 @@ const shellVariables = function () { } } -const uninstall = async function () { - await rmdirRecursiveAsync(getHelperPath()) - await removeConfig(GIT_CONFIG, getGitConfigContent(getGitConfigPath())) - +const cleanupShell = async function () { try { const { configFile, incFilePath } = shellVariables() if (configFile === undefined) { @@ -284,6 +281,14 @@ const uninstall = async function () { } catch (_) {} } +const uninstall = async function () { + await Promise.all([ + rmdirRecursiveAsync(getHelperPath()), + removeConfig(GIT_CONFIG, getGitConfigContent(getGitConfigPath())), + cleanupShell(), + ]) +} + const removeConfig = async function (name, toRemove) { const configPath = path.join(os.homedir(), name)