Skip to content

Commit 27b2932

Browse files
committed
Remove shellQuote references and propagate console error messages to the GUI
1 parent 1598669 commit 27b2932

4 files changed

Lines changed: 27 additions & 13 deletions

File tree

docs/third-party-licenses.json

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -237,13 +237,6 @@
237237
"url": "https://github.com/isaacs/node-glob",
238238
"license": "https://github.com/isaacs/node-glob/blob/main/LICENSE.md"
239239
},
240-
{
241-
"name": "shell-quote",
242-
"version": "1.8.3",
243-
"spdx": "MIT",
244-
"url": "https://github.com/ljharb/shell-quote",
245-
"license": "https://github.com/ljharb/shell-quote/blob/main/LICENSE"
246-
},
247240
{
248241
"name": "tmp",
249242
"version": "0.2.5",

package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@
9797
"react-window": "^1.8.11",
9898
"sax-ts": "^1.2.13",
9999
"semver": "^7.7.4",
100-
"shell-quote": "^1.8.3",
101100
"tcp-port-used": "^1.0.2",
102101
"tmp": "^0.2.5",
103102
"vscode-jsonrpc": "^8.2.1",
@@ -134,7 +133,6 @@
134133
"@types/react-dom": "^18.3.1",
135134
"@types/react-window": "^1.8.8",
136135
"@types/semver": "^7.7.1",
137-
"@types/shell-quote": "^1.7.5",
138136
"@types/targz": "^1.0.5",
139137
"@types/tcp-port-used": "^1.0.4",
140138
"@types/tmp": "^0.2.6",

src/views/solution-outline/commands/merge-command.test.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,16 +216,38 @@ describe('MergeCommand', () => {
216216
mockedExec.mockImplementation((_cmd, _cb) => { throw new Error('unexpected'); });
217217

218218
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => { });
219+
const showErrorMessageSpy = jest.spyOn(vscode.window, 'showErrorMessage');
219220
await command['runVSCodeMerge'](fileNode);
220221
expect(errorSpy).toHaveBeenCalledWith('Merge operations failed:', expect.any(Error));
222+
expect(showErrorMessageSpy).toHaveBeenCalledWith('Merge operation failed: unexpected');
223+
});
224+
225+
it('shows a merge failure message when merge command validation throws', async () => {
226+
const node = new COutlineItem('file');
227+
node.setAttribute('local', '/tmp/safe-local.c');
228+
node.setAttribute('update', '/tmp/update&unsafe.c');
229+
node.setAttribute('base', '/tmp/base.c');
230+
231+
const commandPrivate = command as unknown as {
232+
getVSCodeExecutablePath: () => string | undefined;
233+
};
234+
jest.spyOn(commandPrivate, 'getVSCodeExecutablePath').mockReturnValue('/usr/bin/code');
235+
mockedFs.copyFileSync.mockImplementation(() => { });
236+
mockedFs.existsSync.mockReturnValue(true);
237+
mockedFs.statSync.mockReturnValue({ mtimeMs: 1000 } as fs.Stats);
238+
239+
const showErrorMessageSpy = jest.spyOn(vscode.window, 'showErrorMessage');
240+
241+
await command['runVSCodeMerge'](node);
242+
243+
expect(showErrorMessageSpy).toHaveBeenCalledWith('Merge operation failed: Invalid update file: contains unsupported shell-sensitive characters.');
221244
});
222245

223246
it('performs post-merge file operations and triggers reload when merged file changes', async () => {
224247
const local = path.resolve('tmp', 'component.c');
225248
const update = path.resolve('tmp', 'component.update.c');
226249
const base = path.resolve('tmp', 'component.base.c');
227250
const merged = `${local}.merged`;
228-
const backup = `${local}.bak`;
229251
const expectedBase = path.join(path.dirname(update), path.basename(update).replaceAll('update', 'base'));
230252
const node = new COutlineItem('file');
231253
node.setTag('file');
@@ -249,7 +271,7 @@ describe('MergeCommand', () => {
249271
await command['runVSCodeMerge'](node);
250272

251273
expect(mockedFs.copyFileSync).toHaveBeenCalledWith(local, merged);
252-
expect(mockedFs.copyFileSync).toHaveBeenCalledWith(local, backup);
274+
expect(mockedFs.copyFileSync).toHaveBeenCalledWith(local, `${local}.bak`);
253275
expect(mockedFs.unlinkSync).toHaveBeenCalledWith(local);
254276
expect(mockedFs.unlinkSync).toHaveBeenCalledWith(base);
255277
expect(mockedFs.renameSync).toHaveBeenCalledWith(update, expectedBase);
@@ -277,7 +299,6 @@ describe('MergeCommand', () => {
277299
const update = 'C:\\workspace\\component.update.c';
278300
const base = 'C:\\workspace\\component.base.c';
279301
const merged = `${local}.merged`;
280-
const backup = `${local}.bak`;
281302
const expectedBase = 'C:\\workspace\\component.base.c';
282303
const node = new COutlineItem('file');
283304
node.setTag('file');
@@ -312,7 +333,7 @@ describe('MergeCommand', () => {
312333
expect(mockedPath.dirname).toHaveBeenCalledWith(update);
313334
expect(mockedPath.join).toHaveBeenCalledWith('C:\\workspace', 'component.base.c');
314335
expect(mockedFs.copyFileSync).toHaveBeenCalledWith(local, merged);
315-
expect(mockedFs.copyFileSync).toHaveBeenCalledWith(local, backup);
336+
expect(mockedFs.copyFileSync).toHaveBeenCalledWith(local, `${local}.bak`);
316337
expect(mockedFs.renameSync).toHaveBeenCalledWith(update, expectedBase);
317338
expect(mockedFs.renameSync).toHaveBeenCalledWith(merged, local);
318339
expect(activeSolutionTracker.triggerReload).toHaveBeenCalledTimes(1);

src/views/solution-outline/commands/merge-command.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ export class MergeCommand {
136136

137137
} catch (err) {
138138
console.error('Merge operations failed:', err);
139+
const details = err instanceof Error ? err.message : String(err);
140+
vscode.window.showErrorMessage(`Merge operation failed: ${details}`);
139141
}
140142
}
141143

0 commit comments

Comments
 (0)