Skip to content

Commit d866848

Browse files
Copilotvhvb1989
andcommitted
Refactor validation logic into shared utility function
Based on code review feedback: - Extracted duplicated validation logic to validateFileSystemUri() in cmdUtil.ts - Updated all 8 command files to use the shared function - Simplified test assertions - Improved code maintainability by reducing duplication Co-authored-by: vhvb1989 <24213737+vhvb1989@users.noreply.github.com>
1 parent 4deb151 commit d866848

File tree

10 files changed

+55
-114
lines changed

10 files changed

+55
-114
lines changed

ext/vscode/src/commands/cmdUtil.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,40 @@ import * as vscode from 'vscode';
99
import { createAzureDevCli } from '../utils/azureDevCli';
1010
import { execAsync } from '../utils/execAsync';
1111
import { fileExists } from '../utils/fileUtils';
12+
import { isAzureDevCliModel, isTreeViewModel, TreeViewModel } from '../utils/isTreeViewModel';
1213

1314
const AzureYamlGlobPattern: vscode.GlobPattern = '**/[aA][zZ][uU][rR][eE].{[yY][aA][mM][lL],[yY][mM][lL]}';
1415

16+
/**
17+
* Validates that a URI has a valid fsPath for file system operations.
18+
* Virtual file systems or certain VS Code contexts may not provide a valid fsPath.
19+
* @param context The action context
20+
* @param selectedFile The URI to validate
21+
* @param selectedItem The original selected item (for error message context)
22+
* @param commandName The name of the command being executed (for error message)
23+
* @throws Error if the URI doesn't have a valid fsPath
24+
*/
25+
export function validateFileSystemUri(
26+
context: IActionContext,
27+
selectedFile: vscode.Uri | undefined,
28+
selectedItem: vscode.Uri | TreeViewModel | undefined,
29+
commandName: string
30+
): void {
31+
if (selectedFile && !selectedFile.fsPath) {
32+
context.errorHandling.suppressReportIssue = true;
33+
const itemType = isTreeViewModel(selectedItem) ? 'TreeViewModel' :
34+
isAzureDevCliModel(selectedItem) ? 'AzureDevCliModel' :
35+
selectedItem ? 'vscode.Uri' : 'undefined';
36+
throw new Error(vscode.l10n.t(
37+
"Unable to determine working folder for {0} command. The selected file has an unsupported URI scheme '{1}' (selectedItem type: {2}). " +
38+
"Azure Developer CLI commands are not supported in virtual file systems. Please open a local folder or clone the repository locally.",
39+
commandName,
40+
selectedFile.scheme,
41+
itemType
42+
));
43+
}
44+
}
45+
1546
// If the command was invoked with a specific file context, use the file context as the working directory for running Azure developer CLI commands.
1647
// Otherwise search the workspace for "azure.yaml" or "azure.yml" files. If only one is found, use it (i.e. its folder). If more than one is found, ask the user which one to use.
1748
// If at this point we still do not have a working directory, prompt the user to select one.

ext/vscode/src/commands/deploy.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { executeAsTask } from '../utils/executeAsTask';
1010
import { isAzureDevCliModel, isTreeViewModel, TreeViewModel } from '../utils/isTreeViewModel';
1111
import { AzureDevCliModel } from '../views/workspace/AzureDevCliModel';
1212
import { AzureDevCliService } from '../views/workspace/AzureDevCliService';
13-
import { getAzDevTerminalTitle, getWorkingFolder } from './cmdUtil';
13+
import { getAzDevTerminalTitle, getWorkingFolder, validateFileSystemUri } from './cmdUtil';
1414

