Skip to content

Commit 4968cef

Browse files
author
Afroz Mohammed
committed
Fix #1777: Fixes bug with nuspec dependency version range when versions are specified in RequiredModules section
Fixes bug with generated nuspec dependency version range when RequiredVersion, MaxiumumVersion and ModuleVersion are specified in RequiredModules section
1 parent 28d241e commit 4968cef

File tree

2 files changed

+226
-14
lines changed

2 files changed

+226
-14
lines changed

src/code/PublishHelper.cs

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,16 +1122,38 @@ private string CreateNuspec(
11221122
if (requiredModules != null)
11231123
{
11241124
XmlElement dependenciesElement = doc.CreateElement("dependencies", nameSpaceUri);
1125-
11261125
foreach (string dependencyName in requiredModules.Keys)
11271126
{
11281127
XmlElement element = doc.CreateElement("dependency", nameSpaceUri);
1129-
11301128
element.SetAttribute("id", dependencyName);
1131-
string dependencyVersion = requiredModules[dependencyName].ToString();
1132-
if (!string.IsNullOrEmpty(dependencyVersion))
1129+
1130+
var requiredModulesVersionInfo = (Hashtable)requiredModules[dependencyName];
1131+
string versionRange = "";
1132+
if (requiredModulesVersionInfo.ContainsKey("RequiredVersion"))
1133+
{
1134+
// For RequiredVersion, use exact version notation [x.x.x]
1135+
string requiredModulesVersion = requiredModulesVersionInfo["RequiredVersion"].ToString();
1136+
versionRange = $"[{requiredModulesVersion}]";
1137+
}
1138+
else if (requiredModulesVersionInfo.ContainsKey("ModuleVersion") && requiredModulesVersionInfo.ContainsKey("MaximumVersion"))
1139+
{
1140+
// Version range when both min and max specified: [min,max]
1141+
versionRange = $"[{requiredModulesVersionInfo["ModuleVersion"]}, {requiredModulesVersionInfo["MaximumVersion"]}]";
1142+
}
1143+
else if (requiredModulesVersionInfo.ContainsKey("ModuleVersion"))
1144+
{
1145+
// Only min specified: min (which means ≥ min)
1146+
versionRange = requiredModulesVersionInfo["ModuleVersion"].ToString();
1147+
}
1148+
else if (requiredModulesVersionInfo.ContainsKey("MaximumVersion"))
11331149
{
1134-
element.SetAttribute("version", requiredModules[dependencyName].ToString());
1150+
// Only max specified: (, max]
1151+
versionRange = $"(, {requiredModulesVersionInfo["MaximumVersion"]}]";
1152+
}
1153+
1154+
if (!string.IsNullOrEmpty(versionRange))
1155+
{
1156+
element.SetAttribute("version", versionRange);
11351157
}
11361158

11371159
dependenciesElement.AppendChild(element);
@@ -1173,19 +1195,26 @@ private Hashtable ParseRequiredModules(Hashtable parsedMetadataHash)
11731195
if (LanguagePrimitives.TryConvertTo<Hashtable>(reqModule, out Hashtable moduleHash))
11741196
{
11751197
string moduleName = moduleHash["ModuleName"] as string;
1176-
1177-
if (moduleHash.ContainsKey("ModuleVersion"))
1198+
var versionInfo = new Hashtable();
1199+
1200+
// RequiredVersion cannot be used with ModuleVersion or MaximumVersion
1201+
if (moduleHash.ContainsKey("RequiredVersion"))
11781202
{
1179-
dependenciesHash.Add(moduleName, moduleHash["ModuleVersion"]);
1203+
versionInfo["RequiredVersion"] = moduleHash["RequiredVersion"].ToString();
11801204
}
1181-
else if (moduleHash.ContainsKey("RequiredVersion"))
1182-
{
1183-
dependenciesHash.Add(moduleName, moduleHash["RequiredVersion"]);
1184-
}
1185-
else
1205+
else
11861206
{
1187-
dependenciesHash.Add(moduleName, string.Empty);
1207+
// ModuleVersion and MaximumVersion can be used together
1208+
if (moduleHash.ContainsKey("ModuleVersion"))
1209+
{
1210+
versionInfo["ModuleVersion"] = moduleHash["ModuleVersion"].ToString();
1211+
}
1212+
if (moduleHash.ContainsKey("MaximumVersion"))
1213+
{
1214+
versionInfo["MaximumVersion"] = moduleHash["MaximumVersion"].ToString();
1215+
}
11881216
}
1217+
dependenciesHash.Add(moduleName, versionInfo);
11891218
}
11901219
else if (LanguagePrimitives.TryConvertTo<string>(reqModule, out string moduleName))
11911220
{

test/PublishPSResourceTests/CompressPSResource.Tests.ps1

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,39 @@ function CreateTestModule
4242
'@ | Out-File -FilePath $moduleSrc
4343
}
4444

45+
function CompressExpandRetrieveNuspec
46+
{
47+
param(
48+
[string]$PublishModuleBase,
49+
[string]$PublishModuleName,
50+
[string]$ModuleVersion,
51+
[string]$RepositoryPath,
52+
[string]$ModuleBasePath,
53+
[string]$TestDrive,
54+
[object[]]$RequiredModules,
55+
[switch]$SkipModuleManifestValidate
56+
)
57+
58+
$testFile = Join-Path -Path "TestSubDirectory" -ChildPath "TestSubDirFile.ps1"
59+
$null = New-ModuleManifest -Path (Join-Path -Path $PublishModuleBase -ChildPath "$PublishModuleName.psd1") -ModuleVersion $version -Description "$PublishModuleName module" -RequiredModules $RequiredModules
60+
$null = New-Item -Path (Join-Path -Path $PublishModuleBase -ChildPath $testFile) -Force
61+
62+
$null = Compress-PSResource -Path $PublishModuleBase -DestinationPath $repositoryPath -SkipModuleManifestValidate:$SkipModuleManifestValidate
63+
64+
# Must change .nupkg to .zip so that Expand-Archive can work on Windows PowerShell
65+
$nupkgPath = Join-Path -Path $RepositoryPath -ChildPath "$PublishModuleName.$version.nupkg"
66+
$zipPath = Join-Path -Path $RepositoryPath -ChildPath "$PublishModuleName.$version.zip"
67+
Rename-Item -Path $nupkgPath -NewName $zipPath
68+
$unzippedPath = Join-Path -Path $TestDrive -ChildPath "$PublishModuleName"
69+
$null = New-Item $unzippedPath -Itemtype directory -Force
70+
$null = Expand-Archive -Path $zipPath -DestinationPath $unzippedPath
71+
72+
$nuspecPath = Join-Path -Path $unzippedPath -ChildPath "$PublishModuleName.nuspec"
73+
$nuspecxml = [xml](Get-Content $nuspecPath)
74+
$null = Remove-Item $unzippedPath -Force -Recurse
75+
return $nuspecxml
76+
}
77+
4578
Describe "Test Compress-PSResource" -tags 'CI' {
4679
BeforeAll {
4780
Get-NewPSResourceRepositoryFile
@@ -218,6 +251,156 @@ Describe "Test Compress-PSResource" -tags 'CI' {
218251
$fileInfoObject.Name | Should -Be "$script:PublishModuleName.$version.nupkg"
219252
}
220253

254+
It "Compress-PSResource creates nuspec dependecy version range when RequiredVersion is in RequiredModules section" {
255+
$version = "1.0.0"
256+
$requiredModules = @(
257+
@{
258+
'ModuleName' = 'PSGetTestRequiredModule'
259+
'GUID' = (New-Guid).Guid
260+
'RequiredVersion' = '2.0.0'
261+
}
262+
)
263+
$compressParams = @{
264+
'PublishModuleBase' = $script:PublishModuleBase
265+
'PublishModuleName' = $script:PublishModuleName
266+
'ModuleVersion' = $version
267+
'RepositoryPath' = $script:repositoryPath
268+
'TestDrive' = $TestDrive
269+
'RequiredModules' = $requiredModules
270+
'SkipModuleManifestValidate' = $true
271+
272+
}
273+
$nuspecxml = CompressExpandRetrieveNuspec @compressParams
274+
# removing spaces as the nuget packaging is formatting the version range and adding spaces even when the original nuspec file doesn't have spaces.
275+
# e.g (,2.0.0] is being formatted to (, 2.0.0]
276+
$nuspecxml.package.metadata.dependencies.dependency.version.replace(' ', '') | Should -BeExactly '[2.0.0]'
277+
}
278+
279+
It "Compress-PSResource creates nuspec dependecy version range when ModuleVersion is in RequiredModules section" {
280+
$version = "1.0.0"
281+
$requiredModules = @(
282+
@{
283+
'ModuleName' = 'PSGetTestRequiredModule'
284+
'GUID' = (New-Guid).Guid
285+
'ModuleVersion' = '2.0.0'
286+
}
287+
)
288+
$compressParams = @{
289+
'PublishModuleBase' = $script:PublishModuleBase
290+
'PublishModuleName' = $script:PublishModuleName
291+
'ModuleVersion' = $version
292+
'RepositoryPath' = $script:repositoryPath
293+
'TestDrive' = $TestDrive
294+
'RequiredModules' = $requiredModules
295+
'SkipModuleManifestValidate' = $true
296+
297+
}
298+
$nuspecxml = CompressExpandRetrieveNuspec @compressParams
299+
$nuspecxml.package.metadata.dependencies.dependency.version.replace(' ', '') | Should -BeExactly '2.0.0'
300+
}
301+
302+
It "Compress-PSResource creates nuspec dependecy version range when MaximumVersion is in RequiredModules section" {
303+
$version = "1.0.0"
304+
$requiredModules = @(
305+
@{
306+
'ModuleName' = 'PSGetTestRequiredModule'
307+
'GUID' = (New-Guid).Guid
308+
'MaximumVersion' = '2.0.0'
309+
}
310+
)
311+
$compressParams = @{
312+
'PublishModuleBase' = $script:PublishModuleBase
313+
'PublishModuleName' = $script:PublishModuleName
314+
'ModuleVersion' = $version
315+
'RepositoryPath' = $script:repositoryPath
316+
'TestDrive' = $TestDrive
317+
'RequiredModules' = $requiredModules
318+
'SkipModuleManifestValidate' = $true
319+
320+
}
321+
$nuspecxml = CompressExpandRetrieveNuspec @compressParams
322+
$nuspecxml.package.metadata.dependencies.dependency.version.replace(' ', '') | Should -BeExactly '(,2.0.0]'
323+
}
324+
325+
It "Compress-PSResource creates nuspec dependecy version range when ModuleVersion and MaximumVersion are in RequiredModules section" {
326+
$version = "1.0.0"
327+
$requiredModules = @(
328+
@{
329+
'ModuleName' = 'PSGetTestRequiredModule'
330+
'GUID' = (New-Guid).Guid
331+
'ModuleVersion' = '1.0.0'
332+
'MaximumVersion' = '2.0.0'
333+
}
334+
)
335+
$compressParams = @{
336+
'PublishModuleBase' = $script:PublishModuleBase
337+
'PublishModuleName' = $script:PublishModuleName
338+
'ModuleVersion' = $version
339+
'RepositoryPath' = $script:repositoryPath
340+
'TestDrive' = $TestDrive
341+
'RequiredModules' = $requiredModules
342+
'SkipModuleManifestValidate' = $true
343+
344+
}
345+
$nuspecxml = CompressExpandRetrieveNuspec @compressParams
346+
$nuspecxml.package.metadata.dependencies.dependency.version.replace(' ', '') | Should -BeExactly '[1.0.0,2.0.0]'
347+
}
348+
349+
It "Compress-PSResource creates nuspec dependecy version range when there are multiple modules in RequiredModules section" {
350+
$version = "1.0.0"
351+
$requiredModules = @(
352+
@{
353+
'ModuleName' = 'PSGetTestRequiredModuleRequiredVersion'
354+
'GUID' = (New-Guid).Guid
355+
'RequiredVersion' = '1.0.0'
356+
},
357+
@{
358+
'ModuleName' = 'PSGetTestRequiredModuleModuleVersion'
359+
'GUID' = (New-Guid).Guid
360+
'ModuleVersion' = '2.0.0'
361+
},
362+
@{
363+
'ModuleName' = 'PSGetTestRequiredModuleMaximumVersion'
364+
'GUID' = (New-Guid).Guid
365+
'MaximumVersion' = '3.0.0'
366+
},
367+
368+
@{
369+
'ModuleName' = 'PSGetTestRequiredModuleModuleAndMaximumVersion'
370+
'GUID' = (New-Guid).Guid
371+
'ModuleVersion' = '4.0.0'
372+
'MaximumVersion' = '5.0.0'
373+
}
374+
)
375+
$compressParams = @{
376+
'PublishModuleBase' = $script:PublishModuleBase
377+
'PublishModuleName' = $script:PublishModuleName
378+
'ModuleVersion' = $version
379+
'RepositoryPath' = $script:repositoryPath
380+
'TestDrive' = $TestDrive
381+
'RequiredModules' = $requiredModules
382+
'SkipModuleManifestValidate' = $true
383+
384+
}
385+
$nuspecxml = CompressExpandRetrieveNuspec @compressParams
386+
foreach ($dependency in $nuspecxml.package.metadata.dependencies.dependency) {
387+
switch ($dependency.id) {
388+
"PSGetTestRequiredModuleRequiredVersion" {
389+
$dependency.version.replace(' ', '') | Should -BeExactly '[1.0.0]'
390+
}
391+
"PSGetTestRequiredModuleModuleVersion" {
392+
$dependency.version.replace(' ', '') | Should -BeExactly '2.0.0'
393+
}
394+
"PSGetTestRequiredModuleMaximumVersion" {
395+
$dependency.version.replace(' ', '') | Should -BeExactly '(,3.0.0]'
396+
}
397+
"PSGetTestRequiredModuleModuleAndMaximumVersion" {
398+
$dependency.version.replace(' ', '') | Should -BeExactly '[4.0.0,5.0.0]'
399+
}
400+
}
401+
}
402+
}
403+
221404
<# Test for Signing the nupkg. Signing doesn't work
222405
It "Compressed Module is able to be signed with a certificate" {
223406
$version = "1.0.0"

0 commit comments

Comments
 (0)