From following question How do I list all installed NuGet packages?
I need to get a list of nuget packages from MSBuild itself.
What I try to do:
<Target Name="test" AfterTargets="ResolveReferences">
<ItemGroup>
<BuildOutputInPackage Include="@(ReferenceCopyLocalPaths)"/>
</ItemGroup>
<Message Text="Files @(BuildOutputInPackage -> '%(identity)', ', ')" Importance="high"/>
</Target>
Above code return all references whether its nuget or project references dlls. How exactly to return a list of nuget package that currently project *.csproj used?
Format i.e: packageid:Portable.BouncyCastle version = "1.9.0"
I use old classic non-sdk csproj template and .NET 4.8 and <PackageReference> not packages.config files.
Its very bad to read *.csproj and do regex to get a list of <packageReferences. Maybe there's a recommended MSBuild macro to do this like code shown above <Target....
Very thankful to Jonathan Dodds for his answer above. I combined some approach with his @(PackageReference)
idea to get a version of currently referenced nuget package in old classic csproj template. Because a referenced version will not work with @(PackageReference) only
. Also dotnet list not worked well in old classic csproj template (non-sdk).
A code below do following:
(Note this approach is not 100% organic, MSBuild should provide a simple target for that):
@(PackageReference)
. Jonathan Doods approach above.nuget.exe pack ProjectPath.csproj
a ProjectName.nupkg nuget will generated.Use this code inside Directory.Build.targets or within your .csproj file.
<Target Name="GenerateNuspecFile">
<ItemGroup>
<!-- Get all references -->
<MyReference Include="@(ReferenceCopyLocalPaths)" Condition="%(extension) == '.dll'">
<FirstDir>$([System.IO.Directory]::GetParent(%(RelativeDir)))</FirstDir>
<LibDir>$([System.IO.Path]::GetFileNameWithoutExtension(%(MyReference.FirstDir)))</LibDir>
<SecondDir>$(FirstDir)</SecondDir>
<SecondDir Condition="$(LibDir) != 'lib'">$([System.IO.Directory]::GetParent(%(MyReference.FirstDir)))</SecondDir>
<VersionDir>$([System.IO.Directory]::GetParent(%(MyReference.SecondDir)))</VersionDir>
<PackageDir>$([System.IO.Directory]::GetParent(%(MyReference.VersionDir)))</PackageDir>
<PackageID>$([System.IO.Path]::GetFileName(%(MyReference.PackageDir)))</PackageID>
<NuspecFile>%(MyReference.VersionDir)\%(MyReference.PackageID).nuspec</NuspecFile>
</MyReference>
<!-- Get Non nuget references -->
<ExcludedReference Condition="@(MyReference) != ''" Include="@(MyReference -> '%(PackageID)')" Exclude="@(PackageReference -> '%(identity)')"/>
<!-- Get nuget references after exclude non-nuget references -->
<MyPackage Condition="@(MyReference) != ''" Include="@(MyReference -> '%(PackageID)')" Exclude="@(ExcludedReference -> '%(identity)')"/>
<!-- Read Nuspec File -->
<NuspecContent Condition="@(NuspecFile) != ''" Include="%(MyPackage.NuspecFile)">
<Content>$([System.IO.File]::ReadAllText(%(fullpath)))</Content>
<PackageIDRegex><id>(.*?)</id></PackageIDRegex>
<PackageID>$([System.Text.RegularExpressions.Regex]::Match('%(NuspecContent.Content)', '%(NuspecContent.PackageIDRegex)' ))</PackageID>
<PackageID>$([System.String]::Copy('%(NuspecContent.PackageID)').Replace('<id>','').Replace('</id>', '').Trim())</PackageID>
<VersionRegex><version>(.*?)</version></VersionRegex>
<Version>$([System.Text.RegularExpressions.Regex]::Match('%(NuspecContent.Content)', '%(NuspecContent.VersionRegex)' ))</Version>
<Version>$([System.String]::Copy('%(NuspecContent.Version)').Replace('<version>','').Replace('</version>', '').Trim())</Version>
</NuspecContent>
</ItemGroup>
<!-- Generate Nuspec File with dependencies-->
<PropertyGroup>
<NewLine>%0d%0a</NewLine>
<Space2>%20%20</Space2>
<Space4>$(Space2)$(Space2)</Space4>
<Space6>$(Space4)$(Space2)</Space6>
<HasDependencies>false</HasDependencies>
<HasDependencies Condition="@(MyPackage) != ''">true</HasDependencies>
<Nuspec>$(Nuspec)<?xml version="1.0" encoding="utf-8"?>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)<package >$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space2)<metadata>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<id>$id$</id>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<version>$version$</version>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<title>$title$</title>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<authors>$author$</authors>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<owners>$author$</owners>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<requireLicenseAcceptance>false</requireLicenseAcceptance>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<licenseUrl>https://Your Company.com</licenseUrl>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<icon>PackageIcon.png</icon>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<projectUrl>http://Your Company.com</projectUrl>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<description>$description$</description>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<releaseNotes>$description$</releaseNotes>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<copyright>$copyright$</copyright>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<tags>$title$ Your Company Your Company.com</tags>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<dependencies>$(NewLine)</Nuspec>
<Nuspec Condition="$(HasDependencies)">$(Nuspec)$(Space6)<group targetFramework=".NETFramework4.8">$(NewLine)</Nuspec>
<Nuspec Condition="$(HasDependencies)">$(Nuspec)@(NuspecContent -> '$(Space6)<dependency id="%(PackageID)" version="%(Version)"/>', '$(NewLine)')$(NewLine)</Nuspec>
<Nuspec Condition="$(HasDependencies)">$(Nuspec)$(Space6)</group>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)</dependencies>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space2)</metadata>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space2)<files>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space4)<file src="..\**\PackageIcon.png"/>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)$(Space2)</files>$(NewLine)</Nuspec>
<Nuspec>$(Nuspec)</package>$(NewLine)</Nuspec>
</PropertyGroup>
<WriteLinesToFile Lines="$(Nuspec)" File="$(MSBuildProjectDirectory)\$(MSBuildProjectName).nuspec" Overwrite="true"/>
</Target>
The generated .nuspec
file will be:
<?xml version="1.0" encoding="utf-8"?>
<package >
<metadata>
<id>$id$</id>
<version>$version$</version>
<title>$title$</title>
<authors>$author$</authors>
<owners>$author$</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<licenseUrl>https://company.com</licenseUrl>
<icon>PackageIcon.png</icon>
<projectUrl>http://company.com</projectUrl>
<description>$description$</description>
<releaseNotes>$description$</releaseNotes>
<copyright>$copyright$</copyright>
<tags>$title$ company company.com</tags>
<dependencies>
<dependency id="Company.Globals" version="2022.7.19"/>
<dependency id="Portable.BouncyCastle" version="1.9.0"/>
</dependencies>
</metadata>
<files>
<file src="..\**\PackageIcon.png"/>
</files>
</package>
Its really to hard to achieve anything with MSBuild. Maybe you can create a console app for that and just call console app directly with <Exec Command =""/>
. But current approach is friendly with MSBuild. Its not 100% organic approach. MSBuild should provide us a target to get a referenced nuget packages with its referenced version.