Skip to content

Commit

Permalink
Porting to M153: Searching for csproj, vbproj, fsproj using sdk Micro…
Browse files Browse the repository at this point in the history
…soft.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
  • Loading branch information
issacnitinmsft authored Jul 9, 2019
1 parent b39501b commit 3198d03
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
"loc.messages.dotnetCommandFailed": "Dotnet command failed with non-zero exit code on the following projects : %s",
"loc.messages.noProjectFilesFound": "Project file(s) matching the specified pattern were not found.",
"loc.messages.noPublishFolderFoundToZip": "A publish folder could not be found to zip for project file: %s.",
"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.",
"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.",
"loc.messages.zipFailed": "Zip failed with error: %s",
"loc.messages.Error_ApiKeyNotSupported": "DotNetCore currently does not support using an encrypted Api Key.",
"loc.messages.Error_ExpectedConfigurationElement": "Invalid xml. Expected element named 'configuration'.",
Expand Down
14 changes: 14 additions & 0 deletions Tasks/DotNetCoreCLIV2/Tests/L0.ts
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,20 @@ describe('DotNetCoreExe Suite', function () {
done();
});


it('publish works with publishWebProjects option if .csproj have Microsoft.Net.Sdk.Web', (done: MochaDone) => {
process.env["__projects__"] = "validateWebProject.csproj";
process.env["workingDirectory"] = ".";
process.env["__publishWebProject__"] = "true";
let tp = path.join(__dirname, 'validateWebProject.js');
let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);
tr.run();

assert(tr.invokedToolCount == 1, 'should have invoked been invoked once');
assert(tr.succeeded, 'task should have succeeded');
done();
})

it('publish updates the output with the project name appended', (done: MochaDone) => {
process.env["__projects__"] = "*customoutput/project.json";
process.env["__publishWebProjects__"] = "false";
Expand Down
17 changes: 17 additions & 0 deletions Tasks/DotNetCoreCLIV2/Tests/validateWebProject.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Compile Include="Controllers/ValuesController.fs" />
<Compile Include="Startup.fs" />
<Compile Include="Program.fs" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

</Project>
42 changes: 42 additions & 0 deletions Tasks/DotNetCoreCLIV2/Tests/validateWebProject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import ma = require('azure-pipelines-task-lib/mock-answer');
import tmrm = require('azure-pipelines-task-lib/mock-run');
import path = require('path');

let taskPath = path.join(__dirname, '..', 'dotnetcore.js');
let tmr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath);

tmr.setInput('command', "publish");
tmr.setInput('projects', process.env["__projects__"]);
tmr.setInput('publishWebProjects', process.env["__publishWebProjects__"] && process.env["__publishWebProjects__"] == "true" ? "true" : "false");
tmr.setInput('arguments', process.env["__arguments__"] ? process.env["__arguments__"] : "");
tmr.setInput('modifyOutputPath', process.env["modifyOutput"] == "false" ? "false" : "true");
tmr.setInput('zipAfterPublish', process.env["zipAfterPublish"] ? process.env["zipAfterPublish"] : "false");
tmr.setInput('workingDirectory', process.env["workingDirectory"] ? process.env["workingDirectory"] : "");

process.env['TASK_TEST_TRACE'] = "true";

var projectFile = path.join(__dirname, process.env["__projects__"]);
var execCommand = "dotnet publish " + projectFile

let a: ma.TaskLibAnswers = <ma.TaskLibAnswers>{
"which": {
"dotnet": "dotnet",
},
"checkPath": { "dotnet": true },
"exec": {},
"findMatch": {
"**/*.csproj\n**/*.vbproj\n**/*.fsproj": [projectFile]
}
}

a['exec'][execCommand] = {
"code": 0,
"stdout": "published",
"stderr": ""
}

process.env["MOCK_NORMALIZE_SLASHES"] = "true";
tmr.setAnswers(a)
tmr.registerMock('azure-pipelines-task-lib/toolrunner', require('azure-pipelines-task-lib/mock-toolrunner'));

tmr.run();
39 changes: 34 additions & 5 deletions Tasks/DotNetCoreCLIV2/dotnetcore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import tl = require("azure-pipelines-task-lib/task");
import tr = require("azure-pipelines-task-lib/toolrunner");
import path = require("path");
import fs = require("fs");
import ltx = require("ltx");
var archiver = require('archiver');

import * as packCommand from './packcommand';
Expand Down Expand Up @@ -325,22 +326,50 @@ export class dotNetExe {
}

var projectFiles = utility.getProjectFiles(projectPattern);
var resolvedProjectFiles: string[] = [];

if (searchWebProjects) {
projectFiles = projectFiles.filter(function (file, index, files): boolean {
resolvedProjectFiles = projectFiles.filter(function (file, index, files): boolean {
var directory = path.dirname(file);
return tl.exist(path.join(directory, "web.config"))
|| tl.exist(path.join(directory, "wwwroot"));
});

if (!projectFiles.length) {
tl.error(tl.loc("noWebProjctFound"));
}
if (!resolvedProjectFiles.length) {
var projectFilesUsingWebSdk = projectFiles.filter(this.isWebSdkUsed);
if(!projectFilesUsingWebSdk.length) {
tl.error(tl.loc("noWebProjectFound"));
}
return projectFilesUsingWebSdk;
}
return resolvedProjectFiles;
}

return projectFiles;
}

private isWebSdkUsed(projectfile: string): boolean {
if (projectfile.endsWith('.vbproj')) return false

try {
var fileBuffer: Buffer = fs.readFileSync(projectfile);
var webConfigContent: string;

var fileEncodings = ['utf8', 'utf16le'];

for(var i = 0; i < fileEncodings.length; i++) {
tl.debug("Trying to decode with " + fileEncodings[i]);
webConfigContent = fileBuffer.toString(fileEncodings[i]);
try {
var projectSdkUsed: string = ltx.parse(webConfigContent).getAttr("sdk") || ltx.parse(webConfigContent).getAttr("Sdk");
return projectSdkUsed && projectSdkUsed.toLowerCase() == "microsoft.net.sdk.web";
} catch (error) {}
}
} catch(error) {
tl.warning(error);
}
return false;
}

private isPublishCommand(): boolean {
return this.command === "publish";
}
Expand Down
113 changes: 43 additions & 70 deletions Tasks/DotNetCoreCLIV2/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Tasks/DotNetCoreCLIV2/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"version": {
"Major": 2,
"Minor": 153,
"Patch": 2
"Patch": 3
},
"minimumAgentVersion": "2.115.0",
"instanceNameFormat": "dotnet $(command)",
Expand Down Expand Up @@ -529,7 +529,7 @@
"dotnetCommandFailed": "Dotnet command failed with non-zero exit code on the following projects : %s",
"noProjectFilesFound": "Project file(s) matching the specified pattern were not found.",
"noPublishFolderFoundToZip": "A publish folder could not be found to zip for project file: %s.",
"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.",
"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.",
"zipFailed": "Zip failed with error: %s",
"Error_ApiKeyNotSupported": "DotNetCore currently does not support using an encrypted Api Key.",
"Error_ExpectedConfigurationElement": "Invalid xml. Expected element named 'configuration'.",
Expand Down
2 changes: 1 addition & 1 deletion Tasks/DotNetCoreCLIV2/task.loc.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"version": {
"Major": 2,
"Minor": 153,
"Patch": 2
"Patch": 3
},
"minimumAgentVersion": "2.115.0",
"instanceNameFormat": "ms-resource:loc.instanceNameFormat",
Expand Down

0 comments on commit 3198d03

Please sign in to comment.