Skip to content
This repository was archived by the owner on Jun 13, 2024. It is now read-only.

Commit 18a9a98

Browse files
awickham10edyoung
authored andcommitted
Add SkipAutomaticTags Parameter to Publish-Module (#452)
* Reusing Tags caused using the Length property to be used like an array instead of string * Added EnforceMaximumTagLength switch on Publish-Module to limit tags to 4000 characters * Renamed EnforceMaximumTagLength to SkipAutomaticTags * Keep Tags as string array and make new variable for a space separated string
1 parent 432b55c commit 18a9a98

File tree

4 files changed

+144
-57
lines changed

4 files changed

+144
-57
lines changed

Tests/PSGetPublishModule.Tests.ps1

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,83 @@ Describe PowerShell.PSGet.PublishModuleTests -Tags 'BVT','InnerLoop' {
763763
} `
764764
-Skip:$($PSVersionTable.PSVersion -lt '5.0.0')
765765

766+
# Purpose: Test Publish-Module cmdlet warns when tag length is greater than 4000
767+
#
768+
# Action: Create a module manifest with PrivateData\PSData hashtable, try to publish
769+
#
770+
# Expected Result: Publish operation should succeed and should have warned about tag length.
771+
#
772+
It PublishModuleFunctionsAsTagsWarnWithoutSkipAutomaticTags {
773+
$version = "1.0.0"
774+
$Description = "$script:PublishModuleName module"
775+
$Tags = "PSGet","DSC"
776+
$Author = "AuthorName"
777+
$CompanyName = "CompanyName"
778+
$CopyRight = "CopyRight"
779+
780+
$functionNames = 1..250 | Foreach-Object { "Get-TestFunction$($_)" }
781+
$tempFunctions = 1..250 | Foreach-Object { "function Get-TestFunction$($_) { Get-Date }" + [Environment]::NewLine }
782+
Set-Content (Join-Path -Path $script:PublishModuleBase -ChildPath "$script:PublishModuleName.psm1") -Value $tempFunctions
783+
784+
New-ModuleManifest -Path (Join-Path -Path $script:PublishModuleBase -ChildPath "$script:PublishModuleName.psd1") `
785+
-ModuleVersion $version `
786+
-Description "$script:PublishModuleName module" `
787+
-NestedModules "$script:PublishModuleName.psm1" `
788+
-Author $Author `
789+
-CompanyName $CompanyName `
790+
-Copyright $CopyRight `
791+
-Tags $Tags `
792+
-FunctionsToExport $functionNames
793+
794+
Publish-Module -Path $script:PublishModuleBase `
795+
-NuGetApiKey $script:ApiKey `
796+
-Repository "PSGallery" `
797+
-WarningAction SilentlyContinue `
798+
-WarningVariable wa
799+
800+
Assert ("$wa".Contains('4000 characters')) "Warning messages should include 'Tag list exceeded 4000 characters and may not be accepted by some Nuget feeds.'"
801+
} `
802+
-Skip:$($PSVersionTable.PSVersion -lt '5.0.0')
803+
804+
# Purpose: Test Publish-Module cmdlet excludes functions from tags when using SkipAutomaticTags parameter
805+
#
806+
# Action: Create a module manifest with PrivateData\PSData hashtable, try to publish with SkipAutomaticTags parameter
807+
#
808+
# Expected Result: Publish operation should succeed and should not have warned about tag length
809+
#
810+
It PublishModuleFunctionsAsTagsWithSkipAutomaticTags {
811+
$version = "1.0.0"
812+
$Description = "$script:PublishModuleName module"
813+
$Tags = "PSGet","DSC"
814+
$Author = "AuthorName"
815+
$CompanyName = "CompanyName"
816+
$CopyRight = "CopyRight"
817+
818+
$functionNames = 1..250 | Foreach-Object { "Get-TestFunction$($_)" }
819+
$tempFunctions = 1..250 | Foreach-Object { "function Get-TestFunction$($_) { Get-Date }" + [Environment]::NewLine }
820+
Set-Content (Join-Path -Path $script:PublishModuleBase -ChildPath "$script:PublishModuleName.psm1") -Value $tempFunctions
821+
822+
New-ModuleManifest -Path (Join-Path -Path $script:PublishModuleBase -ChildPath "$script:PublishModuleName.psd1") `
823+
-ModuleVersion $version `
824+
-Description "$script:PublishModuleName module" `
825+
-NestedModules "$script:PublishModuleName.psm1" `
826+
-Author $Author `
827+
-CompanyName $CompanyName `
828+
-Copyright $CopyRight `
829+
-Tags $Tags `
830+
-FunctionsToExport $functionNames
831+
832+
Publish-Module -Path $script:PublishModuleBase `
833+
-NuGetApiKey $script:ApiKey `
834+
-Repository "PSGallery" `
835+
-SkipAutomaticTags `
836+
-WarningAction SilentlyContinue `
837+
-WarningVariable wa
838+
839+
Assert (-not "$wa".Contains('4000 characters')) "Warning messages should not include 'Tag list exceeded 4000 characters and may not be accepted by some Nuget feeds.'"
840+
} `
841+
-Skip:$($PSVersionTable.PSVersion -lt '5.0.0')
842+
766843
# Purpose: Test Publish-Module cmdlet gets the PSData properties from the module manifest file and also with Uri objects specified to the cmdlet
767844
#
768845
# Action: Create a module manifest with PrivateData\PSData hashtable, try to publish it with Uri objects to ProjectUri, IconUri and LicenseUri parameters

src/PowerShellGet/private/functions/New-NuspecFile.ps1

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,9 @@ function New-NuspecFile {
5959
$packageElement = $xml.CreateElement("package", $nameSpaceUri)
6060
$metaDataElement = $xml.CreateElement("metadata", $nameSpaceUri)
6161

62-
#truncate tags if they exceed nuspec specifications for size.
63-
$Tags = $Tags -Join " "
64-
65-
if ($Tags.Length -gt 4000) {
62+
# warn we're over 4000 characters for standard nuget servers
63+
$tagsString = $Tags -Join " "
64+
if ($tagsString.Length -gt 4000) {
6665
Write-Warning -Message "Tag list exceeded 4000 characters and may not be accepted by some Nuget feeds."
6766
}
6867

@@ -75,7 +74,7 @@ function New-NuspecFile {
7574
releaseNotes = $ReleaseNotes
7675
requireLicenseAcceptance = $RequireLicenseAcceptance.ToString().ToLower()
7776
copyright = $Copyright
78-
tags = $Tags
77+
tags = $tagsString
7978
}
8079

8180
if ($LicenseUrl) { $metaDataElementsHash.Add("licenseUrl", $LicenseUrl) }

src/PowerShellGet/private/functions/Publish-PSArtifactUtility.ps1

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ function Publish-PSArtifactUtility {
5353
[string[]]
5454
$Tags,
5555

56+
[Parameter(ParameterSetName = 'PublishModule')]
57+
[switch]
58+
$SkipAutomaticTags,
59+
5660
[Parameter(ParameterSetName = 'PublishModule')]
5761
[Uri]
5862
$LicenseUri,
@@ -227,7 +231,7 @@ function Publish-PSArtifactUtility {
227231
if ($PSScriptInfo) {
228232
$Tags += "PSScript"
229233

230-
if ($PSScriptInfo.DefinedCommands) {
234+
if ($PSScriptInfo.DefinedCommands -and -not $SkipAutomaticTags) {
231235
if ($PSScriptInfo.DefinedFunctions) {
232236
$Tags += "$($script:Includes)_Function"
233237
$Tags += $PSScriptInfo.DefinedFunctions | Microsoft.PowerShell.Core\ForEach-Object { "$($script:Function)_$_" }
@@ -260,52 +264,54 @@ function Publish-PSArtifactUtility {
260264

261265
$ModuleManifestHashTable = Get-ManifestHashTable -Path $ManifestPath
262266

263-
if ($PSModuleInfo.ExportedCommands.Count) {
264-
if ($PSModuleInfo.ExportedCmdlets.Count) {
265-
$Tags += "$($script:Includes)_Cmdlet"
266-
$Tags += $PSModuleInfo.ExportedCmdlets.Keys | Microsoft.PowerShell.Core\ForEach-Object { "$($script:Cmdlet)_$_" }
267+
if (-not $SkipAutomaticTags) {
268+
if ($PSModuleInfo.ExportedCommands.Count) {
269+
if ($PSModuleInfo.ExportedCmdlets.Count) {
270+
$Tags += "$($script:Includes)_Cmdlet"
271+
$Tags += $PSModuleInfo.ExportedCmdlets.Keys | Microsoft.PowerShell.Core\ForEach-Object { "$($script:Cmdlet)_$_" }
267272

268-
#if CmdletsToExport field in manifest file is "*", we suggest the user to include all those cmdlets for best practice
269-
if ($ModuleManifestHashTable -and $ModuleManifestHashTable.ContainsKey('CmdletsToExport') -and ($ModuleManifestHashTable.CmdletsToExport -eq "*")) {
270-
$WarningMessage = $LocalizedData.ShouldIncludeCmdletsToExport -f ($ManifestPath)
271-
Write-Warning -Message $WarningMessage
273+
#if CmdletsToExport field in manifest file is "*", we suggest the user to include all those cmdlets for best practice
274+
if ($ModuleManifestHashTable -and $ModuleManifestHashTable.ContainsKey('CmdletsToExport') -and ($ModuleManifestHashTable.CmdletsToExport -eq "*")) {
275+
$WarningMessage = $LocalizedData.ShouldIncludeCmdletsToExport -f ($ManifestPath)
276+
Write-Warning -Message $WarningMessage
277+
}
272278
}
273-
}
274279

275-
if ($PSModuleInfo.ExportedFunctions.Count) {
276-
$Tags += "$($script:Includes)_Function"
277-
$Tags += $PSModuleInfo.ExportedFunctions.Keys | Microsoft.PowerShell.Core\ForEach-Object { "$($script:Function)_$_" }
280+
if ($PSModuleInfo.ExportedFunctions.Count) {
281+
$Tags += "$($script:Includes)_Function"
282+
$Tags += $PSModuleInfo.ExportedFunctions.Keys | Microsoft.PowerShell.Core\ForEach-Object { "$($script:Function)_$_" }
278283

279-
if ($ModuleManifestHashTable -and $ModuleManifestHashTable.ContainsKey('FunctionsToExport') -and ($ModuleManifestHashTable.FunctionsToExport -eq "*")) {
280-
$WarningMessage = $LocalizedData.ShouldIncludeFunctionsToExport -f ($ManifestPath)
281-
Write-Warning -Message $WarningMessage
284+
if ($ModuleManifestHashTable -and $ModuleManifestHashTable.ContainsKey('FunctionsToExport') -and ($ModuleManifestHashTable.FunctionsToExport -eq "*")) {
285+
$WarningMessage = $LocalizedData.ShouldIncludeFunctionsToExport -f ($ManifestPath)
286+
Write-Warning -Message $WarningMessage
287+
}
282288
}
283-
}
284289

285-
$Tags += $PSModuleInfo.ExportedCommands.Keys | Microsoft.PowerShell.Core\ForEach-Object { "$($script:Command)_$_" }
286-
}
290+
$Tags += $PSModuleInfo.ExportedCommands.Keys | Microsoft.PowerShell.Core\ForEach-Object { "$($script:Command)_$_" }
291+
}
287292

288-
$dscResourceNames = Get-ExportedDscResources -PSModuleInfo $PSModuleInfo
289-
if ($dscResourceNames) {
290-
$Tags += "$($script:Includes)_DscResource"
293+
$dscResourceNames = Get-ExportedDscResources -PSModuleInfo $PSModuleInfo
294+
if ($dscResourceNames) {
295+
$Tags += "$($script:Includes)_DscResource"
291296

292-
$Tags += $dscResourceNames | Microsoft.PowerShell.Core\ForEach-Object { "$($script:DscResource)_$_" }
297+
$Tags += $dscResourceNames | Microsoft.PowerShell.Core\ForEach-Object { "$($script:DscResource)_$_" }
293298

294-
#If DscResourcesToExport is commented out or "*" is used, we will write-warning
295-
if ($ModuleManifestHashTable -and
296-
($ModuleManifestHashTable.ContainsKey("DscResourcesToExport") -and
297-
$ModuleManifestHashTable.DscResourcesToExport -eq "*") -or
298-
-not $ModuleManifestHashTable.ContainsKey("DscResourcesToExport")) {
299-
$WarningMessage = $LocalizedData.ShouldIncludeDscResourcesToExport -f ($ManifestPath)
300-
Write-Warning -Message $WarningMessage
299+
#If DscResourcesToExport is commented out or "*" is used, we will write-warning
300+
if ($ModuleManifestHashTable -and
301+
($ModuleManifestHashTable.ContainsKey("DscResourcesToExport") -and
302+
$ModuleManifestHashTable.DscResourcesToExport -eq "*") -or
303+
-not $ModuleManifestHashTable.ContainsKey("DscResourcesToExport")) {
304+
$WarningMessage = $LocalizedData.ShouldIncludeDscResourcesToExport -f ($ManifestPath)
305+
Write-Warning -Message $WarningMessage
306+
}
301307
}
302-
}
303308

304-
$RoleCapabilityNames = Get-AvailableRoleCapabilityName -PSModuleInfo $PSModuleInfo
305-
if ($RoleCapabilityNames) {
306-
$Tags += "$($script:Includes)_RoleCapability"
309+
$RoleCapabilityNames = Get-AvailableRoleCapabilityName -PSModuleInfo $PSModuleInfo
310+
if ($RoleCapabilityNames) {
311+
$Tags += "$($script:Includes)_RoleCapability"
307312

308-
$Tags += $RoleCapabilityNames | Microsoft.PowerShell.Core\ForEach-Object { "$($script:RoleCapability)_$_" }
313+
$Tags += $RoleCapabilityNames | Microsoft.PowerShell.Core\ForEach-Object { "$($script:RoleCapability)_$_" }
314+
}
309315
}
310316

311317
# Populate the module dependencies elements from RequiredModules and

src/PowerShellGet/public/psgetfunctions/Publish-Module.ps1

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,11 @@ function Publish-Module {
8181

8282
[Parameter(ParameterSetName = "ModuleNameParameterSet")]
8383
[switch]
84-
$AllowPrerelease
84+
$AllowPrerelease,
85+
86+
[Parameter()]
87+
[switch]
88+
$SkipAutomaticTags
8589
)
8690

8791
Begin {
@@ -545,22 +549,23 @@ function Publish-Module {
545549
$shouldProcessMessage = $LocalizedData.PublishModulewhatIfMessage -f ($moduleInfo.Version, $moduleInfo.Name)
546550
if ($Force -or $PSCmdlet.ShouldProcess($shouldProcessMessage, "Publish-Module")) {
547551
$PublishPSArtifactUtility_Params = @{
548-
PSModuleInfo = $moduleInfo
549-
ManifestPath = $manifestPath
550-
NugetApiKey = $NuGetApiKey
551-
Destination = $DestinationLocation
552-
Repository = $Repository
553-
NugetPackageRoot = $tempModulePath
554-
FormatVersion = $FormatVersion
555-
ReleaseNotes = $($ReleaseNotes -join "`r`n")
556-
Tags = $Tags
557-
LicenseUri = $LicenseUri
558-
IconUri = $IconUri
559-
ProjectUri = $ProjectUri
560-
Verbose = $VerbosePreference
561-
WarningAction = $WarningPreference
562-
ErrorAction = $ErrorActionPreference
563-
Debug = $DebugPreference
552+
PSModuleInfo = $moduleInfo
553+
ManifestPath = $manifestPath
554+
NugetApiKey = $NuGetApiKey
555+
Destination = $DestinationLocation
556+
Repository = $Repository
557+
NugetPackageRoot = $tempModulePath
558+
FormatVersion = $FormatVersion
559+
ReleaseNotes = $($ReleaseNotes -join "`r`n")
560+
Tags = $Tags
561+
SkipAutomaticTags = $SkipAutomaticTags
562+
LicenseUri = $LicenseUri
563+
IconUri = $IconUri
564+
ProjectUri = $ProjectUri
565+
Verbose = $VerbosePreference
566+
WarningAction = $WarningPreference
567+
ErrorAction = $ErrorActionPreference
568+
Debug = $DebugPreference
564569
}
565570
if ($PSBoundParameters.Containskey('Credential')) {
566571
$PublishPSArtifactUtility_Params.Add('Credential', $Credential)

0 commit comments

Comments
 (0)