Skip to content

Commit e83611e

Browse files
authored
Fixing 'Run Task' Build for the legacy projects (#26337) (#26339)
* Fixing 'Run Task' Build for the legacy projects * test updates * duplicated problem matcher added during conflicts resolution and unnoticed * removing the duplicated probem matcher while unnoticed conflicts resolution
1 parent 2fa77d4 commit e83611e

File tree

4 files changed

+88
-42
lines changed

4 files changed

+88
-42
lines changed

extensions/sql-database-projects/package.json

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -580,44 +580,6 @@
580580
}
581581
]
582582
},
583-
"problemMatchers": [
584-
{
585-
"name": "sqlproj-problem-matcher",
586-
"owner": "sqlproj-builder",
587-
"fileLocation": "absolute",
588-
"pattern": {
589-
"regexp": "^(.*\\.sql)\\((\\d+),(\\d+),(\\d+),(\\d+)\\):\\s+\\w+\\s+(warning|error)\\s+(\\w+):\\s+(.*?)?$",
590-
"file": 1,
591-
"line": 2,
592-
"column": 3,
593-
"severity": 6,
594-
"code": 7,
595-
"message": 8
596-
}
597-
}
598-
],
599-
"taskDefinitions": [
600-
{
601-
"type": "sqlproj-build",
602-
"required": [
603-
"filePath"
604-
],
605-
"properties": {
606-
"filePath": {
607-
"type": "string",
608-
"description": "The path to the .sqlproj file."
609-
},
610-
"fileDisplayName": {
611-
"type": "string",
612-
"description": "The display name of the .sqlproj file."
613-
},
614-
"runCodeAnalysis": {
615-
"type": "boolean",
616-
"description": "Run code analysis on the SQLProj file. Optional, default is true."
617-
}
618-
}
619-
}
620-
],
621583
"dependencies": {
622584
"@microsoft/ads-extension-telemetry": "^3.0.1",
623585
"@xmldom/xmldom": "0.8.4",
@@ -653,4 +615,4 @@
653615
"publisherDisplayName": "Microsoft",
654616
"publisherId": "Microsoft"
655617
}
656-
}
618+
}

extensions/sql-database-projects/src/controllers/projectController.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ export class ProjectsController {
316316
}
317317
}
318318

319-
// Load tasks from tasks.json and create a new vscode.task if it exist
319+
// Get the build arguments from buildhelper method and create a new vscode.task
320320
const buildArgs: string[] = this.buildHelper.constructBuildArguments(this.buildHelper.extensionBuildDirPath, project.sqlProjStyle);
321321
const vscodeTask: vscode.Task = await this.createVsCodeTask(project, codeAnalysis, buildArgs);
322322

extensions/sql-database-projects/src/tasks/sqlDatabaseProjectTaskProvider.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import * as vscode from 'vscode';
77
import * as path from 'path';
88
import * as constants from '../common/constants';
99
import * as utils from '../common/utils';
10+
import { Project } from '../models/project';
11+
import { ProjectType } from '../common/typeHelper';
12+
import { BuildHelper } from '../tools/buildHelper';
13+
1014

