Skip to content

Commit 3b491fe

Browse files
Afroz Mohammedanamnavi
authored andcommitted
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 4c8aa89 commit 3b491fe

File tree

2 files changed

+224
-12
lines changed

2 files changed

+224
-12
lines changed

src/code/PublishHelper.cs

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,20 +1122,47 @@ 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);
1129+
11311130
string dependencyVersion = requiredModules[dependencyName].ToString();
11321131
if (!string.IsNullOrEmpty(dependencyVersion))
11331132
{
1134-
element.SetAttribute("version", requiredModules[dependencyName].ToString());
1133+
var requiredModulesVersionInfo = (Hashtable)requiredModules[dependencyName];
1134+
string versionRange = String.Empty;
1135+
if (requiredModulesVersionInfo.ContainsKey("RequiredVersion"))
1136+
{
1137+
// For RequiredVersion, use exact version notation [x.x.x]
1138+
string requiredModulesVersion = requiredModulesVersionInfo["RequiredVersion"].ToString();
1139+
versionRange = $"[{requiredModulesVersion}]";
1140+
}
1141+
else if (requiredModulesVersionInfo.ContainsKey("ModuleVersion") && requiredModulesVersionInfo.ContainsKey("MaximumVersion"))
1142+
{
1143+
// Version range when both min and max specified: [min,max]
1144+
versionRange = $"[{requiredModulesVersionInfo["ModuleVersion"]}, {requiredModulesVersionInfo["MaximumVersion"]}]";
1145+
}
1146+
else if (requiredModulesVersionInfo.ContainsKey("ModuleVersion"))
1147+
{
1148+
// Only min specified: min (which means ≥ min)
1149+
versionRange = requiredModulesVersionInfo["ModuleVersion"].ToString();
1150+
}
1151+
else if (requiredModulesVersionInfo.ContainsKey("MaximumVersion"))
1152+
{
1153+
// Only max specified: (, max]
1154+
versionRange = $"(, {requiredModulesVersionInfo["MaximumVersion"]}]";
1155+
}
1156+
1157+
if (!string.IsNullOrEmpty(versionRange))
1158+
{
1159+
element.SetAttribute("version", versionRange);
1160+
}
11351161
}
11361162

11371163
dependenciesElement.AppendChild(element);
11381164
}
1165+
11391166
metadataElement.AppendChild(dependenciesElement);
11401167
}
11411168

