Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
X.Y.Z.Sources nuget package
<Project>
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
<PropertyGroup>
<TargetFramework>netstandard1.0</TargetFramework>
<IsPackable>true</IsPackable>
<IncludeBuildOutput>false</IncludeBuildOutput>
<ContentTargetFolders>contentFiles</ContentTargetFolders>
<DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
<NoWarn>CS8021</NoWarn>
<NoBuild>true</NoBuild>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
</PropertyGroup>
<ItemGroup>
<Compile Update="@(Compile)">
<Pack>true</Pack>
<PackagePath>$(ContentTargetFolders)\cs\netstandard1.0\$(PackageId)\%(RecursiveDir)\</PackagePath>
</Compile>
<EmbeddedResource Update="@(EmbeddedResource)">
<Pack>true</Pack>
<PackagePath>$(ContentTargetFolders)\any\any\$(PackageId)\%(RecursiveDir)\</PackagePath>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<PackageReference Remove="@(PackageReference)" />
</ItemGroup>
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
<Target Name="Compile" />
<Target Name="CopyFilesToOutputDirectory" />
</Project>
@danielcrenna

This comment has been minimized.

Copy link

@danielcrenna danielcrenna commented Nov 10, 2018

@attilah This is great work, thanks for sharing. Do you have a license file you can add?

I modified it to support .pp.cs extensions, so that the .cs files take on the namespace of the package consuming project. It copies transformed .cs files transparently on pre-build. Unfortunately, I have to run a console application to clean up the .nuspec for this due to extra attributes added to the <PackageReference /> and <file /> tags, but it works.

Here's my fork: https://gist.github.com/danielcrenna/f87dd455e31e90ee9c402c0ca06982f2

@gitfool

This comment has been minimized.

Copy link

@gitfool gitfool commented Jan 1, 2019

When generating the NuGet package version with SourceLink I had to remove the following:

<ItemGroup>
  <PackageReference Remove="@(PackageReference)" />
</ItemGroup>

... but now I can suppress the framework dependencies using:

<PropertyGroup>
  <SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
</PropertyGroup>

Links:

@oleg-shilo

This comment has been minimized.

Copy link

@oleg-shilo oleg-shilo commented Apr 18, 2019

Hi there, how one can control the version of the built package. Right now it always builds v1.0.0.0.
Changing the version in the project properties of course has no effect since there is no file nor assembly to be set.

Any ideas?

@oleg-shilo

This comment has been minimized.

Copy link

@oleg-shilo oleg-shilo commented Apr 18, 2019

Found it.:

<PackageVersion>1.2.3.4</PackageVersion>
@oleg-shilo

This comment has been minimized.

Copy link

@oleg-shilo oleg-shilo commented Apr 18, 2019

And the next question :)

Is there any way to define for the included content file that it should be copied to the output folder when the project that references the package is built?

@georgiosd

This comment has been minimized.

Copy link

@georgiosd georgiosd commented Jul 24, 2019

@attilah where is the actual source code kept when the packages are referenced? Is there any way to copy them to the project like in the old days?

@attilah

This comment has been minimized.

Copy link
Owner Author

@attilah attilah commented Jul 24, 2019

@georgiosd I'm sure there is a way, since you can derive the path of the source files from the referenced package's restored folder, but not sure why would you want that. It is like copying over dlls referenced from other packages.

@attilah

This comment has been minimized.

Copy link
Owner Author

@attilah attilah commented Jul 24, 2019

@oleg-shilo to make source references work the project file nulls out the CopyFilesToOutputDirectory target which would interpret the copy to output folder related properties, so I think you cannot combine them with the standard method but you can define your own target that would do just that.

@oleg-shilo

This comment has been minimized.

Copy link

@oleg-shilo oleg-shilo commented Jul 25, 2019

Txs. I is consistent with my observations.

@attilah

This comment has been minimized.

Copy link
Owner Author

@attilah attilah commented Jul 25, 2019

@oleg-shilo Awesome ;-) sorry for the late answer somehow I missed the notification :-S

@oleg-shilo

This comment has been minimized.

Copy link

@oleg-shilo oleg-shilo commented Jul 25, 2019

It happens to me a lot. GitHub sometimes does not send them diligently :)
No drama...

@georgiosd

This comment has been minimized.

Copy link

@georgiosd georgiosd commented Jul 25, 2019

@attilah my question wasn't clear I guess, it's two-fold :)

a) I am puzzled as to where the source files are stored if not added to the project itself LOL

b) I am wondering if you know how to modify this setup such that the files are copied to the project like nuget used in the early versions. The reason for this, is to be able to maintain source code bases without necessarily maintaining a custom nuget server. Each project will own the source code of the version of the package that was imported, kinda like git submodules.

@danielcrenna

This comment has been minimized.

Copy link

@danielcrenna danielcrenna commented Sep 2, 2019

@georgiosd I struggled with that as well, and this is what I came up with: https://github.com/hq-io/Community/tree/master/Squire

@georgiosd

This comment has been minimized.

Copy link

@georgiosd georgiosd commented Sep 3, 2019

@danielcrenna - you sir, are a beast :)

@TrabacchinLuigi

This comment has been minimized.

Copy link

@TrabacchinLuigi TrabacchinLuigi commented Nov 21, 2019

Hi, i've been using this for a little but what i found out is that sometimes source only packages aren't the best, but sometimes i really need em, but i always want to maintain just one code base.
So starting from here i've tried to add configurations, just to fail miserably, i'll share a gist of what i've tried so far, but i have to separate it from the actual project i've tried it on.
Did someone already tried that ? got any advice ?