1515
export async function deploy(context: IActionContext, selectedItem?: vscode.Uri | TreeViewModel): Promise<void> {
1616
let selectedModel: AzureDevCliModel | undefined;
@@ -27,19 +27,7 @@ export async function deploy(context: IActionContext, selectedItem?: vscode.Uri
2727
}
2828

2929
// Validate that selectedFile is valid for file system operations
30-
// Virtual file systems or certain VS Code contexts may not provide a valid fsPath
31-
if (selectedFile && !selectedFile.fsPath) {
32-
context.errorHandling.suppressReportIssue = true;
33-
const itemType = isTreeViewModel(selectedItem) ? 'TreeViewModel' :
34-
isAzureDevCliModel(selectedItem) ? 'AzureDevCliModel' :
35-
selectedItem ? 'vscode.Uri' : 'undefined';
36-
throw new Error(vscode.l10n.t(
37-
"Unable to determine working folder for deploy command. The selected file has an unsupported URI scheme '{0}' (selectedItem type: {1}). " +
38-
"Azure Developer CLI commands are not supported in virtual file systems. Please open a local folder or clone the repository locally.",
39-
selectedFile.scheme,
40-
itemType
41-
));
42-
}
30+
validateFileSystemUri(context, selectedFile, selectedItem, 'deploy');
4331

4432
const workingFolder = await getWorkingFolder(context, selectedFile);
4533

ext/vscode/src/commands/down.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { createAzureDevCli } from '../utils/azureDevCli';
99
import { executeAsTask } from '../utils/executeAsTask';
1010
import { isAzureDevCliModel, isTreeViewModel, TreeViewModel } from '../utils/isTreeViewModel';
1111
import { AzureDevCliApplication } from '../views/workspace/AzureDevCliApplication';
12-
import { getAzDevTerminalTitle, getWorkingFolder, } from './cmdUtil';
12+
import { getAzDevTerminalTitle, getWorkingFolder, validateFileSystemUri, } from './cmdUtil';
1313

1414
/**
1515
* A tuple representing the arguments that must be passed to the `down` command when executed via {@link vscode.commands.executeCommand}
@@ -29,19 +29,7 @@ export async function down(context: IActionContext, selectedItem?: vscode.Uri |
2929
}
3030

3131
// Validate that selectedFile is valid for file system operations
32-
// Virtual file systems or certain VS Code contexts may not provide a valid fsPath
33-
if (selectedFile && !selectedFile.fsPath) {
34-
context.errorHandling.suppressReportIssue = true;
35-
const itemType = isTreeViewModel(selectedItem) ? 'TreeViewModel' :
36-
isAzureDevCliModel(selectedItem) ? 'AzureDevCliModel' :
37-
selectedItem ? 'vscode.Uri' : 'undefined';
38-
throw new Error(vscode.l10n.t(
39-
"Unable to determine working folder for down command. The selected file has an unsupported URI scheme '{0}' (selectedItem type: {1}). " +
40-
"Azure Developer CLI commands are not supported in virtual file systems. Please open a local folder or clone the repository locally.",
41-
selectedFile.scheme,
42-
itemType
43-
));
44-
}
32+
validateFileSystemUri(context, selectedFile, selectedItem, 'down');
4533

4634
const workingFolder = await getWorkingFolder(context, selectedFile);
4735

ext/vscode/src/commands/monitor.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { createAzureDevCli } from '../utils/azureDevCli';
88
import { execAsync } from '../utils/execAsync';
99
import { isAzureDevCliModel, isTreeViewModel, TreeViewModel } from '../utils/isTreeViewModel';
1010
import { AzureDevCliApplication } from '../views/workspace/AzureDevCliApplication';
11-
import { getWorkingFolder } from './cmdUtil';
11+
import { getWorkingFolder, validateFileSystemUri } from './cmdUtil';
1212

1313
const MonitorChoices: IAzureQuickPickItem<string>[] = [
1414
{
@@ -37,19 +37,7 @@ export async function monitor(context: IActionContext, selectedItem?: vscode.Uri
3737
}
3838

3939
// Validate that selectedFile is valid for file system operations
40-
// Virtual file systems or certain VS Code contexts may not provide a valid fsPath
41-
if (selectedFile && !selectedFile.fsPath) {
42-
context.errorHandling.suppressReportIssue = true;
43-
const itemType = isTreeViewModel(selectedItem) ? 'TreeViewModel' :
44-
isAzureDevCliModel(selectedItem) ? 'AzureDevCliModel' :
45-
selectedItem ? 'vscode.Uri' : 'undefined';
46-
throw new Error(vscode.l10n.t(
47-
"Unable to determine working folder for monitor command. The selected file has an unsupported URI scheme '{0}' (selectedItem type: {1}). " +
48-
"Azure Developer CLI commands are not supported in virtual file systems. Please open a local folder or clone the repository locally.",
49-
selectedFile.scheme,
50-
itemType
51-
));
52-
}
40+
validateFileSystemUri(context, selectedFile, selectedItem, 'monitor');
5341

5442
const workingFolder = await getWorkingFolder(context, selectedFile);
5543

ext/vscode/src/commands/packageCli.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { executeAsTask } from '../utils/executeAsTask';
1010
import { isAzureDevCliModel, isTreeViewModel, TreeViewModel } from '../utils/isTreeViewModel';
1111
import { AzureDevCliModel } from '../views/workspace/AzureDevCliModel';
1212
import { AzureDevCliService } from '../views/workspace/AzureDevCliService';
13-
import { getAzDevTerminalTitle, getWorkingFolder } from './cmdUtil';
13+
import { getAzDevTerminalTitle, getWorkingFolder, validateFileSystemUri } from './cmdUtil';
1414

1515
// `package` is a reserved identifier so `packageCli` had to be used instead
1616
export async function packageCli(context: IActionContext, selectedItem?: vscode.Uri | TreeViewModel): Promise<void> {
@@ -28,19 +28,7 @@ export async function packageCli(context: IActionContext, selectedItem?: vscode.
2828
}
2929

3030
// Validate that selectedFile is valid for file system operations
31-
// Virtual file systems or certain VS Code contexts may not provide a valid fsPath
32-
if (selectedFile && !selectedFile.fsPath) {
33-
context.errorHandling.suppressReportIssue = true;
34-
const itemType = isTreeViewModel(selectedItem) ? 'TreeViewModel' :
35-
isAzureDevCliModel(selectedItem) ? 'AzureDevCliModel' :
36-
selectedItem ? 'vscode.Uri' : 'undefined';
37-
throw new Error(vscode.l10n.t(
38-
"Unable to determine working folder for package command. The selected file has an unsupported URI scheme '{0}' (selectedItem type: {1}). " +
39-
"Azure Developer CLI commands are not supported in virtual file systems. Please open a local folder or clone the repository locally.",
40-
selectedFile.scheme,
41-
itemType
42-
));
43-
}
31+
validateFileSystemUri(context, selectedFile, selectedItem, 'package');
4432

4533
const workingFolder = await getWorkingFolder(context, selectedFile);
4634

ext/vscode/src/commands/pipeline.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import { IActionContext } from '@microsoft/vscode-azext-utils';
55
import { composeArgs, withArg } from '@microsoft/vscode-processutils';
66
import * as vscode from 'vscode';
7-
import { getAzDevTerminalTitle, getWorkingFolder } from './cmdUtil';
7+
import { getAzDevTerminalTitle, getWorkingFolder, validateFileSystemUri } from './cmdUtil';
88
import { TelemetryId } from '../telemetry/telemetryId';
99
import { createAzureDevCli } from '../utils/azureDevCli';
1010
import { executeAsTask } from '../utils/executeAsTask';
@@ -29,19 +29,7 @@ export async function pipelineConfig(context: IActionContext, selectedItem?: vsc
2929
}
3030

3131
// Validate that selectedFile is valid for file system operations
32-
// Virtual file systems or certain VS Code contexts may not provide a valid fsPath
33-
if (selectedFile && !selectedFile.fsPath) {
34-
context.errorHandling.suppressReportIssue = true;
35-
const itemType = isTreeViewModel(selectedItem) ? 'TreeViewModel' :
36-
isAzureDevCliModel(selectedItem) ? 'AzureDevCliModel' :
37-
selectedItem ? 'vscode.Uri' : 'undefined';
38-
throw new Error(vscode.l10n.t(
39-
"Unable to determine working folder for pipeline config command. The selected file has an unsupported URI scheme '{0}' (selectedItem type: {1}). " +
40-
"Azure Developer CLI commands are not supported in virtual file systems. Please open a local folder or clone the repository locally.",
41-
selectedFile.scheme,
42-
itemType
43-
));
44-
}
32+
validateFileSystemUri(context, selectedFile, selectedItem, 'pipeline config');
4533

4634
const workingFolder = await getWorkingFolder(context, selectedFile);
4735

ext/vscode/src/commands/provision.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { createAzureDevCli } from '../utils/azureDevCli';
99
import { executeAsTask } from '../utils/executeAsTask';
1010
import { isAzureDevCliModel, isTreeViewModel, TreeViewModel } from '../utils/isTreeViewModel';
1111
import { AzureDevCliApplication } from '../views/workspace/AzureDevCliApplication';
12-
import { getAzDevTerminalTitle, getWorkingFolder } from './cmdUtil';
12+
import { getAzDevTerminalTitle, getWorkingFolder, validateFileSystemUri } from './cmdUtil';
1313

1414
export async function provision(context: IActionContext, selectedItem?: vscode.Uri | TreeViewModel): Promise<void> {
1515
let selectedFile: vscode.Uri | undefined;
@@ -22,19 +22,7 @@ export async function provision(context: IActionContext, selectedItem?: vscode.U
2222
}
2323

2424
// Validate that selectedFile is valid for file system operations
25-
// Virtual file systems or certain VS Code contexts may not provide a valid fsPath
26-
if (selectedFile && !selectedFile.fsPath) {
27-
context.errorHandling.suppressReportIssue = true;
28-
const itemType = isTreeViewModel(selectedItem) ? 'TreeViewModel' :
29-
isAzureDevCliModel(selectedItem) ? 'AzureDevCliModel' :
30-
selectedItem ? 'vscode.Uri' : 'undefined';
31-
throw new Error(vscode.l10n.t(
32-
"Unable to determine working folder for provision command. The selected file has an unsupported URI scheme '{0}' (selectedItem type: {1}). " +
33-
"Azure Developer CLI commands are not supported in virtual file systems. Please open a local folder or clone the repository locally.",
34-
selectedFile.scheme,
35-
itemType
36-
));
37-
}
25+
validateFileSystemUri(context, selectedFile, selectedItem, 'provision');
3826

3927
const workingFolder = await getWorkingFolder(context, selectedFile);
4028

ext/vscode/src/commands/restore.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { executeAsTask } from '../utils/executeAsTask';
1010
import { isAzureDevCliModel, isTreeViewModel, TreeViewModel } from '../utils/isTreeViewModel';
1111
import { AzureDevCliModel } from '../views/workspace/AzureDevCliModel';
1212
import { AzureDevCliService } from '../views/workspace/AzureDevCliService';
13-
import { getAzDevTerminalTitle, getWorkingFolder } from './cmdUtil';
13+
import { getAzDevTerminalTitle, getWorkingFolder, validateFileSystemUri } from './cmdUtil';
1414

1515
export async function restore(context: IActionContext, selectedItem?: vscode.Uri | TreeViewModel): Promise<void> {
1616
let selectedModel: AzureDevCliModel | undefined;
@@ -27,19 +27,7 @@ export async function restore(context: IActionContext, selectedItem?: vscode.Uri
2727
}
2828

2929
// Validate that selectedFile is valid for file system operations
30-
// Virtual file systems or certain VS Code contexts may not provide a valid fsPath
31-
if (selectedFile && !selectedFile.fsPath) {
32-
context.errorHandling.suppressReportIssue = true;
33-
const itemType = isTreeViewModel(selectedItem) ? 'TreeViewModel' :
34-
isAzureDevCliModel(selectedItem) ? 'AzureDevCliModel' :
35-
selectedItem ? 'vscode.Uri' : 'undefined';
36-
throw new Error(vscode.l10n.t(
37-
"Unable to determine working folder for restore command. The selected file has an unsupported URI scheme '{0}' (selectedItem type: {1}). " +
38-
"Azure Developer CLI commands are not supported in virtual file systems. Please open a local folder or clone the repository locally.",
39-
selectedFile.scheme,
40-
itemType
41-
));
42-
}
30+
validateFileSystemUri(context, selectedFile, selectedItem, 'restore');
4331

4432
const workingFolder = await getWorkingFolder(context, selectedFile);
4533

ext/vscode/src/commands/up.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { createAzureDevCli } from '../utils/azureDevCli';
99
import { executeAsTask } from '../utils/executeAsTask';
1010
import { isAzureDevCliModel, isTreeViewModel, TreeViewModel } from '../utils/isTreeViewModel';
1111
import { AzureDevCliApplication } from '../views/workspace/AzureDevCliApplication';
12-
import { getAzDevTerminalTitle, getWorkingFolder } from './cmdUtil';
12+
import { getAzDevTerminalTitle, getWorkingFolder, validateFileSystemUri } from './cmdUtil';
1313

1414
/**
1515
* A tuple representing the arguments that must be passed to the `up` command when executed via {@link vscode.commands.executeCommand}
@@ -29,19 +29,7 @@ export async function up(context: IActionContext, selectedItem?: vscode.Uri | Tr
2929
}
3030

3131
// Validate that selectedFile is valid for file system operations
32-
// Virtual file systems or certain VS Code contexts may not provide a valid fsPath
33-
if (selectedFile && !selectedFile.fsPath) {
34-
context.errorHandling.suppressReportIssue = true;
35-
const itemType = isTreeViewModel(selectedItem) ? 'TreeViewModel' :
36-
isAzureDevCliModel(selectedItem) ? 'AzureDevCliModel' :
37-
selectedItem ? 'vscode.Uri' : 'undefined';
38-
throw new Error(vscode.l10n.t(
39-
"Unable to determine working folder for up command. The selected file has an unsupported URI scheme '{0}' (selectedItem type: {1}). " +
40-
"Azure Developer CLI commands are not supported in virtual file systems. Please open a local folder or clone the repository locally.",
41-
selectedFile.scheme,
42-
itemType
43-
));
44-
}
32+
validateFileSystemUri(context, selectedFile, selectedItem, 'up');
4533

4634
const workingFolder = await getWorkingFolder(context, selectedFile);
4735

ext/vscode/src/test/suite/unit/provision.test.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,14 @@ suite('provision command', () => {
3232
// Mock the URI to ensure fsPath is undefined - simulates virtual file system
3333
const mockUri = {
3434
scheme: 'virtual',
35-
fsPath: undefined as unknown as string
36-
} as vscode.Uri;
35+
fsPath: undefined,
36+
authority: '',
37+
path: '',
38+
query: '',
39+
fragment: '',
40+
with: () => mockUri,
41+
toString: () => 'virtual:/test'
42+
} as unknown as vscode.Uri;
3743

3844
try {
3945
await provision(mockContext, mockUri);

0 commit comments

Comments
 (0)