Skip to content

Commit

Permalink
Fixed ASP.NET Core 'web project' probing logic to consider more scena…
Browse files Browse the repository at this point in the history
…rios (#152)
  • Loading branch information
kichalla committed May 21, 2019
1 parent b602cb6 commit 6ee490a
Show file tree
Hide file tree
Showing 5 changed files with 204 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// Licensed under the MIT license.
// --------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -145,9 +146,29 @@ public string GetProjectFile(ISourceRepo sourceRepo)
// To enable unit testing
internal static bool IsAspNetCoreWebApplicationProject(XDocument projectFileDoc)
{
var webSdkProjectElement = projectFileDoc.XPathSelectElement(
DotnetCoreConstants.WebSdkProjectXPathExpression);
return webSdkProjectElement != null;
// For reference
// https://docs.microsoft.com/en-us/visualstudio/msbuild/project-element-msbuild?view=vs-2019

// Look for the attribute value on Project element first as that is more common
// Example: <Project Sdk="Microsoft.NET.Sdk.Web/1.0.0">
var expectedWebSdkName = DotnetCoreConstants.WebSdkName.ToLowerInvariant();
var sdkAttributeValue = projectFileDoc.XPathEvaluate(
DotnetCoreConstants.ProjectSdkAttributeValueXPathExpression);
var sdkName = sdkAttributeValue as string;
if (!string.IsNullOrEmpty(sdkName) &&
sdkName.StartsWith(expectedWebSdkName, StringComparison.OrdinalIgnoreCase))
{
return true;
}

// Example:
// <Project>
// <Sdk Name="Microsoft.NET.Sdk.Web" Version="1.0.0" />
var sdkNameAttributeValue = projectFileDoc.XPathEvaluate(
DotnetCoreConstants.ProjectSdkElementNameAttributeValueXPathExpression);
sdkName = sdkNameAttributeValue as string;

return string.Equals(sdkName, expectedWebSdkName, StringComparison.OrdinalIgnoreCase);
}

private static IEnumerable<string> GetAllProjectFilesInRepo(
Expand All @@ -167,11 +188,11 @@ private static string GetProjectFileAtRoot(ISourceRepo sourceRepo, string projec
private static bool IsAspNetCore30App(XDocument projectFileDoc)
{
var targetFrameworkElement = projectFileDoc.XPathSelectElement(
DotnetCoreConstants.TargetFrameworkXPathExpression);
DotnetCoreConstants.TargetFrameworkElementXPathExpression);
if (string.Equals(targetFrameworkElement.Value, DotnetCoreConstants.NetCoreApp30))
{
var projectElement = projectFileDoc.XPathSelectElement(
DotnetCoreConstants.WebSdkProjectXPathExpression);
DotnetCoreConstants.ProjectSdkAttributeValueXPathExpression);
return projectElement != null;
}

Expand Down
8 changes: 4 additions & 4 deletions src/BuildScriptGenerator/DotNetCore/DotnetCoreConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ public static class DotnetCoreConstants

public const string ProjectFileLanguageDetectorProperty = "ProjectFile";

public const string WebSdkProjectXPathExpression = "/Project[@Sdk='Microsoft.NET.Sdk.Web']";
public const string ProjectReferenceXPathExpression = "/Project/ItemGroup/PackageReference";
public const string AssemblyNameXPathExpression = "/Project/PropertyGroup/AssemblyName";
public const string TargetFrameworkXPathExpression = "/Project/PropertyGroup/TargetFramework";
public const string WebSdkName = "Microsoft.NET.Sdk.Web";
public const string ProjectSdkAttributeValueXPathExpression = "string(/Project/@Sdk)";
public const string ProjectSdkElementNameAttributeValueXPathExpression = "string(/Project/Sdk/@Name)";
public const string TargetFrameworkElementXPathExpression = "/Project/PropertyGroup/TargetFramework";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public LanguageDetectorResult Detect(ISourceRepo sourceRepo)

var projectFileDoc = XDocument.Load(new StringReader(sourceRepo.ReadFile(projectFile)));
var targetFrameworkElement = projectFileDoc.XPathSelectElement(
DotnetCoreConstants.TargetFrameworkXPathExpression);
DotnetCoreConstants.TargetFrameworkElementXPathExpression);
var targetFramework = targetFrameworkElement?.Value;
if (string.IsNullOrEmpty(targetFramework))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,75 @@ public class DefaultAspNetCoreWebAppProjectFileProviderTest : IClassFixture<Test
</ItemGroup>
</Project>";

private const string WebSdkProjectFileWithVersion = @"
<Project Sdk=""Microsoft.NET.Sdk.Web/1.0.0"">
<PropertyGroup>
<LangVersion>7.3</LangVersion>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include=""Microsoft.AspNetCore"" Version=""2.1.0"" />
</ItemGroup>
</Project>";

private const string NonWebSdkProjectFileWithVersion = @"
<Project Sdk=""Microsoft.NET.Sdk/1.0.0"">
<PropertyGroup>
<LangVersion>7.3</LangVersion>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include=""Microsoft.AspNetCore"" Version=""2.1.0"" />
</ItemGroup>
</Project>";

private const string WebSdkProjectFileWithSdkInfoAsElement = @"
<Project>
<Sdk Name=""Microsoft.NET.Sdk.Web"" Version=""1.0.0"" />
<PropertyGroup>
<LangVersion>7.3</LangVersion>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include=""Microsoft.AspNetCore"" Version=""2.1.0"" />
</ItemGroup>
</Project>";

private const string NonWebSdkProjectFileWithSdkInfoAsElement = @"
<Project>
<Sdk Name=""Microsoft.NET.Sdk"" Version=""1.0.0"" />
<PropertyGroup>
<LangVersion>7.3</LangVersion>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include=""Microsoft.AspNetCore"" Version=""2.1.0"" />
</ItemGroup>
</Project>";

private const string NoSdkInformationProjectFile = @"
<Project>
<PropertyGroup>
<LangVersion>7.3</LangVersion>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include=""Microsoft.AspNetCore"" Version=""2.1.0"" />
</ItemGroup>
</Project>";

private const string WebSdkProjectFileWithMultipleSdkInfoAsElement = @"
<Project Sdk=""Microsoft.NET.Sdk/1.0.0"">
<Sdk Name=""Microsoft.NET.Sdk.Web"" Version=""1.0.0"" />
<PropertyGroup>
<LangVersion>7.3</LangVersion>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include=""Microsoft.AspNetCore"" Version=""2.1.0"" />
</ItemGroup>
</Project>";

private readonly string _tempDirRoot;

public DefaultAspNetCoreWebAppProjectFileProviderTest(TestTempDirTestFixture testFixture)
Expand Down Expand Up @@ -106,6 +175,108 @@ public void GetProjectFile_ReturnsProjectFile_PresentAtRoot_IfPresent(string pro
Assert.Equal(expectedFile, actual);
}

[Fact]
public void GetProjectFile_ReturnsProjectFile_IfSdkHasBothNameAndVersion()
{
// Arrange
var sourceRepoDir = CreateSourceRepoDir();
var expectedFile = Path.Combine(sourceRepoDir, "WebApp1.csproj");
File.WriteAllText(expectedFile, WebSdkProjectFileWithVersion);
var sourceRepo = CreateSourceRepo(sourceRepoDir);
var provider = CreateProjectFileProvider();

// Act
var actual = provider.GetProjectFile(sourceRepo);

// Assert
Assert.Equal(expectedFile, actual);
}

[Fact]
public void GetProjectFile_ReturnsNull_IfSdkHasBothNameAndVersion_AndIsNotWebSdk()
{
// Arrange
var sourceRepoDir = CreateSourceRepoDir();
var expectedFile = Path.Combine(sourceRepoDir, "WebApp1.csproj");
File.WriteAllText(expectedFile, NonWebSdkProjectFileWithVersion);
var sourceRepo = CreateSourceRepo(sourceRepoDir);
var provider = CreateProjectFileProvider();

// Act
var actual = provider.GetProjectFile(sourceRepo);

// Assert
Assert.Null(actual);
}

[Fact]
public void GetProjectFile_ReturnsProjectFile_IfSdkIsPresentAsElement()
{
// Arrange
var sourceRepoDir = CreateSourceRepoDir();
var expectedFile = Path.Combine(sourceRepoDir, "WebApp1.csproj");
File.WriteAllText(expectedFile, WebSdkProjectFileWithSdkInfoAsElement);
var sourceRepo = CreateSourceRepo(sourceRepoDir);
var provider = CreateProjectFileProvider();

// Act
var actual = provider.GetProjectFile(sourceRepo);

// Assert
Assert.Equal(expectedFile, actual);
}

[Fact]
public void GetProjectFile_ReturnsNull_IfSdkIsPresentAsElement_AndIsNotWebSdk()
{
// Arrange
var sourceRepoDir = CreateSourceRepoDir();
var expectedFile = Path.Combine(sourceRepoDir, "WebApp1.csproj");
File.WriteAllText(expectedFile, NonWebSdkProjectFileWithSdkInfoAsElement);
var sourceRepo = CreateSourceRepo(sourceRepoDir);
var provider = CreateProjectFileProvider();

// Act
var actual = provider.GetProjectFile(sourceRepo);

// Assert
Assert.Null(actual);
}

[Fact]
public void GetProjectFile_ReturnsNull_WhenNoInformationAboutSdkIsPresentInProjectFile()
{
// Arrange
var sourceRepoDir = CreateSourceRepoDir();
var expectedFile = Path.Combine(sourceRepoDir, "WebApp1.csproj");
File.WriteAllText(expectedFile, NoSdkInformationProjectFile);
var sourceRepo = CreateSourceRepo(sourceRepoDir);
var provider = CreateProjectFileProvider();

// Act
var actual = provider.GetProjectFile(sourceRepo);

// Assert
Assert.Null(actual);
}

[Fact]
public void GetProjectFile_ReturnsProjectFile_IfMultiplePlacesHaveSdkInfo()
{
// Arrange
var sourceRepoDir = CreateSourceRepoDir();
var expectedFile = Path.Combine(sourceRepoDir, "WebApp1.csproj");
File.WriteAllText(expectedFile, WebSdkProjectFileWithMultipleSdkInfoAsElement);
var sourceRepo = CreateSourceRepo(sourceRepoDir);
var provider = CreateProjectFileProvider();

// Act
var actual = provider.GetProjectFile(sourceRepo);

// Assert
Assert.Equal(expectedFile, actual);
}

[Theory]
[InlineData(DotnetCoreConstants.CSharpProjectFileExtension)]
[InlineData(DotnetCoreConstants.FSharpProjectFileExtension)]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<Project Sdk="Microsoft.NET.Sdk">
<Sdk Name="Microsoft.NET.Sdk.Web" Version="1.0.0" />
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
Expand Down

0 comments on commit 6ee490a

Please sign in to comment.