Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix transitive contentFiles support that's missing in nuget #9

Merged
merged 2 commits into from
Sep 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,16 @@ the annotation by attribute name.
### Your Own ServiceAttribute

If you want to declare your own `ServiceAttribute` and reuse from your projects,
you can do it too. Just exclude the automatic `contentFiles` that the package
reference contributes to your project:
you can do it too by setting the following property in your project file:

```xml
<ItemGroup>
<PackageReference Include="Devlooped.Extensions.DependencyInjection.Attributed" ExcludeAssets="contentFiles" Version="..." />
</ItemGroup>
<PropertyGroup>
<IncludeServiceAttribute>false</IncludeServiceAttribute>
</PropertyGroup>
```

This will not add the attribute to the project. You can now create the attribute
in your own shared library project like so:
This will not add the attribute to the project's compilation. You can now create
the attribute in your own shared library project like so:

```csharp
[AttributeUsage(AttributeTargets.Class)]
Expand All @@ -107,7 +106,7 @@ public class ServiceAttribute : Attribute

> NOTE: since the constructor argument is only used by the source generation to
> detemine the registration style, but never at run-time, you don't even need
> to keep it in a field or property!
> to keep it around in a field or property!

With this in place, you only need to add the package to the top-level project
that is adding the services to the collection!
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">

<Import Project="..\DependencyInjection.Attributed\Devlooped.Extensions.DependencyInjection.Attributed.props" />
<Import Project="..\DependencyInjection.Attributed\buildTransitive\Devlooped.Extensions.DependencyInjection.Attributed.props" />

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
Expand All @@ -27,6 +27,6 @@
<Using Include="Xunit.Abstractions" />
</ItemGroup>

<Import Project="..\DependencyInjection.Attributed\Devlooped.Extensions.DependencyInjection.Attributed.targets" />
<Import Project="..\DependencyInjection.Attributed\buildTransitive\Devlooped.Extensions.DependencyInjection.Attributed.targets" />

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,14 @@
<Title>Automatic compile-time service registrations for Microsoft.Extensions.DependencyInjection with no run-time dependencies.</Title>
<Description>$(Title)</Description>
<PackFolder>analyzers/dotnet</PackFolder>
<PackNone>true</PackNone>
</PropertyGroup>

<ItemGroup>
<Compile Remove="ServiceAttribute.cs" />
</ItemGroup>

<ItemGroup>
<Content Include="ServiceAttribute.cs" BuildAction="Compile" CodeLanguage="cs" Pack="true" />
</ItemGroup>

<ItemGroup>
<None Update="Devlooped.Extensions.DependencyInjection.Attributed.props" PackFolder="build" />
<None Update="Devlooped.Extensions.DependencyInjection.Attributed.targets" PackFolder="build" />
<!-- PackFolder=None causes the PackagePath to equal the relative path in the project -->
<None Update="@(None)" CopyToOutputDirectory="PreserveNewest" PackFolder="None" />
</ItemGroup>

<ItemGroup>
Expand All @@ -30,4 +25,69 @@
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
</ItemGroup>

<Target Name="PokePackageVersion" BeforeTargets="GetPackageContents" DependsOnTargets="CopyFilesToOutputDirectory"
Condition="'$(dotnet-nugetize)' == '' and Exists('$(OutputPath)\buildTransitive\Devlooped.Extensions.DependencyInjection.Attributed.props')">
<XmlPoke XmlInputPath="$(OutputPath)\buildTransitive\Devlooped.Extensions.DependencyInjection.Attributed.props" Query="/Project/PropertyGroup/DevloopedExtensionsDependencyInjectionVersion" Value="$(PackageVersion)" />
</Target>

<UsingTask
TaskName="XmlPoke"
TaskFactory="RoslynCodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
<Namespaces />
<Query />
<Value ParameterType="Microsoft.Build.Framework.ITaskItem" Required="true" />
<XmlInputPath ParameterType="Microsoft.Build.Framework.ITaskItem" Required="true" />
</ParameterGroup>
<Task>
<Using Namespace="Microsoft.Build.Framework" />
<Using Namespace="System.Xml" />
<Using Namespace="System.Xml.Linq" />
<Using Namespace="System.Xml.XPath" />
<Code Type="Fragment" Language="cs">
<![CDATA[
var xmlns = new XmlNamespaceManager(new NameTable());
if (!string.IsNullOrEmpty(Namespaces))
{
using (var reader = XmlReader.Create(new StringReader(Namespaces), new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment }))
{
while (reader.Read())
{
var prefix = reader.GetAttribute("Prefix");
var uri = reader.GetAttribute("Uri");
xmlns.AddNamespace(prefix, uri);
}
}
}

var doc = XDocument.Load(XmlInputPath.GetMetadata("FullPath"), LoadOptions.PreserveWhitespace);
var expr = doc.CreateNavigator().Compile(Query);
expr.SetContext (xmlns);

var replacements = 0;
foreach (var node in doc.CreateNavigator().Select(expr).OfType<XPathNavigator>().Select(x => x.UnderlyingObject))
{
var attr = node as XAttribute;
var elem = node as XElement;
if (attr != null) {
attr.SetValue (Value.ItemSpec);
replacements++;
} else if (elem != null) {
elem.SetValue (Value.ItemSpec);
replacements++;
}
}

if (replacements != 0) {
Log.LogMessage ("Made {0} replacement(s).", replacements);
doc.Save(XmlInputPath.GetMetadata ("FullPath"), SaveOptions.DisableFormatting);
} else {
Log.LogMessage("No nodes were affected.");
}
]]>
</Code>
</Task>
</UsingTask>

</Project>

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<Project>

<PropertyGroup>
<DevloopedExtensionsDependencyInjectionVersion>42.42.42</DevloopedExtensionsDependencyInjectionVersion>
</PropertyGroup>

<ItemGroup>
<CompilerVisibleProperty Include="AddServicesNamespace" />
<CompilerVisibleProperty Include="AddServicesClassName" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Project>

<PropertyGroup>
<DevloopedDependencyInjectionContentFilesPath>$(MSBuildThisFileDirectory)..\contentFiles\$(DefaultLanguageSourceExtension.TrimStart('.'))\netstandard2.0</DevloopedDependencyInjectionContentFilesPath>
</PropertyGroup>

<!-- In transitive mode, contentFiles will not flow: https://github.com/NuGet/Home/issues/6720 and others -->
<ItemGroup Condition="'$(IncludeServiceAttribute)' != 'false' and Exists('$(DevloopedDependencyInjectionContentFilesPath)') and '@(Compile -> WithMetadataValue('NuGetPackageId', 'Devlooped.Extensions.DependencyInjection.Attributed'))' == ''">
<Compile Include="$(DevloopedDependencyInjectionContentFilesPath)\*$(DefaultLanguageSourceExtension)">
<NuGetPackageId>Devlooped.Extensions.DependencyInjection.Attributed</NuGetPackageId>
<NuGetPackageVersion>$(DevloopedExtensionsDependencyInjectionVersion)</NuGetPackageVersion>
<NuGetItemType>Compile</NuGetItemType>
<Pack>false</Pack>
<Private>False</Private>
</Compile>
</ItemGroup>

<ItemGroup Condition="'$(IncludeServiceAttribute)' == 'false'">
<Compile Remove="@(Compile -> WithMetadataValue('NuGetPackageId', 'Devlooped.Extensions.DependencyInjection.Attributed'))" />
</ItemGroup>

<!-- Update Link/Visible for both transitively and non-transitively added contentFiles -->
<ItemGroup Condition="'$(IncludeServiceAttribute)' != 'false'">
<Compile Update="@(Compile -> WithMetadataValue('NuGetPackageId', 'Devlooped.Extensions.DependencyInjection.Attributed'))"
Visible="false"
Link="Devlooped\Extensions\DependencyInjection\Attributed\%(Filename)%(Extension)"/>
</ItemGroup>

</Project>