-
-
Save a4099181/074a6c3dd524ea0d343382137492399c to your computer and use it in GitHub Desktop.
Function Convert-ToPackageReference | |
{ | |
Param ( [Parameter( Mandatory, ValueFromPipeline )][String] $inputUri, | |
[String] $stylesheetUri = "https://gist.githubusercontent.com/a4099181/074a6c3dd524ea0d343382137492399c/raw/cdd0fb31efd70c4c0f8c86ddb314de86ab8972e8/Convert-ToPackageReference.xsl", | |
[String] $resultsFile = [System.IO.Path]::GetTempFileName() ) | |
Process { | |
$xslt = New-Object System.Xml.Xsl.XslCompiledTransform | |
$xslt.Load( $stylesheetUri ) | |
$xslt.Transform( $inputUri, $resultsFile ) | |
Get-Content $resultsFile | |
} | |
} | |
Function Update-ProjectFile | |
{ | |
Param ( [Parameter( Mandatory )][String] $projectFile, | |
[Parameter( Mandatory, ValueFromPipeline )][String] $content ) | |
Begin { $packageReference = '' } | |
Process { $packageReference += $content } | |
End { | |
$projXml = New-Object System.Xml.XmlDocument | |
$projXml.Load( $projectFile ) | |
$nameSpc = New-Object System.Xml.XmlNamespaceManager $projXml.NameTable | |
$nameSpc.AddNamespace("x", "http://schemas.microsoft.com/developer/msbuild/2003"); | |
$prefXml = New-Object System.Xml.XmlDocument | |
$prefXml.LoadXml( $packageReference ) | |
$prefXml.SelectNodes( "/x:Project/x:ItemGroup/x:PackageReference", $nameSpc ) | | |
% { | |
$pkgNode = $projXml.ImportNode( $_, $true ) | |
$pkgName = $_.Include.Split('-')[0] | |
$version = $_.Version | |
$nodes = $projXml.SelectNodes( "/x:Project/x:ItemGroup/x:Reference", $nameSpc ) | | |
? Include -Like "$pkgName*" | |
if ( $nodes.Count -eq 0 ) | |
{ | |
Write-Information "$projectFile $pkgName package outside the project file." | |
$itemGroup = $projXml.CreateElement( "ItemGroup", $nameSpc.LookupNamespace( "x" ) ) | |
$itemGroup.AppendChild( $pkgNode ) | |
$projXml.DocumentElement.AppendChild( $itemGroup ) | |
} | |
else { | |
$nodes | % { | |
if ( $_.Include -Match "$version" ) | |
{ | |
Write-Information "$projectFile $pkgName valid reference." | |
$_.ParentNode.AppendChild( $pkgNode ) | |
$_.ParentNode.RemoveChild( $_ ) | |
} | |
else | |
{ | |
Write-Warning "$projectFile $pkgName version mismatched." | |
$_.ParentNode.InsertBefore( $pkgNode, $_ ) | |
} | |
} | |
} | |
} | |
$projXml.SelectNodes( "/x:Project/x:ItemGroup/x:*[@Include='packages.config']", $nameSpc ) | | |
% { $_.ParentNode.RemoveChild( $_ ) } | |
$projXml.Save( $projectFile ) | |
} | |
} | |
Get-ChildItem . -Recurse -File -Filter packages.config | | |
select @{ Name="ProjectFile"; Expression={ "$($_.Directory)\$($_.Directory.BaseName).csproj" } }, | |
@{ Name="PackagesConfig"; Expression={ $_.FullName } } | | |
? { Test-Path $_.ProjectFile } | | |
% { | |
$_.PackagesConfig | Convert-ToPackageReference | Update-ProjectFile $_.ProjectFile -InformationAction Continue | |
Remove-Item $_.PackagesConfig | |
} |
<?xml version="1.0" encoding="utf-8" ?> | |
<xsl:stylesheet version="1.0" | |
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" | |
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |
<xsl:output omit-xml-declaration="yes" method="xml" indent="no"/> | |
<xsl:template match="/"> | |
<xsl:element name="Project"> | |
<xsl:element name="ItemGroup"> | |
<xsl:apply-templates/> | |
</xsl:element> | |
</xsl:element> | |
</xsl:template> | |
<xsl:template match="package"> | |
<xsl:element name="PackageReference"> | |
<xsl:attribute name="Include"> | |
<xsl:value-of select="@id" /> | |
</xsl:attribute> | |
<xsl:attribute name="Version"> | |
<xsl:value-of select="@version" /> | |
</xsl:attribute> | |
</xsl:element> | |
</xsl:template> | |
</xsl:stylesheet> |
@a4099181, thank you for this script, but unfortunately it doesn't work for me.
I can see that your "usage tip" doesn't include downloading xslt
file too. I've downloaded it manually but it still doesn't work - I execute ./Convert-ToPackageReference.ps1
and get no any response (so it silently executes), no changes are done (as I can see with git).
UPD. It seems it cannot locate project files in my case, as their names don't match the folder names.
UPD. Ok, I was able to rewrite bottom part of this script to make it usable for case when .csproj
file name doesn't match the folder name:
Get-ChildItem . -Recurse -File -Filter packages.config |
select @{ Name="ProjectFile"; Expression={ (Get-ChildItem -Path "$($_.Directory)\*.csproj").FullName } },
@{ Name="PackagesConfig"; Expression={ $_.FullName } } |
? { $_.ProjectFile } |
% {
Write-Host "Found: " $_.ProjectFile
$_.PackagesConfig | Convert-ToPackageReference | Update-ProjectFile $_.ProjectFile -InformationAction Continue
Remove-Item $_.PackagesConfig
}
My fork https://gist.github.com/aienabled/0bce5e4b17118122f2772e7c9218bf9c
@aienabled Fine, well done. I'm very glad that you've got it worked out and my script is useful anyway. Yes, "usage tip" does not include downloading xslt
file. It is not required while
$xslt.Load( $stylesheetUri )
is able to handle xslt
file from web.
The script saved my night! Thanks!
Usage tip
Open
Powershell
prompt and type:Synopsis
This script recognizes three possibilities:
PackageReference is appended to the project file.
Reference is replaced with PackageReference
PackageReference is inserted before Reference. Warning is written to the output.
User attention is requested. Please, clean up references manually with Visual Studio.
If you don't want to care about the version, you can simply tweak/edit the script to ignore it.
Enjoy new nuget package references with MSBuild 15 or Visual Studio 2017 ;)