Skip to content

Commit 3198d03

Browse files
Porting to M153: Searching for csproj, vbproj, fsproj using sdk Microsoft.Net.Sdk.Web (#10776)
* Searching for csproj, fsproj that uses Microsoft.Net.Sdk.Web (#10704) * Searching for csproj, vbproj, fsproj using sdk Microsoft.Net.Sdk.Web * Updating package.json * Updating error message * Review comments * Review comments * Try-catch * Iteratively find and check for file encodings * Review comments * Supporting only utf encodings * L0 * Adding semicolons * Removing vbproj * Comments * Updating error message * Updating error message * Updating task version * Updating L0 for DotNetCoreCLIV2 task (#10773) * Updating L0 * Removing unnecessary imports * Review comments
1 parent b39501b commit 3198d03

File tree

8 files changed

+154
-79
lines changed

8 files changed

+154
-79
lines changed

Tasks/DotNetCoreCLIV2/Strings/resources.resjson/en-US/resources.resjson

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@
103103
"loc.messages.dotnetCommandFailed": "Dotnet command failed with non-zero exit code on the following projects : %s",
104104
"loc.messages.noProjectFilesFound": "Project file(s) matching the specified pattern were not found.",
105105
"loc.messages.noPublishFolderFoundToZip": "A publish folder could not be found to zip for project file: %s.",
106-
"loc.messages.noWebProjctFound": "No web project was found in the repository. Web projects are identified by presence of either a web.config file or wwwroot folder in the directory.",
106+
"loc.messages.noWebProjectFound": "No web project was found in the repository. Web projects are identified by presence of either a web.config file, wwwroot folder in the directory, or by the usage of Microsoft.Net.Web.Sdk in your project file. You can set Publish Web Projects property to false (publishWebProjects: false in yml) if your project doesn't follow this convention or if you want to publish projects other than web projects.",
107107
"loc.messages.zipFailed": "Zip failed with error: %s",
108108
"loc.messages.Error_ApiKeyNotSupported": "DotNetCore currently does not support using an encrypted Api Key.",
109109
"loc.messages.Error_ExpectedConfigurationElement": "Invalid xml. Expected element named 'configuration'.",

Tasks/DotNetCoreCLIV2/Tests/L0.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,20 @@ describe('DotNetCoreExe Suite', function () {
312312
done();
313313
});
314314

315+
316+
it('publish works with publishWebProjects option if .csproj have Microsoft.Net.Sdk.Web', (done: MochaDone) => {
317+
process.env["__projects__"] = "validateWebProject.csproj";
318+
process.env["workingDirectory"] = ".";
319+
process.env["__publishWebProject__"] = "true";
320+
let tp = path.join(__dirname, 'validateWebProject.js');
321+
let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);
322+
tr.run();
323+
324+
assert(tr.invokedToolCount == 1, 'should have invoked been invoked once');
325+
assert(tr.succeeded, 'task should have succeeded');
326+
done();
327+
})
328+
315329
it('publish updates the output with the project name appended', (done: MochaDone) => {
316330
process.env["__projects__"] = "*customoutput/project.json";
317331
process.env["__publishWebProjects__"] = "false";
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netcoreapp2.1</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<Compile Include="Controllers/ValuesController.fs" />
9+
<Compile Include="Startup.fs" />
10+
<Compile Include="Program.fs" />
11+
</ItemGroup>
12+
13+
<ItemGroup>
14+
<PackageReference Include="Microsoft.AspNetCore.App" />
15+
</ItemGroup>
16+
17+
</Project>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import ma = require('azure-pipelines-task-lib/mock-answer');
2+
import tmrm = require('azure-pipelines-task-lib/mock-run');
3+
import path = require('path');
4+
5+
let taskPath = path.join(__dirname, '..', 'dotnetcore.js');
6+
let tmr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath);
7+
8+
tmr.setInput('command', "publish");
9+
tmr.setInput('projects', process.env["__projects__"]);
10+
tmr.setInput('publishWebProjects', process.env["__publishWebProjects__"] && process.env["__publishWebProjects__"] == "true" ? "true" : "false");
11+
tmr.setInput('arguments', process.env["__arguments__"] ? process.env["__arguments__"] : "");
12+
tmr.setInput('modifyOutputPath', process.env["modifyOutput"] == "false" ? "false" : "true");
13+
tmr.setInput('zipAfterPublish', process.env["zipAfterPublish"] ? process.env["zipAfterPublish"] : "false");
14+
tmr.setInput('workingDirectory', process.env["workingDirectory"] ? process.env["workingDirectory"] : "");
15+
16+
process.env['TASK_TEST_TRACE'] = "true";
17+
18+
var projectFile = path.join(__dirname, process.env["__projects__"]);
19+
var execCommand = "dotnet publish " + projectFile
20+
21+
let a: ma.TaskLibAnswers = <ma.TaskLibAnswers>{
22+
"which": {
23+
"dotnet": "dotnet",
24+
},
25+
"checkPath": { "dotnet": true },
26+
"exec": {},
27+
"findMatch": {
28+
"**/*.csproj\n**/*.vbproj\n**/*.fsproj": [projectFile]
29+
}
30+
}
31+
32+
a['exec'][execCommand] = {
33+
"code": 0,
34+
"stdout": "published",
35+
"stderr": ""
36+
}
37+
38+
process.env["MOCK_NORMALIZE_SLASHES"] = "true";
39+
tmr.setAnswers(a)
40+
tmr.registerMock('azure-pipelines-task-lib/toolrunner', require('azure-pipelines-task-lib/mock-toolrunner'));
41+
42+
tmr.run();

Tasks/DotNetCoreCLIV2/dotnetcore.ts

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import tl = require("azure-pipelines-task-lib/task");
22
import tr = require("azure-pipelines-task-lib/toolrunner");
33
import path = require("path");
44
import fs = require("fs");
5+
import ltx = require("ltx");
56
var archiver = require('archiver');
67

78
import * as packCommand from './packcommand';
@@ -325,22 +326,50 @@ export class dotNetExe {
325326
}
326327

327328
var projectFiles = utility.getProjectFiles(projectPattern);
329+
var resolvedProjectFiles: string[] = [];
328330

329331
if (searchWebProjects) {
330-
projectFiles = projectFiles.filter(function (file, index, files): boolean {
332+
resolvedProjectFiles = projectFiles.filter(function (file, index, files): boolean {
331333
var directory = path.dirname(file);
332334
return tl.exist(path.join(directory, "web.config"))
333335
|| tl.exist(path.join(directory, "wwwroot"));
334336
});
335337

336-
if (!projectFiles.length) {
337-
tl.error(tl.loc("noWebProjctFound"));
338-
}
338+
if (!resolvedProjectFiles.length) {
339+
var projectFilesUsingWebSdk = projectFiles.filter(this.isWebSdkUsed);
340+
if(!projectFilesUsingWebSdk.length) {
341+
tl.error(tl.loc("noWebProjectFound"));
342+
}
343+
return projectFilesUsingWebSdk;
344+
}
345+
return resolvedProjectFiles;
339346
}
340-
341347
return projectFiles;
342348
}
343349

350+
private isWebSdkUsed(projectfile: string): boolean {
351+
if (projectfile.endsWith('.vbproj')) return false
352+
353+
try {
354+
var fileBuffer: Buffer = fs.readFileSync(projectfile);
355+
var webConfigContent: string;
356+
357+
var fileEncodings = ['utf8', 'utf16le'];
358+
359+
for(var i = 0; i < fileEncodings.length; i++) {
360+
tl.debug("Trying to decode with " + fileEncodings[i]);
361+
webConfigContent = fileBuffer.toString(fileEncodings[i]);
362+
try {
363+
var projectSdkUsed: string = ltx.parse(webConfigContent).getAttr("sdk") || ltx.parse(webConfigContent).getAttr("Sdk");
364+
return projectSdkUsed && projectSdkUsed.toLowerCase() == "microsoft.net.sdk.web";
365+
} catch (error) {}
366+
}
367+
} catch(error) {
368+
tl.warning(error);
369+
}
370+
return false;
371+
}
372+
344373
private isPublishCommand(): boolean {
345374
return this.command === "publish";
346375
}

Tasks/DotNetCoreCLIV2/package-lock.json

Lines changed: 43 additions & 70 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tasks/DotNetCoreCLIV2/task.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"version": {
1919
"Major": 2,
2020
"Minor": 153,
21-
"Patch": 2
21+
"Patch": 3
2222
},
2323
"minimumAgentVersion": "2.115.0",
2424
"instanceNameFormat": "dotnet $(command)",
@@ -529,7 +529,7 @@
529529
"dotnetCommandFailed": "Dotnet command failed with non-zero exit code on the following projects : %s",
530530
"noProjectFilesFound": "Project file(s) matching the specified pattern were not found.",
531531
"noPublishFolderFoundToZip": "A publish folder could not be found to zip for project file: %s.",
532-
"noWebProjctFound": "No web project was found in the repository. Web projects are identified by presence of either a web.config file or wwwroot folder in the directory.",
532+
"noWebProjectFound": "No web project was found in the repository. Web projects are identified by presence of either a web.config file, wwwroot folder in the directory, or by the usage of Microsoft.Net.Web.Sdk in your project file. You can set Publish Web Projects property to false (publishWebProjects: false in yml) if your project doesn't follow this convention or if you want to publish projects other than web projects.",
533533
"zipFailed": "Zip failed with error: %s",
534534
"Error_ApiKeyNotSupported": "DotNetCore currently does not support using an encrypted Api Key.",
535535
"Error_ExpectedConfigurationElement": "Invalid xml. Expected element named 'configuration'.",

Tasks/DotNetCoreCLIV2/task.loc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"version": {
1919
"Major": 2,
2020
"Minor": 153,
21-
"Patch": 2
21+
"Patch": 3
2222
},
2323
"minimumAgentVersion": "2.115.0",
2424
"instanceNameFormat": "ms-resource:loc.instanceNameFormat",

0 commit comments

Comments
 (0)