diff --git a/scripts/build.mjs b/scripts/build.mjs index ef6ef94d47..fe42d1e82b 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -60,7 +60,22 @@ async function build(args) { const mainCachePath = getCachePath(getDefaultBranch()); if (existsSync(mainCachePath)) { mkdirSync(cachePath, { recursive: true }); - cpSync(mainCachePath, cachePath, { recursive: true, force: true }); + try { + cpSync(mainCachePath, cachePath, { recursive: true, force: true }); + } catch (err) { + switch (err?.code) { + case "EPERM": + case "EACCES": + try { + chmodSync(mainCachePath, 0o777); + } catch (e2) {} + + cpSync(mainCachePath, cachePath, { recursive: true, force: true }); + break; + default: + throw err; + } + } } } generateOptions["-DCACHE_PATH"] = cmakePath(cachePath); diff --git a/src/bun.js/node/node_fs.zig b/src/bun.js/node/node_fs.zig index c08b4a2690..ca3339b259 100644 --- a/src/bun.js/node/node_fs.zig +++ b/src/bun.js/node/node_fs.zig @@ -6732,18 +6732,20 @@ pub const NodeFS = struct { }; } - if (comptime Environment.isMac) { + if (comptime Environment.isMac) try_with_clonefile: { if (Maybe(Return.Cp).errnoSysP(C.clonefile(src, dest, 0), .clonefile, src)) |err| { switch (err.getErrno()) { - .ACCES, - .NAMETOOLONG, - .ROFS, - .PERM, - .INVAL, - => { + .NAMETOOLONG, .ROFS, .INVAL, .ACCES, .PERM => |errno| { + if (errno == .ACCES or errno == .PERM) { + if (args.flags.force) { + break :try_with_clonefile; + } + } + @memcpy(this.sync_error_buf[0..src.len], src); return .{ .err = err.err.withPath(this.sync_error_buf[0..src.len]) }; }, + // Other errors may be due to clonefile() not being supported // We'll fall back to other implementations else => {},