From c6483017433e8ff8cfc79b16861c18fb7db67f7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9l=C3=A9my=20Ledoux?= Date: Wed, 25 Apr 2018 16:42:26 -0500 Subject: [PATCH] fix: vue invoke should delete renamed/removed files (#1049) --- packages/@vue/cli/__tests__/invoke.spec.js | 9 +++++++++ packages/@vue/cli/lib/Generator.js | 6 ++++-- packages/@vue/cli/lib/util/writeFileTree.js | 16 +++++++++++++++- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/packages/@vue/cli/__tests__/invoke.spec.js b/packages/@vue/cli/__tests__/invoke.spec.js index 817929f60..3ebe234af 100644 --- a/packages/@vue/cli/__tests__/invoke.spec.js +++ b/packages/@vue/cli/__tests__/invoke.spec.js @@ -128,3 +128,12 @@ extends: - '@vue/airbnb' `.trim()) }) + +test('invoking a plugin that renames files', async () => { + const project = await create(`invoke-rename`, { plugins: {}}) + const pkg = JSON.parse(await project.read('package.json')) + pkg.devDependencies['@vue/cli-plugin-typescript'] = '*' + await project.write('package.json', JSON.stringify(pkg, null, 2)) + await project.run(`${require.resolve('../bin/vue')} invoke typescript -d`) + expect(project.has('src/main.js')).toBe(false) +}) diff --git a/packages/@vue/cli/lib/Generator.js b/packages/@vue/cli/lib/Generator.js index 9c84f59a9..fa35a4b6a 100644 --- a/packages/@vue/cli/lib/Generator.js +++ b/packages/@vue/cli/lib/Generator.js @@ -51,6 +51,8 @@ module.exports = class Generator { extractConfigFiles = false, checkExisting = false } = {}) { + // save the file system before applying plugin for comparison + const initialFiles = Object.assign({}, this.files) // extract configs from package.json into dedicated files. this.extractConfigFiles(extractConfigFiles, checkExisting) // wait for file resolve @@ -58,8 +60,8 @@ module.exports = class Generator { // set package.json this.sortPkg() this.files['package.json'] = JSON.stringify(this.pkg, null, 2) - // write file tree to disk - await writeFileTree(this.context, this.files) + // write/update file tree to disk + await writeFileTree(this.context, this.files, initialFiles) } extractConfigFiles (extractAll, checkExisting) { diff --git a/packages/@vue/cli/lib/util/writeFileTree.js b/packages/@vue/cli/lib/util/writeFileTree.js index 4fea95011..595c651c6 100644 --- a/packages/@vue/cli/lib/util/writeFileTree.js +++ b/packages/@vue/cli/lib/util/writeFileTree.js @@ -1,13 +1,27 @@ const fs = require('fs') const path = require('path') const { promisify } = require('util') +const unlink = promisify(fs.unlink) const mkdirp = promisify(require('mkdirp')) const write = promisify(fs.writeFile) -module.exports = function writeFileTree (dir, files) { +async function deleteRemovedFiles (directory, newFiles, previousFiles) { + // get all files that are not in the new filesystem and are still existing + const filesToDelete = Object.keys(previousFiles) + .filter(filename => !newFiles[filename]) + + // delete each of these files + const unlinkPromises = filesToDelete.map(filename => unlink(path.join(directory, filename))) + return Promise.all(unlinkPromises) +} + +module.exports = async function writeFileTree (dir, files, previousFiles) { if (process.env.VUE_CLI_SKIP_WRITE) { return } + if (previousFiles) { + await deleteRemovedFiles(dir, files, previousFiles) + } return Promise.all(Object.keys(files).map(async (name) => { const filePath = path.join(dir, name) await mkdirp(path.dirname(filePath))