diff --git a/packages/@vue/cli/__tests__/invoke.spec.js b/packages/@vue/cli/__tests__/invoke.spec.js index 82cc0f26b3..ab3f1888ee 100644 --- a/packages/@vue/cli/__tests__/invoke.spec.js +++ b/packages/@vue/cli/__tests__/invoke.spec.js @@ -149,3 +149,20 @@ test('invoking a plugin that renames files', async () => { await project.run(`${require.resolve('../bin/vue')} invoke typescript -d`) expect(project.has('src/main.js')).toBe(false) }) + +test('should prompt if invoking in a git repository with uncommited changes', async () => { + delete process.env.VUE_CLI_SKIP_DIRTY_GIT_PROMPT + const project = await create('invoke-dirty', { + plugins: { + '@vue/cli-plugin-babel': {} + } + }) + await project.write('some-random-file', '') + expectPrompts([ + { + message: `Still proceed?`, + confirm: true + } + ]) + await invoke(`babel`, {}, project.dir) +}) diff --git a/packages/@vue/cli/lib/add.js b/packages/@vue/cli/lib/add.js index 8f6b989c63..a10b49cc6e 100644 --- a/packages/@vue/cli/lib/add.js +++ b/packages/@vue/cli/lib/add.js @@ -10,8 +10,13 @@ const { resolvePluginId, resolveModule } = require('@vue/cli-shared-utils') +const confirmIfGitDirty = require('./util/confirmIfGitDirty') async function add (pluginName, options = {}, context = process.cwd()) { + if (!(await confirmIfGitDirty(context))) { + return + } + const packageName = resolvePluginId(pluginName) log() diff --git a/packages/@vue/cli/lib/invoke.js b/packages/@vue/cli/lib/invoke.js index e9120e8ae1..3317992580 100644 --- a/packages/@vue/cli/lib/invoke.js +++ b/packages/@vue/cli/lib/invoke.js @@ -18,6 +18,7 @@ const { const Generator = require('./Generator') const { loadOptions } = require('./options') const { installDeps } = require('./util/installDeps') +const confirmIfGitDirty = require('./util/confirmIfGitDirty') const readFiles = require('./util/readFiles') function getPkg (context) { @@ -33,6 +34,10 @@ function getPkg (context) { } async function invoke (pluginName, options = {}, context = process.cwd()) { + if (!(await confirmIfGitDirty(context))) { + return + } + delete options._ const pkg = getPkg(context) diff --git a/packages/@vue/cli/lib/upgrade.js b/packages/@vue/cli/lib/upgrade.js index 19447a758b..8531f5e768 100644 --- a/packages/@vue/cli/lib/upgrade.js +++ b/packages/@vue/cli/lib/upgrade.js @@ -27,6 +27,7 @@ const getPackageJson = require('./util/getPackageJson') const getInstalledVersion = require('./util/getInstalledVersion') const tryGetNewerRange = require('./util/tryGetNewerRange') const readFiles = require('./util/readFiles') +const confirmIfGitDirty = require('./util/confirmIfGitDirty') const isTestOrDebug = process.env.VUE_CLI_TEST || process.env.VUE_CLI_DEBUG @@ -245,6 +246,10 @@ async function upgradeAll (context) { } async function upgrade (packageName, options, context = process.cwd()) { + if (!(await confirmIfGitDirty(context))) { + return + } + if (!packageName) { if (options.to) { error(`Must specify a package name to upgrade to ${options.to}`) diff --git a/packages/@vue/cli/lib/util/confirmIfGitDirty.js b/packages/@vue/cli/lib/util/confirmIfGitDirty.js new file mode 100644 index 0000000000..883143f2cd --- /dev/null +++ b/packages/@vue/cli/lib/util/confirmIfGitDirty.js @@ -0,0 +1,30 @@ +const execa = require('execa') +const inquirer = require('inquirer') + +const { warn, hasProjectGit } = require('@vue/cli-shared-utils') + +module.exports = async function confirmIfGitDirty (context) { + if (process.env.VUE_CLI_SKIP_DIRTY_GIT_PROMPT) { + return true + } + + if (!hasProjectGit(context)) { + return true + } + + const { stdout } = await execa('git', ['status', '--porcelain'], { cwd: context }) + if (!stdout) { + return true + } + + warn(`There are uncommited changes in the current repository, it's recommended to commit or stash them first.`) + const { ok } = await inquirer.prompt([ + { + name: 'ok', + type: 'confirm', + message: 'Still proceed', + default: false + } + ]) + return ok +} diff --git a/scripts/testSetup.js b/scripts/testSetup.js index 7d383ea148..997754c282 100644 --- a/scripts/testSetup.js +++ b/scripts/testSetup.js @@ -1 +1,2 @@ process.env.VUE_CLI_TEST = true +process.env.VUE_CLI_SKIP_DIRTY_GIT_PROMPT = true