Suports discovery of static web assets from referenced projects (dotnet/aspnetcore-tooling#605)
* Define static web assets in the current project
* These are assets under the wwwroot folder.
* By convention, the base path for these assets is `_content/<<PackageId>>`
with spaces and dots removed and all characters lower-cased.
* Retrieve static web assets from referenced projects\n\nCommit migrated from 50646aae64
This commit is contained in:
parent
66dd6b35d3
commit
68f5fec0b0
|
|
@ -0,0 +1,40 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using Microsoft.Build.Framework;
|
||||||
|
using Microsoft.Build.Utilities;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Razor.Tasks
|
||||||
|
{
|
||||||
|
public class GetDefaultStaticWebAssetsBasePath : Task
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
public string BasePath { get; set; }
|
||||||
|
|
||||||
|
[Output]
|
||||||
|
public string SafeBasePath { get; set; }
|
||||||
|
|
||||||
|
public override bool Execute()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(BasePath))
|
||||||
|
{
|
||||||
|
Log.LogError($"Base path '{BasePath ?? "(null)"}' must contain non-whitespace characters.");
|
||||||
|
return !Log.HasLoggedErrors;
|
||||||
|
}
|
||||||
|
|
||||||
|
var safeBasePath = BasePath
|
||||||
|
.Replace(" ", "")
|
||||||
|
.Replace(".", "")
|
||||||
|
.ToLowerInvariant();
|
||||||
|
|
||||||
|
if (safeBasePath == "")
|
||||||
|
{
|
||||||
|
Log.LogError($"Base path '{BasePath}' must contain non '.' characters.");
|
||||||
|
return !Log.HasLoggedErrors;
|
||||||
|
}
|
||||||
|
SafeBasePath = safeBasePath;
|
||||||
|
|
||||||
|
return !Log.HasLoggedErrors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -27,17 +27,33 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
AssemblyFile="$(RazorSdkBuildTasksAssembly)"
|
AssemblyFile="$(RazorSdkBuildTasksAssembly)"
|
||||||
Condition="'$(RazorSdkBuildTasksAssembly)' != ''" />
|
Condition="'$(RazorSdkBuildTasksAssembly)' != ''" />
|
||||||
|
|
||||||
|
<UsingTask
|
||||||
|
TaskName="Microsoft.AspNetCore.Razor.Tasks.GetDefaultStaticWebAssetsBasePath"
|
||||||
|
AssemblyFile="$(RazorSdkBuildTasksAssembly)"
|
||||||
|
Condition="'$(RazorSdkBuildTasksAssembly)' != ''" />
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<GenerateStaticWebAssetsManifestDependsOn>
|
<GenerateStaticWebAssetsManifestDependsOn>
|
||||||
ResolveStaticWebAssetsInputs;
|
ResolveStaticWebAssetsInputs;
|
||||||
_CreateStaticWebAssetsInputsCacheFile
|
_CreateStaticWebAssetsInputsCacheFile;
|
||||||
|
$(GenerateStaticWebAssetsManifestDependsOn)
|
||||||
</GenerateStaticWebAssetsManifestDependsOn>
|
</GenerateStaticWebAssetsManifestDependsOn>
|
||||||
|
|
||||||
|
<GetCurrentProjectStaticWebAssetsDependsOn>
|
||||||
|
ResolveStaticWebAssetsInputs;
|
||||||
|
$(GetCurrentProjectStaticWebAssetsDependsOn)
|
||||||
|
</GetCurrentProjectStaticWebAssetsDependsOn>
|
||||||
|
|
||||||
<AssignTargetPathsDependsOn>
|
<AssignTargetPathsDependsOn>
|
||||||
GenerateStaticWebAssetsManifest;
|
GenerateStaticWebAssetsManifest;
|
||||||
$(AssignTargetPathsDependsOn)
|
$(AssignTargetPathsDependsOn)
|
||||||
</AssignTargetPathsDependsOn>
|
</AssignTargetPathsDependsOn>
|
||||||
|
|
||||||
|
<ResolveStaticWebAssetsInputsDependsOn>
|
||||||
|
_ResolveStaticWebAssetsProjectReferences;
|
||||||
|
$(ResolveStaticWebAssetsInputsDependsOn)
|
||||||
|
</ResolveStaticWebAssetsInputsDependsOn>
|
||||||
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|
@ -119,34 +135,45 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
restores the package and includes the package props file for the package.
|
restores the package and includes the package props file for the package.
|
||||||
-->
|
-->
|
||||||
<Target
|
<Target
|
||||||
Name="ResolveStaticWebAssetsInputs">
|
Name="ResolveStaticWebAssetsInputs"
|
||||||
<PropertyGroup>
|
DependsOnTargets="$(ResolveStaticWebAssetsInputsDependsOn)">
|
||||||
<!-- The _SafeBasePath is used as a path segment in the urls that we will
|
|
||||||
be exposing content from when the library is referenced as a package
|
|
||||||
or as a project by a web application. Our convention will be to expose
|
|
||||||
content directly on _content/<<_SafeBasePath>>
|
|
||||||
|
|
||||||
We simply remove the dots from the package id so that a package
|
|
||||||
like Microsoft.AspNetCore.Identity becomes MicrosoftAspNetCoreIdentity
|
|
||||||
|
|
||||||
TODO: Investigate if we need to do something more sophisticated here.
|
|
||||||
-->
|
|
||||||
<_SafeBasePath>$(PackageId.Replace('.',''))</_SafeBasePath>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<!-- StaticWebAssets from the current project -->
|
<!-- StaticWebAssets from the current project -->
|
||||||
|
|
||||||
|
<!-- Computes a default safe base path from the $(PackageId) that will be a prefix
|
||||||
|
to all the resources being exported from this library by default. The convention
|
||||||
|
consists of removing intermediate whitespaces, dots and lower casing all letters
|
||||||
|
in the package id using an invariant culture.
|
||||||
|
|
||||||
|
We don't aim to handle all possible cases for this prefix, as it can get really
|
||||||
|
complicated (non-unicode characters for example), so for that case,
|
||||||
|
StaticWebAssetBasePath can be set explicitly and we won't interfere.
|
||||||
|
-->
|
||||||
|
<GetDefaultStaticWebAssetsBasePath
|
||||||
|
BasePath="$(PackageId)"
|
||||||
|
Condition="'$(StaticWebAssetBasePath)' == ''">
|
||||||
|
<Output TaskParameter="SafeBasePath" PropertyName="_StaticWebAssetSafeBasePath" />
|
||||||
|
</GetDefaultStaticWebAssetsBasePath>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<StaticWebAssetBasePath Condition="$(StaticWebAssetBasePath) == ''">_content/$(_StaticWebAssetSafeBasePath)</StaticWebAssetBasePath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
||||||
|
<_ThisProjectStaticWebAsset
|
||||||
|
Include="$(MSBuildProjectDirectory)\wwwroot\**"
|
||||||
|
Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
|
||||||
<!--
|
<!--
|
||||||
Should we promote 'wwwroot\**'' to a property?
|
Should we promote 'wwwroot\**'' to a property?
|
||||||
We don't want to capture any content outside the content root, that's why we don't do
|
We don't want to capture any content outside the content root, that's why we don't do
|
||||||
@(Content) here.
|
@(Content) here.
|
||||||
-->
|
-->
|
||||||
<StaticWebAsset Include="wwwroot\**" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)">
|
<StaticWebAsset Include="@(_ThisProjectStaticWebAsset)">
|
||||||
<!-- (PackageReference,ProjectReference,'' (CurrentProject)) -->
|
<!-- (Package, Project, '' (CurrentProject)) -->
|
||||||
<SourceType></SourceType>
|
<SourceType></SourceType>
|
||||||
<!-- Identifier describing the source, the package id, the project name, empty for the current project. -->
|
<!-- Identifier describing the source, the package id, the project name, empty for the current project. -->
|
||||||
<SourceId></SourceId>
|
<SourceId>$(PackageId)</SourceId>
|
||||||
<!--
|
<!--
|
||||||
Full path to the content root for the item:
|
Full path to the content root for the item:
|
||||||
* For packages it corresponds to %userprofile%/.nuget/packages/<<PackageId>>/<<PackageVersion>>/razorContent
|
* For packages it corresponds to %userprofile%/.nuget/packages/<<PackageId>>/<<PackageVersion>>/razorContent
|
||||||
|
|
@ -155,7 +182,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
-->
|
-->
|
||||||
<ContentRoot>$(MSBuildProjectDirectory)\wwwroot\</ContentRoot>
|
<ContentRoot>$(MSBuildProjectDirectory)\wwwroot\</ContentRoot>
|
||||||
<!-- Subsection (folder) from the url space where content for this library will be served. -->
|
<!-- Subsection (folder) from the url space where content for this library will be served. -->
|
||||||
<BasePath>_content\$(_SafeBasePath)\</BasePath>
|
<BasePath>$(StaticWebAssetBasePath)</BasePath>
|
||||||
<!-- Relative path from the content root for the file. At publish time, we combine the BasePath + Relative
|
<!-- Relative path from the content root for the file. At publish time, we combine the BasePath + Relative
|
||||||
path to determine the final path for the file. -->
|
path to determine the final path for the file. -->
|
||||||
<RelativePath>%(RecursiveDir)%(FileName)%(Extension)</RelativePath>
|
<RelativePath>%(RecursiveDir)%(FileName)%(Extension)</RelativePath>
|
||||||
|
|
@ -164,9 +191,57 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<!-- StaticWebAssets from referenced projects. -->
|
<!-- StaticWebAssets from referenced projects. -->
|
||||||
<!-- TODO: Include implementation -->
|
|
||||||
|
<MSBuild
|
||||||
|
Condition="'@(_StaticWebAssetsProjectReference->Count())' != '0'"
|
||||||
|
Projects="@(_StaticWebAssetsProjectReference)"
|
||||||
|
BuildInParallel="$(BuildInParallel)"
|
||||||
|
ContinueOnError="!$(BuildingProject)"
|
||||||
|
Targets="GetCurrentProjectStaticWebAssets"
|
||||||
|
Properties="_StaticWebAssetsSkipDependencies=true"
|
||||||
|
SkipNonexistentTargets="true">
|
||||||
|
<Output TaskParameter="TargetOutputs" ItemName="_ReferencedProjectStaticWebAssets" />
|
||||||
|
</MSBuild>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<StaticWebAsset Include="@(_ReferencedProjectStaticWebAssets)" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<!-- StaticWebAssets from packages are already available, so we don't do anything. -->
|
<!-- StaticWebAssets from packages are already available, so we don't do anything. -->
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
|
<!-- This is a helper task to compute the project references we need to invoke to retrieve
|
||||||
|
the static assets for a given application. We do it this way so that we can
|
||||||
|
pass additional build properties to compute the assets from the package when referenced
|
||||||
|
as a project. For example, Identity uses this hook to extend the project reference and
|
||||||
|
pass in the bootstrap version to use.
|
||||||
|
-->
|
||||||
|
<Target Name="_ResolveStaticWebAssetsProjectReferences"
|
||||||
|
DependsOnTargets="ResolveReferences"
|
||||||
|
Condition="'$(_StaticWebAssetsSkipDependencies)' == ''">
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<_StaticWebAssetsProjectReference Include="%(ReferencePath.MSBuildSourceProjectFile)" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Child target to retrieve content from referenced projects
|
||||||
|
-->
|
||||||
|
|
||||||
|
<Target Name="GetCurrentProjectStaticWebAssets"
|
||||||
|
DependsOnTargets="$(GetCurrentProjectStaticWebAssetsDependsOn)"
|
||||||
|
Returns="@(_ThisProjectStaticWebAssets)">
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<_ThisProjectStaticWebAssets
|
||||||
|
Include="@(StaticWebAsset)"
|
||||||
|
Condition="'%(StaticWebAsset.SourceType)' == ''">
|
||||||
|
<SourceType>Project</SourceType>
|
||||||
|
</_ThisProjectStaticWebAssets>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Target>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Build.Framework;
|
||||||
|
using Moq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Razor.Tasks
|
||||||
|
{
|
||||||
|
public class GetDefaultStaticWebAssetsBasePathTest
|
||||||
|
{
|
||||||
|
[Theory]
|
||||||
|
[InlineData(null)]
|
||||||
|
[InlineData("")]
|
||||||
|
[InlineData(" ")]
|
||||||
|
[InlineData(" ")]
|
||||||
|
public void ReturnsError_WhenBasePath_DoesNotContainNonWhitespaceCharacters(string basePath)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var expectedError = $"Base path '{basePath ?? "(null)"}' must contain non-whitespace characters.";
|
||||||
|
|
||||||
|
var errorMessages = new List<string>();
|
||||||
|
var buildEngine = new Mock<IBuildEngine>();
|
||||||
|
buildEngine.Setup(e => e.LogErrorEvent(It.IsAny<BuildErrorEventArgs>()))
|
||||||
|
.Callback<BuildErrorEventArgs>(args => errorMessages.Add(args.Message));
|
||||||
|
|
||||||
|
var task = new GetDefaultStaticWebAssetsBasePath
|
||||||
|
{
|
||||||
|
BuildEngine = buildEngine.Object,
|
||||||
|
BasePath = basePath
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = task.Execute();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.False(result);
|
||||||
|
var message = Assert.Single(errorMessages);
|
||||||
|
Assert.Equal(expectedError, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(".")]
|
||||||
|
[InlineData("..")]
|
||||||
|
[InlineData(". ")]
|
||||||
|
[InlineData(" .")]
|
||||||
|
[InlineData(" . ")]
|
||||||
|
[InlineData(". .")]
|
||||||
|
public void ReturnsError_WhenSafeBasePath_MapsToTheEmptyString(string basePath)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var expectedError = $"Base path '{basePath}' must contain non '.' characters.";
|
||||||
|
|
||||||
|
var errorMessages = new List<string>();
|
||||||
|
var buildEngine = new Mock<IBuildEngine>();
|
||||||
|
buildEngine.Setup(e => e.LogErrorEvent(It.IsAny<BuildErrorEventArgs>()))
|
||||||
|
.Callback<BuildErrorEventArgs>(args => errorMessages.Add(args.Message));
|
||||||
|
|
||||||
|
var task = new GetDefaultStaticWebAssetsBasePath
|
||||||
|
{
|
||||||
|
BuildEngine = buildEngine.Object,
|
||||||
|
BasePath = basePath
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = task.Execute();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.False(result);
|
||||||
|
var message = Assert.Single(errorMessages);
|
||||||
|
Assert.Equal(expectedError, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("Identity", "identity")]
|
||||||
|
[InlineData("Microsoft.AspNetCore.Identity", "microsoftaspnetcoreidentity")]
|
||||||
|
public void ReturnsSafeBasePath_WhenBasePath_ContainsUnsafeCharacters(string basePath, string expectedSafeBasePath)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var task = new GetDefaultStaticWebAssetsBasePath
|
||||||
|
{
|
||||||
|
BuildEngine = Mock.Of<IBuildEngine>(),
|
||||||
|
BasePath = basePath
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = task.Execute();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.True(result);
|
||||||
|
Assert.Equal(expectedSafeBasePath, task.SafeBasePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,7 @@ using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Extensions.CommandLineUtils;
|
using Microsoft.Extensions.CommandLineUtils;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -32,7 +33,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
public ITestOutputHelper Output { get; private set; }
|
public ITestOutputHelper Output { get; private set; }
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[InitializeTestProject("AppWithPackageAndP2PReference")]
|
[InitializeTestProject("AppWithPackageAndP2PReference",language: "C#", additionalProjects: new[] { "ClassLibrary", "ClassLibrary2" })]
|
||||||
public async Task Build_GeneratesStaticWebAssetsManifest_Success_CreatesManifest()
|
public async Task Build_GeneratesStaticWebAssetsManifest_Success_CreatesManifest()
|
||||||
{
|
{
|
||||||
var result = await DotnetMSBuild("Build", "/restore");
|
var result = await DotnetMSBuild("Build", "/restore");
|
||||||
|
|
@ -71,7 +72,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[InitializeTestProject("AppWithPackageAndP2PReference")]
|
[InitializeTestProject("AppWithPackageAndP2PReference",language: "C#", additionalProjects: new[] { "ClassLibrary", "ClassLibrary2" })]
|
||||||
public async Task Clean_Success_RemovesManifestAndCache()
|
public async Task Clean_Success_RemovesManifestAndCache()
|
||||||
{
|
{
|
||||||
var result = await DotnetMSBuild("Build", "/restore");
|
var result = await DotnetMSBuild("Build", "/restore");
|
||||||
|
|
@ -92,7 +93,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[InitializeTestProject("AppWithPackageAndP2PReference")]
|
[InitializeTestProject("AppWithPackageAndP2PReference",language: "C#", additionalProjects: new[] { "ClassLibrary", "ClassLibrary2" })]
|
||||||
public async Task Rebuild_Success_RecreatesManifestAndCache()
|
public async Task Rebuild_Success_RecreatesManifestAndCache()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
|
|
@ -142,7 +143,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[InitializeTestProject("AppWithPackageAndP2PReference")]
|
[InitializeTestProject("AppWithPackageAndP2PReference",language: "C#", additionalProjects: new[] { "ClassLibrary", "ClassLibrary2" })]
|
||||||
public async Task GenerateStaticWebAssetsManifest_IncrementalBuild_ReusesManifest()
|
public async Task GenerateStaticWebAssetsManifest_IncrementalBuild_ReusesManifest()
|
||||||
{
|
{
|
||||||
var result = await DotnetMSBuild("GenerateStaticWebAssetsManifest", "/restore");
|
var result = await DotnetMSBuild("GenerateStaticWebAssetsManifest", "/restore");
|
||||||
|
|
@ -192,16 +193,25 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
|
|
||||||
private string GetExpectedManifest()
|
private string GetExpectedManifest()
|
||||||
{
|
{
|
||||||
|
// We need to do this for Mac as apparently the temp folder in mac is prepended by /private by the os, even though the current user
|
||||||
|
// can refer to it without the /private prefix. We don't care a lot about the specific path in this test as we will have tests that
|
||||||
|
// validate the behavior at runtime.
|
||||||
|
var source = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? $"/private{Project.SolutionPath}" : Project.SolutionPath;
|
||||||
|
|
||||||
var restorePath = LocalNugetPackagesCacheTempPath;
|
var restorePath = LocalNugetPackagesCacheTempPath;
|
||||||
var projects = new[]
|
var projects = new[]
|
||||||
{
|
{
|
||||||
Path.Combine(restorePath, "packagelibrarytransitivedependency", "1.0.0", "buildTransitive", "..", "razorContent") + Path.DirectorySeparatorChar,
|
Path.Combine(restorePath, "packagelibrarytransitivedependency", "1.0.0", "buildTransitive", "..", "razorContent") + Path.DirectorySeparatorChar,
|
||||||
Path.Combine(restorePath, "packagelibrarydirectdependency", "1.0.0", "build", "..", "razorContent") + Path.DirectorySeparatorChar
|
Path.Combine(restorePath, "packagelibrarydirectdependency", "1.0.0", "build", "..", "razorContent") + Path.DirectorySeparatorChar,
|
||||||
|
Path.GetFullPath(Path.Combine(source, "ClassLibrary", "wwwroot")) + Path.DirectorySeparatorChar,
|
||||||
|
Path.GetFullPath(Path.Combine(source, "ClassLibrary2", "wwwroot")) + Path.DirectorySeparatorChar
|
||||||
};
|
};
|
||||||
|
|
||||||
return $@"<StaticWebAssets Version=""1.0"">
|
return $@"<StaticWebAssets Version=""1.0"">
|
||||||
<ContentRoot BasePath=""_content/PackageLibraryTransitiveDependency"" Path=""{projects[0]}"" />
|
<ContentRoot BasePath=""_content/PackageLibraryTransitiveDependency"" Path=""{projects[0]}"" />
|
||||||
<ContentRoot BasePath=""_content/PackageLibraryDirectDependency"" Path=""{projects[1]}"" />
|
<ContentRoot BasePath=""_content/PackageLibraryDirectDependency"" Path=""{projects[1]}"" />
|
||||||
|
<ContentRoot BasePath=""_content/classlibrary"" Path=""{projects[2]}"" />
|
||||||
|
<ContentRoot BasePath=""_content/classlibrary2"" Path=""{projects[3]}"" />
|
||||||
</StaticWebAssets>";
|
</StaticWebAssets>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@
|
||||||
$(RestoreSources);
|
$(RestoreSources);
|
||||||
$(RuntimeAdditionalRestoreSources)
|
$(RuntimeAdditionalRestoreSources)
|
||||||
</RestoreSources>
|
</RestoreSources>
|
||||||
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
@ -30,7 +29,11 @@
|
||||||
<PackageReference Include="PackageLibraryDirectDependency" Version="1.0.0" />
|
<PackageReference Include="PackageLibraryDirectDependency" Version="1.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(BinariesRoot)'==''">
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\ClassLibrary2\ClassLibrary2.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(BinariesRoot)'==''">
|
||||||
<!-- In test scenarios $(BinariesRoot) is defined in a generated Directory.Build.props file -->
|
<!-- In test scenarios $(BinariesRoot) is defined in a generated Directory.Build.props file -->
|
||||||
<BinariesRoot>$(RepositoryRoot)artifacts\bin\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib\$(Configuration)\netstandard2.0\</BinariesRoot>
|
<BinariesRoot>$(RepositoryRoot)artifacts\bin\Microsoft.AspNetCore.Razor.Test.MvcShim.ClassLib\$(Configuration)\netstandard2.0\</BinariesRoot>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
(function () {
|
||||||
|
document.getElementById('project-transitive-dep').innerHTML = 'project-transitive-dep';
|
||||||
|
})()
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
div.fluent { display: inline-block }
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
(function () {
|
||||||
|
document.getElementById('project-direct-dep').innerHTML = 'project-direct-dep';
|
||||||
|
})()
|
||||||
Loading…
Reference in New Issue