Skip to content

Commit b27b9ff

Browse files
committed
Handle non-relative target paths
1 parent 18766d0 commit b27b9ff

File tree

2 files changed

+39
-12
lines changed

2 files changed

+39
-12
lines changed

src/assets.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,11 @@ export class AssetGenerator {
162162
}
163163

164164
const relativeTargetPath = path.relative(this.workspaceFolder.uri.fsPath, this.startupProject.TargetPath);
165+
if (relativeTargetPath === this.startupProject.TargetPath) {
166+
// This can happen if, for example, the workspace folder and the target path
167+
// are on completely different drives.
168+
return this.startupProject.TargetPath;
169+
}
165170
return path.join('${workspaceFolder}', relativeTargetPath);
166171
}
167172

@@ -170,6 +175,8 @@ export class AssetGenerator {
170175
throw new Error("Startup project not set");
171176
}
172177

178+
// Startup project will always be a child of the workspace folder,
179+
// so the special check above isn't necessary.
173180
const relativeProjectPath = path.relative(this.workspaceFolder.uri.fsPath, this.startupProject.Path);
174181
return path.join('${workspaceFolder}', path.dirname(relativeProjectPath));
175182
}

test/featureTests/assets.test.ts

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ suite("Asset generation: csproj", () => {
108108

109109
test(`Create launch.json for NET ${version} project opened in workspace with shortname '${shortName}'`, () => {
110110
let rootPath = path.resolve('testRoot');
111-
let info = createMSBuildWorkspaceInformation(path.join(rootPath, 'testApp.csproj'), 'testApp', shortName, /*isExe*/ true);
111+
let info = createMSBuildWorkspaceInformation(path.join(rootPath, 'testApp.csproj'), 'testApp', shortName, /*targetPath*/ undefined, /*isExe*/ true);
112112
let generator = new AssetGenerator(info, createMockWorkspaceFolder(rootPath));
113113
generator.setStartupProject(0);
114114
let launchJson = parse(generator.createLaunchJsonConfigurations(ProgramLaunchType.Console), undefined, { disallowComments: true });
@@ -129,9 +129,25 @@ suite("Asset generation: csproj", () => {
129129
checkProgramPath(rootPath, programPath, info.MsBuild.Projects[0].TargetPath);
130130
});
131131

132+
test("Create launch.json for project opened in workspace with non-relative output path", function() {
133+
if (process.platform !== "win32") {
134+
this.skip();
135+
}
136+
137+
let rootPath = path.resolve('testRoot');
138+
let differentDrive = rootPath.startsWith('C:') ? 'D:' : 'C:';
139+
let info = createMSBuildWorkspaceInformation(path.join(rootPath, 'testApp.csproj'), 'testApp', 'netcoreapp1.0', `${differentDrive}\\output.dll`);
140+
let generator = new AssetGenerator(info, createMockWorkspaceFolder(rootPath));
141+
generator.setStartupProject(0);
142+
let launchJson = parse(generator.createLaunchJsonConfigurations(ProgramLaunchType.Console), undefined, { disallowComments: true });
143+
let programPath: string = launchJson[0].program;
144+
145+
checkProgramPath(rootPath, programPath, info.MsBuild.Projects[0].TargetPath);
146+
});
147+
132148
test("Create launch.json for Blazor web assembly standalone project opened in workspace", () => {
133149
const rootPath = path.resolve('testRoot');
134-
const info = createMSBuildWorkspaceInformation(path.join(rootPath, 'testApp.csproj'), 'testApp', 'netstandard2.1', /*isExe*/ true, /*isWebProject*/ true, /*isBlazorWebAssemblyStandalone*/ true);
150+
const info = createMSBuildWorkspaceInformation(path.join(rootPath, 'testApp.csproj'), 'testApp', 'netstandard2.1', /*targetPath*/ undefined, /*isExe*/ true, /*isWebProject*/ true, /*isBlazorWebAssemblyStandalone*/ true);
135151
const generator = new AssetGenerator(info, createMockWorkspaceFolder(rootPath));
136152
generator.setStartupProject(0);
137153
const launchJson = parse(generator.createLaunchJsonConfigurations(ProgramLaunchType.BlazorWebAssemblyStandalone), undefined, { disallowComments: true });
@@ -143,7 +159,7 @@ suite("Asset generation: csproj", () => {
143159

144160
test("Create launch.json for nested Blazor web assembly standalone project opened in workspace", () => {
145161
let rootPath = path.resolve('testRoot');
146-
let info = createMSBuildWorkspaceInformation(path.join(rootPath, 'nested', 'testApp.csproj'), 'testApp', 'netstandard2.1', /*isExe*/ true, /*isWebProject*/ true, /*isBlazorWebAssemblyStandalone*/ true);
162+
let info = createMSBuildWorkspaceInformation(path.join(rootPath, 'nested', 'testApp.csproj'), 'testApp', 'netstandard2.1', /*targetPath*/ undefined, /*isExe*/ true, /*isWebProject*/ true, /*isBlazorWebAssemblyStandalone*/ true);
147163
let generator = new AssetGenerator(info, createMockWorkspaceFolder(rootPath));
148164
generator.setStartupProject(0);
149165
let launchJson = parse(generator.createLaunchJsonConfigurations(ProgramLaunchType.BlazorWebAssemblyStandalone), undefined, { disallowComments: true });
@@ -155,7 +171,7 @@ suite("Asset generation: csproj", () => {
155171

156172
test("Create launch.json for Blazor web assembly hosted project opened in workspace", () => {
157173
const rootPath = path.resolve('testRoot');
158-
const info = createMSBuildWorkspaceInformation(path.join(rootPath, 'testApp.csproj'), 'testApp', 'netcoreapp3.0', /*isExe*/ true, /*isWebProject*/ true, /*isBlazorWebAssemblyStandalone*/ false, /*isBlazorWebAssemblyHosted*/ true);
174+
const info = createMSBuildWorkspaceInformation(path.join(rootPath, 'testApp.csproj'), 'testApp', 'netcoreapp3.0', /*targetPath*/ undefined, /*isExe*/ true, /*isWebProject*/ true, /*isBlazorWebAssemblyStandalone*/ false, /*isBlazorWebAssemblyHosted*/ true);
159175
const generator = new AssetGenerator(info, createMockWorkspaceFolder(rootPath));
160176
generator.setStartupProject(0);
161177
const launchJson = parse(generator.createLaunchJsonConfigurations(ProgramLaunchType.BlazorWebAssemblyHosted), undefined, { disallowComments: true });
@@ -172,7 +188,7 @@ suite("Asset generation: csproj", () => {
172188

173189
test("Create launch.json for nested Blazor web assembly hosted project opened in workspace", () => {
174190
let rootPath = path.resolve('testRoot');
175-
let info = createMSBuildWorkspaceInformation(path.join(rootPath, 'nested', 'testApp.csproj'), 'testApp', 'netcoreapp3.0', /*isExe*/ true, /*isWebProject*/ true, /*isBlazorWebAssemblyStandalone*/ false, /*isBlazorWebAssemblyHosted*/ true);
191+
let info = createMSBuildWorkspaceInformation(path.join(rootPath, 'nested', 'testApp.csproj'), 'testApp', 'netcoreapp3.0', /*targetPath*/ undefined, /*isExe*/ true, /*isWebProject*/ true, /*isBlazorWebAssemblyStandalone*/ false, /*isBlazorWebAssemblyHosted*/ true);
176192
let generator = new AssetGenerator(info, createMockWorkspaceFolder(rootPath));
177193
generator.setStartupProject(0);
178194
let launchJson = parse(generator.createLaunchJsonConfigurations(ProgramLaunchType.BlazorWebAssemblyHosted), undefined, { disallowComments: true });
@@ -189,7 +205,7 @@ suite("Asset generation: csproj", () => {
189205

190206
test("Create launch.json for web project opened in workspace", () => {
191207
let rootPath = path.resolve('testRoot');
192-
let info = createMSBuildWorkspaceInformation(path.join(rootPath, 'testApp.csproj'), 'testApp', 'netcoreapp1.0', /*isExe*/ true, /*isWebProject*/ true);
208+
let info = createMSBuildWorkspaceInformation(path.join(rootPath, 'testApp.csproj'), 'testApp', 'netcoreapp1.0', /*targetPath*/ undefined, /*isExe*/ true, /*isWebProject*/ true);
193209
let generator = new AssetGenerator(info, createMockWorkspaceFolder(rootPath));
194210
generator.setStartupProject(0);
195211
let launchJson = parse(generator.createLaunchJsonConfigurations(ProgramLaunchType.Web), undefined, { disallowComments: true });
@@ -200,7 +216,7 @@ suite("Asset generation: csproj", () => {
200216

201217
test("Create launch.json for nested web project opened in workspace", () => {
202218
let rootPath = path.resolve('testRoot');
203-
let info = createMSBuildWorkspaceInformation(path.join(rootPath, 'nested', 'testApp.csproj'), 'testApp', 'netcoreapp1.0', /*isExe*/ true, /*isWebProject*/ true);
219+
let info = createMSBuildWorkspaceInformation(path.join(rootPath, 'nested', 'testApp.csproj'), 'testApp', 'netcoreapp1.0', /*targetPath*/ undefined, /*isExe*/ true, /*isWebProject*/ true);
204220
let generator = new AssetGenerator(info, createMockWorkspaceFolder(rootPath));
205221
generator.setStartupProject(0);
206222
let launchJson = parse(generator.createLaunchJsonConfigurations(ProgramLaunchType.Web), undefined, { disallowComments: true });
@@ -291,7 +307,7 @@ suite("Asset generation: csproj", () => {
291307

292308
test("createLaunchJsonConfigurationsArray removes comments", () => {
293309
let rootPath = path.resolve('testRoot');
294-
let info = createMSBuildWorkspaceInformation(path.join(rootPath, 'testApp.csproj'), 'testApp', 'netcoreapp1.0', /*isExe*/ true, /*isWebProject*/ true);
310+
let info = createMSBuildWorkspaceInformation(path.join(rootPath, 'testApp.csproj'), 'testApp', 'netcoreapp1.0', /*targetPath*/ undefined, /*isExe*/ true, /*isWebProject*/ true);
295311
let generator = new AssetGenerator(info, createMockWorkspaceFolder(rootPath));
296312
generator.setStartupProject(0);
297313
let launchConfigurations: vscode.DebugConfiguration[] = generator.createLaunchJsonConfigurationsArray(ProgramLaunchType.Web);
@@ -309,8 +325,12 @@ suite("Asset generation: csproj", () => {
309325
});
310326

311327
function checkProgramPath(rootPath: string, programPath: string, targetPath: string): void {
312-
programPath.should.startWith('${workspaceFolder}/');
313-
programPath.should.equal(targetPath.replace(rootPath, '${workspaceFolder}').replaceAll(path.win32.sep, path.posix.sep));
328+
if (path.relative(rootPath, targetPath) !== targetPath) {
329+
programPath.should.startWith('${workspaceFolder}/');
330+
programPath.should.equal(targetPath.replace(rootPath, '${workspaceFolder}').replaceAll(path.win32.sep, path.posix.sep));
331+
} else {
332+
programPath.should.equal(targetPath.replaceAll(path.win32.sep, path.posix.sep));
333+
}
314334
}
315335

316336
function createMockWorkspaceFolder(rootPath: string): vscode.WorkspaceFolder {
@@ -321,7 +341,7 @@ function createMockWorkspaceFolder(rootPath: string): vscode.WorkspaceFolder {
321341
};
322342
}
323343

324-
function createMSBuildWorkspaceInformation(projectPath: string, assemblyName: string, targetFrameworkShortName: string, isExe: boolean = true, isWebProject: boolean = false, isBlazorWebAssemblyStandalone: boolean = false, isBlazorWebAssemblyHosted: boolean = false): protocol.WorkspaceInformationResponse {
344+
function createMSBuildWorkspaceInformation(projectPath: string, assemblyName: string, targetFrameworkShortName: string, targetPath: string = undefined, isExe: boolean = true, isWebProject: boolean = false, isBlazorWebAssemblyStandalone: boolean = false, isBlazorWebAssemblyHosted: boolean = false): protocol.WorkspaceInformationResponse {
325345
return {
326346
MsBuild: {
327347
SolutionPath: '',
@@ -330,7 +350,7 @@ function createMSBuildWorkspaceInformation(projectPath: string, assemblyName: st
330350
ProjectGuid: '',
331351
Path: projectPath,
332352
AssemblyName: assemblyName,
333-
TargetPath: path.join(path.dirname(projectPath), 'bin', 'Debug', new Date().getTime().toString(), targetFrameworkShortName, `${assemblyName}.dll`),
353+
TargetPath: targetPath ?? path.join(path.dirname(projectPath), 'bin', 'Debug', new Date().getTime().toString(), targetFrameworkShortName, `${assemblyName}.dll`),
334354
TargetFramework: '',
335355
SourceFiles: [],
336356
TargetFrameworks: [

0 commit comments

Comments
 (0)