Skip to content

Commit ddb1c69

Browse files
authored
Revert "workspace renaming with path update (usebruno#7437)" (usebruno#7455)
This reverts commit e7c2c7c.
1 parent 6f6a910 commit ddb1c69

File tree

4 files changed

+14
-216
lines changed

4 files changed

+14
-216
lines changed

packages/bruno-app/src/providers/ReduxStore/slices/workspaces/actions.js

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -524,38 +524,21 @@ const handleWorkspaceAction = async (action, workspaceUid, ...args) => {
524524
export const renameWorkspaceAction = (workspaceUid, newName) => {
525525
return async (dispatch, getState) => {
526526
try {
527-
const { workspaces, activeWorkspaceUid } = getState().workspaces;
527+
const { workspaces } = getState().workspaces;
528528
const workspace = workspaces.find((w) => w.uid === workspaceUid);
529529

530530
if (!workspace) {
531531
throw new Error('Workspace not found');
532532
}
533533

534-
const result = await ipcRenderer.invoke('renderer:rename-workspace', workspace.pathname, newName);
535-
536-
if (result.newWorkspacePath) {
537-
const { generateUidBasedOnHash } = await import('utils/common');
538-
const newWorkspaceUid = generateUidBasedOnHash(result.newWorkspacePath);
539-
const wasActive = activeWorkspaceUid === workspaceUid;
540-
541-
dispatch(removeWorkspace(workspaceUid));
542-
543-
dispatch(createWorkspace({
544-
...workspace,
545-
uid: newWorkspaceUid,
546-
name: newName,
547-
pathname: result.newWorkspacePath
548-
}));
534+
await handleWorkspaceAction((...args) => ipcRenderer.invoke('renderer:rename-workspace', ...args),
535+
workspace.pathname,
536+
newName);
549537

550-
if (wasActive) {
551-
dispatch(setActiveWorkspace(newWorkspaceUid));
552-
}
553-
} else {
554-
dispatch(updateWorkspace({
555-
uid: workspaceUid,
556-
name: newName
557-
}));
558-
}
538+
dispatch(updateWorkspace({
539+
uid: workspaceUid,
540+
name: newName
541+
}));
559542
} catch (error) {
560543
throw error;
561544
}

packages/bruno-electron/src/ipc/workspace.js

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const {
1616
readWorkspaceConfig,
1717
writeWorkspaceConfig,
1818
validateWorkspaceConfig,
19+
updateWorkspaceName,
1920
updateWorkspaceDocs,
2021
addCollectionToWorkspace,
2122
removeCollectionFromWorkspace,
@@ -24,8 +25,7 @@ const {
2425
normalizeCollectionEntry,
2526
validateWorkspacePath,
2627
validateWorkspaceDirectory,
27-
getWorkspaceUid,
28-
renameWorkspace
28+
getWorkspaceUid
2929
} = require('../utils/workspace-config');
3030

3131
const { isValidCollectionDirectory } = require('../utils/filesystem');
@@ -270,20 +270,7 @@ const registerWorkspaceIpc = (mainWindow, workspaceWatcher) => {
270270

271271
ipcMain.handle('renderer:rename-workspace', async (event, workspacePath, newName) => {
272272
try {
273-
const result = await renameWorkspace(workspacePath, newName);
274-
275-
if (result.newWorkspacePath) {
276-
if (workspaceWatcher) {
277-
workspaceWatcher.removeWatcher(workspacePath);
278-
workspaceWatcher.addWatcher(mainWindow, result.newWorkspacePath);
279-
}
280-
281-
lastOpenedWorkspaces.remove(workspacePath);
282-
lastOpenedWorkspaces.add(result.newWorkspacePath);
283-
284-
return { success: true, newWorkspacePath: result.newWorkspacePath };
285-
}
286-
273+
await updateWorkspaceName(workspacePath, newName);
287274
return { success: true };
288275
} catch (error) {
289276
throw error;

packages/bruno-electron/src/utils/workspace-config.js

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const fs = require('fs');
22
const path = require('path');
33
const yaml = require('js-yaml');
4-
const { writeFile, validateName, isValidCollectionDirectory, sanitizeName } = require('./filesystem');
4+
const { writeFile, validateName, isValidCollectionDirectory } = require('./filesystem');
55
const { generateUidBasedOnHash } = require('./common');
66
const { withLock, getWorkspaceLockKey } = require('./workspace-lock');
77

@@ -563,44 +563,6 @@ const getWorkspaceUid = (workspacePath) => {
563563
return generateUidBasedOnHash(workspacePath);
564564
};
565565

566-
/**
567-
* Renames a workspace folder and updates the workspace.yml config.
568-
* @param {string} workspacePath - Current absolute path to the workspace folder
569-
* @param {string} newName - New name for the workspace
570-
* @returns {Promise<{newWorkspacePath: string|null}>} - New path if folder was renamed, null otherwise
571-
*/
572-
const renameWorkspace = async (workspacePath, newName) => {
573-
const parentDir = path.dirname(workspacePath);
574-
const newFolderName = sanitizeName(newName);
575-
const newWorkspacePath = path.join(parentDir, newFolderName);
576-
577-
const pathsAreSame = path.normalize(workspacePath).toLowerCase() === path.normalize(newWorkspacePath).toLowerCase();
578-
579-
if (!pathsAreSame) {
580-
if (fs.existsSync(newWorkspacePath)) {
581-
throw new Error(`A folder named "${newFolderName}" already exists at this location`);
582-
}
583-
584-
fs.renameSync(workspacePath, newWorkspacePath);
585-
586-
try {
587-
await updateWorkspaceName(newWorkspacePath, newName);
588-
} catch (error) {
589-
try {
590-
fs.renameSync(newWorkspacePath, workspacePath);
591-
} catch (rollbackError) {
592-
console.error('Failed to rollback workspace folder rename:', rollbackError);
593-
}
594-
throw error;
595-
}
596-
597-
return { newWorkspacePath };
598-
}
599-
600-
await updateWorkspaceName(workspacePath, newName);
601-
return { newWorkspacePath: null };
602-
};
603-
604566
module.exports = {
605567
makeRelativePath,
606568
normalizeCollectionEntry,
@@ -623,6 +585,5 @@ module.exports = {
623585
getWorkspaceUid,
624586
writeWorkspaceFileAtomic,
625587
isValidCollectionEntry,
626-
isValidSpecEntry,
627-
renameWorkspace
588+
isValidSpecEntry
628589
};

packages/bruno-electron/tests/utils/workspace-config.spec.js

Lines changed: 1 addition & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const path = require('path');
22
const fs = require('fs');
33
const os = require('os');
44
const yaml = require('js-yaml');
5-
const { reorderWorkspaceCollections, renameWorkspace } = require('../../src/utils/workspace-config');
5+
const { reorderWorkspaceCollections } = require('../../src/utils/workspace-config');
66

77
const collection = (name, pathSegment) => ({ name, path: pathSegment });
88

@@ -74,136 +74,3 @@ describe('reorderWorkspaceCollections', () => {
7474
expect(getCollectionPathsFromYml()).toEqual(['collections/api', 'collections/backend']);
7575
});
7676
});
77-
78-
describe('renameWorkspace', () => {
79-
let parentDir;
80-
let workspacePath;
81-
82-
/** Creates a workspace directory with workspace.yml */
83-
const createWorkspace = (folderName, workspaceName) => {
84-
const wsPath = path.join(parentDir, folderName);
85-
fs.mkdirSync(wsPath, { recursive: true });
86-
const content = [
87-
'opencollection: 1.0.0',
88-
'info:',
89-
` name: "${workspaceName}"`,
90-
' type: workspace',
91-
'collections:',
92-
'specs:',
93-
'docs: \'\''
94-
].join('\n');
95-
fs.writeFileSync(path.join(wsPath, 'workspace.yml'), content);
96-
return wsPath;
97-
};
98-
99-
/** Gets the workspace name from workspace.yml */
100-
const getWorkspaceName = (wsPath) => {
101-
const raw = fs.readFileSync(path.join(wsPath, 'workspace.yml'), 'utf8');
102-
const config = yaml.load(raw);
103-
return config.info?.name;
104-
};
105-
106-
beforeEach(() => {
107-
parentDir = fs.mkdtempSync(path.join(os.tmpdir(), 'bruno-ws-parent-'));
108-
workspacePath = createWorkspace('Untitled Workspace', 'Untitled Workspace');
109-
});
110-
111-
afterEach(() => {
112-
fs.rmSync(parentDir, { recursive: true, force: true });
113-
});
114-
115-
test('renames workspace folder and updates config', async () => {
116-
const result = await renameWorkspace(workspacePath, 'My API Project');
117-
118-
expect(result.newWorkspacePath).toBe(path.join(parentDir, 'My API Project'));
119-
expect(fs.existsSync(path.join(parentDir, 'Untitled Workspace'))).toBe(false);
120-
expect(fs.existsSync(path.join(parentDir, 'My API Project'))).toBe(true);
121-
expect(getWorkspaceName(result.newWorkspacePath)).toBe('My API Project');
122-
});
123-
124-
test('only updates config when folder name stays the same', async () => {
125-
// Create workspace where folder name matches sanitized target but display name differs
126-
const sameFolderPath = createWorkspace('My-Project', 'Old Name');
127-
128-
// Rename to name that sanitizes to same folder name
129-
const result = await renameWorkspace(sameFolderPath, 'My:Project');
130-
131-
expect(result.newWorkspacePath).toBeNull();
132-
expect(fs.existsSync(sameFolderPath)).toBe(true);
133-
// Verify config was actually updated
134-
expect(getWorkspaceName(sameFolderPath)).toBe('My:Project');
135-
});
136-
137-
test('sanitizes special characters in folder name', async () => {
138-
const result = await renameWorkspace(workspacePath, 'My:API/Project<Test>');
139-
140-
expect(result.newWorkspacePath).toBe(path.join(parentDir, 'My-API-Project-Test-'));
141-
expect(fs.existsSync(result.newWorkspacePath)).toBe(true);
142-
expect(getWorkspaceName(result.newWorkspacePath)).toBe('My:API/Project<Test>');
143-
});
144-
145-
test('throws error when target folder already exists', async () => {
146-
// Create another workspace with the target name
147-
createWorkspace('Existing Project', 'Existing Project');
148-
149-
await expect(renameWorkspace(workspacePath, 'Existing Project'))
150-
.rejects.toThrow('A folder named "Existing Project" already exists at this location');
151-
152-
// Original workspace should still exist
153-
expect(fs.existsSync(workspacePath)).toBe(true);
154-
});
155-
156-
test('handles case-only rename by updating config without renaming folder', async () => {
157-
// Create workspace with lowercase name
158-
const lowerPath = createWorkspace('myworkspace', 'myworkspace');
159-
160-
// Rename to different case - code uses case-insensitive comparison
161-
// so this only updates config, doesn't rename folder (cross-platform safety)
162-
const result = await renameWorkspace(lowerPath, 'MyWorkspace');
163-
164-
expect(result.newWorkspacePath).toBeNull();
165-
expect(fs.existsSync(lowerPath)).toBe(true);
166-
expect(getWorkspaceName(lowerPath)).toBe('MyWorkspace');
167-
});
168-
169-
test('preserves workspace.yml content after rename', async () => {
170-
// Add collections, specs, and other fields to the workspace
171-
const configPath = path.join(workspacePath, 'workspace.yml');
172-
const content = [
173-
'opencollection: 1.0.0',
174-
'info:',
175-
' name: "Untitled Workspace"',
176-
' type: workspace',
177-
'collections:',
178-
' - name: "API"',
179-
' path: "collections/api"',
180-
' remote: "https://github.com/example/api"',
181-
'specs:',
182-
' - name: "OpenAPI"',
183-
' path: "specs/openapi.yaml"',
184-
'docs: \'Some documentation\'',
185-
'',
186-
'activeEnvironmentUid: env_123'
187-
].join('\n');
188-
fs.writeFileSync(configPath, content);
189-
190-
const result = await renameWorkspace(workspacePath, 'My Project');
191-
192-
const newConfigPath = path.join(result.newWorkspacePath, 'workspace.yml');
193-
const newContent = fs.readFileSync(newConfigPath, 'utf8');
194-
const config = yaml.load(newContent);
195-
196-
// Verify all fields are preserved
197-
expect(config.opencollection).toBe('1.0.0');
198-
expect(config.info.name).toBe('My Project');
199-
expect(config.info.type).toBe('workspace');
200-
expect(config.collections).toHaveLength(1);
201-
expect(config.collections[0].name).toBe('API');
202-
expect(config.collections[0].path).toBe('collections/api');
203-
expect(config.collections[0].remote).toBe('https://github.com/example/api');
204-
expect(config.specs).toHaveLength(1);
205-
expect(config.specs[0]).toEqual({ name: 'OpenAPI', path: 'specs/openapi.yaml' });
206-
expect(config.docs).toBe('Some documentation');
207-
expect(config.activeEnvironmentUid).toBe('env_123');
208-
});
209-
});

0 commit comments

Comments
 (0)