@@ -1173,19 +1200,26 @@ private Hashtable ParseRequiredModules(Hashtable parsedMetadataHash)
11731200
if (LanguagePrimitives.TryConvertTo<Hashtable>(reqModule, out Hashtable moduleHash))
11741201
{
11751202
string moduleName = moduleHash["ModuleName"] as string;
1176-
1177-
if (moduleHash.ContainsKey("ModuleVersion"))
1203+
var versionInfo = new Hashtable();
1204+
1205+
// RequiredVersion cannot be used with ModuleVersion or MaximumVersion
1206+
if (moduleHash.ContainsKey("RequiredVersion"))
11781207
{
1179-
dependenciesHash.Add(moduleName, moduleHash["ModuleVersion"]);
1208+
versionInfo["RequiredVersion"] = moduleHash["RequiredVersion"].ToString();
11801209
}
1181-
else if (moduleHash.ContainsKey("RequiredVersion"))
1210+
else
11821211
{
1183-
dependenciesHash.Add(moduleName, moduleHash["RequiredVersion"]);
1184-
}
1185-
else
1186-
{
1187-
dependenciesHash.Add(moduleName, string.Empty);
1212+
// ModuleVersion and MaximumVersion can be used together
1213+
if (moduleHash.ContainsKey("ModuleVersion"))
1214+
{
1215+
versionInfo["ModuleVersion"] = moduleHash["ModuleVersion"].ToString();
1216+
}
1217+
if (moduleHash.ContainsKey("MaximumVersion"))
1218+
{
1219+
versionInfo["MaximumVersion"] = moduleHash["MaximumVersion"].ToString();
1220+
}
11881221
}
1222+
dependenciesHash.Add(moduleName, versionInfo);
11891223
}
11901224
else if (LanguagePrimitives.TryConvertTo<string>(reqModule, out string moduleName))
11911225
{

test/PublishPSResourceTests/CompressPSResource.Tests.ps1

Lines changed: 178 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
@@ -152,6 +185,7 @@ Describe "Test Compress-PSResource" -tags 'CI' {
152185
Expand-Archive -Path $zipPath -DestinationPath $unzippedPath
153186

154187
Test-Path -Path (Join-Path -Path $unzippedPath -ChildPath $testFile) | Should -Be $True
188+
$null = Remove-Item $unzippedPath -Force -Recurse
155189
}
156190

157191
It "Compresses a script" {
@@ -218,6 +252,150 @@ Describe "Test Compress-PSResource" -tags 'CI' {
218252
$fileInfoObject.Name | Should -Be "$script:PublishModuleName.$version.nupkg"
219253
}
220254

255+
It "Compress-PSResource creates nuspec dependecy version range when RequiredVersion is in RequiredModules section" {
256+
$version = "1.0.0"
257+
$requiredModules = @(
258+
@{
259+
'ModuleName' = 'PSGetTestRequiredModule'
260+
'GUID' = (New-Guid).Guid
261+
'RequiredVersion' = '2.0.0'
262+
}
263+
)
264+
$compressParams = @{
265+
'PublishModuleBase' = $script:PublishModuleBase
266+
'PublishModuleName' = $script:PublishModuleName
267+
'ModuleVersion' = $version
268+
'RepositoryPath' = $script:repositoryPath
269+
'TestDrive' = $TestDrive
270+
'RequiredModules' = $requiredModules
271+
'SkipModuleManifestValidate' = $true
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+
$nuspecxml = CompressExpandRetrieveNuspec @compressParams
298+
$nuspecxml.package.metadata.dependencies.dependency.version.replace(' ', '') | Should -BeExactly '2.0.0'
299+
}
300+
301+
It "Compress-PSResource creates nuspec dependecy version range when MaximumVersion is in RequiredModules section" {
302+
$version = "1.0.0"
303+
$requiredModules = @(
304+
@{
305+
'ModuleName' = 'PSGetTestRequiredModule'
306+
'GUID' = (New-Guid).Guid
307+
'MaximumVersion' = '2.0.0'
308+
}
309+
)
310+
$compressParams = @{
311+
'PublishModuleBase' = $script:PublishModuleBase
312+
'PublishModuleName' = $script:PublishModuleName
313+
'ModuleVersion' = $version
314+
'RepositoryPath' = $script:repositoryPath
315+
'TestDrive' = $TestDrive
316+
'RequiredModules' = $requiredModules
317+
'SkipModuleManifestValidate' = $true
318+
}
319+
$nuspecxml = CompressExpandRetrieveNuspec @compressParams
320+
$nuspecxml.package.metadata.dependencies.dependency.version.replace(' ', '') | Should -BeExactly '(,2.0.0]'
321+
}
322+
323+
It "Compress-PSResource creates nuspec dependecy version range when ModuleVersion and MaximumVersion are in RequiredModules section" {
324+
$version = "1.0.0"
325+
$requiredModules = @(
326+
@{
327+
'ModuleName' = 'PSGetTestRequiredModule'
328+
'GUID' = (New-Guid).Guid
329+
'ModuleVersion' = '1.0.0'
330+
'MaximumVersion' = '2.0.0'
331+
}
332+
)
333+
$compressParams = @{
334+
'PublishModuleBase' = $script:PublishModuleBase
335+
'PublishModuleName' = $script:PublishModuleName
336+
'ModuleVersion' = $version
337+
'RepositoryPath' = $script:repositoryPath
338+
'TestDrive' = $TestDrive
339+
'RequiredModules' = $requiredModules
340+
'SkipModuleManifestValidate' = $true
341+
}
342+
$nuspecxml = CompressExpandRetrieveNuspec @compressParams
343+
$nuspecxml.package.metadata.dependencies.dependency.version.replace(' ', '') | Should -BeExactly '[1.0.0,2.0.0]'
344+
}
345+
346+
It "Compress-PSResource creates nuspec dependecy version range when there are multiple modules in RequiredModules section" {
347+
$version = "1.0.0"
348+
$requiredModules = @(
349+
@{
350+
'ModuleName' = 'PSGetTestRequiredModuleRequiredVersion'
351+
'GUID' = (New-Guid).Guid
352+
'RequiredVersion' = '1.0.0'
353+
},
354+
@{
355+
'ModuleName' = 'PSGetTestRequiredModuleModuleVersion'
356+
'GUID' = (New-Guid).Guid
357+
'ModuleVersion' = '2.0.0'
358+
},
359+
@{
360+
'ModuleName' = 'PSGetTestRequiredModuleMaximumVersion'
361+
'GUID' = (New-Guid).Guid
362+
'MaximumVersion' = '3.0.0'
363+
},
364+
@{
365+
'ModuleName' = 'PSGetTestRequiredModuleModuleAndMaximumVersion'
366+
'GUID' = (New-Guid).Guid
367+
'ModuleVersion' = '4.0.0'
368+
'MaximumVersion' = '5.0.0'
369+
}
370+
)
371+
$compressParams = @{
372+
'PublishModuleBase' = $script:PublishModuleBase
373+
'PublishModuleName' = $script:PublishModuleName
374+
'ModuleVersion' = $version
375+
'RepositoryPath' = $script:repositoryPath
376+
'TestDrive' = $TestDrive
377+
'RequiredModules' = $requiredModules
378+
'SkipModuleManifestValidate' = $true
379+
}
380+
$nuspecxml = CompressExpandRetrieveNuspec @compressParams
381+
foreach ($dependency in $nuspecxml.package.metadata.dependencies.dependency) {
382+
switch ($dependency.id) {
383+
"PSGetTestRequiredModuleRequiredVersion" {
384+
$dependency.version.replace(' ', '') | Should -BeExactly '[1.0.0]'
385+
}
386+
"PSGetTestRequiredModuleModuleVersion" {
387+
$dependency.version.replace(' ', '') | Should -BeExactly '2.0.0'
388+
}
389+
"PSGetTestRequiredModuleMaximumVersion" {
390+
$dependency.version.replace(' ', '') | Should -BeExactly '(,3.0.0]'
391+
}
392+
"PSGetTestRequiredModuleModuleAndMaximumVersion" {
393+
$dependency.version.replace(' ', '') | Should -BeExactly '[4.0.0,5.0.0]'
394+
}
395+
}
396+
}
397+
}
398+
221399
<# Test for Signing the nupkg. Signing doesn't work
222400
It "Compressed Module is able to be signed with a certificate" {
223401
$version = "1.0.0"

0 commit comments

Comments
 (0)