feat: Graceful handle rename/move: Fix EPERM Error When Renaming Parent Folders on Windows (#3236)

* refactor filesystem.js to use isWindowsOS()

* add tempDir logic to gracefully rename the parent folder in a collection. fix: `EPERM`

---------

Co-authored-by: Anoop M D <anoop.md1421@gmail.com>
This commit is contained in:
Pragadesh-45 2024-11-29 12:18:11 +05:30 committed by GitHub
parent 707cddea90
commit f2cfcab091
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 23 additions and 7 deletions

View File

@ -1,5 +1,7 @@
const _ = require('lodash');
const fs = require('fs');
const fsExtra = require('fs-extra');
const os = require('os');
const path = require('path');
const { ipcMain, shell, dialog, app } = require('electron');
const { envJsonToBru, bruToJson, jsonToBru, jsonToCollectionBru } = require('../bru');
@ -18,6 +20,7 @@ const {
normalizeWslPath,
normalizeAndResolvePath,
safeToRename,
isWindowsOS,
isValidFilename
} = require('../utils/filesystem');
const { openCollectionDialog } = require('../app/collections');
@ -361,11 +364,20 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
const newBruFilePath = bruFile.replace(oldPath, newPath);
moveRequestUid(bruFile, newBruFilePath);
}
return fs.renameSync(oldPath, newPath);
if (isWindowsOS() && !isWSLPath(oldPath)) {
const tempDir = path.join(os.tmpdir(), `temp-folder-${Date.now()}`);
await fsExtra.copy(oldPath, tempDir);
await fsExtra.move(tempDir, newPath, { overwrite: true });
await fsExtra.remove(oldPath);
} else {
await fs.rename(oldPath, newPath);
}
return newPath;
}
const isBru = hasBruExtension(oldPath);
if (!isBru) {
if (!hasBruExtension(oldPath)) {
throw new Error(`path: ${oldPath} is not a bru file`);
}
@ -374,14 +386,13 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
}
// update name in file and save new copy, then delete old copy
const data = fs.readFileSync(oldPath, 'utf8');
const data = await fs.promises.readFile(oldPath, 'utf8'); // Use async read
const jsonData = bruToJson(data);
jsonData.name = newName;
moveRequestUid(oldPath, newPath);
const content = jsonToBru(jsonData);
await fs.unlinkSync(oldPath);
await fs.promises.unlink(oldPath);
await writeFile(newPath, content);
return newPath;

View File

@ -160,6 +160,10 @@ const sanitizeDirectoryName = (name) => {
return name.replace(/[<>:"/\\|?*\x00-\x1F]+/g, '-');
};
const isWindowsOS = () => {
return os.platform() === 'win32';
}
const isValidFilename = (fileName) => {
const inValidChars = /[\\/:*?"<>|]/;
@ -184,7 +188,7 @@ const safeToRename = (oldPath, newPath) => {
const oldStat = fs.statSync(oldPath);
const newStat = fs.statSync(newPath);
if (os.platform() === 'win32') {
if (isWindowsOS()) {
// Windows-specific comparison:
// Check if both files have the same birth time, size (Since, Win FAT-32 doesn't use inodes)
@ -218,6 +222,7 @@ module.exports = {
searchForFiles,
searchForBruFiles,
sanitizeDirectoryName,
isWindowsOS,
safeToRename,
isValidFilename
};