Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(core): throw error if build folder already exists on initial clean #9112

Merged
merged 13 commits into from
Jun 30, 2023
Merged
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions packages/docusaurus/src/webpack/plugins/CleanWebpackPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
// More context: https://github.com/facebook/docusaurus/pull/1839

import path from 'path';
import fs from 'fs-extra';
import {sync as delSync} from 'del';
import type {Compiler, Stats} from 'webpack';

Expand Down Expand Up @@ -115,6 +116,19 @@ export default class CleanWebpackPlugin {
this.removeFiles = this.removeFiles.bind(this);
}

private checkIfFileNameIsDuplicate(): boolean {
thedevwonder marked this conversation as resolved.
Show resolved Hide resolved
const dir = path.dirname(this.outputPath);
const baseName = path.basename(this.outputPath).toLowerCase();
// eslint-disable-next-line no-restricted-properties
const duplicateFiles = fs
.readdirSync(dir)
.filter((fileName) => fileName.toLowerCase() === baseName);
if (duplicateFiles.length > 0) {
return true;
}
return false;
}
Copy link
Collaborator

@slorber slorber Jun 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be enough

if (
      (await fs.pathExists(outputPath)) &&
      (await fs.stat(outputPath)).isFile()
    ) {
   throw new Error("...");
}

On:

  • case insensitive FS: this should throw for files like BUILD or build
  • case-sensitive FS: if a file named BUILD exists, I think it's allowed to create a folder named build? 🤔

I only have access to a case insensitive file-system. Can someone test my assumption on case sensitive file-system?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@slorber, I think yours is better because it doesn't break the abstraction of whether the FS is case-sensitive or not :)

Copy link
Contributor Author

@thedevwonder thedevwonder Jun 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be enough

if (
      (await fs.pathExists(outputPath)) &&
      (await fs.stat(outputPath)).isFile()
    ) {
   throw new Error("...");
}

On:

  • case insensitive FS: this should throw for files like BUILD or build
  • case-sensitive FS: if a file named BUILD exists, I think it's allowed to create a folder named build? 🤔

I only have access to a case insensitive file-system. Can someone test my assumption on case sensitive file-system?

I used gitpod.io to test this usecase. It is a case-sensitive system. I changed the code because I thought someone using case-sensitive FS may create a BUILD file and someone not using this FS may find this file throwing an error during the build

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about this, any suggestions? @slorber @Josh-Cena

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine. Running the same project on different systems can often run into inconsistencies, like some imports that work on case-insensitive systems suddenly fail in case-sensitive ones.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Josh-Cena I see, keeping it simple then!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Josh-Cena @slorber I have used the sync version of pathExists and stat functions and fixed the error message. Let me know if this looks good.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have also tested the code in my local env. Works fine:)


apply(compiler: Compiler): void {
if (!compiler.options.output.path) {
console.warn(
Expand Down Expand Up @@ -152,6 +166,12 @@ export default class CleanWebpackPlugin {
return;
}

if (this.checkIfFileNameIsDuplicate()) {
throw new Error(
`Output file ${this.outputPath} already exists. Docusaurus needs this directory to save the build output. Either remove/change the file or choose a different build directory via '--out-dir'.`,
);
}

this.initialClean = true;

this.removeFiles(this.cleanOnceBeforeBuildPatterns);
Expand Down