summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/astro/src/core/build/fs.ts46
1 files changed, 45 insertions, 1 deletions
diff --git a/packages/astro/src/core/build/fs.ts b/packages/astro/src/core/build/fs.ts
index badfc815d..510f84c77 100644
--- a/packages/astro/src/core/build/fs.ts
+++ b/packages/astro/src/core/build/fs.ts
@@ -4,6 +4,8 @@ import fs from 'fs';
import npath from 'path';
import { fileURLToPath } from 'url';
+const isWindows = process.platform === 'win32';
+
export function emptyDir(dir: string, skip?: Set<string>): void {
for (const file of fs.readdirSync(dir)) {
if (skip?.has(file)) {
@@ -11,7 +13,20 @@ export function emptyDir(dir: string, skip?: Set<string>): void {
}
const abs = npath.resolve(dir, file);
// baseline is Node 12 so can't use rmSync :(
- if (fs.lstatSync(abs).isDirectory()) {
+ let isDir = false;
+ try {
+ isDir = fs.lstatSync(abs).isDirectory();
+ } catch (err: any) {
+ // Taken from:
+ // https://github.com/isaacs/rimraf/blob/9219c937be159edbdf1efa961f2904e863c3ce2d/rimraf.js#L293-L296
+ if (err.code === 'EPERM' && isWindows) {
+ fixWinEPERMSync(abs, err);
+ } else {
+ throw err;
+ }
+ }
+
+ if (isDir) {
emptyDir(abs);
fs.rmdirSync(abs);
} else {
@@ -26,3 +41,32 @@ export function prepareOutDir(astroConfig: AstroConfig) {
return emptyDir(outDir, new Set(['.git']));
}
}
+
+function fixWinEPERMSync(path: string, error: Error) {
+ try {
+ fs.chmodSync(path, 0o666);
+ } catch (er2: any) {
+ if (er2.code === 'ENOENT') {
+ return;
+ } else {
+ throw error;
+ }
+ }
+
+ let stats;
+ try {
+ stats = fs.statSync(path);
+ } catch (er3: any) {
+ if (er3.code === 'ENOENT') {
+ return;
+ } else {
+ throw error;
+ }
+ }
+
+ if (stats.isDirectory()) {
+ emptyDir(path);
+ } else {
+ fs.unlinkSync(path);
+ }
+}