Adds support for packing and publishing static web assets
* Adds support for publishing static web assets
* At publish time, it copies all the referenced assets from referenced
projects and packages into their final locations.
* Automatically pack static web assets for consumption
* Generate Microsoft.AspNetCore.StaticWebAssets.props and pack it into
build\Microsoft.AspNetCore.StaticWebAssets.props
* Generate `<<PackageId>>.props` and pack it into `build\<<PackageId>>.props`
importing Microsoft.AspNetCore.StaticWebAssets.props
* Generate `<<PackageId>>.props` and pack it into buildMultiTargeting\`<<PackageId>>.props`
importing `build\<<PackageId>>.props`
* Generate `<<PackageId>>.props` and pack it into buildTransitive\`<<PackageId>>.props`
importing buildMultiTargeting\`<<PackageId>>.props`
* Pack all the static web assets from the current project into `staticwebassets\**`\n\nCommit migrated from 87817bed3e
This commit is contained in:
parent
33e8098b4f
commit
1c27d78420
|
|
@ -4,6 +4,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
|
@ -85,7 +86,8 @@ namespace Microsoft.AspNetCore.Razor.Tasks
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodes;
|
// Its important that we order the nodes here to produce a manifest deterministically.
|
||||||
|
return nodes.OrderBy(e=>e.Attribute(BasePath).Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private XmlWriter GetXmlWriter(XmlWriterSettings settings)
|
private XmlWriter GetXmlWriter(XmlWriterSettings settings)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,159 @@
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using Microsoft.Build.Framework;
|
||||||
|
using Microsoft.Build.Utilities;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Razor.Tasks
|
||||||
|
{
|
||||||
|
public class GenerateStaticWebAsssetsPropsFile : Task
|
||||||
|
{
|
||||||
|
private const string SourceType = "SourceType";
|
||||||
|
private const string SourceId = "SourceId";
|
||||||
|
private const string ContentRoot = "ContentRoot";
|
||||||
|
private const string BasePath = "BasePath";
|
||||||
|
private const string RelativePath = "RelativePath";
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public string TargetPropsFilePath { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public ITaskItem[] StaticWebAssets { get; set; }
|
||||||
|
|
||||||
|
public override bool Execute()
|
||||||
|
{
|
||||||
|
if (!ValidateArguments())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ExecuteCore();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ExecuteCore()
|
||||||
|
{
|
||||||
|
if (StaticWebAssets.Length == 0)
|
||||||
|
{
|
||||||
|
return !Log.HasLoggedErrors;
|
||||||
|
}
|
||||||
|
|
||||||
|
var template = StaticWebAssets[0];
|
||||||
|
|
||||||
|
var document = new XDocument(new XDeclaration("1.0", "utf-8", "yes"));
|
||||||
|
var root = new XElement(
|
||||||
|
"Project",
|
||||||
|
new XElement("ItemGroup",
|
||||||
|
new XElement("StaticWebAsset",
|
||||||
|
new XAttribute("Include", @"$(MSBuildThisFileDirectory)..\staticwebassets\**"),
|
||||||
|
new XElement(SourceType, "Package"),
|
||||||
|
new XElement(SourceId, template.GetMetadata(SourceId)),
|
||||||
|
new XElement(ContentRoot, @"$(MSBuildThisFileDirectory)..\staticwebassets\"),
|
||||||
|
new XElement(BasePath, template.GetMetadata(BasePath)),
|
||||||
|
new XElement(RelativePath, "%(RecursiveDir)%(FileName)%(Extension)"))));
|
||||||
|
|
||||||
|
document.Add(root);
|
||||||
|
|
||||||
|
var settings = new XmlWriterSettings
|
||||||
|
{
|
||||||
|
Encoding = Encoding.UTF8,
|
||||||
|
CloseOutput = true,
|
||||||
|
OmitXmlDeclaration = true,
|
||||||
|
Indent = true,
|
||||||
|
NewLineOnAttributes = false,
|
||||||
|
Async = true
|
||||||
|
};
|
||||||
|
|
||||||
|
using (var xmlWriter = GetXmlWriter(settings))
|
||||||
|
{
|
||||||
|
document.WriteTo(xmlWriter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return !Log.HasLoggedErrors;
|
||||||
|
}
|
||||||
|
|
||||||
|
private XmlWriter GetXmlWriter(XmlWriterSettings settings)
|
||||||
|
{
|
||||||
|
var fileStream = new FileStream(TargetPropsFilePath, FileMode.Create);
|
||||||
|
return XmlWriter.Create(fileStream, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ValidateArguments()
|
||||||
|
{
|
||||||
|
ITaskItem firstAsset = null;
|
||||||
|
|
||||||
|
for (var i = 0; i < StaticWebAssets.Length; i++)
|
||||||
|
{
|
||||||
|
var webAsset = StaticWebAssets[i];
|
||||||
|
if (!EnsureRequiredMetadata(webAsset, SourceId) ||
|
||||||
|
!EnsureRequiredMetadata(webAsset, SourceType, allowEmpty: true) ||
|
||||||
|
!EnsureRequiredMetadata(webAsset, ContentRoot) ||
|
||||||
|
!EnsureRequiredMetadata(webAsset, BasePath) ||
|
||||||
|
!EnsureRequiredMetadata(webAsset, RelativePath))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstAsset == null)
|
||||||
|
{
|
||||||
|
firstAsset = webAsset;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ValidateMetadataMatches(firstAsset, webAsset, SourceId) ||
|
||||||
|
!ValidateMetadataMatches(firstAsset, webAsset, SourceType) ||
|
||||||
|
!ValidateMetadataMatches(firstAsset, webAsset, ContentRoot) ||
|
||||||
|
!ValidateMetadataMatches(firstAsset, webAsset, BasePath))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ValidateMetadataMatches(ITaskItem reference, ITaskItem candidate, string metadata)
|
||||||
|
{
|
||||||
|
var referenceMetadata = reference.GetMetadata(metadata);
|
||||||
|
var candidateMetadata = candidate.GetMetadata(metadata);
|
||||||
|
if (!string.Equals(referenceMetadata, candidateMetadata, System.StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
Log.LogError($"Static web assets have different '{metadata}' metadata values '{referenceMetadata}' and '{candidateMetadata}' for '{reference.ItemSpec}' and '{candidate.ItemSpec}'.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool EnsureRequiredMetadata(ITaskItem item, string metadataName, bool allowEmpty = false)
|
||||||
|
{
|
||||||
|
var value = item.GetMetadata(metadataName);
|
||||||
|
var isInvalidValue = allowEmpty ? !HasMetadata(item, metadataName) : string.IsNullOrEmpty(value);
|
||||||
|
|
||||||
|
if (isInvalidValue)
|
||||||
|
{
|
||||||
|
Log.LogError($"Missing required metadata '{metadataName}' for '{item.ItemSpec}'.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HasMetadata(ITaskItem item, string metadataName)
|
||||||
|
{
|
||||||
|
foreach (var name in item.MetadataNames)
|
||||||
|
{
|
||||||
|
if (string.Equals(metadataName, (string)name, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using Microsoft.Build.Framework;
|
||||||
|
using Microsoft.Build.Utilities;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Razor.Tasks
|
||||||
|
{
|
||||||
|
public class StaticWebAssetsGeneratePackagePropsFile : Task
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
public string PropsFileImport { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public string BuildTargetPath { get; set; }
|
||||||
|
|
||||||
|
public override bool Execute()
|
||||||
|
{
|
||||||
|
var document = new XDocument(new XDeclaration("1.0", "utf-8", "yes"));
|
||||||
|
var root = new XElement(
|
||||||
|
"Project",
|
||||||
|
new XElement("Import",
|
||||||
|
new XAttribute("Project", PropsFileImport)));
|
||||||
|
|
||||||
|
document.Add(root);
|
||||||
|
|
||||||
|
var settings = new XmlWriterSettings
|
||||||
|
{
|
||||||
|
Encoding = Encoding.UTF8,
|
||||||
|
CloseOutput = true,
|
||||||
|
OmitXmlDeclaration = true,
|
||||||
|
Indent = true,
|
||||||
|
NewLineOnAttributes = false,
|
||||||
|
Async = true
|
||||||
|
};
|
||||||
|
|
||||||
|
using (var xmlWriter = GetXmlWriter(settings))
|
||||||
|
{
|
||||||
|
document.WriteTo(xmlWriter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return !Log.HasLoggedErrors;
|
||||||
|
}
|
||||||
|
|
||||||
|
private XmlWriter GetXmlWriter(XmlWriterSettings settings)
|
||||||
|
{
|
||||||
|
var fileStream = new FileStream(BuildTargetPath, FileMode.Create);
|
||||||
|
return XmlWriter.Create(fileStream, settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -20,6 +20,11 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
* Current project.
|
* Current project.
|
||||||
* Referenced project.
|
* Referenced project.
|
||||||
* Referenced packages.
|
* Referenced packages.
|
||||||
|
* GenerateStaticWebAssetsPackTargets: Includes the static web assets in the current project
|
||||||
|
under the 'staticwebassets' folder in the nuget package and generates and includes in the
|
||||||
|
package the appropriate .props files to support discovering the packaged static web assets.
|
||||||
|
* GetCurrentProjectStaticWebAssets: Called on each referenced project to retrieve the list of
|
||||||
|
static web assets in the project.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<UsingTask
|
<UsingTask
|
||||||
|
|
@ -32,6 +37,16 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
AssemblyFile="$(RazorSdkBuildTasksAssembly)"
|
AssemblyFile="$(RazorSdkBuildTasksAssembly)"
|
||||||
Condition="'$(RazorSdkBuildTasksAssembly)' != ''" />
|
Condition="'$(RazorSdkBuildTasksAssembly)' != ''" />
|
||||||
|
|
||||||
|
<UsingTask
|
||||||
|
TaskName="Microsoft.AspNetCore.Razor.Tasks.GenerateStaticWebAsssetsPropsFile"
|
||||||
|
AssemblyFile="$(RazorSdkBuildTasksAssembly)"
|
||||||
|
Condition="'$(RazorSdkBuildTasksAssembly)' != ''" />
|
||||||
|
|
||||||
|
<UsingTask
|
||||||
|
TaskName="Microsoft.AspNetCore.Razor.Tasks.StaticWebAssetsGeneratePackagePropsFile"
|
||||||
|
AssemblyFile="$(RazorSdkBuildTasksAssembly)"
|
||||||
|
Condition="'$(RazorSdkBuildTasksAssembly)' != ''" />
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<GenerateStaticWebAssetsManifestDependsOn>
|
<GenerateStaticWebAssetsManifestDependsOn>
|
||||||
ResolveStaticWebAssetsInputs;
|
ResolveStaticWebAssetsInputs;
|
||||||
|
|
@ -49,25 +64,76 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
$(AssignTargetPathsDependsOn)
|
$(AssignTargetPathsDependsOn)
|
||||||
</AssignTargetPathsDependsOn>
|
</AssignTargetPathsDependsOn>
|
||||||
|
|
||||||
<ResolveStaticWebAssetsInputsDependsOn>
|
<ResolveStaticWebAssetsInputsDependsOn Condition="$(NoBuild) != 'true'">
|
||||||
_ResolveStaticWebAssetsProjectReferences;
|
_ResolveStaticWebAssetsProjectReferences;
|
||||||
$(ResolveStaticWebAssetsInputsDependsOn)
|
$(ResolveStaticWebAssetsInputsDependsOn)
|
||||||
</ResolveStaticWebAssetsInputsDependsOn>
|
</ResolveStaticWebAssetsInputsDependsOn>
|
||||||
|
|
||||||
|
<GenerateStaticWebAssetsPackTargetsDependsOn>
|
||||||
|
_CreateStaticWebAssetsCustomPropsCacheFile;
|
||||||
|
$(GenerateStaticWebAssetsPackTargetsDependsOn)
|
||||||
|
</GenerateStaticWebAssetsPackTargetsDependsOn>
|
||||||
|
|
||||||
|
<TargetsForTfmSpecificContentInPackage>
|
||||||
|
GenerateStaticWebAssetsPackTargets;
|
||||||
|
$(TargetsForTfmSpecificContentInPackage)
|
||||||
|
</TargetsForTfmSpecificContentInPackage>
|
||||||
|
|
||||||
|
<PackDependsOn>
|
||||||
|
_RemoveWebRootContentFromPackaging;
|
||||||
|
$(PackDependsOn)
|
||||||
|
</PackDependsOn>
|
||||||
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<_GeneratedStaticWebAssetsInputsCacheFile>$(IntermediateOutputPath)$(TargetName).StaticWebAssets.cache</_GeneratedStaticWebAssetsInputsCacheFile>
|
<_StaticWebAssetsIntermediateOutputPath>$(IntermediateOutputPath)staticwebassets\</_StaticWebAssetsIntermediateOutputPath>
|
||||||
<_GeneratedStaticWebAssetsDevelopmentManifest>$(IntermediateOutputPath)$(TargetName).StaticWebAssets.xml</_GeneratedStaticWebAssetsDevelopmentManifest>
|
|
||||||
|
<!-- Development manifest generation -->
|
||||||
|
<_GeneratedStaticWebAssetsInputsCacheFile>$(_StaticWebAssetsIntermediateOutputPath)$(TargetName).StaticWebAssets.Manifest.cache</_GeneratedStaticWebAssetsInputsCacheFile>
|
||||||
|
<_GeneratedStaticWebAssetsDevelopmentManifest>$(_StaticWebAssetsIntermediateOutputPath)$(TargetName).StaticWebAssets.xml</_GeneratedStaticWebAssetsDevelopmentManifest>
|
||||||
|
|
||||||
|
<!-- Project packing generation -->
|
||||||
|
<_GeneratedStaticWebAssetsCustomPropsCacheFile>$(_StaticWebAssetsIntermediateOutputPath)$(TargetName).StaticWebAssets.Pack.cache</_GeneratedStaticWebAssetsCustomPropsCacheFile>
|
||||||
|
|
||||||
|
<!-- Temporary files -->
|
||||||
|
<_GeneratedStaticWebAssetsPropsFile>$(_StaticWebAssetsIntermediateOutputPath)msbuild.$(PackageId).Microsoft.AspNetCore.StaticWebAssets.props</_GeneratedStaticWebAssetsPropsFile>
|
||||||
|
<_GeneratedBuildPropsFile>$(_StaticWebAssetsIntermediateOutputPath)msbuild.build.$(PackageId).props</_GeneratedBuildPropsFile>
|
||||||
|
<_GeneratedBuildMultitargetingPropsFile>$(_StaticWebAssetsIntermediateOutputPath)msbuild.buildMultiTargeting.$(PackageId).props</_GeneratedBuildMultitargetingPropsFile>
|
||||||
|
<_GeneratedBuildTransitivePropsFile>$(_StaticWebAssetsIntermediateOutputPath)msbuild.buildTransitive.$(PackageId).props</_GeneratedBuildTransitivePropsFile>
|
||||||
|
|
||||||
|
<!-- Package relative import paths -->
|
||||||
|
<_StaticWebAssetsPropsFileImportPath>Microsoft.AspNetCore.StaticWebAssets.props</_StaticWebAssetsPropsFileImportPath>
|
||||||
|
<_StaticWebAssetsGeneratedBuildPropsFileImportPath>..\build\$(PackageId).props</_StaticWebAssetsGeneratedBuildPropsFileImportPath>
|
||||||
|
<_StaticWebAssetsGeneratedBuildMultiTargetingPropsFileImportPath>..\buildMultiTargeting\$(PackageId).props</_StaticWebAssetsGeneratedBuildMultiTargetingPropsFileImportPath>
|
||||||
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<Target
|
<!-- Helper target invoked by other tasks below to ensure that the intermediate output path has the correct
|
||||||
|
shape for the intermediate output files that might be generated.
|
||||||
|
-->
|
||||||
|
<Target Name="_PrepareForStaticWebAssets">
|
||||||
|
<MakeDir
|
||||||
|
Directories="$(_StaticWebAssetsIntermediateOutputPath)"
|
||||||
|
Condition="!Exists('$(_StaticWebAssetsIntermediateOutputPath)')" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
============================================================
|
||||||
|
Static web assets development manifest generation targets
|
||||||
|
|
||||||
|
The main targets for generating a development manifest with information about the static web
|
||||||
|
assets found in referenced packages and projects.
|
||||||
|
============================================================
|
||||||
|
-->
|
||||||
|
|
||||||
|
<Target
|
||||||
Name="_CreateStaticWebAssetsInputsCacheFile"
|
Name="_CreateStaticWebAssetsInputsCacheFile"
|
||||||
DependsOnTargets="ResolveStaticWebAssetsInputs">
|
DependsOnTargets="ResolveStaticWebAssetsInputs;_PrepareForStaticWebAssets">
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<!--
|
<!--
|
||||||
This is the list of inputs that will be used for generating the manifest used during development.
|
This is the list of inputs that will be used for generating the manifest used during development.
|
||||||
-->
|
-->
|
||||||
<_ExternalStaticWebAsset
|
<_ExternalStaticWebAsset
|
||||||
Include="%(StaticWebAsset.Identity)"
|
Include="%(StaticWebAsset.Identity)"
|
||||||
|
|
@ -82,10 +148,10 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
<Output TaskParameter="HashResult" PropertyName="_StaticWebAssetsCacheHash" />
|
<Output TaskParameter="HashResult" PropertyName="_StaticWebAssetsCacheHash" />
|
||||||
</Hash>
|
</Hash>
|
||||||
|
|
||||||
<WriteLinesToFile
|
<WriteLinesToFile
|
||||||
Lines="$(_StaticWebAssetsCacheHash)"
|
Lines="$(_StaticWebAssetsCacheHash)"
|
||||||
File="$(_GeneratedStaticWebAssetsInputsCacheFile)"
|
File="$(_GeneratedStaticWebAssetsInputsCacheFile)"
|
||||||
Overwrite="True"
|
Overwrite="True"
|
||||||
WriteOnlyWhenDifferent="True" />
|
WriteOnlyWhenDifferent="True" />
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
@ -94,7 +160,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
This target generates a manifest for development time that includes information
|
This target generates a manifest for development time that includes information
|
||||||
about the base path for the referenced package and project static web assets. The
|
about the base path for the referenced package and project static web assets. The
|
||||||
manifest includes the content root and the base path for each of the referenced
|
manifest includes the content root and the base path for each of the referenced
|
||||||
|
|
@ -104,21 +170,31 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
root, but we don't check for duplicates on either of them.
|
root, but we don't check for duplicates on either of them.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<Target
|
<Target
|
||||||
Name="GenerateStaticWebAssetsManifest"
|
Name="GenerateStaticWebAssetsManifest"
|
||||||
Inputs="$(_GeneratedStaticWebAssetsInputsCacheFile)"
|
Inputs="$(_GeneratedStaticWebAssetsInputsCacheFile)"
|
||||||
Outputs="$(_GeneratedStaticWebAssetsDevelopmentManifest)"
|
Outputs="$(_GeneratedStaticWebAssetsDevelopmentManifest)"
|
||||||
DependsOnTargets="$(GenerateStaticWebAssetsManifestDependsOn)">
|
DependsOnTargets="$(GenerateStaticWebAssetsManifestDependsOn)">
|
||||||
|
|
||||||
<GenerateStaticWebAssetsManifest
|
<GenerateStaticWebAssetsManifest
|
||||||
ContentRootDefinitions="@(_ExternalStaticWebAsset)"
|
ContentRootDefinitions="@(_ExternalStaticWebAsset)"
|
||||||
TargetManifestPath="$(_GeneratedStaticWebAssetsDevelopmentManifest)" />
|
TargetManifestPath="$(_GeneratedStaticWebAssetsDevelopmentManifest)" />
|
||||||
|
|
||||||
<!-- This is the list of inputs that will be used for generating the manifest used during development. -->
|
<!-- This is the list of inputs that will be used for generating the manifest used during development. -->
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Condition="'@(_ExternalStaticWebAsset->Count())' != '0'"
|
<EmbeddedResource Condition="'@(_ExternalStaticWebAsset->Count())' != '0'"
|
||||||
Include="$(_GeneratedStaticWebAssetsDevelopmentManifest)"
|
Include="$(_GeneratedStaticWebAssetsDevelopmentManifest)"
|
||||||
LogicalName="Microsoft.AspNetCore.StaticWebAssets.xml" />
|
LogicalName="Microsoft.AspNetCore.StaticWebAssets.xml" />
|
||||||
|
|
||||||
|
<!-- Include it as content as we plan to avoid using an embedded file for the manifest -->
|
||||||
|
<Content
|
||||||
|
Include="$(_GeneratedStaticWebAssetsDevelopmentManifest)"
|
||||||
|
Condition="'@(_ExternalStaticWebAsset->Count())' != '0'"
|
||||||
|
Link="$(TargetName).StaticWebAssets.xml">
|
||||||
|
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
@ -127,6 +203,15 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
============================================================
|
||||||
|
Static web assets discovery related targets
|
||||||
|
|
||||||
|
The main targets for discovering static web assets inside referenced packages, projects and
|
||||||
|
the current project.
|
||||||
|
============================================================
|
||||||
|
-->
|
||||||
|
|
||||||
<!-- This target collects all the StaticWebAssets from different sources:
|
<!-- This target collects all the StaticWebAssets from different sources:
|
||||||
* The current project StaticWebAssets that come from wwwroot\** by default.
|
* The current project StaticWebAssets that come from wwwroot\** by default.
|
||||||
* Assets from referenced projects that get retrieved invoking an MSBuild target on
|
* Assets from referenced projects that get retrieved invoking an MSBuild target on
|
||||||
|
|
@ -134,7 +219,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
* Assets from the referenced packages. These will be implicitly included when nuget
|
* Assets from the referenced packages. These will be implicitly included when nuget
|
||||||
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"
|
||||||
DependsOnTargets="$(ResolveStaticWebAssetsInputsDependsOn)">
|
DependsOnTargets="$(ResolveStaticWebAssetsInputsDependsOn)">
|
||||||
|
|
||||||
|
|
@ -164,7 +249,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
<_ThisProjectStaticWebAsset
|
<_ThisProjectStaticWebAsset
|
||||||
Include="$(MSBuildProjectDirectory)\wwwroot\**"
|
Include="$(MSBuildProjectDirectory)\wwwroot\**"
|
||||||
Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
|
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.
|
||||||
|
|
@ -174,7 +259,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
<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>$(PackageId)</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
|
||||||
* For referenced projects it corresponds to <<FullProjectRefPath>>/wwwroot
|
* For referenced projects it corresponds to <<FullProjectRefPath>>/wwwroot
|
||||||
|
|
@ -214,7 +299,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
the static assets for a given application. We do it this way so that we can
|
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
|
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
|
as a project. For example, Identity uses this hook to extend the project reference and
|
||||||
pass in the bootstrap version to use.
|
pass in the bootstrap version to use.
|
||||||
-->
|
-->
|
||||||
<Target Name="_ResolveStaticWebAssetsProjectReferences"
|
<Target Name="_ResolveStaticWebAssetsProjectReferences"
|
||||||
DependsOnTargets="ResolveReferences"
|
DependsOnTargets="ResolveReferences"
|
||||||
|
|
@ -244,4 +329,198 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
============================================================
|
||||||
|
Static web assets packing related targets
|
||||||
|
|
||||||
|
The main targets to enable auto-packing of static web assets.
|
||||||
|
============================================================
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- We need to remove any content item under wwwroot right before packing to prevent it from getting included
|
||||||
|
in the package as content or contentFiles. Unfortunately marking it with pack=false doesn't work as it also
|
||||||
|
prevents the content from being packed even though we are including it explictily in
|
||||||
|
GenerateStaticWebAssetsPackTargets
|
||||||
|
-->
|
||||||
|
<Target Name="_RemoveWebRootContentFromPackaging" DependsOnTargets="_CreateStaticWebAssetsCustomPropsCacheFile" >
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Remove="@(_CurrentProjectStaticWebAsset->'wwwroot\%(RelativePath)')" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<Target
|
||||||
|
Name="_CreateStaticWebAssetsCustomPropsCacheFile"
|
||||||
|
DependsOnTargets="ResolveStaticWebAssetsInputs;_PrepareForStaticWebAssets">
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<!-- This is the list of inputs that will be used for generating the props file that will be packed with
|
||||||
|
the package. -->
|
||||||
|
<_CurrentProjectStaticWebAsset
|
||||||
|
Include="@(StaticWebAsset)"
|
||||||
|
Condition="'%(SourceType)' == ''" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Hash ItemsToHash="@(_CurrentProjectStaticWebAsset->'%(BasePath)%(SourceId)')">
|
||||||
|
<Output TaskParameter="HashResult" PropertyName="_StaticWebAssetsPropsFileHash" />
|
||||||
|
</Hash>
|
||||||
|
|
||||||
|
<WriteLinesToFile
|
||||||
|
Lines="$(_StaticWebAssetsPropsFileHash)"
|
||||||
|
File="$(_GeneratedStaticWebAssetsCustomPropsCacheFile)"
|
||||||
|
Overwrite="True"
|
||||||
|
WriteOnlyWhenDifferent="True" />
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<FileWrites Include="$(_GeneratedStaticWebAssetsCustomPropsCacheFile)" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<!-- This target makes sure that all static web assets for the current project get included
|
||||||
|
in the package under the folder staticwebassets and generates MSBuild props files to
|
||||||
|
ensure that consuming packages can discover and use the static web assets.
|
||||||
|
This target generates and includes a Microsoft.AspNetCore.StaticWebAssets.props file that
|
||||||
|
goes inside the build directory and describes the static web assets in the package as an
|
||||||
|
item group.
|
||||||
|
This target also generates and includes a $(PackageId).props file under the build, buildMultiTargeting
|
||||||
|
and buildTransitive folders that are setup so that:
|
||||||
|
* buildTransitive\$(PackageId).props simply imports buildMultitargeting\$(PackageId).props
|
||||||
|
* buildMultitargeting\$(PackageId).props simply imports build\$(PackageId).props
|
||||||
|
* build\$(PackageId).props simply imports Microsoft.AspNetCore.StaticWebAssets.props
|
||||||
|
|
||||||
|
We do it this way to preserve the ability of package authors to customize the package in any way
|
||||||
|
they see fit and to make sure the package works in all scenarios. Authors including custom MSBuild
|
||||||
|
targets into their packages are expected to disable the generation of $(PackageId).props files and
|
||||||
|
to manually import build\Microsoft.AspNetCore.StaticWebAssets.props in their custom props files.
|
||||||
|
-->
|
||||||
|
<Target
|
||||||
|
Name="GenerateStaticWebAssetsPackTargets"
|
||||||
|
DependsOnTargets="$(GenerateStaticWebAssetsPackTargetsDependsOn)"
|
||||||
|
Inputs="$(_GeneratedStaticWebAssetsCustomPropsCacheFile)"
|
||||||
|
Outputs="$(_GeneratedStaticWebAssetsPropsFile)">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<_CurrentProjectHasStaticWebAssets Condition="'@(_CurrentProjectStaticWebAsset->Count())' != '0'">true</_CurrentProjectHasStaticWebAssets>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<!-- Generates a props file that goes in build\Microsoft.AspNetCore.StaticWebAssets.props
|
||||||
|
and that describes the static web assets for the package.
|
||||||
|
-->
|
||||||
|
<GenerateStaticWebAsssetsPropsFile
|
||||||
|
Condition="'$(_CurrentProjectHasStaticWebAssets)' == 'true'"
|
||||||
|
StaticWebAssets="@(_CurrentProjectStaticWebAsset)"
|
||||||
|
TargetPropsFilePath="$(_GeneratedStaticWebAssetsPropsFile)" />
|
||||||
|
|
||||||
|
<!-- Generates a props file the goes in build\$(PackageId).props and that simply imports
|
||||||
|
build\Microsoft.AspNetCore.StaticWebAssets.props
|
||||||
|
-->
|
||||||
|
<StaticWebAssetsGeneratePackagePropsFile
|
||||||
|
Condition="'$(_CurrentProjectHasStaticWebAssets)' == 'true'"
|
||||||
|
PropsFileImport="$(_StaticWebAssetsPropsFileImportPath)"
|
||||||
|
BuildTargetPath="$(_GeneratedBuildPropsFile)" />
|
||||||
|
|
||||||
|
<!-- Generates a props file the goes in buildMultiTargeting\$(PackageId).props and that simply imports
|
||||||
|
build\$(PackageId).props
|
||||||
|
-->
|
||||||
|
<StaticWebAssetsGeneratePackagePropsFile
|
||||||
|
Condition="'$(_CurrentProjectHasStaticWebAssets)' == 'true'"
|
||||||
|
PropsFileImport="$(_StaticWebAssetsGeneratedBuildPropsFileImportPath)"
|
||||||
|
BuildTargetPath="$(_GeneratedBuildMultitargetingPropsFile)" />
|
||||||
|
|
||||||
|
<!-- Generates a props file the goes in buildTransitive\$(PackageId).props and that simply imports
|
||||||
|
buildMultiTargeting\$(PackageId)
|
||||||
|
-->
|
||||||
|
<StaticWebAssetsGeneratePackagePropsFile
|
||||||
|
Condition="'$(_CurrentProjectHasStaticWebAssets)' == 'true'"
|
||||||
|
PropsFileImport="$(_StaticWebAssetsGeneratedBuildMultiTargetingPropsFileImportPath)"
|
||||||
|
BuildTargetPath="$(_GeneratedBuildTransitivePropsFile)" />
|
||||||
|
|
||||||
|
<!-- All files potentially created within this target -->
|
||||||
|
<ItemGroup>
|
||||||
|
<FileWrites Include="$(_GeneratedStaticWebAssetsPropsFile)" />
|
||||||
|
<FileWrites Include="$(_GeneratedBuildPropsFile)" />
|
||||||
|
<FileWrites Include="$(_GeneratedBuildMultitargetingPropsFile)" />
|
||||||
|
<FileWrites Include="$(_GeneratedBuildTransitivePropsFile)" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<!-- All files that go into the nuget package -->
|
||||||
|
<ItemGroup Condition="'$(_CurrentProjectHasStaticWebAssets)' == 'true'">
|
||||||
|
|
||||||
|
<!-- MSBuild prop files -->
|
||||||
|
|
||||||
|
<TfmSpecificPackageFile Include="$(_GeneratedStaticWebAssetsPropsFile)"
|
||||||
|
Condition="'$(DisableStaticWebAssetsBuildPropsFileGeneration)' == ''">
|
||||||
|
|
||||||
|
<PackagePath>build\Microsoft.AspNetCore.StaticWebAssets.props</PackagePath>
|
||||||
|
</TfmSpecificPackageFile>
|
||||||
|
|
||||||
|
<TfmSpecificPackageFile Include="$(_GeneratedBuildPropsFile)"
|
||||||
|
Condition="'$(StaticWebAssetsDisableProjectBuildPropsFileGeneration)' == ''">
|
||||||
|
|
||||||
|
<PackagePath>build\$(PackageId).props</PackagePath>
|
||||||
|
</TfmSpecificPackageFile>
|
||||||
|
|
||||||
|
<TfmSpecificPackageFile Include="$(_GeneratedBuildMultitargetingPropsFile)"
|
||||||
|
Condition="'$(StaticWebAssetsDisableProjectBuildMultiTargetingPropsFileGeneration)' == ''">
|
||||||
|
|
||||||
|
<PackagePath>buildMultiTargeting\$(PackageId).props</PackagePath>
|
||||||
|
</TfmSpecificPackageFile>
|
||||||
|
|
||||||
|
<TfmSpecificPackageFile Include="$(_GeneratedBuildTransitivePropsFile)"
|
||||||
|
Condition="'$(StaticWebAssetsDisableProjectBuildTransitivePropsFileGeneration)' == ''">
|
||||||
|
|
||||||
|
<PackagePath>buildTransitive\$(PackageId).props</PackagePath>
|
||||||
|
</TfmSpecificPackageFile>
|
||||||
|
|
||||||
|
<!-- Project file contents -->
|
||||||
|
|
||||||
|
<TfmSpecificPackageFile Include="%(_CurrentProjectStaticWebAsset.Identity)">
|
||||||
|
<PackagePath>staticwebassets\%(_CurrentProjectStaticWebAsset.RelativePath)</PackagePath>
|
||||||
|
</TfmSpecificPackageFile>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
|
||||||
|
<!--
|
||||||
|
============================================================
|
||||||
|
Static web assets publish related targets
|
||||||
|
|
||||||
|
The main targets for publishing static web assets coming from referenced projects
|
||||||
|
and packages.
|
||||||
|
============================================================
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Called after ComputeRefAssembliesToPublish but before CopyFilesToPublishDirectory - this target is called when
|
||||||
|
publishing the project to get a list of files to the output directory.
|
||||||
|
-->
|
||||||
|
<Target
|
||||||
|
Name="_StaticWebAssetsComputeFilesToPublish"
|
||||||
|
AfterTargets="ComputeRefAssembliesToPublish"
|
||||||
|
DependsOnTargets="ResolveStaticWebAssetsInputs">
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
|
||||||
|
<!-- Filter the static web assets foreign to the project and then add them to the list of resolved
|
||||||
|
files to publish.
|
||||||
|
-->
|
||||||
|
<_ExternalPublishStaticWebAsset
|
||||||
|
Include="%(StaticWebAsset.FullPath)"
|
||||||
|
Condition="'%(SourceType)' != ''">
|
||||||
|
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
<RelativePath>$([MSBuild]::MakeRelative('$(MSBuildProjectDirectory)','$([MSBuild]::NormalizePath('wwwroot\%(BasePath)\%(RelativePath)'))'))</RelativePath>
|
||||||
|
|
||||||
|
</_ExternalPublishStaticWebAsset>
|
||||||
|
|
||||||
|
<!-- Remove any existing external static web asset that might have been added as part of the
|
||||||
|
regular publish pipeline. -->
|
||||||
|
<ResolvedFileToPublish Remove="@(_ExternalPublishStaticWebAsset)" />
|
||||||
|
|
||||||
|
<ResolvedFileToPublish Include="@(_ExternalPublishStaticWebAsset)" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Target>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -75,7 +75,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<EnableRazorSdkContent Condition=" '$(UsingMicrosoftNETSdkWeb)' == '' ">true</EnableRazorSdkContent>
|
<EnableRazorSdkContent Condition="'$(EnableRazorSdkContent)' =='' and '$(UsingMicrosoftNETSdkWeb)' == '' ">true</EnableRazorSdkContent>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<Import
|
<Import
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,10 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
'$(RazorLangVersion)' == 'Latest' OR
|
'$(RazorLangVersion)' == 'Latest' OR
|
||||||
'$(RazorLangVersion)' == 'Experimental' OR
|
'$(RazorLangVersion)' == 'Experimental' OR
|
||||||
('$(RazorLangVersion)' != '' AND '$(RazorLangVersion)' >= '3.0')">true</_Targeting30OrNewerRazorLangVersion>
|
('$(RazorLangVersion)' != '' AND '$(RazorLangVersion)' >= '3.0')">true</_Targeting30OrNewerRazorLangVersion>
|
||||||
|
|
||||||
|
<!-- Controls whether or not the static web assets feature is enabled. By default is enabled for netcoreapp3.0
|
||||||
|
applications and RazorLangVersion 3 or above. -->
|
||||||
|
<StaticWebAssetsEnabled Condition="'$(StaticWebAssetsEnabled)' == ''">$(_Targeting30OrNewerRazorLangVersion)</StaticWebAssetsEnabled>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -338,7 +342,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
|
||||||
<Import Project="Microsoft.NET.Sdk.Razor.Component.targets" Condition="'$(_Targeting30OrNewerRazorLangVersion)' == 'true'" />
|
<Import Project="Microsoft.NET.Sdk.Razor.Component.targets" Condition="'$(_Targeting30OrNewerRazorLangVersion)' == 'true'" />
|
||||||
|
|
||||||
<Import Project="Microsoft.NET.Sdk.Razor.StaticWebAssets.targets" Condition="'$(_Targeting30OrNewerRazorLangVersion)' == 'true'" />
|
<Import Project="Microsoft.NET.Sdk.Razor.StaticWebAssets.targets" Condition="'$(StaticWebAssetsEnabled)' == 'true'" />
|
||||||
|
|
||||||
<Import Project="Microsoft.NET.Sdk.Razor.GenerateAssemblyInfo.targets" />
|
<Import Project="Microsoft.NET.Sdk.Razor.GenerateAssemblyInfo.targets" />
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,433 @@
|
||||||
|
// 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 System.IO;
|
||||||
|
using Microsoft.AspNetCore.Razor.Tasks;
|
||||||
|
using Microsoft.Build.Framework;
|
||||||
|
using Microsoft.Build.Utilities;
|
||||||
|
using Moq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Razor.Tasks
|
||||||
|
{
|
||||||
|
public class GenerateStaticWebAssetsPropsFileTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void Fails_WhenStaticWebAsset_DoesNotContainSourceType()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
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 GenerateStaticWebAsssetsPropsFile
|
||||||
|
{
|
||||||
|
BuildEngine = buildEngine.Object,
|
||||||
|
StaticWebAssets = new TaskItem[]
|
||||||
|
{
|
||||||
|
CreateItem(Path.Combine("wwwroot","js","sample.js"), new Dictionary<string,string>
|
||||||
|
{
|
||||||
|
["SourceId"] = "MyLibrary",
|
||||||
|
["ContentRoot"] = @"$(MSBuildThisFileDirectory)..\staticwebassets",
|
||||||
|
["BasePath"] = "_content/mylibrary",
|
||||||
|
["RelativePath"] = Path.Combine("js", "sample.js"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = task.Execute();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.False(result);
|
||||||
|
var message = Assert.Single(errorMessages);
|
||||||
|
Assert.Equal($"Missing required metadata 'SourceType' for '{Path.Combine("wwwroot", "js", "sample.js")}'.", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Fails_WhenStaticWebAsset_DoesNotContainSourceId()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
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 GenerateStaticWebAsssetsPropsFile
|
||||||
|
{
|
||||||
|
BuildEngine = buildEngine.Object,
|
||||||
|
StaticWebAssets = new TaskItem[]
|
||||||
|
{
|
||||||
|
CreateItem(Path.Combine("wwwroot","js","sample.js"), new Dictionary<string,string>
|
||||||
|
{
|
||||||
|
["SourceType"] = "",
|
||||||
|
["ContentRoot"] = @"$(MSBuildThisFileDirectory)..\staticwebassets",
|
||||||
|
["BasePath"] = "_content/mylibrary",
|
||||||
|
["RelativePath"] = Path.Combine("js", "sample.js"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = task.Execute();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.False(result);
|
||||||
|
var message = Assert.Single(errorMessages);
|
||||||
|
Assert.Equal($"Missing required metadata 'SourceId' for '{Path.Combine("wwwroot", "js", "sample.js")}'.", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Fails_WhenStaticWebAsset_DoesNotContainContentRoot()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
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 GenerateStaticWebAsssetsPropsFile
|
||||||
|
{
|
||||||
|
BuildEngine = buildEngine.Object,
|
||||||
|
StaticWebAssets = new TaskItem[]
|
||||||
|
{
|
||||||
|
CreateItem(Path.Combine("wwwroot","js","sample.js"), new Dictionary<string,string>
|
||||||
|
{
|
||||||
|
["SourceType"] = "",
|
||||||
|
["SourceId"] = "MyLibrary",
|
||||||
|
["BasePath"] = "_content/mylibrary",
|
||||||
|
["RelativePath"] = Path.Combine("js", "sample.js"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = task.Execute();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.False(result);
|
||||||
|
var message = Assert.Single(errorMessages);
|
||||||
|
Assert.Equal($"Missing required metadata 'ContentRoot' for '{Path.Combine("wwwroot", "js", "sample.js")}'.", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Fails_WhenStaticWebAsset_DoesNotContainBasePath()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
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 GenerateStaticWebAsssetsPropsFile
|
||||||
|
{
|
||||||
|
BuildEngine = buildEngine.Object,
|
||||||
|
StaticWebAssets = new TaskItem[]
|
||||||
|
{
|
||||||
|
CreateItem(Path.Combine("wwwroot","js","sample.js"), new Dictionary<string,string>
|
||||||
|
{
|
||||||
|
["SourceType"] = "",
|
||||||
|
["SourceId"] = "MyLibrary",
|
||||||
|
["ContentRoot"] = @"$(MSBuildThisFileDirectory)..\staticwebassets",
|
||||||
|
["RelativePath"] = Path.Combine("js", "sample.js"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = task.Execute();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.False(result);
|
||||||
|
var message = Assert.Single(errorMessages);
|
||||||
|
Assert.Equal($"Missing required metadata 'BasePath' for '{Path.Combine("wwwroot", "js", "sample.js")}'.", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Fails_WhenStaticWebAsset_DoesNotContainRelativePath()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
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 GenerateStaticWebAsssetsPropsFile
|
||||||
|
{
|
||||||
|
BuildEngine = buildEngine.Object,
|
||||||
|
StaticWebAssets = new TaskItem[]
|
||||||
|
{
|
||||||
|
CreateItem(Path.Combine("wwwroot","js","sample.js"), new Dictionary<string,string>
|
||||||
|
{
|
||||||
|
["SourceType"] = "",
|
||||||
|
["SourceId"] = "MyLibrary",
|
||||||
|
["ContentRoot"] = @"$(MSBuildThisFileDirectory)..\staticwebassets",
|
||||||
|
["BasePath"] = "_content/mylibrary",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = task.Execute();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.False(result);
|
||||||
|
var message = Assert.Single(errorMessages);
|
||||||
|
Assert.Equal($"Missing required metadata 'RelativePath' for '{Path.Combine("wwwroot", "js", "sample.js")}'.", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Fails_WhenStaticWebAsset_HaveDifferentSourceType()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var expectedError = "Static web assets have different 'SourceType' metadata values " +
|
||||||
|
"'' and 'Package' " +
|
||||||
|
$"for '{Path.Combine("wwwroot", "js", "sample.js")}' and '{Path.Combine("wwwroot", "css", "site.css")}'.";
|
||||||
|
|
||||||
|
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 GenerateStaticWebAsssetsPropsFile
|
||||||
|
{
|
||||||
|
BuildEngine = buildEngine.Object,
|
||||||
|
StaticWebAssets = new TaskItem[]
|
||||||
|
{
|
||||||
|
CreateItem(Path.Combine("wwwroot","js","sample.js"), new Dictionary<string,string>
|
||||||
|
{
|
||||||
|
["SourceType"] = "",
|
||||||
|
["SourceId"] = "MyLibrary",
|
||||||
|
["ContentRoot"] = @"$(MSBuildThisFileDirectory)..\staticwebassets",
|
||||||
|
["BasePath"] = "_content/mylibrary",
|
||||||
|
["RelativePath"] = Path.Combine("js", "sample.js"),
|
||||||
|
}),
|
||||||
|
CreateItem(Path.Combine("wwwroot","css","site.css"), new Dictionary<string,string>
|
||||||
|
{
|
||||||
|
["SourceType"] = "Package",
|
||||||
|
["SourceId"] = "MyLibrary",
|
||||||
|
["ContentRoot"] = @"$(MSBuildThisFileDirectory)..\staticwebassets",
|
||||||
|
["BasePath"] = "_content/mylibrary",
|
||||||
|
["RelativePath"] = Path.Combine("css", "site.css"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = task.Execute();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.False(result);
|
||||||
|
var message = Assert.Single(errorMessages);
|
||||||
|
Assert.Equal(expectedError, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Fails_WhenStaticWebAsset_HaveDifferentSourceId()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var expectedError = "Static web assets have different 'SourceId' metadata values " +
|
||||||
|
"'MyLibrary' and 'MyLibrary2' " +
|
||||||
|
$"for '{Path.Combine("wwwroot", "js", "sample.js")}' and '{Path.Combine("wwwroot", "css", "site.css")}'.";
|
||||||
|
|
||||||
|
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 GenerateStaticWebAsssetsPropsFile
|
||||||
|
{
|
||||||
|
BuildEngine = buildEngine.Object,
|
||||||
|
StaticWebAssets = new TaskItem[]
|
||||||
|
{
|
||||||
|
CreateItem(Path.Combine("wwwroot","js","sample.js"), new Dictionary<string,string>
|
||||||
|
{
|
||||||
|
["SourceType"] = "",
|
||||||
|
["SourceId"] = "MyLibrary",
|
||||||
|
["ContentRoot"] = @"$(MSBuildThisFileDirectory)..\staticwebassets",
|
||||||
|
["BasePath"] = "_content/mylibrary",
|
||||||
|
["RelativePath"] = Path.Combine("js", "sample.js"),
|
||||||
|
}),
|
||||||
|
CreateItem(Path.Combine("wwwroot","css","site.css"), new Dictionary<string,string>
|
||||||
|
{
|
||||||
|
["SourceType"] = "",
|
||||||
|
["SourceId"] = "MyLibrary2",
|
||||||
|
["ContentRoot"] = @"$(MSBuildThisFileDirectory)..\staticwebassets",
|
||||||
|
["BasePath"] = "_content/mylibrary",
|
||||||
|
["RelativePath"] = Path.Combine("css", "site.css"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = task.Execute();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.False(result);
|
||||||
|
var message = Assert.Single(errorMessages);
|
||||||
|
Assert.Equal(expectedError, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Fails_WhenStaticWebAsset_HaveDifferentContentRoot()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var expectedError = "Static web assets have different 'ContentRoot' metadata values " +
|
||||||
|
@"'$(MSBuildThisFileDirectory)..\staticwebassets' and '..\staticwebassets' " +
|
||||||
|
$"for '{Path.Combine("wwwroot", "js", "sample.js")}' and '{Path.Combine("wwwroot", "css", "site.css")}'.";
|
||||||
|
|
||||||
|
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 GenerateStaticWebAsssetsPropsFile
|
||||||
|
{
|
||||||
|
BuildEngine = buildEngine.Object,
|
||||||
|
StaticWebAssets = new TaskItem[]
|
||||||
|
{
|
||||||
|
CreateItem(Path.Combine("wwwroot","js","sample.js"), new Dictionary<string,string>
|
||||||
|
{
|
||||||
|
["SourceType"] = "",
|
||||||
|
["SourceId"] = "MyLibrary",
|
||||||
|
["ContentRoot"] = @"$(MSBuildThisFileDirectory)..\staticwebassets",
|
||||||
|
["BasePath"] = "_content/mylibrary",
|
||||||
|
["RelativePath"] = Path.Combine("js", "sample.js"),
|
||||||
|
}),
|
||||||
|
CreateItem(Path.Combine("wwwroot","css","site.css"), new Dictionary<string,string>
|
||||||
|
{
|
||||||
|
["SourceType"] = "",
|
||||||
|
["SourceId"] = "MyLibrary",
|
||||||
|
["ContentRoot"] = @"..\staticwebassets",
|
||||||
|
["BasePath"] = "_content/mylibrary",
|
||||||
|
["RelativePath"] = Path.Combine("css", "site.css"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = task.Execute();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.False(result);
|
||||||
|
var message = Assert.Single(errorMessages);
|
||||||
|
Assert.Equal(expectedError, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Fails_WhenStaticWebAsset_HaveDifferentBasePath()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var expectedError = "Static web assets have different 'BasePath' metadata values " +
|
||||||
|
"'_content/mylibrary' and '_content/mylibrary2' " +
|
||||||
|
$"for '{Path.Combine("wwwroot", "js", "sample.js")}' and '{Path.Combine("wwwroot", "css", "site.css")}'.";
|
||||||
|
|
||||||
|
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 GenerateStaticWebAsssetsPropsFile
|
||||||
|
{
|
||||||
|
BuildEngine = buildEngine.Object,
|
||||||
|
StaticWebAssets = new TaskItem[]
|
||||||
|
{
|
||||||
|
CreateItem(Path.Combine("wwwroot","js","sample.js"), new Dictionary<string,string>
|
||||||
|
{
|
||||||
|
["SourceType"] = "",
|
||||||
|
["SourceId"] = "MyLibrary",
|
||||||
|
["ContentRoot"] = @"$(MSBuildThisFileDirectory)..\staticwebassets",
|
||||||
|
["BasePath"] = "_content/mylibrary",
|
||||||
|
["RelativePath"] = Path.Combine("js", "sample.js"),
|
||||||
|
}),
|
||||||
|
CreateItem(Path.Combine("wwwroot","css","site.css"), new Dictionary<string,string>
|
||||||
|
{
|
||||||
|
["SourceType"] = "",
|
||||||
|
["SourceId"] = "MyLibrary",
|
||||||
|
["ContentRoot"] = @"$(MSBuildThisFileDirectory)..\staticwebassets",
|
||||||
|
["BasePath"] = "_content/mylibrary2",
|
||||||
|
["RelativePath"] = Path.Combine("css", "site.css"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = task.Execute();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.False(result);
|
||||||
|
var message = Assert.Single(errorMessages);
|
||||||
|
Assert.Equal(expectedError, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void WritesPropsFile_WhenThereIsAtLeastOneStaticAsset()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var file = Path.GetTempFileName();
|
||||||
|
var expectedDocument = @"<Project>
|
||||||
|
<ItemGroup>
|
||||||
|
<StaticWebAsset Include=""$(MSBuildThisFileDirectory)..\staticwebassets\**"">
|
||||||
|
<SourceType>Package</SourceType>
|
||||||
|
<SourceId>MyLibrary</SourceId>
|
||||||
|
<ContentRoot>$(MSBuildThisFileDirectory)..\staticwebassets\</ContentRoot>
|
||||||
|
<BasePath>_content/mylibrary</BasePath>
|
||||||
|
<RelativePath>%(RecursiveDir)%(FileName)%(Extension)</RelativePath>
|
||||||
|
</StaticWebAsset>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var buildEngine = new Mock<IBuildEngine>();
|
||||||
|
|
||||||
|
var task = new GenerateStaticWebAsssetsPropsFile
|
||||||
|
{
|
||||||
|
BuildEngine = buildEngine.Object,
|
||||||
|
TargetPropsFilePath = file,
|
||||||
|
StaticWebAssets = new TaskItem[]
|
||||||
|
{
|
||||||
|
CreateItem(Path.Combine("wwwroot","js","sample.js"), new Dictionary<string,string>
|
||||||
|
{
|
||||||
|
["SourceType"] = "",
|
||||||
|
["SourceId"] = "MyLibrary",
|
||||||
|
["ContentRoot"] = @"$(MSBuildThisFileDirectory)..\staticwebassets",
|
||||||
|
["BasePath"] = "_content/mylibrary",
|
||||||
|
["RelativePath"] = Path.Combine("js", "sample.js"),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = task.Execute();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.True(result);
|
||||||
|
var document = File.ReadAllText(file);
|
||||||
|
Assert.Equal(expectedDocument, document);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (File.Exists(file))
|
||||||
|
{
|
||||||
|
File.Delete(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TaskItem CreateItem(
|
||||||
|
string spec,
|
||||||
|
IDictionary<string, string> metadata)
|
||||||
|
{
|
||||||
|
var result = new TaskItem(spec);
|
||||||
|
foreach (var (key, value) in metadata)
|
||||||
|
{
|
||||||
|
result.SetMetadata(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -485,6 +485,40 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This method extracts the nupkg to a fixed directory path. To avoid the extra work of
|
||||||
|
// cleaning up after each invocation, this method accepts multiple files.
|
||||||
|
public static void NupkgDoesNotContain(MSBuildResult result, string nupkgPath, params string[] filePaths)
|
||||||
|
{
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nupkgPath == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(nupkgPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filePaths == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(filePaths));
|
||||||
|
}
|
||||||
|
|
||||||
|
nupkgPath = Path.Combine(result.Project.DirectoryPath, nupkgPath);
|
||||||
|
FileExists(result, nupkgPath);
|
||||||
|
|
||||||
|
var unzipped = Path.Combine(result.Project.DirectoryPath, Path.GetFileNameWithoutExtension(nupkgPath));
|
||||||
|
ZipFile.ExtractToDirectory(nupkgPath, unzipped);
|
||||||
|
|
||||||
|
foreach (var filePath in filePaths)
|
||||||
|
{
|
||||||
|
if (File.Exists(Path.Combine(unzipped, filePath)))
|
||||||
|
{
|
||||||
|
throw new NupkgFileFoundException(result, nupkgPath, filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void AssemblyContainsType(MSBuildResult result, string assemblyPath, string fullTypeName)
|
public static void AssemblyContainsType(MSBuildResult result, string assemblyPath, string fullTypeName)
|
||||||
{
|
{
|
||||||
if (result == null)
|
if (result == null)
|
||||||
|
|
@ -872,5 +906,21 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
|
|
||||||
protected override string Heading => $"File: '{FilePath}' was not found was not found in {NupkgPath}.";
|
protected override string Heading => $"File: '{FilePath}' was not found was not found in {NupkgPath}.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class NupkgFileFoundException : MSBuildXunitException
|
||||||
|
{
|
||||||
|
public NupkgFileFoundException(MSBuildResult result, string nupkgPath, string filePath)
|
||||||
|
: base(result)
|
||||||
|
{
|
||||||
|
NupkgPath = nupkgPath;
|
||||||
|
FilePath = filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FilePath { get; }
|
||||||
|
|
||||||
|
public string NupkgPath { get; }
|
||||||
|
|
||||||
|
protected override string Heading => $"File: '{FilePath}' was found in {NupkgPath}.";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
@ -176,5 +177,150 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
Path.Combine("bin", Configuration, "ClassLibrary.1.0.0.nupkg"),
|
Path.Combine("bin", Configuration, "ClassLibrary.1.0.0.nupkg"),
|
||||||
Path.Combine("lib", "netcoreapp3.0", "ClassLibrary.Views.dll"));
|
Path.Combine("lib", "netcoreapp3.0", "ClassLibrary.Views.dll"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[InitializeTestProject("PackageLibraryDirectDependency", additionalProjects: new[] { "PackageLibraryTransitiveDependency" })]
|
||||||
|
public async Task Pack_IncludesStaticWebAssets()
|
||||||
|
{
|
||||||
|
var result = await DotnetMSBuild("Pack");
|
||||||
|
|
||||||
|
Assert.BuildPassed(result, allowWarnings: true);
|
||||||
|
|
||||||
|
Assert.FileExists(result, OutputPath, "PackageLibraryDirectDependency.dll");
|
||||||
|
|
||||||
|
Assert.NupkgContains(
|
||||||
|
result,
|
||||||
|
Path.Combine("..", "TestPackageRestoreSource", "PackageLibraryDirectDependency.1.0.0.nupkg"),
|
||||||
|
filePaths: new[]
|
||||||
|
{
|
||||||
|
Path.Combine("staticwebassets", "js", "pkg-direct-dep.js"),
|
||||||
|
Path.Combine("staticwebassets", "css", "site.css"),
|
||||||
|
Path.Combine("build", "Microsoft.AspNetCore.StaticWebAssets.props"),
|
||||||
|
Path.Combine("build", "PackageLibraryDirectDependency.props"),
|
||||||
|
Path.Combine("buildMultiTargeting", "PackageLibraryDirectDependency.props"),
|
||||||
|
Path.Combine("buildTransitive", "PackageLibraryDirectDependency.props")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[InitializeTestProject("PackageLibraryDirectDependency", additionalProjects: new[] { "PackageLibraryTransitiveDependency" })]
|
||||||
|
public async Task Pack_StaticWebAssetsEnabledFalse_DoesNotPackAnyStaticWebAssets()
|
||||||
|
{
|
||||||
|
var result = await DotnetMSBuild("Pack", "/p:StaticWebAssetsEnabled=false");
|
||||||
|
|
||||||
|
Assert.BuildPassed(result, allowWarnings: true);
|
||||||
|
|
||||||
|
Assert.FileExists(result, OutputPath, "PackageLibraryDirectDependency.dll");
|
||||||
|
|
||||||
|
Assert.NupkgDoesNotContain(
|
||||||
|
result,
|
||||||
|
Path.Combine("..", "TestPackageRestoreSource", "PackageLibraryDirectDependency.1.0.0.nupkg"),
|
||||||
|
filePaths: new[]
|
||||||
|
{
|
||||||
|
Path.Combine("staticwebassets", "js", "pkg-direct-dep.js"),
|
||||||
|
Path.Combine("staticwebassets", "css", "site.css"),
|
||||||
|
Path.Combine("build", "Microsoft.AspNetCore.StaticWebAssets.props"),
|
||||||
|
Path.Combine("build", "PackageLibraryDirectDependency.props"),
|
||||||
|
Path.Combine("buildMultiTargeting", "PackageLibraryDirectDependency.props"),
|
||||||
|
Path.Combine("buildTransitive", "PackageLibraryDirectDependency.props")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[InitializeTestProject("PackageLibraryDirectDependency", additionalProjects: new[] { "PackageLibraryTransitiveDependency" })]
|
||||||
|
public async Task Pack_NoBuild_IncludesStaticWebAssets()
|
||||||
|
{
|
||||||
|
var result = await DotnetMSBuild("Build");
|
||||||
|
Assert.BuildPassed(result, allowWarnings: true);
|
||||||
|
|
||||||
|
var pack = await DotnetMSBuild("Pack", "/p:NoBuild=true");
|
||||||
|
Assert.BuildPassed(pack, allowWarnings: true);
|
||||||
|
|
||||||
|
Assert.FileExists(pack, OutputPath, "PackageLibraryDirectDependency.dll");
|
||||||
|
|
||||||
|
Assert.NupkgContains(
|
||||||
|
pack,
|
||||||
|
Path.Combine("..", "TestPackageRestoreSource", "PackageLibraryDirectDependency.1.0.0.nupkg"),
|
||||||
|
filePaths: new[]
|
||||||
|
{
|
||||||
|
Path.Combine("staticwebassets", "js", "pkg-direct-dep.js"),
|
||||||
|
Path.Combine("staticwebassets", "css", "site.css"),
|
||||||
|
Path.Combine("build", "Microsoft.AspNetCore.StaticWebAssets.props"),
|
||||||
|
Path.Combine("build", "PackageLibraryDirectDependency.props"),
|
||||||
|
Path.Combine("buildMultiTargeting", "PackageLibraryDirectDependency.props"),
|
||||||
|
Path.Combine("buildTransitive", "PackageLibraryDirectDependency.props")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[InitializeTestProject("ComponentLibrary")]
|
||||||
|
public async Task Pack_DoesNotIncludeAnyCustomPropsFiles_WhenNoStaticAssetsAreAvailable()
|
||||||
|
{
|
||||||
|
MSBuildIntegrationTestBase.TargetFramework = "netstandard2.0";
|
||||||
|
|
||||||
|
var result = await DotnetMSBuild("Pack");
|
||||||
|
|
||||||
|
Assert.BuildPassed(result, allowWarnings: true);
|
||||||
|
|
||||||
|
Assert.FileExists(result, OutputPath, "ComponentLibrary.dll");
|
||||||
|
|
||||||
|
Assert.NupkgDoesNotContain(
|
||||||
|
result,
|
||||||
|
Path.Combine("bin", Configuration, "ComponentLibrary.1.0.0.nupkg"),
|
||||||
|
filePaths: new[]
|
||||||
|
{
|
||||||
|
Path.Combine("build", "Microsoft.AspNetCore.StaticWebAssets.props"),
|
||||||
|
Path.Combine("build", "ComponentLibrary.props"),
|
||||||
|
Path.Combine("buildMultiTargeting", "ComponentLibrary.props"),
|
||||||
|
Path.Combine("buildTransitive", "ComponentLibrary.props")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[InitializeTestProject("PackageLibraryTransitiveDependency")]
|
||||||
|
public async Task Pack_Incremental_DoesNotRegenerateCacheAndPropsFiles()
|
||||||
|
{
|
||||||
|
TargetFramework = "netstandard2.0";
|
||||||
|
var result = await DotnetMSBuild("Pack");
|
||||||
|
|
||||||
|
Assert.BuildPassed(result, allowWarnings: true);
|
||||||
|
|
||||||
|
Assert.FileExists(result, OutputPath, "PackageLibraryTransitiveDependency.dll");
|
||||||
|
|
||||||
|
Assert.FileExists(result, IntermediateOutputPath, "staticwebassets", "msbuild.PackageLibraryTransitiveDependency.Microsoft.AspNetCore.StaticWebAssets.props");
|
||||||
|
Assert.FileExists(result, IntermediateOutputPath, "staticwebassets", "msbuild.build.PackageLibraryTransitiveDependency.props");
|
||||||
|
Assert.FileExists(result, IntermediateOutputPath, "staticwebassets", "msbuild.buildMultiTargeting.PackageLibraryTransitiveDependency.props");
|
||||||
|
Assert.FileExists(result, IntermediateOutputPath, "staticwebassets", "msbuild.buildTransitive.PackageLibraryTransitiveDependency.props");
|
||||||
|
Assert.FileExists(result, IntermediateOutputPath, "staticwebassets", "PackageLibraryTransitiveDependency.StaticWebAssets.Pack.cache");
|
||||||
|
|
||||||
|
var directoryPath = Path.Combine(result.Project.DirectoryPath, IntermediateOutputPath, "staticwebassets");
|
||||||
|
var thumbPrints = new Dictionary<string, FileThumbPrint>();
|
||||||
|
var thumbPrintFiles = new[]
|
||||||
|
{
|
||||||
|
Path.Combine(directoryPath, "msbuild.PackageLibraryTransitiveDependency.Microsoft.AspNetCore.StaticWebAssets.props"),
|
||||||
|
Path.Combine(directoryPath, "msbuild.build.PackageLibraryTransitiveDependency.props"),
|
||||||
|
Path.Combine(directoryPath, "msbuild.buildMultiTargeting.PackageLibraryTransitiveDependency.props"),
|
||||||
|
Path.Combine(directoryPath, "msbuild.buildTransitive.PackageLibraryTransitiveDependency.props"),
|
||||||
|
Path.Combine(directoryPath, "PackageLibraryTransitiveDependency.StaticWebAssets.Pack.cache"),
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var file in thumbPrintFiles)
|
||||||
|
{
|
||||||
|
var thumbprint = GetThumbPrint(file);
|
||||||
|
thumbPrints[file] = thumbprint;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var incremental = await DotnetMSBuild("Pack");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.BuildPassed(incremental, allowWarnings: true);
|
||||||
|
|
||||||
|
foreach (var file in thumbPrintFiles)
|
||||||
|
{
|
||||||
|
var thumbprint = GetThumbPrint(file);
|
||||||
|
Assert.Equal(thumbPrints[file], thumbprint);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,18 +43,73 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
Assert.BuildPassed(result);
|
Assert.BuildPassed(result);
|
||||||
|
|
||||||
// GenerateStaticWebAssetsManifest should generate the manifest and the cache.
|
// GenerateStaticWebAssetsManifest should generate the manifest and the cache.
|
||||||
Assert.FileExists(result, IntermediateOutputPath, "AppWithPackageAndP2PReference.StaticWebAssets.xml");
|
Assert.FileExists(result, IntermediateOutputPath, "staticwebassets", "AppWithPackageAndP2PReference.StaticWebAssets.xml");
|
||||||
Assert.FileExists(result, IntermediateOutputPath, "AppWithPackageAndP2PReference.StaticWebAssets.cache");
|
Assert.FileExists(result, IntermediateOutputPath, "staticwebassets", "AppWithPackageAndP2PReference.StaticWebAssets.Manifest.cache");
|
||||||
|
if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||||
|
{
|
||||||
|
// Skip this check on mac as the CI seems to use a somewhat different path on OSX.
|
||||||
|
// This check works just fine on a local OSX instance, but the CI path seems to require prepending /private.
|
||||||
|
// There is nothing OS specific about publishing this file, so the chances of this breaking are infinitesimal.
|
||||||
|
Assert.FileExists(result, OutputPath, "AppWithPackageAndP2PReference.StaticWebAssets.xml");
|
||||||
|
}
|
||||||
|
|
||||||
var path = Assert.FileExists(result, OutputPath, "AppWithPackageAndP2PReference.dll");
|
var path = Assert.FileExists(result, OutputPath, "AppWithPackageAndP2PReference.dll");
|
||||||
var assembly = Assert.ContainsEmbeddedResource(path, "Microsoft.AspNetCore.StaticWebAssets.xml");
|
var assembly = Assert.ContainsEmbeddedResource(path, "Microsoft.AspNetCore.StaticWebAssets.xml");
|
||||||
using (var reader = new StreamReader(assembly))
|
using (var reader = new StreamReader(assembly))
|
||||||
{
|
{
|
||||||
var data = await reader.ReadToEndAsync();
|
var data = await reader.ReadToEndAsync();
|
||||||
|
Output.WriteLine("Manifest:");
|
||||||
|
Output.WriteLine(data);
|
||||||
Assert.Equal(expectedManifest, data);
|
Assert.Equal(expectedManifest, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[InitializeTestProject("AppWithPackageAndP2PReference", additionalProjects: new[] { "ClassLibrary", "ClassLibrary2" })]
|
||||||
|
public async Task Publish_CopiesStaticWebAssetsToDestinationFolder()
|
||||||
|
{
|
||||||
|
var result = await DotnetMSBuild("Publish", "/restore");
|
||||||
|
|
||||||
|
Assert.BuildPassed(result);
|
||||||
|
|
||||||
|
Assert.FileExists(result, PublishOutputPath, Path.Combine("wwwroot", "_content", "classlibrary", "js", "project-transitive-dep.js"));
|
||||||
|
Assert.FileExists(result, PublishOutputPath, Path.Combine("wwwroot", "_content", "classlibrary", "js", "project-transitive-dep.v4.js"));
|
||||||
|
Assert.FileExists(result, PublishOutputPath, Path.Combine("wwwroot", "_content", "classlibrary2", "css", "site.css"));
|
||||||
|
Assert.FileExists(result, PublishOutputPath, Path.Combine("wwwroot", "_content", "classlibrary2", "js", "project-direct-dep.js"));
|
||||||
|
Assert.FileExists(result, PublishOutputPath, Path.Combine("wwwroot", "_content", "packagelibrarydirectdependency", "css", "site.css"));
|
||||||
|
Assert.FileExists(result, PublishOutputPath, Path.Combine("wwwroot", "_content", "packagelibrarydirectdependency", "js", "pkg-direct-dep.js"));
|
||||||
|
Assert.FileExists(result, PublishOutputPath, Path.Combine("wwwroot", "_content", "packagelibrarytransitivedependency", "js", "pkg-transitive-dep.js"));
|
||||||
|
|
||||||
|
// Validate that static web assets don't get published as content too on their regular path
|
||||||
|
Assert.FileDoesNotExist(result, PublishOutputPath, Path.Combine("wwwroot", "js", "project-transitive-dep.js"));
|
||||||
|
Assert.FileDoesNotExist(result, PublishOutputPath, Path.Combine("wwwroot", "js", "project-transitive-dep.v4.js"));
|
||||||
|
|
||||||
|
// Validate that the manifest never gets copied
|
||||||
|
Assert.FileDoesNotExist(result, PublishOutputPath, "AppWithPackageAndP2PReference.StaticWebAssets.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[InitializeTestProject("AppWithPackageAndP2PReference", additionalProjects: new[] { "ClassLibrary", "ClassLibrary2" })]
|
||||||
|
public async Task Publish_WithBuildReferencesDisabled_CopiesStaticWebAssetsToDestinationFolder()
|
||||||
|
{
|
||||||
|
var build = await DotnetMSBuild("Build", "/restore");
|
||||||
|
|
||||||
|
Assert.BuildPassed(build);
|
||||||
|
|
||||||
|
var publish = await DotnetMSBuild("Publish", "/p:BuildProjectReferences=false");
|
||||||
|
|
||||||
|
Assert.BuildPassed(publish);
|
||||||
|
|
||||||
|
Assert.FileExists(publish, PublishOutputPath, Path.Combine("wwwroot", "_content", "classlibrary", "js", "project-transitive-dep.js"));
|
||||||
|
Assert.FileExists(publish, PublishOutputPath, Path.Combine("wwwroot", "_content", "classlibrary", "js", "project-transitive-dep.v4.js"));
|
||||||
|
Assert.FileExists(publish, PublishOutputPath, Path.Combine("wwwroot", "_content", "classlibrary2", "css", "site.css"));
|
||||||
|
Assert.FileExists(publish, PublishOutputPath, Path.Combine("wwwroot", "_content", "classlibrary2", "js", "project-direct-dep.js"));
|
||||||
|
Assert.FileExists(publish, PublishOutputPath, Path.Combine("wwwroot", "_content", "packagelibrarydirectdependency", "css", "site.css"));
|
||||||
|
Assert.FileExists(publish, PublishOutputPath, Path.Combine("wwwroot", "_content", "packagelibrarydirectdependency", "js", "pkg-direct-dep.js"));
|
||||||
|
Assert.FileExists(publish, PublishOutputPath, Path.Combine("wwwroot", "_content", "packagelibrarytransitivedependency", "js", "pkg-transitive-dep.js"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[InitializeTestProject("SimpleMvc")]
|
[InitializeTestProject("SimpleMvc")]
|
||||||
public async Task Build_DoesNotEmbedManifestWhen_NoStaticResourcesAvailable()
|
public async Task Build_DoesNotEmbedManifestWhen_NoStaticResourcesAvailable()
|
||||||
|
|
@ -64,8 +119,9 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
Assert.BuildPassed(result);
|
Assert.BuildPassed(result);
|
||||||
|
|
||||||
// GenerateStaticWebAssetsManifest should generate the manifest and the cache.
|
// GenerateStaticWebAssetsManifest should generate the manifest and the cache.
|
||||||
Assert.FileExists(result, IntermediateOutputPath, "SimpleMvc.StaticWebAssets.xml");
|
Assert.FileExists(result, IntermediateOutputPath, "staticwebassets", "SimpleMvc.StaticWebAssets.xml");
|
||||||
Assert.FileExists(result, IntermediateOutputPath, "SimpleMvc.StaticWebAssets.cache");
|
Assert.FileExists(result, IntermediateOutputPath, "staticwebassets", "SimpleMvc.StaticWebAssets.Manifest.cache");
|
||||||
|
Assert.FileDoesNotExist(result, OutputPath, "SimpleMvc.StaticWebAssets.xml");
|
||||||
|
|
||||||
var path = Assert.FileExists(result, OutputPath, "SimpleMvc.dll");
|
var path = Assert.FileExists(result, OutputPath, "SimpleMvc.dll");
|
||||||
Assert.DoesNotContainEmbeddedResource(path, "SimpleMvc.StaticWebAssets.xml");
|
Assert.DoesNotContainEmbeddedResource(path, "SimpleMvc.StaticWebAssets.xml");
|
||||||
|
|
@ -80,16 +136,16 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
Assert.BuildPassed(result);
|
Assert.BuildPassed(result);
|
||||||
|
|
||||||
// GenerateStaticWebAssetsManifest should generate the manifest and the cache.
|
// GenerateStaticWebAssetsManifest should generate the manifest and the cache.
|
||||||
Assert.FileExists(result, IntermediateOutputPath, "AppWithPackageAndP2PReference.StaticWebAssets.xml");
|
Assert.FileExists(result, IntermediateOutputPath, "staticwebassets", "AppWithPackageAndP2PReference.StaticWebAssets.xml");
|
||||||
Assert.FileExists(result, IntermediateOutputPath, "AppWithPackageAndP2PReference.StaticWebAssets.cache");
|
Assert.FileExists(result, IntermediateOutputPath, "staticwebassets", "AppWithPackageAndP2PReference.StaticWebAssets.Manifest.cache");
|
||||||
|
|
||||||
var cleanResult = await DotnetMSBuild("Clean");
|
var cleanResult = await DotnetMSBuild("Clean");
|
||||||
|
|
||||||
Assert.BuildPassed(cleanResult);
|
Assert.BuildPassed(cleanResult);
|
||||||
|
|
||||||
// Clean should delete the manifest and the cache.
|
// Clean should delete the manifest and the cache.
|
||||||
Assert.FileDoesNotExist(result, IntermediateOutputPath, "AppWithPackageAndP2PReference.StaticWebAssets.cache");
|
Assert.FileDoesNotExist(result, IntermediateOutputPath, "staticwebassets", "AppWithPackageAndP2PReference.StaticWebAssets.Manifest.cache");
|
||||||
Assert.FileDoesNotExist(result, IntermediateOutputPath, "AppWithPackageAndP2PReference.StaticWebAssets.xml");
|
Assert.FileDoesNotExist(result, IntermediateOutputPath, "staticwebassets", "AppWithPackageAndP2PReference.StaticWebAssets.xml");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -104,15 +160,15 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
Assert.BuildPassed(result);
|
Assert.BuildPassed(result);
|
||||||
|
|
||||||
// GenerateStaticWebAssetsManifest should generate the manifest and the cache.
|
// GenerateStaticWebAssetsManifest should generate the manifest and the cache.
|
||||||
Assert.FileExists(result, IntermediateOutputPath, "AppWithPackageAndP2PReference.StaticWebAssets.xml");
|
Assert.FileExists(result, IntermediateOutputPath, "staticwebassets", "AppWithPackageAndP2PReference.StaticWebAssets.xml");
|
||||||
Assert.FileExists(result, IntermediateOutputPath, "AppWithPackageAndP2PReference.StaticWebAssets.cache");
|
Assert.FileExists(result, IntermediateOutputPath, "staticwebassets", "AppWithPackageAndP2PReference.StaticWebAssets.Manifest.cache");
|
||||||
|
|
||||||
var directoryPath = Path.Combine(result.Project.DirectoryPath, IntermediateOutputPath);
|
var directoryPath = Path.Combine(result.Project.DirectoryPath, IntermediateOutputPath, "staticwebassets");
|
||||||
var thumbPrints = new Dictionary<string, FileThumbPrint>();
|
var thumbPrints = new Dictionary<string, FileThumbPrint>();
|
||||||
var thumbPrintFiles = new[]
|
var thumbPrintFiles = new[]
|
||||||
{
|
{
|
||||||
Path.Combine(directoryPath, "AppWithPackageAndP2PReference.StaticWebAssets.xml"),
|
Path.Combine(directoryPath, "AppWithPackageAndP2PReference.StaticWebAssets.xml"),
|
||||||
Path.Combine(directoryPath, "AppWithPackageAndP2PReference.StaticWebAssets.cache"),
|
Path.Combine(directoryPath, "AppWithPackageAndP2PReference.StaticWebAssets.Manifest.cache"),
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var file in thumbPrintFiles)
|
foreach (var file in thumbPrintFiles)
|
||||||
|
|
@ -151,15 +207,15 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
Assert.BuildPassed(result);
|
Assert.BuildPassed(result);
|
||||||
|
|
||||||
// GenerateStaticWebAssetsManifest should generate the manifest and the cache.
|
// GenerateStaticWebAssetsManifest should generate the manifest and the cache.
|
||||||
Assert.FileExists(result, IntermediateOutputPath, "AppWithPackageAndP2PReference.StaticWebAssets.xml");
|
Assert.FileExists(result, IntermediateOutputPath, "staticwebassets", "AppWithPackageAndP2PReference.StaticWebAssets.xml");
|
||||||
Assert.FileExists(result, IntermediateOutputPath, "AppWithPackageAndP2PReference.StaticWebAssets.cache");
|
Assert.FileExists(result, IntermediateOutputPath, "staticwebassets", "AppWithPackageAndP2PReference.StaticWebAssets.Manifest.cache");
|
||||||
|
|
||||||
var directoryPath = Path.Combine(result.Project.DirectoryPath, IntermediateOutputPath);
|
var directoryPath = Path.Combine(result.Project.DirectoryPath, IntermediateOutputPath, "staticwebassets");
|
||||||
var thumbPrints = new Dictionary<string, FileThumbPrint>();
|
var thumbPrints = new Dictionary<string, FileThumbPrint>();
|
||||||
var thumbPrintFiles = new[]
|
var thumbPrintFiles = new[]
|
||||||
{
|
{
|
||||||
Path.Combine(directoryPath, "AppWithPackageAndP2PReference.StaticWebAssets.xml"),
|
Path.Combine(directoryPath, "AppWithPackageAndP2PReference.StaticWebAssets.xml"),
|
||||||
Path.Combine(directoryPath, "AppWithPackageAndP2PReference.StaticWebAssets.cache"),
|
Path.Combine(directoryPath, "AppWithPackageAndP2PReference.StaticWebAssets.Manifest.cache"),
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var file in thumbPrintFiles)
|
foreach (var file in thumbPrintFiles)
|
||||||
|
|
@ -201,17 +257,17 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
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", "build", "..", "staticwebassets") + Path.DirectorySeparatorChar,
|
||||||
Path.Combine(restorePath, "packagelibrarydirectdependency", "1.0.0", "build", "..", "razorContent") + Path.DirectorySeparatorChar,
|
Path.Combine(restorePath, "packagelibrarydirectdependency", "1.0.0", "build", "..", "staticwebassets") + Path.DirectorySeparatorChar,
|
||||||
Path.GetFullPath(Path.Combine(source, "ClassLibrary", "wwwroot")) + Path.DirectorySeparatorChar,
|
Path.GetFullPath(Path.Combine(source, "ClassLibrary", "wwwroot")) + Path.DirectorySeparatorChar,
|
||||||
Path.GetFullPath(Path.Combine(source, "ClassLibrary2", "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/PackageLibraryDirectDependency"" Path=""{projects[1]}"" />
|
|
||||||
<ContentRoot BasePath=""_content/classlibrary"" Path=""{projects[2]}"" />
|
<ContentRoot BasePath=""_content/classlibrary"" Path=""{projects[2]}"" />
|
||||||
<ContentRoot BasePath=""_content/classlibrary2"" Path=""{projects[3]}"" />
|
<ContentRoot BasePath=""_content/classlibrary2"" Path=""{projects[3]}"" />
|
||||||
|
<ContentRoot BasePath=""_content/packagelibrarydirectdependency"" Path=""{projects[1]}"" />
|
||||||
|
<ContentRoot BasePath=""_content/packagelibrarytransitivedependency"" Path=""{projects[0]}"" />
|
||||||
</StaticWebAssets>";
|
</StaticWebAssets>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
// 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;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using Microsoft.AspNetCore.Razor.Tasks;
|
||||||
|
using Microsoft.Build.Framework;
|
||||||
|
using Moq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Razor.Tasks
|
||||||
|
{
|
||||||
|
public class StaticWebAssetsGeneratePackagePropsFileTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void WritesPropsFile_WithProvidedImportPath()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var file = Path.GetTempFileName();
|
||||||
|
var expectedDocument = @"<Project>
|
||||||
|
<Import Project=""Microsoft.AspNetCore.StaticWebAssets.props"" />
|
||||||
|
</Project>";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var buildEngine = new Mock<IBuildEngine>();
|
||||||
|
|
||||||
|
var task = new StaticWebAssetsGeneratePackagePropsFile
|
||||||
|
{
|
||||||
|
BuildEngine = buildEngine.Object,
|
||||||
|
PropsFileImport="Microsoft.AspNetCore.StaticWebAssets.props",
|
||||||
|
BuildTargetPath=file
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = task.Execute();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.True(result);
|
||||||
|
var document = File.ReadAllText(file);
|
||||||
|
Assert.Equal(expectedDocument, document);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (File.Exists(file))
|
||||||
|
{
|
||||||
|
File.Delete(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -36,9 +36,9 @@
|
||||||
<!-- Test Placeholder -->
|
<!-- Test Placeholder -->
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="build\**" Pack="true" PackagePath="build" />
|
<!-- <Content Include="build\**" Pack="true" PackagePath="build" /> -->
|
||||||
<!-- We will remove the line below when we do the item to support packing -->
|
<!-- We will remove the line below when we do the item to support packing -->
|
||||||
<Content Update="wwwroot\**" Pack="true" PackagePath="razorContent" />
|
<!-- <Content Update="wwwroot\**" Pack="true" PackagePath="razorContent" /> -->
|
||||||
<ProjectReference Include="..\PackageLibraryTransitiveDependency\PackageLibraryTransitiveDependency.csproj" />
|
<ProjectReference Include="..\PackageLibraryTransitiveDependency\PackageLibraryTransitiveDependency.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
<Project>
|
|
||||||
<ItemGroup>
|
|
||||||
<StaticWebAsset Include="$(MSBuildThisFileDirectory)..\razorContent\**">
|
|
||||||
<SourceType>Package</SourceType>
|
|
||||||
<SourceId>PackageLibraryDirectDependency</SourceId>
|
|
||||||
<ContentRoot>$([MSBuild]::EnsureTrailingSlash('$(MSBuildThisFileDirectory)..\razorContent'))</ContentRoot>
|
|
||||||
<BasePath>_content\PackageLibraryDirectDependency</BasePath>
|
|
||||||
<RelativePath>%(RecursiveDir)%(FileName)%(Extension)</RelativePath>
|
|
||||||
</StaticWebAsset>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
|
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
|
||||||
|
<RazorLangVersion>3.0</RazorLangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|
@ -35,10 +36,4 @@
|
||||||
|
|
||||||
<!-- Test Placeholder -->
|
<!-- Test Placeholder -->
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Content Include="build\**" Pack="true" PackagePath="buildTransitive" />
|
|
||||||
<!-- We will remove the line below when we do the item to support packing -->
|
|
||||||
<Content Update="wwwroot\**" Pack="true" PackagePath="razorContent" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
<Project>
|
|
||||||
<ItemGroup>
|
|
||||||
<StaticWebAsset Include="$(MSBuildThisFileDirectory)..\razorContent\**">
|
|
||||||
<SourceType>Package</SourceType>
|
|
||||||
<SourceId>PackageLibraryTransitiveDependency</SourceId>
|
|
||||||
<ContentRoot>$([MSBuild]::EnsureTrailingSlash('$(MSBuildThisFileDirectory)..\razorContent'))</ContentRoot>
|
|
||||||
<BasePath>_content\PackageLibraryTransitiveDependency</BasePath>
|
|
||||||
<RelativePath>%(RecursiveDir)%(FileName)%(Extension)</RelativePath>
|
|
||||||
</StaticWebAsset>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
Loading…
Reference in New Issue