Skip to content

Instantly share code, notes, and snippets.

@a4099181
Last active February 18, 2021 07:00
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save a4099181/074a6c3dd524ea0d343382137492399c to your computer and use it in GitHub Desktop.
Save a4099181/074a6c3dd524ea0d343382137492399c to your computer and use it in GitHub Desktop.
Converts packages.config into PackageReference at *.csproj project file. Requires XSLT stylesheet available as second file in the gist.
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>
@agat366
Copy link

agat366 commented Jan 26, 2018

The script saved my night! Thanks!

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