From d55382ed7957d36a666cec091aad715a358e393b Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Wed, 10 Nov 2021 19:39:49 +0300 Subject: [PATCH 1/3] fix: remove links in clean plugin --- lib/CleanPlugin.js | 17 ++++++++++++++++- lib/util/fs.js | 1 + types.d.ts | 4 ++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/CleanPlugin.js b/lib/CleanPlugin.js index e7903edff..e6fbf1d60 100644 --- a/lib/CleanPlugin.js +++ b/lib/CleanPlugin.js @@ -16,6 +16,7 @@ const processAsyncTree = require("./util/processAsyncTree"); /** @typedef {import("./Compiler")} Compiler */ /** @typedef {import("./logging/Logger").Logger} Logger */ /** @typedef {import("./util/fs").OutputFileSystem} OutputFileSystem */ +/** @typedef {import("./util/fs").StatsCallback} StatsCallback */ /** @typedef {(function(string):boolean)|RegExp} IgnoreItem */ /** @typedef {function(IgnoreItem): void} AddToIgnoreCallback */ @@ -102,6 +103,20 @@ const getDiffToOldAssets = (currentAssets, oldAssets) => { return diff; }; +/** + * @param {OutputFileSystem} fs filesystem + * @param {string} filename path to file + * @param {StatsCallback} callback callback for provided filename + * @returns {void} + */ +const doStat = (fs, filename, callback) => { + if ("lstat" in fs) { + fs.lstat(filename, callback); + } else { + fs.stat(filename, callback); + } +}; + /** * @param {OutputFileSystem} fs filesystem * @param {string} outputPath output path @@ -150,7 +165,7 @@ const applyDiff = (fs, outputPath, dry, logger, diff, isKept, callback) => { log(`${filename} will be kept`); return process.nextTick(callback); } - fs.stat(path, (err, stats) => { + doStat(fs, path, (err, stats) => { if (err) return handleError(err); if (!stats.isDirectory()) { push({ diff --git a/lib/util/fs.js b/lib/util/fs.js index 9ba425c06..d93d7806f 100644 --- a/lib/util/fs.js +++ b/lib/util/fs.js @@ -93,6 +93,7 @@ const path = require("path"); * @property {function(string, Callback): void=} rmdir * @property {function(string, Callback): void=} unlink * @property {function(string, StatsCallback): void} stat + * @property {function(string, StatsCallback): void=} lstat * @property {function(string, BufferOrStringCallback): void} readFile * @property {(function(string, string): string)=} join * @property {(function(string, string): string)=} relative diff --git a/types.d.ts b/types.d.ts index a6468b578..f632e8525 100644 --- a/types.d.ts +++ b/types.d.ts @@ -8348,6 +8348,10 @@ declare interface OutputFileSystem { arg0: string, arg1: (arg0?: null | NodeJS.ErrnoException, arg1?: IStats) => void ) => void; + lstat?: ( + arg0: string, + arg1: (arg0?: null | NodeJS.ErrnoException, arg1?: IStats) => void + ) => void; readFile: ( arg0: string, arg1: (arg0?: null | NodeJS.ErrnoException, arg1?: string | Buffer) => void From d2c5c1f6231e695c6c8c6a1c93554e973c4cd8a5 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Wed, 10 Nov 2021 20:18:02 +0300 Subject: [PATCH 2/3] test: added --- test/configCases/clean/link/index.js | 1 + test/configCases/clean/link/webpack.config.js | 41 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 test/configCases/clean/link/index.js create mode 100644 test/configCases/clean/link/webpack.config.js diff --git a/test/configCases/clean/link/index.js b/test/configCases/clean/link/index.js new file mode 100644 index 000000000..bbd9de415 --- /dev/null +++ b/test/configCases/clean/link/index.js @@ -0,0 +1 @@ +it("should compile and run the test", function() {}); diff --git a/test/configCases/clean/link/webpack.config.js b/test/configCases/clean/link/webpack.config.js new file mode 100644 index 000000000..6250f15d4 --- /dev/null +++ b/test/configCases/clean/link/webpack.config.js @@ -0,0 +1,41 @@ +const fs = require("fs"); +const path = require("path"); +const readDir = require("../enabled/readdir"); + +/** @type {import("../../../../").Configuration} */ +module.exports = { + output: { + clean: true + }, + plugins: [ + compiler => { + let once = true; + compiler.hooks.environment.tap("Test", () => { + if (once) { + const outputPath = compiler.options.output.path; + const originalPath = path.join(outputPath, "file.ext"); + fs.writeFileSync(originalPath, ""); + const customDir = path.join(outputPath, "this/dir/should/be/removed"); + fs.mkdirSync(customDir, { recursive: true }); + fs.symlinkSync( + originalPath, + path.join(customDir, "file-link.ext"), + "file" + ); + once = false; + } + }); + compiler.hooks.afterEmit.tap("Test", compilation => { + const outputPath = compilation.getPath(compiler.outputPath, {}); + expect(readDir(outputPath)).toMatchInlineSnapshot(` + Object { + "directories": Array [], + "files": Array [ + "bundle0.js", + ], + } + `); + }); + } + ] +}; From cdf9427bb5027bbdc227b0e216fbc018703b1737 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 15 Nov 2021 10:31:33 +0100 Subject: [PATCH 3/3] skip test on windows without admin --- test/configCases/clean/link/test.filter.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 test/configCases/clean/link/test.filter.js diff --git a/test/configCases/clean/link/test.filter.js b/test/configCases/clean/link/test.filter.js new file mode 100644 index 000000000..abb7722f5 --- /dev/null +++ b/test/configCases/clean/link/test.filter.js @@ -0,0 +1,16 @@ +const fs = require("fs"); +const path = require("path"); + +module.exports = () => { + try { + fs.symlinkSync( + path.join(__dirname, "index.js"), + path.join(__dirname, ".testlink"), + "file" + ); + fs.unlinkSync(path.join(__dirname, ".testlink")); + return true; + } catch (e) { + return false; + } +};