Skip to content

Commit

Permalink
Fix #1777: Fixes bug with nuspec dependency version range when versio…
Browse files Browse the repository at this point in the history
…ns are specified in RequiredModules section

Fixes bug with generated nuspec dependency version range when RequiredVersion,MaxiumumVersion and ModuleVersion are specified in RequiredModules section
  • Loading branch information
Afroz Mohammed committed Jan 24, 2025
1 parent 28d241e commit eb2443b
Show file tree
Hide file tree
Showing 2 changed files with 220 additions and 14 deletions.
57 changes: 43 additions & 14 deletions src/code/PublishHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1122,16 +1122,38 @@ private string CreateNuspec(
if (requiredModules != null)
{
XmlElement dependenciesElement = doc.CreateElement("dependencies", nameSpaceUri);

foreach (string dependencyName in requiredModules.Keys)
{
XmlElement element = doc.CreateElement("dependency", nameSpaceUri);

element.SetAttribute("id", dependencyName);
string dependencyVersion = requiredModules[dependencyName].ToString();
if (!string.IsNullOrEmpty(dependencyVersion))

var requiredModulesVersionInfo = (Hashtable)requiredModules[dependencyName];
string versionRange = "";
if (requiredModulesVersionInfo.ContainsKey("RequiredVersion"))
{
// For RequiredVersion, use exact version notation [x.x.x]
string requiredModulesVersion = requiredModulesVersionInfo["RequiredVersion"].ToString();
versionRange = $"[{requiredModulesVersion}]";
}
else if (requiredModulesVersionInfo.ContainsKey("ModuleVersion") && requiredModulesVersionInfo.ContainsKey("MaximumVersion"))
{
// Version range when both min and max specified: [min,max]
versionRange = $"[{requiredModulesVersionInfo["ModuleVersion"]}, {requiredModulesVersionInfo["MaximumVersion"]}]";
}
else if (requiredModulesVersionInfo.ContainsKey("ModuleVersion"))
{
// Only min specified: min (which means ≥ min)
versionRange = requiredModulesVersionInfo["ModuleVersion"].ToString();
}
else if (requiredModulesVersionInfo.ContainsKey("MaximumVersion"))
{
element.SetAttribute("version", requiredModules[dependencyName].ToString());
// Only max specified: (, max]
versionRange = $"(, {requiredModulesVersionInfo["MaximumVersion"]}]";
}

if (!string.IsNullOrEmpty(versionRange))
{
element.SetAttribute("version", versionRange);
}

dependenciesElement.AppendChild(element);
Expand Down Expand Up @@ -1173,19 +1195,26 @@ private Hashtable ParseRequiredModules(Hashtable parsedMetadataHash)
if (LanguagePrimitives.TryConvertTo<Hashtable>(reqModule, out Hashtable moduleHash))
{
string moduleName = moduleHash["ModuleName"] as string;

if (moduleHash.ContainsKey("ModuleVersion"))
var versionInfo = new Hashtable();

// RequiredVersion cannot be used with ModuleVersion or MaximumVersion
if (moduleHash.ContainsKey("RequiredVersion"))
{
dependenciesHash.Add(moduleName, moduleHash["ModuleVersion"]);
versionInfo["RequiredVersion"] = moduleHash["RequiredVersion"].ToString();
}
else if (moduleHash.ContainsKey("RequiredVersion"))
{
dependenciesHash.Add(moduleName, moduleHash["RequiredVersion"]);
}
else
else
{
dependenciesHash.Add(moduleName, string.Empty);
// ModuleVersion and MaximumVersion can be used together
if (moduleHash.ContainsKey("ModuleVersion"))
{
versionInfo["ModuleVersion"] = moduleHash["ModuleVersion"].ToString();
}
if (moduleHash.ContainsKey("MaximumVersion"))
{
versionInfo["MaximumVersion"] = moduleHash["MaximumVersion"].ToString();
}
}
dependenciesHash.Add(moduleName, versionInfo);
}
else if (LanguagePrimitives.TryConvertTo<string>(reqModule, out string moduleName))
{
Expand Down
177 changes: 177 additions & 0 deletions test/PublishPSResourceTests/CompressPSResource.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,39 @@ function CreateTestModule
'@ | Out-File -FilePath $moduleSrc
}

function CompressExpandRetrieveNuspec
{
param(
[string]$PublishModuleBase,
[string]$PublishModuleName,
[string]$ModuleVersion,
[string]$RepositoryPath,
[string]$ModuleBasePath,
[string]$TestDrive,
[object[]]$RequiredModules,
[switch]$SkipModuleManifestValidate
)

$testFile = Join-Path -Path "TestSubDirectory" -ChildPath "TestSubDirFile.ps1"
$null = New-ModuleManifest -Path (Join-Path -Path $PublishModuleBase -ChildPath "$PublishModuleName.psd1") -ModuleVersion $version -Description "$PublishModuleName module" -RequiredModules $RequiredModules
$null = New-Item -Path (Join-Path -Path $PublishModuleBase -ChildPath $testFile) -Force

$null = Compress-PSResource -Path $PublishModuleBase -DestinationPath $repositoryPath -SkipModuleManifestValidate:$SkipModuleManifestValidate

# Must change .nupkg to .zip so that Expand-Archive can work on Windows PowerShell
$nupkgPath = Join-Path -Path $RepositoryPath -ChildPath "$PublishModuleName.$version.nupkg"
$zipPath = Join-Path -Path $RepositoryPath -ChildPath "$PublishModuleName.$version.zip"
Rename-Item -Path $nupkgPath -NewName $zipPath
$unzippedPath = Join-Path -Path $TestDrive -ChildPath "$PublishModuleName"
$null = New-Item $unzippedPath -Itemtype directory -Force
$null = Expand-Archive -Path $zipPath -DestinationPath $unzippedPath

$nuspecPath = Join-Path -Path $unzippedPath -ChildPath "$PublishModuleName.nuspec"
$nuspecxml = [xml](Get-Content $nuspecPath)
$null = Remove-Item $unzippedPath -Force -Recurse
return $nuspecxml
}

Describe "Test Compress-PSResource" -tags 'CI' {
BeforeAll {
Get-NewPSResourceRepositoryFile
Expand Down Expand Up @@ -218,6 +251,150 @@ Describe "Test Compress-PSResource" -tags 'CI' {
$fileInfoObject.Name | Should -Be "$script:PublishModuleName.$version.nupkg"
}

It "Compress-PSResource creates nuspec dependecy version range when RequiredVersion is in RequiredModules section" {
$version = "1.0.0"
$requiredModules = @(
@{
'ModuleName' = 'PSGetTestRequiredModule'
'GUID' = (New-Guid).Guid
'RequiredVersion' = '2.0.0'
}
)
$compressParams = @{
'PublishModuleBase' = $script:PublishModuleBase
'PublishModuleName' = $script:PublishModuleName
'ModuleVersion' = $version
'RepositoryPath' = $script:repositoryPath
'TestDrive' = $TestDrive
'RequiredModules' = $requiredModules
'SkipModuleManifestValidate' = $true
}
$nuspecxml = CompressExpandRetrieveNuspec @compressParams
# removing spaces as the nuget packaging is formatting the version range and adding spaces even when the original nuspec file doesn't have spaces.
# e.g (,2.0.0] is being formatted to (, 2.0.0]
$nuspecxml.package.metadata.dependencies.dependency.version.replace(' ', '') | Should -BeExactly '[2.0.0]'
}

It "Compress-PSResource creates nuspec dependecy version range when ModuleVersion is in RequiredModules section" {
$version = "1.0.0"
$requiredModules = @(
@{
'ModuleName' = 'PSGetTestRequiredModule'
'GUID' = (New-Guid).Guid
'ModuleVersion' = '2.0.0'
}
)
$compressParams = @{
'PublishModuleBase' = $script:PublishModuleBase
'PublishModuleName' = $script:PublishModuleName
'ModuleVersion' = $version
'RepositoryPath' = $script:repositoryPath
'TestDrive' = $TestDrive
'RequiredModules' = $requiredModules
'SkipModuleManifestValidate' = $true
}
$nuspecxml = CompressExpandRetrieveNuspec @compressParams
$nuspecxml.package.metadata.dependencies.dependency.version.replace(' ', '') | Should -BeExactly '2.0.0'
}

It "Compress-PSResource creates nuspec dependecy version range when MaximumVersion is in RequiredModules section" {
$version = "1.0.0"
$requiredModules = @(
@{
'ModuleName' = 'PSGetTestRequiredModule'
'GUID' = (New-Guid).Guid
'MaximumVersion' = '2.0.0'
}
)
$compressParams = @{
'PublishModuleBase' = $script:PublishModuleBase
'PublishModuleName' = $script:PublishModuleName
'ModuleVersion' = $version
'RepositoryPath' = $script:repositoryPath
'TestDrive' = $TestDrive
'RequiredModules' = $requiredModules
'SkipModuleManifestValidate' = $true
}
$nuspecxml = CompressExpandRetrieveNuspec @compressParams
$nuspecxml.package.metadata.dependencies.dependency.version.replace(' ', '') | Should -BeExactly '(,2.0.0]'
}

It "Compress-PSResource creates nuspec dependecy version range when ModuleVersion and MaximumVersion are in RequiredModules section" {
$version = "1.0.0"
$requiredModules = @(
@{
'ModuleName' = 'PSGetTestRequiredModule'
'GUID' = (New-Guid).Guid
'ModuleVersion' = '1.0.0'
'MaximumVersion' = '2.0.0'
}
)
$compressParams = @{
'PublishModuleBase' = $script:PublishModuleBase
'PublishModuleName' = $script:PublishModuleName
'ModuleVersion' = $version
'RepositoryPath' = $script:repositoryPath
'TestDrive' = $TestDrive
'RequiredModules' = $requiredModules
'SkipModuleManifestValidate' = $true
}
$nuspecxml = CompressExpandRetrieveNuspec @compressParams
$nuspecxml.package.metadata.dependencies.dependency.version.replace(' ', '') | Should -BeExactly '[1.0.0,2.0.0]'
}

It "Compress-PSResource creates nuspec dependecy version range when there are multiple modules in RequiredModules section" {
$version = "1.0.0"
$requiredModules = @(
@{
'ModuleName' = 'PSGetTestRequiredModuleRequiredVersion'
'GUID' = (New-Guid).Guid
'RequiredVersion' = '1.0.0'
},
@{
'ModuleName' = 'PSGetTestRequiredModuleModuleVersion'
'GUID' = (New-Guid).Guid
'ModuleVersion' = '2.0.0'
},
@{
'ModuleName' = 'PSGetTestRequiredModuleMaximumVersion'
'GUID' = (New-Guid).Guid
'MaximumVersion' = '3.0.0'
},
@{
'ModuleName' = 'PSGetTestRequiredModuleModuleAndMaximumVersion'
'GUID' = (New-Guid).Guid
'ModuleVersion' = '4.0.0'
'MaximumVersion' = '5.0.0'
}
)
$compressParams = @{
'PublishModuleBase' = $script:PublishModuleBase
'PublishModuleName' = $script:PublishModuleName
'ModuleVersion' = $version
'RepositoryPath' = $script:repositoryPath
'TestDrive' = $TestDrive
'RequiredModules' = $requiredModules
'SkipModuleManifestValidate' = $true
}
$nuspecxml = CompressExpandRetrieveNuspec @compressParams
foreach ($dependency in $nuspecxml.package.metadata.dependencies.dependency) {
switch ($dependency.id) {
"PSGetTestRequiredModuleRequiredVersion" {
$dependency.version.replace(' ', '') | Should -BeExactly '[1.0.0]'
}
"PSGetTestRequiredModuleModuleVersion" {
$dependency.version.replace(' ', '') | Should -BeExactly '2.0.0'
}
"PSGetTestRequiredModuleMaximumVersion" {
$dependency.version.replace(' ', '') | Should -BeExactly '(,3.0.0]'
}
"PSGetTestRequiredModuleModuleAndMaximumVersion" {
$dependency.version.replace(' ', '') | Should -BeExactly '[4.0.0,5.0.0]'
}
}
}
}

<# Test for Signing the nupkg. Signing doesn't work
It "Compressed Module is able to be signed with a certificate" {
$version = "1.0.0"
Expand Down

0 comments on commit eb2443b

Please # to comment.