Fondue.psm1
|
#Region '.\Prefix.ps1' -1 $currentPrincipal = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent() if (-not $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { throw 'Fondue must be imported in an elevated (Administrator) PowerShell session.' } #EndRegion '.\Prefix.ps1' 6 #Region '.\private\Assert-LicenseValid.ps1' -1 function Assert-LicenseValid { [CmdletBinding()] Param( [Parameter()] [String] $LicenseFile = "$env:ChocolateyInstall\license\chocolatey.license.xml" ) end { $licenseFound = Test-Path $LicenseFile $xmlDoc = [System.Xml.XmlDocument]::new() $xmlDoc.Load($LicenseFile) $licenseNode = $xmlDoc.SelectSingleNode('/license') $expirationDate = [datetime]::Parse($licenseNode.Attributes["expiration"].Value) $LicenseExpired = $expirationDate -lt (Get-Date) if($licenseFound -and (-not $LicenseExpired)){ return $true } else { return $false } } } #EndRegion '.\private\Assert-LicenseValid.ps1' 28 #Region '.\private\Scaffold-Nuspec.ps1' -1 function Scaffold-Nuspec { Param( [Parameter(Mandatory)] [String] $Path ) $settings = [System.Xml.XmlWriterSettings]::new() $settings.Indent = $true $utf8WithoutBom = [System.Text.UTF8Encoding]::new($false) $stream = [System.IO.StreamWriter]::new($Path, $false, $utf8WithoutBom) try { $writer = [System.Xml.XmlWriter]::Create($stream, $settings) $writer.WriteStartDocument() $writer.WriteComment("Do not remove this test for UTF-8: if 'Ω' doesn’t appear as greek uppercase omega letter enclosed in quotation marks, you should use an editor that supports UTF-8, not this one.") $writer.WriteStartElement('', 'package', 'http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd') $writer.WriteStartElement('metadata') $writer.WriteFullEndElement() # metadata $writer.WriteEndElement() # package $writer.WriteEndDocument() } finally { $writer.Flush() $writer.Close() $stream.Close() $stream.Dispose() $writer.Dispose() } return (Get-Item $Path) } #EndRegion '.\private\Scaffold-Nuspec.ps1' 34 #Region '.\private\Write-Metadata.ps1' -1 function Write-Metadata { [CmdletBinding()] Param( [Parameter(Mandatory)] [Hashtable] $Metadata, [Parameter(Mandatory)] [String] $NuspecFile ) process { [xml]$xmlDoc = Get-Content $NuspecFile $namespaceManager = New-Object System.Xml.XmlNamespaceManager($xmlDoc.NameTable) $namespaceManager.AddNamespace("ns", "http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd") $metadataNode = $xmlDoc.SelectSingleNode("//*[local-name()='metadata']", $namespaceManager) $Metadata.GetEnumerator() | ForEach-Object { $node = $xmlDoc.SelectSingleNode("//*[local-name()='$($_.Key)']", $namespaceManager) if (-not $node) { $node = $xmlDoc.CreateElement($_.Key) } else { 'Node exists: {0}, updating' -f $_.Key } $null = $node.InnerText = $_.Value $null = $metadataNode.AppendChild($node) } #we don't need the namespace on all the nodes, so strip it off $xmlDoc = $xmlDoc.OuterXml -replace 'xmlns=""', '' $settings = New-Object System.Xml.XmlWriterSettings $settings.Indent = $true $settings.Encoding = [System.Text.Encoding]::UTF8 $writer = [System.Xml.XmlWriter]::Create($NuspecFile, $settings) try { $xmlDoc.WriteTo($writer) } finally { $writer.Flush() $writer.Close() $writer.Dispose() } } } #EndRegion '.\private\Write-Metadata.ps1' 48 #Region '.\public\Convert-Xml.ps1' -1 Function Convert-Xml { <# .SYNOPSIS Converts XML from a URL or a file to a hash table. .DESCRIPTION The Convert-Xml function takes a URL or a file path as input and converts the XML content to a hash table. If a URL is provided, the function downloads the XML content from the URL. If a file path is provided, the function reads the XML content from the file. The function then converts the XML content to a hash table and returns it. .PARAMETER Url The URL of the XML content to convert. If this parameter is provided, the function will download the XML content from the URL. .PARAMETER File The file path of the XML content to convert. If this parameter is provided, the function will read the XML content from the file. .EXAMPLE Convert-Xml -Url "http://example.com/data.xml" This example downloads the XML content from the specified URL and converts it to a hash table. .EXAMPLE Convert-Xml -File "C:\path\to\data.xml" This example reads the XML content from the specified file and converts it to a hash table. .NOTES The function does not support XML content that contains dependencies or comments. #> [cmdletBinding(HelpUri='https://steviecoaster.github.io/Fondue/Convert-Xml')] Param( [Parameter()] [String] $Url, [Parameter()] [String] $File ) process { if ($url) { [xml]$xml = [System.Net.WebClient]::new().DownloadString($url) } if ($File) { [xml]$xml = Get-Content $File } $hash = @{} foreach ($node in ($xml.package.metadata.ChildNodes | Where-Object {$_.Name -notmatch 'dependencies|#comment'})) { $hash.Add($node.Name, $node.'#text') } return $hash } } #EndRegion '.\public\Convert-Xml.ps1' 60 #Region '.\public\New-Dependency.ps1' -1 function New-Dependency { <# .SYNOPSIS Injects a <dependency> node into a Chocolatey package nuspec file .DESCRIPTION Long description .PARAMETER Nuspec THe Chocolatey package nuspec to which add a dependency .PARAMETER Dependency A hashtable containing the package id and version range for the dependency .PARAMETER Recompile Recompile the Chocolatey package with the new dependency information. .PARAMETER OutputDirectory Save the recompiled Chocolatey Package to this location .EXAMPLE Add a single dependency with a version New-Dependency -Nuspec C:\packages\foo.1.1.1.nuspec -dependency @{id= 'baz'; version='3.4.2'} .EXAMPLE Add multiple dependencies New-Dependency -Nuspec C:\packages\foo.1.1.0.nuspec -Dependency @{id='baz'; version='1.1.1'},@{id='boo';version=[1.0.1,2.9.0]} .EXAMPLE Add a dependency and recompile the package $newDependencySplat = @{ Nuspec = 'C:\packagesfoo.1.1.1.nuspec' Dependency = @{id= 'baz'; version='3.4.2'} Recompile = $true } New-Dependency @newDependencySplat .EXAMPLE Add a dependency, recompile the package, and save it to a new location $newDependencySplat = @{ Nuspec = 'C:\packagesfoo.1.1.1.nuspec' Dependency = @{id= 'baz'; version='3.4.2'} Recompile = $true OutputDirectory = 'C:\recompiled' } New-Dependency @newDependencySplat #> [CmdletBinding(HelpUri = 'https://steviecoaster.github.io/Fondue/New-Dependency')] Param( [Parameter(Mandatory)] [String] $Nuspec, [Parameter(Mandatory)] [Hashtable[]] $Dependency, [Parameter()] [Switch] $Recompile, [Parameter()] [String] [ValidateScript({ Test-Path $_ })] $OutputDirectory ) process { [xml]$xmlContent = Get-Content $Nuspec # Define the XML namespace $namespaceManager = New-Object System.Xml.XmlNamespaceManager($xmlContent.NameTable) $namespaceManager.AddNamespace("ns", "http://schemas.microsoft.com/packaging/2015/08/nuspec.xsd") # Check if the package node exists and verify its namespace $packageNode = $xmlContent.SelectSingleNode("//*[local-name()='package']", $namespaceManager) if ($null -eq $packageNode) { Write-Error "Package node not found. Exiting." -Category ObjectNotFound break } else { Write-Verbose "Package node found." } # Check if the metadata node exists within the package node $metadataNode = $xmlContent.SelectSingleNode("//*[local-name()='metadata']", $namespaceManager) if ($null -eq $metadataNode) { Write-Error "Metadata node not found." -Category ObjectNotFound break } else { Write-Verbose "Metadata node found." } # Find the dependencies node $dependenciesNode = $xmlContent.SelectSingleNode("//*[local-name()='dependencies']", $namespaceManager) if ($null -eq $dependenciesNode) { $null = $dependenciesNode = $xmlContent.CreateElement('dependencies') $null = $metadataNode.AppendChild($dependenciesNode) } else { Write-Verbose "Dependencies node found." } #Loop over the given dependencies and create new nodes for each foreach ($D in $Dependency) { # Create a new XmlDocument $newDoc = New-Object System.Xml.XmlDocument # Create a new dependency element in the new document $newDependency = $newDoc.CreateElement("dependency") $newDependency.SetAttribute("id", "$($D['id'])") if ($D.version) { # Check if the version string contains invalid characters # Valid ranges: https://learn.microsoft.com/en-us/nuget/concepts/package-versioning?tabs=semver20sort#version-ranges if ($($D['version']) -match '\([^,]*?\)') { Write-Error "Invalid version string: $($D['version']) for package $($D['id'])" continue } $newDependency.SetAttribute("version", "$($D['version'])") } # Import the new dependency into the original document $importedDependency = $xmlContent.ImportNode($newDependency, $true) # Append the imported dependency to the dependencies node $null = $dependenciesNode.AppendChild($importedDependency) } # Save the xml back to the nuspec file $settings = New-Object System.Xml.XmlWriterSettings $settings.Indent = $true $settings.Encoding = [System.Text.Encoding]::UTF8 $writer = [System.Xml.XmlWriter]::Create($Nuspec, $settings) try { $xmlContent.WriteTo($writer) } finally { $writer.Flush() $writer.Close() $writer.Dispose() } # Stupid hack to get rid of the 'xlmns=' part of the new dependency nodes. .Net methods are "overly helpful" $content = Get-Content -Path $Nuspec -Raw $content = $content -replace ' xmlns=""', '' Set-Content -Path $Nuspec -Value $content if ($Recompile) { if (-not (Get-Command choco)) { Write-Error "Choco is required to recompile the package but was not found on this system" -Category ResourceUnavailable } else { $OD = if ($OutputDirectory) { $OutputDirectory } else { Split-Path -Parent $Nuspec } $chocoArgs = ('pack', $Nuspec, $OD) $choco = (Get-Command choco).Source $null = & $choco @chocoArgs if ($LASTEXITCODE -eq 0) { 'Package is ready and available at {0}' -f $OD } else { throw 'Recompile had an error, see chocolatey.log for details' } } } } } #EndRegion '.\public\New-Dependency.ps1' 183 #Region '.\public\New-MetaPackage.ps1' -1 function New-Metapackage { <# .SYNOPSIS Creates a new Chocolatey Meta (virtual) package .DESCRIPTION This function generates the necessary nuspec needed to create a Chocolatey metapackage .PARAMETER Id The id of the meta package to create .PARAMETER Summary Provide a brief summary of what the metapackage provides .PARAMETER Dependency An array of hashtables containing the id and (optional) version of the package to include in the metapackage. .PARAMETER Path The folder in which to generate the metapackage .PARAMETER Version A valid semver for the package. Defaults to 0.1.0 .EXAMPLE A minimal example of a metapackage using mandatory parameters $newMetapackageSplat = @{ Id = 'example' Summary = 'This is a simple example' Dependency = @{id='putty'}, @{id='git';version = '2.5.98'} } New-Metapackage @newMetapackageSplat .EXAMPLE Create a meta package with a pre-release version, and save it to C:\chocopackages $newMetapackageSplat = @{ Id = 'example' Summary = 'This is a simple example' Dependency = @{id='putty'}, @{id='git';version = '2.5.98'} Version = 1.0.0-pre Path = C:\chocopackages } New-Metapackage @newMetapackageSplat .NOTES General notes #> [Alias('New-VirtualPackage')] [CmdletBinding(HelpUri = 'https://steviecoaster.github.io/Fondue/New-Metapackage')] Param( [Parameter(Position = 0, Mandatory)] [String] $Id, [Parameter(Position = 1, Mandatory)] [String] $Summary, [Parameter(Position = 2, Mandatory)] [Hashtable[]] $Dependency, [Parameter(Mandatory)] [ValidateScript({ if ($_.Length -ge 30) { $true } else { throw "Description must be at least 30 characters long." } })] [String] $Description, [Parameter()] [String] $Path = $PWD, [Parameter()] [ValidateScript({ $matcher = '^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$' $_ -match $matcher })] [String] $Version = '0.1.0' ) begin { $chocoTemplatesPath = 'C:\ProgramData\chocolatey\templates' if (-not (Test-Path $chocoTemplatesPath)) { $null = New-Item -ItemType Directory -Path $chocoTemplatesPath -Force } $copyItemSplat = @{ Path = Join-Path $PSScriptRoot 'template\metapackage' Destination = $chocoTemplatesPath Recurse = $true Force = $true } Copy-Item @copyItemSplat } end { $chocoArgs = @('new', "$Id", '--template="metapackage"', "Id=$Id", "Summary=$Summary", "Description=$Description", "Version=$Version") & choco @chocoArgs } } #EndRegion '.\public\New-MetaPackage.ps1' 112 #Region '.\public\New-Package.ps1' -1 function New-Package { <# .SYNOPSIS Generates a new Chocolatey Package .DESCRIPTION Generates a Chocolatey Package. Can be used to generate from an installer (licensed versions only), meta (virtual) packages, or FOSS style packages .PARAMETER Name The name (Id) to give to the package .PARAMETER IsMetapackage Instructs Chocolatey to create a MetaPackage .PARAMETER File An installer to package. Should be of type exe, msi, msu, or zip .PARAMETER Url The url of an installer to package. Installer will be downloaded and embedded into package. Supports same extensions as -File parameter. .PARAMETER Dependency Dependencies to inject into the package. Required when using -IsMetaPackage. .PARAMETER Metadata A hashtable of MetaData to include in the Nuspec File .PARAMETER OutputDirectory This is where the Chocolatey packaging will be generated. Defaults to the current working directory. .PARAMETER Recompile When used runs the pack command against the nuspec file .EXAMPLE Creating a basic package with a name: $params = @{ Name = "MyPackage" } New-Package @params .EXAMPLE Create a package from an installer file New-Package -Name "MyInstallerPackage" -File "C:\path\to\installer.exe" .EXAMPLE Create a package from an installer URL New-Package -Name "MyUrlPackage" -Url "http://example.com/installer.exe" .EXAMPLE Create a package with metadata New-Package -Name "MyPackageWithMetadata" -Metadata @{Author="Me"; Version="1.0.0"} .EXAMPLE Create a package in a specific output directory New-Package -Name "MyPackage" -OutputDirectory "C:\path\to\output\directory" .NOTES .LINK https://docs.chocolatey.org/en-us/guides/create/ #> [CmdletBinding(DefaultParameterSetName = 'Default', HelpUri = 'https://steviecoaster.github.io/Fondue/New-Package')] Param( [Parameter(Mandatory, ParameterSetName = 'Default')] [String] $Name, [Parameter(Mandatory, ParameterSetName = 'File')] [ValidateScript({ Test-Path $_ })] [String] $File, [Parameter(Mandatory, ParameterSetName = 'Url')] [String] $Url, [Parameter(ParameterSetName = 'Default')] [Parameter(ParameterSetName = 'File')] [Parameter(ParameterSetName = 'Url')] [Hashtable[]] $Dependency, [Parameter(ParameterSetName = 'Default')] [Parameter(ParameterSetName = 'File')] [Parameter(ParameterSetName = 'Url')] [Hashtable] $Metadata, [Parameter(ParameterSetName = 'Default')] [Parameter(ParameterSetName = 'File')] [Parameter(ParameterSetName = 'Url')] [String] $OutputDirectory = $PWD, [Parameter(ParameterSetName = 'FIle')] [Parameter(ParameterSetName = 'Url')] [Switch] $Recompile ) process { switch ($PSCmdlet.ParameterSetName) { 'File' { $licenseValid = Assert-LicenseValid $extensionInstalled = Test-Path "$env:ChocolateyInstall\lib\chocolatey.extension" if (-not $licenseValid) { throw 'A valid Chocolatey license is required to use -File but was not found on this system.' } if (-not $extensionInstalled) { throw 'A valid license file was found, but the Chocolatey Licensed Extension is not installed. The Chocolatey Licensed Extension is required to use -File.' } $chocoArgs = @('new', "--file='$file'", "--output-directory='$OutputDirectory'", '--build-package') $i = 4 } 'Url' { $licenseValid = Assert-LicenseValid $extensionInstalled = Test-Path "$env:ChocolateyInstall\lib\chocolatey.extension" if (-not $licenseValid) { throw 'A valid Chocolatey license is required to use -Url but was not found on this system.' } if (-not $extensionInstalled) { throw 'A valid license file was found, but the Chocolatey Licensed Extension is not installed. The Chocolatey Licensed Extension is required to use -Url.' } $chocoArgs = @('new', "--url='$url'", "--output-directory='$OutputDirectory'", '--build-package', '--no-progress') $i = 7 } default { $chocoArgs = @('new', "$Name", "--output-directory='$OutputDirectory'") $i = 3 } } $matcher = "(?<nuspec>(?<=').*(?='))" $choco = & choco @chocoArgs Write-Verbose -Message $('Matching against {0}' -f $choco[$i]) $null = $choco[$i] -match $matcher if ($matches.nuspec) { 'Adding dependencies to package {0}, if any' -f $matches.nuspec } else { throw 'Something went wrong, check the chocolatey.log file for details!' } if ($Dependency) { $newDependencySplat = @{ Nuspec = $matches.nuspec Dependency = $Dependency OutputDirectory = $OutputDirectory } New-Dependency @newDependencySplat } if ($Metadata) { Write-Metadata -Metadata $Metadata -NuspecFile $matches.nuspec } if ($Recompile) { $chocoArgs = ('pack', $matches.nuspec, $OutputDirectory) $choco = (Get-Command choco).Source $null = & $choco @chocoArgs if ($LASTEXITCODE -eq 0) { 'Package is ready and available at {0}' -f $OutputDirectory } else { throw 'Recompile had an error, see chocolatey.log for details' } } } } #EndRegion '.\public\New-Package.ps1' 193 #Region '.\public\Open-FondueHelp.ps1' -1 function Open-FondueHelp { <# .SYNOPSIS Opens the documentation for the Fondue PowerShell module #> [CmdletBinding(HelpUri = 'https://steviecoaster.github.io/Fondue/Open-FondueHelp')] Param() end { Start-Process https://steviecoaster.github.io/Fondue/ } } #EndRegion '.\public\Open-FondueHelp.ps1' 14 #Region '.\public\Remove-Dependency.ps1' -1 function Remove-Dependency { <# .SYNOPSIS Removes a dependency from a NuGet package specification file. .DESCRIPTION The Remove-Dependency function takes a NuGet package specification (.nuspec) file and an array of dependencies as input. It removes the specified dependencies from the .nuspec file. .PARAMETER PackageNuspec The path to the .nuspec file from which to remove dependencies. This parameter is mandatory. .PARAMETER Dependency An array of dependencies to remove from the .nuspec file. This parameter is mandatory. .EXAMPLE Remove-Dependency -PackageNuspec "C:\path\to\package.nuspec" -Dependency "Dependency1", "Dependency2" This example removes the dependencies "Dependency1" and "Dependency2" from the .nuspec file at the specified path. .NOTES The function does not support removing dependencies that are not directly listed in the .nuspec file. #> [CmdletBinding(HelpUri = 'https://steviecoaster.github.io/Fondue/Remove-Dependency')] Param( [Parameter(Mandatory)] [String] $PackageNuspec, [Parameter(Mandatory)] [String[]] $Dependency ) process { $xmlDoc = [System.Xml.XmlDocument]::new() $xmlDoc.Load($PackageNuspec) # Create an XmlNamespaceManager and add the namespace $nsManager = New-Object System.Xml.XmlNamespaceManager($xmlDoc.NameTable) $nsManager.AddNamespace('ns', $xmlDoc.DocumentElement.NamespaceURI) # Use the XmlNamespaceManager when selecting nodes $dependenciesNode = $xmlDoc.SelectSingleNode('//ns:metadata/ns:dependencies', $nsManager) foreach ($d in $Dependency) { if ($null -ne $dependenciesNode) { $dependencyToRemove = $dependenciesNode.SelectSingleNode("ns:dependency[@id='$d']", $nsManager) if ($null -ne $dependencyToRemove) { $null = $dependenciesNode.RemoveChild($dependencyToRemove) } } } $settings = New-Object System.Xml.XmlWriterSettings $settings.Indent = $true $settings.Encoding = [System.Text.Encoding]::UTF8 $writer = [System.Xml.XmlWriter]::Create($PackageNuspec, $settings) try { $xmlDoc.WriteTo($writer) } finally { $writer.Flush() $writer.Close() } } } #EndRegion '.\public\Remove-Dependency.ps1' 69 #Region '.\public\Sync-Package.ps1' -1 function Sync-Package { <# .SYNOPSIS Runs choco sync on a system .DESCRIPTION Run choco sync against a system with eiher a single item or from a map .PARAMETER Id The Package id for the synced package .PARAMETER DisplayName The Diplay Name From Programs and Features .PARAMETER Map A hashtable of DisplayName and PackageIds .EXAMPLE Sync-Package Sync everything from Programs and Features not under Chocolatey management .EXAMPLE Sync-Package -Id googlechrome -DisplayName 'Google Chrome' Sync the Google Chrome application from Programs and Features to the googlechrome package id .EXAMPLE Sync-Package -Map @{'Google Chrome' = 'googlechrome'} Sync from a hashtable of DisplayName:PackageId pairs .NOTES Requires a Chocolatey For Business license #> [CmdletBinding(DefaultParameterSetName = 'Default', HelpUri = 'https://steviecoaster.github.io/Fondue/Sync-Package')] Param( [Parameter(Mandatory, ParameterSetName = 'Package')] [String] $Id, [Parameter(Mandatory, ParameterSetName = 'Package')] [String] $DisplayName, [Parameter(Mandatory, ParameterSetName = 'Map')] [hashtable] $Map, [Parameter(ParameterSetName = 'Default')] [Parameter(ParameterSetName = 'Map')] [Parameter(ParameterSetName = 'Package')] [String] $OutputDirectory = $PWD ) begin { $licenseValid = Assert-LicenseValid $extensionInstalled = Test-Path "$env:ChocolateyInstall\lib\chocolatey.extension" if (-not $licenseValid) { throw 'A valid Chocolatey license is required to use -File but was not found on this system.' } if (-not $extensionInstalled) { throw 'A valid license file was found, but the Chocolatey Licensed Extension is not installed. The Chocolatey Licensed Extension is required to use -File.' } } end { switch ($PSCmdlet.ParameterSetName) { 'Package' { choco sync --id="$DisplayName" --package-id="$Id" --output-directory="$OutputDirectory" $packageFolder = Join-path $OutputDirectory -ChildPath "sync\$Id" $todo = Join-Path $packageFolder -ChildPath 'TODO.txt' if (Test-Path $todo) { Write-Warning (Get-Content $todo) } } 'Map' { $map.GetEnumerator() | Foreach-Object { choco sync --id="$($_.Key)" --package-id="$($_.Value)" --output-directory="$OutputDirectory" $packageFolder = Join-path $OutputDirectory -ChildPath $_.Value $todo = Join-Path $packageFolder -ChildPath 'TODO.txt' if (Test-Path $todo) { Write-Warning (Get-Content $todo) } } } default { choco sync --output-directory="$OutputDirectory" } } } } #EndRegion '.\public\Sync-Package.ps1' 100 #Region '.\public\Test-Nuspec.ps1' -1 function Test-Nuspec { <# .SYNOPSIS Tests a NuGet package specification (.nuspec) file for compliance with specified rules. .DESCRIPTION The Test-Nuspec function takes a .nuspec file and a set of rules as input. It tests the .nuspec file for compliance with the specified rules. The function can test for compliance with only the required rules, or it can also test for compliance with community rules. Additional tests can be specified. .PARAMETER NuspecFile The path to the .nuspec file to test. This parameter is validated to ensure that it is a valid path. .PARAMETER Metadata A hash table of metadata to test. This parameter is optional. .PARAMETER OnlyRequiredRules A switch that, when present, causes the function to test for compliance with only the required rules. .PARAMETER TestCommunityRules A switch that, when present, causes the function to test for compliance with community rules. .PARAMETER AdditionalTest An array of additional tests to run. This parameter is optional. .EXAMPLE Test-Nuspec -NuspecFile "C:\path\to\package.nuspec" -OnlyRequiredRules This example tests the .nuspec file at the specified path for compliance with only the required rules. .EXAMPLE Test-Nuspec -NuspecFile "C:\path\to\package.nuspec" -TestCommunityRules -AdditionalTest "Test1", "Test2" This example tests the .nuspec file at the specified path for compliance with community rules and runs the additional tests "Test1" and "Test2". .NOTES The function uses the Convert-Xml function to convert the .nuspec file to a hash table of metadata. #> [CmdletBinding(HelpUri = 'https://steviecoaster.github.io/Fondue/Test-Nuspec')] Param( [Parameter()] [ValidateScript({ Test-Path $_ })] [String] $NuspecFile, [Parameter()] [Hashtable] $Metadata, [Parameter()] [Switch] $SkipBuiltinTests, [Parameter()] [String[]] $AdditionalTest ) process { $data = if ($NuspecFile) { $Metadata = Convert-Xml -File $NuspecFile @{ metadata = $Metadata } } else { @{ Metadata = $Metadata } } $moduleRoot = (Get-Module Fondue).ModuleBase $SystemTests = (Get-ChildItem (Join-Path $moduleRoot -ChildPath 'module_tests') -Recurse -Filter nuspec*.tests.ps1) | Select-Object Name, FullName $containerCollection = [System.Collections.Generic.List[psobject]]::new() if(-not $SkipBuiltinTests){ $SystemTests |ForEach-Object{ $containerCollection.Add($_.FullName)} } if ($AdditionalTest) { $AdditionalTest | ForEach-Object { $containerCollection.Add($_) } } if($SkipBuiltinTests -and (-not $AdditionalTest)){ throw '-SkipBuiltinTests was passed, but not additional tests. Please pass additional tests, or remove -SkipBuiltinTests' } $containers = $containerCollection | Foreach-object { New-PesterContainer -Path $_ -Data $data } $configuration = [PesterConfiguration]@{ Run = @{ Container = $Containers Passthru = $true } Output = @{ Verbosity = 'Detailed' } TestResult = @{ Enabled = $false } } $results = Invoke-Pester -Configuration $configuration } } #EndRegion '.\public\Test-Nuspec.ps1' 101 #Region '.\public\Test-Package.ps1' -1 function Test-Package { <# .SYNOPSIS Tests a NuGet package for compliance with specified rules. .DESCRIPTION The Test-Package function takes a NuGet package and a set of rules as input. It tests the package for compliance with the specified rules. The function can test for compliance with only the required rules, or it can also test for compliance with all system rules. Additional tests can be specified. .PARAMETER PackagePath The path to the NuGet package to test. This parameter is mandatory and validated to ensure that it is a valid path. .PARAMETER OnlyRequiredRules A switch that, when present, causes the function to test for compliance with only the required rules. .PARAMETER AdditionalTest An array of additional tests to run. This parameter is optional. .EXAMPLE Test-Package -PackagePath "C:\path\to\package.nupkg" -OnlyRequiredRules This example tests the NuGet package at the specified path for compliance with only the required rules. .EXAMPLE Test-Package -PackagePath "C:\path\to\package.nupkg" -AdditionalTest "Test1", "Test2" This example tests the NuGet package at the specified path and runs the additional tests "Test1" and "Test2". .NOTES The function uses the Fondue module to perform the tests. #> [CmdletBinding(HelpUri = 'https://steviecoaster.github.io/Fondue/Test-Package')] Param( [Parameter(Mandatory)] [ValidateScript({ Test-Path $_ })] [String] $PackagePath, [Parameter()] [Switch] $OnlyRequiredRules, [Parameter()] [String[]] $AdditionalTest ) process { $Data = @{ PackagePath = $PackagePath } $moduleRoot = (Get-Module Fondue).ModuleBase $SystemTests = (Get-ChildItem (Join-Path $moduleRoot -ChildPath 'module_tests') -Recurse -Filter package*.tests.ps1) | Select-Object Name, FullName $containerCollection = [System.Collections.Generic.List[psobject]]::new() if ($OnlyRequiredRules) { $tests = ($SystemTests | Where-Object Name -match 'required').FullName $containerCollection.Add($tests) } else { $tests = ($SystemTests).FullName $containerCollection.Add($tests) } if ($AdditionalTest) { $AdditionalTest | ForEach-Object { $containerCollection.Add($_) } } $containers = $containerCollection | Foreach-object { New-PesterContainer -Path $_ -Data $Data } $configuration = [PesterConfiguration]@{ Run = @{ Container = $Containers Passthru = $true } Output = @{ Verbosity = 'Detailed' } TestResult = @{ Enabled = $false } } $results = Invoke-Pester -Configuration $configuration } } #EndRegion '.\public\Test-Package.ps1' 89 #Region '.\public\Update-ChocolateyMetadata.ps1' -1 function Update-ChocolateyMetadata { <# .SYNOPSIS Updates the metadata of a Chocolatey package. .DESCRIPTION The Update-ChocolateyMetadata function takes a metadata hash table and a .nuspec file as input. It updates the metadata of the Chocolatey package specified by the .nuspec file with the values in the metadata hash table. .PARAMETER Metadata A hash table of metadata to update. The keys should be the names of the metadata elements to update, and the values should be the new values for these elements. .PARAMETER NuspecFile The path to the .nuspec file of the Chocolatey package to update. This parameter is mandatory and validated to ensure that it is a valid path. .EXAMPLE $Metadata = @{ id = "newId"; version = "1.0.1" } Update-ChocolateyMetadata -Metadata $Metadata -NuspecFile "C:\path\to\package.nuspec" This example updates the id and version of the Chocolatey package specified by the .nuspec file at the specified path. .NOTES The function uses the Write-Metadata function to write the updated metadata to the .nuspec file. #> [CmdletBinding(HelpUri = 'https://steviecoaster.github.io/Fondue/Update-ChocolateyMetadata')] Param( [Parameter(Mandatory,ValueFromPipeline,ValueFromRemainingArguments)] [Hashtable] $Metadata, [Parameter(Mandatory)] [ValidateScript({Test-Path $_})] [String] $NuspecFile ) process { Write-metadata -MetaData $Metadata -Nuspecfile $NuspecFile } } #EndRegion '.\public\Update-ChocolateyMetadata.ps1' 40 #Region '.\Suffix.ps1' -1 #EndRegion '.\Suffix.ps1' 1 |