mirror of
https://github.com/usebruno/bruno.git
synced 2025-06-25 14:31:44 +02:00
Bugfix/rename with same name (#3171)
* fix rename with same name with different case * added `_temp` to the filename to change the request name (handle case insensitivity) on Win and macOS * chore: remove whitespaces and added path added path resolver * refactor: wslpath check * feat: safeToRename check added * refactor * refactor: code cleanup * chore: improved error message --------- Co-authored-by: Linhart Lukáš <Lukas.Linhart@tescosw.cz> Co-authored-by: Anoop M D <anoop.md1421@gmail.com>
This commit is contained in:
parent
a1719a33fc
commit
8e222189bc
@ -28,9 +28,12 @@ const RenameCollectionItem = ({ collection, item, onClose }) => {
|
|||||||
if (!isFolder && item.draft) {
|
if (!isFolder && item.draft) {
|
||||||
await dispatch(saveRequest(item.uid, collection.uid, true));
|
await dispatch(saveRequest(item.uid, collection.uid, true));
|
||||||
}
|
}
|
||||||
|
if (item.name === values.name) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
dispatch(renameItem(values.name, item.uid, collection.uid))
|
dispatch(renameItem(values.name, item.uid, collection.uid))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
toast.success('Request renamed!');
|
toast.success('Request renamed');
|
||||||
onClose();
|
onClose();
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
@ -55,7 +58,7 @@ const RenameCollectionItem = ({ collection, item, onClose }) => {
|
|||||||
handleConfirm={onSubmit}
|
handleConfirm={onSubmit}
|
||||||
handleCancel={onClose}
|
handleCancel={onClose}
|
||||||
>
|
>
|
||||||
<form className="bruno-form" onSubmit={e => e.preventDefault()}>
|
<form className="bruno-form" onSubmit={(e) => e.preventDefault()}>
|
||||||
<div>
|
<div>
|
||||||
<label htmlFor="name" className="block font-semibold">
|
<label htmlFor="name" className="block font-semibold">
|
||||||
{isFolder ? 'Folder' : 'Request'} Name
|
{isFolder ? 'Folder' : 'Request'} Name
|
||||||
|
@ -43,6 +43,7 @@ import { resolveRequestFilename } from 'utils/common/platform';
|
|||||||
import { parsePathParams, parseQueryParams, splitOnFirst } from 'utils/url/index';
|
import { parsePathParams, parseQueryParams, splitOnFirst } from 'utils/url/index';
|
||||||
import { sendCollectionOauth2Request as _sendCollectionOauth2Request } from 'utils/network/index';
|
import { sendCollectionOauth2Request as _sendCollectionOauth2Request } from 'utils/network/index';
|
||||||
import { name } from 'file-loader';
|
import { name } from 'file-loader';
|
||||||
|
import slash from 'utils/common/slash';
|
||||||
|
|
||||||
export const renameCollection = (newName, collectionUid) => (dispatch, getState) => {
|
export const renameCollection = (newName, collectionUid) => (dispatch, getState) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
@ -401,7 +402,7 @@ export const renameItem = (newName, itemUid, collectionUid) => (dispatch, getSta
|
|||||||
}
|
}
|
||||||
const { ipcRenderer } = window;
|
const { ipcRenderer } = window;
|
||||||
|
|
||||||
ipcRenderer.invoke('renderer:rename-item', item.pathname, newPathname, newName).then(resolve).catch(reject);
|
ipcRenderer.invoke('renderer:rename-item', slash(item.pathname), newPathname, newName).then(resolve).catch(reject);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -16,7 +16,8 @@ const {
|
|||||||
sanitizeDirectoryName,
|
sanitizeDirectoryName,
|
||||||
isWSLPath,
|
isWSLPath,
|
||||||
normalizeWslPath,
|
normalizeWslPath,
|
||||||
normalizeAndResolvePath
|
normalizeAndResolvePath,
|
||||||
|
safeToRename
|
||||||
} = require('../utils/filesystem');
|
} = require('../utils/filesystem');
|
||||||
const { openCollectionDialog } = require('../app/collections');
|
const { openCollectionDialog } = require('../app/collections');
|
||||||
const { generateUidBasedOnHash, stringifyJson, safeParseJSON, safeStringifyJSON } = require('../utils/common');
|
const { generateUidBasedOnHash, stringifyJson, safeParseJSON, safeStringifyJSON } = require('../utils/common');
|
||||||
@ -333,14 +334,15 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
|
|||||||
oldPath = isWSLPath(oldPath) ? normalizeWslPath(oldPath) : normalizeAndResolvePath(oldPath);
|
oldPath = isWSLPath(oldPath) ? normalizeWslPath(oldPath) : normalizeAndResolvePath(oldPath);
|
||||||
newPath = isWSLPath(newPath) ? normalizeWslPath(newPath) : normalizeAndResolvePath(newPath);
|
newPath = isWSLPath(newPath) ? normalizeWslPath(newPath) : normalizeAndResolvePath(newPath);
|
||||||
|
|
||||||
|
// Check if the old path exists
|
||||||
if (!fs.existsSync(oldPath)) {
|
if (!fs.existsSync(oldPath)) {
|
||||||
throw new Error(`path: ${oldPath} does not exist`);
|
throw new Error(`path: ${oldPath} does not exist`);
|
||||||
}
|
}
|
||||||
if (fs.existsSync(newPath)) {
|
|
||||||
throw new Error(`path: ${oldPath} already exists`);
|
if (!safeToRename(oldPath, newPath)) {
|
||||||
|
throw new Error(`path: ${newPath} already exists`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if its directory, rename and return
|
|
||||||
if (isDirectory(oldPath)) {
|
if (isDirectory(oldPath)) {
|
||||||
const bruFilesAtSource = await searchForBruFiles(oldPath);
|
const bruFilesAtSource = await searchForBruFiles(oldPath);
|
||||||
|
|
||||||
@ -361,12 +363,13 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
|
|||||||
const jsonData = bruToJson(data);
|
const jsonData = bruToJson(data);
|
||||||
|
|
||||||
jsonData.name = newName;
|
jsonData.name = newName;
|
||||||
|
|
||||||
moveRequestUid(oldPath, newPath);
|
moveRequestUid(oldPath, newPath);
|
||||||
|
|
||||||
const content = jsonToBru(jsonData);
|
const content = jsonToBru(jsonData);
|
||||||
await writeFile(newPath, content);
|
|
||||||
await fs.unlinkSync(oldPath);
|
await fs.unlinkSync(oldPath);
|
||||||
|
await writeFile(newPath, content);
|
||||||
|
|
||||||
|
return newPath;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ const fs = require('fs-extra');
|
|||||||
const fsPromises = require('fs/promises');
|
const fsPromises = require('fs/promises');
|
||||||
const { dialog } = require('electron');
|
const { dialog } = require('electron');
|
||||||
const isValidPathname = require('is-valid-path');
|
const isValidPathname = require('is-valid-path');
|
||||||
|
const os = require('os');
|
||||||
|
|
||||||
const exists = async (p) => {
|
const exists = async (p) => {
|
||||||
try {
|
try {
|
||||||
@ -155,12 +156,34 @@ const searchForBruFiles = (dir) => {
|
|||||||
return searchForFiles(dir, '.bru');
|
return searchForFiles(dir, '.bru');
|
||||||
};
|
};
|
||||||
|
|
||||||
// const isW
|
|
||||||
|
|
||||||
const sanitizeDirectoryName = (name) => {
|
const sanitizeDirectoryName = (name) => {
|
||||||
return name.replace(/[<>:"/\\|?*\x00-\x1F]+/g, '-');
|
return name.replace(/[<>:"/\\|?*\x00-\x1F]+/g, '-');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const safeToRename = (oldPath, newPath) => {
|
||||||
|
try {
|
||||||
|
// If the new path doesn't exist, it's safe to rename
|
||||||
|
if (!fs.existsSync(newPath)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const oldStat = fs.statSync(oldPath);
|
||||||
|
const newStat = fs.statSync(newPath);
|
||||||
|
|
||||||
|
if (os.platform() === 'win32') {
|
||||||
|
// Windows-specific comparison:
|
||||||
|
// Check if both files have the same birth time, size (Since, Win FAT-32 doesn't use inodes)
|
||||||
|
|
||||||
|
return oldStat.birthtimeMs === newStat.birthtimeMs && oldStat.size === newStat.size;
|
||||||
|
}
|
||||||
|
// Unix/Linux/MacOS: Check inode to see if they are the same file
|
||||||
|
return oldStat.ino === newStat.ino;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error checking file rename safety for ${oldPath} and ${newPath}:`, error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
isValidPathname,
|
isValidPathname,
|
||||||
exists,
|
exists,
|
||||||
@ -180,5 +203,6 @@ module.exports = {
|
|||||||
chooseFileToSave,
|
chooseFileToSave,
|
||||||
searchForFiles,
|
searchForFiles,
|
||||||
searchForBruFiles,
|
searchForBruFiles,
|
||||||
sanitizeDirectoryName
|
sanitizeDirectoryName,
|
||||||
|
safeToRename
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user