1115
/**
1216
* Extends to vscode.TaskDefinition to add task definition properties.
@@ -15,6 +19,7 @@ import * as utils from '../common/utils';
1519
interface SqlprojTaskDefinition extends vscode.TaskDefinition {
1620
fileDisplayName: string;
1721
filePath: string;
22+
projectStyle: ProjectType;
1823
runCodeAnalysis?: boolean;
1924
workspaceFolder?: vscode.WorkspaceFolder;
2025
}
@@ -28,6 +33,7 @@ export class SqlDatabaseProjectTaskProvider implements vscode.TaskProvider {
2833
private sqlTasks: Thenable<vscode.Task[]> | undefined = undefined;
2934
private _onDidChangeTasks = new vscode.EventEmitter<void>();
3035
private workspaceFoldersListener: vscode.Disposable | undefined;
36+
private buildHelper: BuildHelper;
3137

3238
/**
3339
* Event that fires when the tasks change (e.g., when .sqlproj files are created, modified, or deleted)
@@ -40,6 +46,7 @@ export class SqlDatabaseProjectTaskProvider implements vscode.TaskProvider {
4046
* or deletions of `.sqlproj` files. When any of these events occur, the `sqlTasks` cache is invalidated.
4147
*/
4248
constructor() {
49+
this.buildHelper = new BuildHelper();
4350
// Watch for workspace folder changes
4451
this.workspaceFoldersListener = vscode.workspace.onDidChangeWorkspaceFolders(() => {
4552
this.invalidateTasks();
@@ -153,12 +160,16 @@ export class SqlDatabaseProjectTaskProvider implements vscode.TaskProvider {
153160
// Add the file to the processed set to avoid duplicates
154161
processedFiles.add(uri.fsPath);
155162

163+
// Determine project style once
164+
const project = await Project.openProject(uri.fsPath);
165+
156166
// Create a task definition for the .sqlproj file
157167
const taskDefinition: SqlprojTaskDefinition = {
158168
type: constants.sqlProjTaskType,
159169
filePath: utils.getNonQuotedPath(uri.fsPath),
160170
fileDisplayName: path.basename(uri.fsPath),
161-
workspaceFolder: workspaceFolder
171+
workspaceFolder: workspaceFolder,
172+
projectStyle: project.sqlProjStyle
162173
};
163174

164175
// Create a Build task
@@ -184,6 +195,9 @@ export class SqlDatabaseProjectTaskProvider implements vscode.TaskProvider {
184195
// Set the runCodeAnalysis flag in the definition
185196
definition.runCodeAnalysis = runCodeAnalysis;
186197

198+
// Get the build arguments for the task
199+
const buildArgs: string[] = this.buildHelper.constructBuildArguments(this.buildHelper.extensionBuildDirPath, definition.projectStyle);
200+
187201
// Construct the task name
188202
const taskName = runCodeAnalysis
189203
? `${definition.fileDisplayName} - ${constants.buildWithCodeAnalysisTaskName}`
@@ -193,6 +207,7 @@ export class SqlDatabaseProjectTaskProvider implements vscode.TaskProvider {
193207
const args: string[] = [
194208
constants.build,
195209
definition.filePath, // vscode shell execution handles the quotes around the file path
210+
...buildArgs
196211
];
197212

198213
if (runCodeAnalysis) {

extensions/sql-database-projects/src/test/tasks/sqlDatabaseProjectTaskProvider.test.ts

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import * as vscode from 'vscode';
77
import * as sinon from 'sinon';
88
import * as should from 'should';
99
import * as path from 'path';
10+
import * as vscodeMssql from 'vscode-mssql';
1011
import { SqlDatabaseProjectTaskProvider } from '../../tasks/sqlDatabaseProjectTaskProvider';
1112

1213
describe('Sql Database Projects Task Provider', function (): void {
@@ -33,6 +34,19 @@ describe('Sql Database Projects Task Provider', function (): void {
3334
sandbox.stub(vscode.workspace, 'findFiles').resolves(sqlProjUri);
3435
}
3536

37+
// Helper to create and stub a mock project
38+
function stubProjectOpenWithStyle(projectStyle: vscodeMssql.ProjectType) {
39+
const mockProject = {
40+
sqlProjStyle: projectStyle,
41+
readProjFile: sandbox.stub().resolves()
42+
};
43+
44+
const projectModule = require('../../models/project');
45+
sandbox.stub(projectModule.Project, 'openProject').resolves(mockProject);
46+
47+
return mockProject;
48+
}
49+
3650
beforeEach(() => {
3751
// Create a new Sinon sandbox before each test
3852
sandbox = sinon.createSandbox();
@@ -45,10 +59,13 @@ describe('Sql Database Projects Task Provider', function (): void {
4559
sandbox.restore();
4660
});
4761

48-
it('Should create build and buildWithCodeAnalysis tasks for .sqlproj file with correct properties', async function (): Promise<void> {
62+
it('Should create build and buildWithCodeAnalysis tasks for .sqlproj file with correct properties for SDK style project', async function (): Promise<void> {
4963
// Define mock .sqlproj file URIs for testing
5064
stubWorkspaceAndFiles([sqlProjUris[0]]);
5165

66+
// Stub the project as SDK style
67+
stubProjectOpenWithStyle(vscodeMssql.ProjectType.SdkStyle);
68+
5269
// Act: create tasks using the provider
5370
const tasks = await taskProvider.createTasks();
5471

@@ -93,13 +110,23 @@ describe('Sql Database Projects Task Provider', function (): void {
93110
should(buildTask.execution.args).not.be.undefined();
94111
should(buildTask.execution.args).be.Array();
95112
should(buildTask.execution.args[0]).equal('build');
113+
114+
const argsString = buildTask.execution.args.join(' ');
115+
should(argsString).containEql('/p:NetCoreBuild=true');
116+
should(argsString).containEql('/p:SystemDacpacsLocation=');
117+
should(argsString).not.containEql('/p:NETCoreTargetsPath='); // This should NOT be present for SDK projects
118+
should(argsString).containEql('-v:detailed');
119+
96120
}
97121
});
98122

99123
it('Should not create any tasks when no .sqlproj files are present in the workspace', async function (): Promise<void> {
100124
// Define mock .sqlproj file URIs for testing
101125
stubWorkspaceAndFiles([]);
102126

127+
// Stub the project as SDK style
128+
stubProjectOpenWithStyle(vscodeMssql.ProjectType.SdkStyle);
129+
103130
// Act: Attempt to create tasks using the provider
104131
const tasks = await taskProvider.createTasks();
105132

@@ -112,6 +139,9 @@ describe('Sql Database Projects Task Provider', function (): void {
112139
// Define mock .sqlproj file URIs for testing
113140
stubWorkspaceAndFiles(sqlProjUris);
114141

142+
// Stub the project as SDK style
143+
stubProjectOpenWithStyle(vscodeMssql.ProjectType.SdkStyle);
144+
115145
// Act: create tasks using the provider
116146
const tasks = await taskProvider.createTasks();
117147

@@ -160,4 +190,43 @@ describe('Sql Database Projects Task Provider', function (): void {
160190
}
161191
}
162192
});
193+
194+
it('Should create tasks with correct build arguments for legacy-style project', async function (): Promise<void> {
195+
// Define mock .sqlproj file URIs for testing
196+
stubWorkspaceAndFiles([sqlProjUris[0]]);
197+
198+
// Stub the project as SDK style
199+
stubProjectOpenWithStyle(vscodeMssql.ProjectType.LegacyStyle);
200+
201+
// Act: create tasks using the provider
202+
const tasks = await taskProvider.createTasks();
203+
204+
// Assert: tasks should be defined and have the expected length
205+
should(tasks).not.be.undefined();
206+
should(tasks).be.Array().and.have.length(2);
207+
208+
// Find the build task
209+
const buildTask = tasks.find(t => t.name === 'ProjectA.sqlproj - Build');
210+
211+
// Assert: build task should exist
212+
should(buildTask).not.be.undefined();
213+
214+
// Assert: build task execution should contain legacy-style arguments
215+
should(buildTask?.execution).not.be.undefined();
216+
if (buildTask?.execution instanceof vscode.ShellExecution) {
217+
should(buildTask.execution.command).equal('dotnet');
218+
should(buildTask.execution.args).not.be.undefined();
219+
should(buildTask.execution.args).be.Array();
220+
221+
// Verify it contains build command
222+
should(buildTask.execution.args[0]).equal('build');
223+
224+
// Verify it contains legacy-style build arguments
225+
const argsString = buildTask.execution.args.join(' ');
226+
should(argsString).containEql('/p:NetCoreBuild=true');
227+
should(argsString).containEql('/p:SystemDacpacsLocation=');
228+
should(argsString).containEql('/p:NETCoreTargetsPath='); // This is only for legacy projects
229+
should(argsString).containEql('-v:detailed');
230+
}
231+
});
163232
});

0 commit comments

Comments
 (0)