I've managed to make it work.
The tricky part where the Target tags, that where overriding the imported targets even with the condition specified. putting them in a separate file that get imported only when needed yielded the desired result.
My version of this Gist is here.

@kzu

This comment has been minimized.

Copy link

@kzu kzu commented May 20, 2020

@attilah I think it would be great if you added the property mentioned by @gitfool, SuppressDependenciesWhenPacking=true

@danielcrenna

This comment has been minimized.

Copy link

@danielcrenna danielcrenna commented May 22, 2020

When .NET 5.0 SourceGenerators are able to actually reference other .NET Standard libraries through the Roslyn Analyzers path (see: dotnet/roslyn#43903), I think this will be a preferred way to ship sources, since you are able to control their generation at the user's build time, which makes most scenarios we wish we had with source packages (like getting updates or tweaking values post-install) first-class experiences, again.

@markusschaber

This comment has been minimized.

Copy link

@markusschaber markusschaber commented Aug 4, 2020

Just one question: Do project references to this projects still work?
We have the habit of using project references of "nuget packaged" projects within the same solution, so when building the solution, we get the latest changes without the roundtrip of CI system and NuGet Package.

@attilah

This comment has been minimized.

Copy link
Owner Author

@attilah attilah commented Aug 4, 2020

@kzu updated the gist with the property

@markusschaber

This comment has been minimized.

Copy link

@markusschaber markusschaber commented Aug 10, 2020

It seems that project references do not work, and another problem seems to be that, while the ResX files are included within the NuGet Package, they're ignored (not processed) in the referencing project.

It seems to be hard to find documentation about this. :-(

I put a small code example on github: https://github.com/markusschaber/SourceOnlyNugetTest
The ConsoleApp1 fails with MissingManifestResource Exception.

@JakobFerdinand

This comment has been minimized.

Copy link

@JakobFerdinand JakobFerdinand commented Mar 25, 2021

Hello,
Thank you for that great example and medium article.
I tried to use it but I experienced some issues when using it in an WPF environment.
As soon as an UserControl is added to the Project, the compailer cant find the nuget imported c# files.

I created that sample project to demonstrate the problem.
Can anyone help here? ;) Thank you!

@kzu

This comment has been minimized.

Copy link

@kzu kzu commented Mar 28, 2021

Added support in NuGetizer for the SuppressDependenciesWhenPacking property: devlooped/nugetizer#68

I learned about it thanks to this gist, so, thanks!

@gitfool

This comment has been minimized.

Copy link

@gitfool gitfool commented Mar 28, 2021

@kzu can NuGetizer be used to define NuGet source packages more concisely?

@kzu

This comment has been minimized.

Copy link

@kzu kzu commented Mar 30, 2021

Oh, absolutely.

The above sample would look like the following:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard1.0</TargetFramework>
    <PackageId>X.Y.Z</PackageId>
    <PackBuildOutput>false</PackBuildOutput>
    <PackCompile>true</PackCompile>
    <PackEmbeddedResource>true</PackEmbeddedResource>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="NuGetizer" Version="0.6.0" />
  </ItemGroup>

</Project>

And given a couple .cs and a .resx, you'd get a package with the following content after running dotnet restore followed by dotnet pack:

Package: X.Y.Z.1.0.0.nupkg
         C:\Delete\sourceonly\bin\X.Y.Z.nuspec
    Authors    : X.Y.Z.Sources
    Description: Package Description
    Version    : 1.0.0
  Contents:
    /contentFiles/
      any/
        netstandard1.0/
          Properties/
            Resources.resx (buildAction=EmbeddedResource)
      cs/
        netstandard1.0/
          Program.cs (buildAction=Compile)
          Shared/
            Helper.cs (buildAction=Compile)

(the output is from the dotnet-nugetize global tool, which can be run simply with nugetize on the project directory).

The actual console output looks way nicer though ;)

image

It makes it very easy to quickly iterate on the packaging structure without ever having to build or even pack/zip files.

If you wanted the .resx to also be provided only for the cs code language you just update those appropriately:

  <ItemGroup>
    <EmbeddedResource Update="@(EmbeddedResource)" CodeLanguage="cs" />
  </ItemGroup>
pwsh> nugetize

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:01.61
Package: X.Y.Z.1.0.0.nupkg
         C:\Delete\sourceonly\bin\X.Y.Z.nuspec
    Authors    : X.Y.Z.Sources
    Description: Package Description
    Version    : 1.0.0
  Contents:
    /contentFiles/
      cs/
        netstandard1.0/
          Program.cs (buildAction=Compile)
          Properties/
            Resources.resx (buildAction=EmbeddedResource)
          Shared/
            Helper.cs (buildAction=Compile)
@JakobFerdinand

This comment has been minimized.

Copy link

@JakobFerdinand JakobFerdinand commented Apr 15, 2021

Hello,
Thank you for that great example and medium article.
I tried to use it but I experienced some issues when using it in an WPF environment.
As soon as an UserControl is added to the Project, the compailer cant find the nuget imported c# files.

I created that sample project to demonstrate the problem.
Can anyone help here? ;) Thank you!

I could find a fix for the problem.
You have to add

<IncludePackageReferencesDuringMarkupCompilation>true</IncludePackageReferencesDuringMarkupCompilation>

to your WPF project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment