From 0774602cd37c0d5165295381209385822b68b2ee Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Thu, 19 Dec 2024 12:31:38 -0500 Subject: [PATCH 01/18] add code needed to publish .nupkg directly to ACR --- src/code/ContainerRegistryServerAPICalls.cs | 192 +++++++++++++++++++- src/code/PublishHelper.cs | 67 ++++++- 2 files changed, 255 insertions(+), 4 deletions(-) diff --git a/src/code/ContainerRegistryServerAPICalls.cs b/src/code/ContainerRegistryServerAPICalls.cs index d32b2300f..816ba0831 100644 --- a/src/code/ContainerRegistryServerAPICalls.cs +++ b/src/code/ContainerRegistryServerAPICalls.cs @@ -20,6 +20,7 @@ using System.Text; using System.Security.Cryptography; using System.Text.Json; +using System.Xml; namespace Microsoft.PowerShell.PSResourceGet { @@ -1115,12 +1116,123 @@ private static Collection> GetDefaultHeaders(string #endregion #region Publish Methods + + /// + /// This method is called if Publish-PSResource is called with -NupkgPath specified for a ContainerRegistry + /// Extracts metadata from the .nupkg + /// + internal Hashtable GetMetadataFromNupkg(string copiedNupkgPath, string packageName, out ErrorRecord errRecord) + { + _cmdletPassedIn.WriteDebug("In ContainerRegistryServerAPICalls::GetMetadataFromNupkg()"); + + Hashtable pkgMetadata = new Hashtable(StringComparer.OrdinalIgnoreCase); + errRecord = null; + + // create temp directory where we will copy .nupkg to, extract contents, etc. + string nupkgDirPath = Directory.GetParent(copiedNupkgPath).FullName; //someGuid/nupkg.myPkg.nupkg -> /someGuid/nupkg + string tempPath = Directory.GetParent(nupkgDirPath).FullName; // someGuid + var extractPath = Path.Combine(tempPath, "extract"); + string packageFullName = Path.GetFileName(copiedNupkgPath); + // string packageName = Path.GetFileNameWithoutExtension(packageFullName); + + try + { + var dir = Directory.CreateDirectory(extractPath); + dir.Attributes &= ~FileAttributes.ReadOnly; + + // copy .nupkg + // string destNupkgPath = Path.Combine(tempDiscoveryPath, packageFullName); + // File.Copy(packagePath, destNupkgPath); + + // change extension to .zip + string zipFilePath = Path.ChangeExtension(copiedNupkgPath, ".zip"); + File.Move(copiedNupkgPath, zipFilePath); + + // extract from .zip + _cmdletPassedIn.WriteDebug($"Extracting '{zipFilePath}' to '{extractPath}'"); + System.IO.Compression.ZipFile.ExtractToDirectory(zipFilePath, extractPath); + + string psd1FilePath = String.Empty; + string ps1FilePath = String.Empty; + string nuspecFilePath = String.Empty; + Utils.GetMetadataFilesFromPath(extractPath, packageName, out psd1FilePath, out ps1FilePath, out nuspecFilePath, out string properCasingPkgName); + + List pkgTags = new List(); + + if (File.Exists(psd1FilePath)) + { + _cmdletPassedIn.WriteDebug($"Attempting to read module manifest file '{psd1FilePath}'"); + if (!Utils.TryReadManifestFile(psd1FilePath, out pkgMetadata, out Exception readManifestError)) + { + errRecord = new ErrorRecord( + readManifestError, + "GetMetadataFromNupkgFailure", + ErrorCategory.ParserError, + this); + + return pkgMetadata; + } + } + else if (File.Exists(ps1FilePath)) + { + _cmdletPassedIn.WriteDebug($"Attempting to read script file '{ps1FilePath}'"); + if (!PSScriptFileInfo.TryTestPSScriptFileInfo(ps1FilePath, out PSScriptFileInfo parsedScript, out ErrorRecord[] errors, out string[] verboseMsgs)) + { + errRecord = new ErrorRecord( + new InvalidDataException($"PSScriptFile could not be read properly"), + "GetMetadataFromNupkgFailure", + ErrorCategory.ParserError, + this); + + return pkgMetadata; + } + + pkgMetadata = parsedScript.ToHashtable(); + } + else if (File.Exists(nuspecFilePath)) + { + _cmdletPassedIn.WriteDebug($"Attempting to read nuspec file '{nuspecFilePath}'"); + pkgMetadata = GetHashtableForNuspec(nuspecFilePath, out errRecord); + if (errRecord != null) + { + return pkgMetadata; + } + } + else + { + errRecord = new ErrorRecord( + new InvalidDataException($".nupkg package must contain either .psd1, .ps1, or .nuspec file and none were found"), + "GetMetadataFromNupkgFailure", + ErrorCategory.InvalidData, + this); + + return pkgMetadata; + } + } + catch (Exception e) + { + errRecord = new ErrorRecord( + new InvalidOperationException($"Temporary folder for installation could not be created or set due to: {e.Message}"), + "GetMetadataFromNupkgFailure", + ErrorCategory.InvalidOperation, + this); + } + finally + { + if (Directory.Exists(extractPath)) + { + Utils.DeleteDirectory(extractPath); + } + } + + return pkgMetadata; + } /// /// Helper method that publishes a package to the container registry. /// This gets called from Publish-PSResource. /// - internal bool PushNupkgContainerRegistry(string psd1OrPs1File, + internal bool PushNupkgContainerRegistry( string outputNupkgDir, string packageName, string modulePrefix, @@ -1128,10 +1240,20 @@ internal bool PushNupkgContainerRegistry(string psd1OrPs1File, ResourceType resourceType, Hashtable parsedMetadataHash, Hashtable dependencies, + bool isNupkgPathSpecified, + string originalNupkgPath, out ErrorRecord errRecord) { _cmdletPassedIn.WriteDebug("In ContainerRegistryServerAPICalls::PushNupkgContainerRegistry()"); - string fullNupkgFile = System.IO.Path.Combine(outputNupkgDir, packageName + "." + packageVersion.ToNormalizedString() + ".nupkg"); + + if (isNupkgPathSpecified) + { + var copiedNupkgPath = System.IO.Path.Combine(outputNupkgDir, packageName + "." + packageVersion.ToNormalizedString() + ".nupkg"); + parsedMetadataHash = GetMetadataFromNupkg(copiedNupkgPath, packageName, out errRecord); + } + + // if isNupkgPathSpecified, then we need to publish the original .nupkg file, as it may be signed + string fullNupkgFile = !isNupkgPathSpecified ? System.IO.Path.Combine(outputNupkgDir, packageName + "." + packageVersion.ToNormalizedString() + ".nupkg") : originalNupkgPath; string pkgNameForUpload = string.IsNullOrEmpty(modulePrefix) ? packageName : modulePrefix + "/" + packageName; string packageNameLowercase = pkgNameForUpload.ToLower(); @@ -1708,6 +1830,72 @@ private string PrependMARPrefix(string packageName) return updatedPackageName; } + /// + /// Method that loads file content into XMLDocument. Used when reading .nuspec file. + /// + private XmlDocument LoadXmlDocument(string filePath, out ErrorRecord errRecord) + { + errRecord = null; + XmlDocument doc = new XmlDocument(); + doc.PreserveWhitespace = true; + try { doc.Load(filePath); } + catch (Exception e) + { + errRecord = new ErrorRecord( + exception: e, + "LoadXmlDocumentFailure", + ErrorCategory.ReadError, + this); + } + + return doc; + } + + /// + /// Method that reads .nuspec file and parses out metadata information into Hashtable. + /// + private Hashtable GetHashtableForNuspec(string filePath, out ErrorRecord errRecord) + { + Hashtable nuspecHashtable = new Hashtable(StringComparer.InvariantCultureIgnoreCase); + + XmlDocument nuspecXmlDocument = LoadXmlDocument(filePath, out errRecord); + if (errRecord != null) + { + return nuspecHashtable; + } + + try + { + XmlNodeList elemList = nuspecXmlDocument.GetElementsByTagName("metadata"); + for(int i = 0; i < elemList.Count; i++) + { + XmlNode metadataInnerXml = elemList[i]; + + for(int j= 0; j Date: Thu, 19 Dec 2024 15:02:39 -0500 Subject: [PATCH 02/18] clean up and factor out code --- src/code/ContainerRegistryServerAPICalls.cs | 185 +--------------- src/code/PublishHelper.cs | 234 +++++++++++++++----- src/code/Utils.cs | 68 ++++++ 3 files changed, 251 insertions(+), 236 deletions(-) diff --git a/src/code/ContainerRegistryServerAPICalls.cs b/src/code/ContainerRegistryServerAPICalls.cs index 816ba0831..ecda71779 100644 --- a/src/code/ContainerRegistryServerAPICalls.cs +++ b/src/code/ContainerRegistryServerAPICalls.cs @@ -20,7 +20,7 @@ using System.Text; using System.Security.Cryptography; using System.Text.Json; -using System.Xml; +using Microsoft.PowerShell.Commands; namespace Microsoft.PowerShell.PSResourceGet { @@ -1117,117 +1117,6 @@ private static Collection> GetDefaultHeaders(string #region Publish Methods - /// - /// This method is called if Publish-PSResource is called with -NupkgPath specified for a ContainerRegistry - /// Extracts metadata from the .nupkg - /// - internal Hashtable GetMetadataFromNupkg(string copiedNupkgPath, string packageName, out ErrorRecord errRecord) - { - _cmdletPassedIn.WriteDebug("In ContainerRegistryServerAPICalls::GetMetadataFromNupkg()"); - - Hashtable pkgMetadata = new Hashtable(StringComparer.OrdinalIgnoreCase); - errRecord = null; - - // create temp directory where we will copy .nupkg to, extract contents, etc. - string nupkgDirPath = Directory.GetParent(copiedNupkgPath).FullName; //someGuid/nupkg.myPkg.nupkg -> /someGuid/nupkg - string tempPath = Directory.GetParent(nupkgDirPath).FullName; // someGuid - var extractPath = Path.Combine(tempPath, "extract"); - string packageFullName = Path.GetFileName(copiedNupkgPath); - // string packageName = Path.GetFileNameWithoutExtension(packageFullName); - - try - { - var dir = Directory.CreateDirectory(extractPath); - dir.Attributes &= ~FileAttributes.ReadOnly; - - // copy .nupkg - // string destNupkgPath = Path.Combine(tempDiscoveryPath, packageFullName); - // File.Copy(packagePath, destNupkgPath); - - // change extension to .zip - string zipFilePath = Path.ChangeExtension(copiedNupkgPath, ".zip"); - File.Move(copiedNupkgPath, zipFilePath); - - // extract from .zip - _cmdletPassedIn.WriteDebug($"Extracting '{zipFilePath}' to '{extractPath}'"); - System.IO.Compression.ZipFile.ExtractToDirectory(zipFilePath, extractPath); - - string psd1FilePath = String.Empty; - string ps1FilePath = String.Empty; - string nuspecFilePath = String.Empty; - Utils.GetMetadataFilesFromPath(extractPath, packageName, out psd1FilePath, out ps1FilePath, out nuspecFilePath, out string properCasingPkgName); - - List pkgTags = new List(); - - if (File.Exists(psd1FilePath)) - { - _cmdletPassedIn.WriteDebug($"Attempting to read module manifest file '{psd1FilePath}'"); - if (!Utils.TryReadManifestFile(psd1FilePath, out pkgMetadata, out Exception readManifestError)) - { - errRecord = new ErrorRecord( - readManifestError, - "GetMetadataFromNupkgFailure", - ErrorCategory.ParserError, - this); - - return pkgMetadata; - } - } - else if (File.Exists(ps1FilePath)) - { - _cmdletPassedIn.WriteDebug($"Attempting to read script file '{ps1FilePath}'"); - if (!PSScriptFileInfo.TryTestPSScriptFileInfo(ps1FilePath, out PSScriptFileInfo parsedScript, out ErrorRecord[] errors, out string[] verboseMsgs)) - { - errRecord = new ErrorRecord( - new InvalidDataException($"PSScriptFile could not be read properly"), - "GetMetadataFromNupkgFailure", - ErrorCategory.ParserError, - this); - - return pkgMetadata; - } - - pkgMetadata = parsedScript.ToHashtable(); - } - else if (File.Exists(nuspecFilePath)) - { - _cmdletPassedIn.WriteDebug($"Attempting to read nuspec file '{nuspecFilePath}'"); - pkgMetadata = GetHashtableForNuspec(nuspecFilePath, out errRecord); - if (errRecord != null) - { - return pkgMetadata; - } - } - else - { - errRecord = new ErrorRecord( - new InvalidDataException($".nupkg package must contain either .psd1, .ps1, or .nuspec file and none were found"), - "GetMetadataFromNupkgFailure", - ErrorCategory.InvalidData, - this); - - return pkgMetadata; - } - } - catch (Exception e) - { - errRecord = new ErrorRecord( - new InvalidOperationException($"Temporary folder for installation could not be created or set due to: {e.Message}"), - "GetMetadataFromNupkgFailure", - ErrorCategory.InvalidOperation, - this); - } - finally - { - if (Directory.Exists(extractPath)) - { - Utils.DeleteDirectory(extractPath); - } - } - - return pkgMetadata; - } - /// /// Helper method that publishes a package to the container registry. /// This gets called from Publish-PSResource. @@ -1246,12 +1135,6 @@ internal bool PushNupkgContainerRegistry( { _cmdletPassedIn.WriteDebug("In ContainerRegistryServerAPICalls::PushNupkgContainerRegistry()"); - if (isNupkgPathSpecified) - { - var copiedNupkgPath = System.IO.Path.Combine(outputNupkgDir, packageName + "." + packageVersion.ToNormalizedString() + ".nupkg"); - parsedMetadataHash = GetMetadataFromNupkg(copiedNupkgPath, packageName, out errRecord); - } - // if isNupkgPathSpecified, then we need to publish the original .nupkg file, as it may be signed string fullNupkgFile = !isNupkgPathSpecified ? System.IO.Path.Combine(outputNupkgDir, packageName + "." + packageVersion.ToNormalizedString() + ".nupkg") : originalNupkgPath; @@ -1830,72 +1713,6 @@ private string PrependMARPrefix(string packageName) return updatedPackageName; } - /// - /// Method that loads file content into XMLDocument. Used when reading .nuspec file. - /// - private XmlDocument LoadXmlDocument(string filePath, out ErrorRecord errRecord) - { - errRecord = null; - XmlDocument doc = new XmlDocument(); - doc.PreserveWhitespace = true; - try { doc.Load(filePath); } - catch (Exception e) - { - errRecord = new ErrorRecord( - exception: e, - "LoadXmlDocumentFailure", - ErrorCategory.ReadError, - this); - } - - return doc; - } - - /// - /// Method that reads .nuspec file and parses out metadata information into Hashtable. - /// - private Hashtable GetHashtableForNuspec(string filePath, out ErrorRecord errRecord) - { - Hashtable nuspecHashtable = new Hashtable(StringComparer.InvariantCultureIgnoreCase); - - XmlDocument nuspecXmlDocument = LoadXmlDocument(filePath, out errRecord); - if (errRecord != null) - { - return nuspecHashtable; - } - - try - { - XmlNodeList elemList = nuspecXmlDocument.GetElementsByTagName("metadata"); - for(int i = 0; i < elemList.Count; i++) - { - XmlNode metadataInnerXml = elemList[i]; - - for(int j= 0; j /someGuid/nupkg + string tempPath = Directory.GetParent(nupkgDirPath).FullName; // someGuid + var extractPath = System.IO.Path.Combine(tempPath, "extract"); + string packageFullName = System.IO.Path.GetFileName(copiedNupkgPath); + + try + { + var dir = Directory.CreateDirectory(extractPath); + dir.Attributes &= ~FileAttributes.ReadOnly; + + // copy .nupkg + // string destNupkgPath = Path.Combine(tempDiscoveryPath, packageFullName); + // File.Copy(packagePath, destNupkgPath); + + // change extension to .zip + string zipFilePath = System.IO.Path.ChangeExtension(copiedNupkgPath, ".zip"); + File.Move(copiedNupkgPath, zipFilePath); + + // extract from .zip + _cmdletPassedIn.WriteDebug($"Extracting '{zipFilePath}' to '{extractPath}'"); + System.IO.Compression.ZipFile.ExtractToDirectory(zipFilePath, extractPath); + + string psd1FilePath = String.Empty; + string ps1FilePath = String.Empty; + string nuspecFilePath = String.Empty; + Utils.GetMetadataFilesFromPath(extractPath, packageName, out psd1FilePath, out ps1FilePath, out nuspecFilePath, out string properCasingPkgName); + + List pkgTags = new List(); + + if (File.Exists(psd1FilePath)) + { + _cmdletPassedIn.WriteDebug($"Attempting to read module manifest file '{psd1FilePath}'"); + if (!Utils.TryReadManifestFile(psd1FilePath, out pkgMetadata, out Exception readManifestError)) + { + errRecord = new ErrorRecord( + readManifestError, + "GetMetadataFromNupkgFailure", + ErrorCategory.ParserError, + this); + + return pkgMetadata; + } + } + else if (File.Exists(ps1FilePath)) + { + _cmdletPassedIn.WriteDebug($"Attempting to read script file '{ps1FilePath}'"); + if (!PSScriptFileInfo.TryTestPSScriptFileInfo(ps1FilePath, out PSScriptFileInfo parsedScript, out ErrorRecord[] errors, out string[] verboseMsgs)) + { + errRecord = new ErrorRecord( + new InvalidDataException($"PSScriptFile could not be read properly"), + "GetMetadataFromNupkgFailure", + ErrorCategory.ParserError, + this); + + return pkgMetadata; + } + + pkgMetadata = parsedScript.ToHashtable(); + } + else if (File.Exists(nuspecFilePath)) + { + _cmdletPassedIn.WriteDebug($"Attempting to read nuspec file '{nuspecFilePath}'"); + pkgMetadata = Utils.GetMetadataFromNuspec(nuspecFilePath, _cmdletPassedIn, out errRecord); + if (errRecord != null) + { + return pkgMetadata; + } + } + else + { + errRecord = new ErrorRecord( + new InvalidDataException($".nupkg package must contain either .psd1, .ps1, or .nuspec file and none were found"), + "GetMetadataFromNupkgFailure", + ErrorCategory.InvalidData, + this); + + return pkgMetadata; + } + } + catch (Exception e) + { + errRecord = new ErrorRecord( + new InvalidOperationException($"Temporary folder for installation could not be created or set due to: {e.Message}"), + "GetMetadataFromNupkgFailure", + ErrorCategory.InvalidOperation, + this); + } + finally + { + if (Directory.Exists(extractPath)) + { + Utils.DeleteDirectory(extractPath); + } + } + + return pkgMetadata; + } + #endregion } } diff --git a/src/code/Utils.cs b/src/code/Utils.cs index da80d3f42..4d062e107 100644 --- a/src/code/Utils.cs +++ b/src/code/Utils.cs @@ -23,6 +23,7 @@ using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; +using System.Xml; namespace Microsoft.PowerShell.PSResourceGet.UtilClasses { @@ -1830,6 +1831,73 @@ public static void CreateFile(string filePath) #endregion + #region Nuspec file parsing methods + + public static Hashtable GetMetadataFromNuspec(string nuspecFilePath, PSCmdlet cmdletPassedIn, out ErrorRecord errorRecord) + { + Hashtable nuspecHashtable = new Hashtable(StringComparer.InvariantCultureIgnoreCase); + + XmlDocument nuspecXmlDocument = LoadXmlDocument(nuspecFilePath, cmdletPassedIn, out errorRecord); + if (errorRecord != null) + { + return nuspecHashtable; + } + + try + { + XmlNodeList elemList = nuspecXmlDocument.GetElementsByTagName("metadata"); + for(int i = 0; i < elemList.Count; i++) + { + XmlNode metadataInnerXml = elemList[i]; + + for(int j= 0; j + /// Method that loads file content into XMLDocument. Used when reading .nuspec file. + /// + public static XmlDocument LoadXmlDocument(string filePath, PSCmdlet cmdletPassedIn, out ErrorRecord errRecord) + { + errRecord = null; + XmlDocument doc = new XmlDocument(); + doc.PreserveWhitespace = true; + try { doc.Load(filePath); } + catch (Exception e) + { + errRecord = new ErrorRecord( + exception: e, + "LoadXmlDocumentFailure", + ErrorCategory.ReadError, + cmdletPassedIn); + } + + return doc; + } + + #endregion + } #endregion From 5e17233bab0343c8f93d4edfb242af58fa1549b4 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Thu, 19 Dec 2024 15:10:07 -0500 Subject: [PATCH 03/18] clean up code and add comments --- src/code/ContainerRegistryServerAPICalls.cs | 1 - src/code/PublishHelper.cs | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/code/ContainerRegistryServerAPICalls.cs b/src/code/ContainerRegistryServerAPICalls.cs index ecda71779..35a29cf2d 100644 --- a/src/code/ContainerRegistryServerAPICalls.cs +++ b/src/code/ContainerRegistryServerAPICalls.cs @@ -20,7 +20,6 @@ using System.Text; using System.Security.Cryptography; using System.Text.Json; -using Microsoft.PowerShell.Commands; namespace Microsoft.PowerShell.PSResourceGet { diff --git a/src/code/PublishHelper.cs b/src/code/PublishHelper.cs index 22ff4159f..2843971fe 100644 --- a/src/code/PublishHelper.cs +++ b/src/code/PublishHelper.cs @@ -434,7 +434,6 @@ internal void PushResource(string Repository, string modulePrefix, bool SkipDepe } } - // TODO: do we not want to additionally publish to DesintationPath if NupkgPath is specified? } string repositoryUri = repository.Uri.AbsoluteUri; @@ -445,6 +444,7 @@ internal void PushResource(string Repository, string modulePrefix, bool SkipDepe if (_isNupkgPathSpecified) { + // copy the .nupkg to a temp path (outputNupkgDir field) as we don't want to tamper with the original, possibly signed, .nupkg file string copiedNupkgFilePath = CopyNupkgFileToTempPath(nupkgFilePath: Path, errRecord: out ErrorRecord copyErrRecord); if (copyErrRecord != null) { @@ -452,6 +452,7 @@ internal void PushResource(string Repository, string modulePrefix, bool SkipDepe return; } + // get package info (name, version, metadata hashtable) from the copied .nupkg package and then populate appropriate fields (_pkgName, _pkgVersion, parsedMetadata) GetPackageInfoFromNupkg(nupkgFilePath: copiedNupkgFilePath, errRecord: out ErrorRecord pkgInfoErrRecord); if (pkgInfoErrRecord != null) { @@ -463,7 +464,6 @@ internal void PushResource(string Repository, string modulePrefix, bool SkipDepe if (!containerRegistryServer.PushNupkgContainerRegistry(outputNupkgDir, _pkgName, modulePrefix, _pkgVersion, resourceType, parsedMetadata, dependencies, _isNupkgPathSpecified, Path, out ErrorRecord pushNupkgContainerRegistryError)) { _cmdletPassedIn.WriteError(pushNupkgContainerRegistryError); - // exit out of processing return; } } From 0429c43c49ffd7b674ad14ea27abb162e143d6e3 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Thu, 19 Dec 2024 15:20:11 -0500 Subject: [PATCH 04/18] add more comments --- src/code/PublishHelper.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/code/PublishHelper.cs b/src/code/PublishHelper.cs index 2843971fe..20b7261fd 100644 --- a/src/code/PublishHelper.cs +++ b/src/code/PublishHelper.cs @@ -1262,6 +1262,10 @@ private bool CheckDependenciesExist(Hashtable dependencies, string repositoryNam return true; } + /// + /// This method is called by Publish-PSResource when the -NupkgPath parameter is specified + /// The method copies the .nupkg file to a temp path (populated at outputNupkgDir field) as we dont' want to extract and read original .nupkg file + /// private string CopyNupkgFileToTempPath(string nupkgFilePath, out ErrorRecord errRecord) { errRecord = null; @@ -1296,6 +1300,9 @@ private string CopyNupkgFileToTempPath(string nupkgFilePath, out ErrorRecord err return destinationFilePath; } + /// + /// Get package info from the .nupkg file provided, inluding package name (_pkgName), package version (_pkgVersion), and metadata parsed into a hashtable (parsedMetadata) + /// private void GetPackageInfoFromNupkg(string nupkgFilePath, out ErrorRecord errRecord) { errRecord = null; @@ -1332,6 +1339,9 @@ private void GetPackageInfoFromNupkg(string nupkgFilePath, out ErrorRecord errRe parsedMetadata = GetMetadataFromNupkg(nupkgFilePath, _pkgName, out errRecord); } + /// + /// Extract copied .nupkg, find metadata file (either .ps1, .psd1, or .nuspec) and read metadata into a hashtable + /// internal Hashtable GetMetadataFromNupkg(string copiedNupkgPath, string packageName, out ErrorRecord errRecord) { Hashtable pkgMetadata = new Hashtable(StringComparer.OrdinalIgnoreCase); From ac8d77a1602c580ba00129f1605708af953efcb3 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Thu, 19 Dec 2024 15:28:29 -0500 Subject: [PATCH 05/18] remove unused code --- src/code/PublishHelper.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/code/PublishHelper.cs b/src/code/PublishHelper.cs index 20b7261fd..6509d4e2f 100644 --- a/src/code/PublishHelper.cs +++ b/src/code/PublishHelper.cs @@ -1348,20 +1348,15 @@ internal Hashtable GetMetadataFromNupkg(string copiedNupkgPath, string packageNa errRecord = null; // in temp directory create an "extract" folder to which we'll copy .nupkg to, extract contents, etc. - string nupkgDirPath = Directory.GetParent(copiedNupkgPath).FullName; //someGuid/nupkg.myPkg.nupkg -> /someGuid/nupkg + string nupkgDirPath = Directory.GetParent(copiedNupkgPath).FullName; //someGuid/nupkg/myPkg.nupkg -> /someGuid/nupkg string tempPath = Directory.GetParent(nupkgDirPath).FullName; // someGuid - var extractPath = System.IO.Path.Combine(tempPath, "extract"); - string packageFullName = System.IO.Path.GetFileName(copiedNupkgPath); + var extractPath = System.IO.Path.Combine(tempPath, "extract"); // someGuid/extract try { var dir = Directory.CreateDirectory(extractPath); dir.Attributes &= ~FileAttributes.ReadOnly; - // copy .nupkg - // string destNupkgPath = Path.Combine(tempDiscoveryPath, packageFullName); - // File.Copy(packagePath, destNupkgPath); - // change extension to .zip string zipFilePath = System.IO.Path.ChangeExtension(copiedNupkgPath, ".zip"); File.Move(copiedNupkgPath, zipFilePath); From 8fc277874301bbc2e95d917e7d6d1944e497848e Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Fri, 20 Dec 2024 13:09:10 -0500 Subject: [PATCH 06/18] add tests with test nupkg files --- ...SResourceContainerRegistryServer.Tests.ps1 | 39 ++++++++++++++++++ .../temp-testmodule-nupkgpath.1.0.0.nupkg | Bin 0 -> 3393 bytes .../temp-testnupkg-nupkgpath.1.0.0.nupkg | Bin 0 -> 2046 bytes .../temp-testscript-nupkgpath.1.0.0.nupkg | Bin 0 -> 2211 bytes 4 files changed, 39 insertions(+) create mode 100644 test/testFiles/testNupkgs/temp-testmodule-nupkgpath.1.0.0.nupkg create mode 100644 test/testFiles/testNupkgs/temp-testnupkg-nupkgpath.1.0.0.nupkg create mode 100644 test/testFiles/testNupkgs/temp-testscript-nupkgpath.1.0.0.nupkg diff --git a/test/PublishPSResourceTests/PublishPSResourceContainerRegistryServer.Tests.ps1 b/test/PublishPSResourceTests/PublishPSResourceContainerRegistryServer.Tests.ps1 index 1426efe11..0de6769d6 100644 --- a/test/PublishPSResourceTests/PublishPSResourceContainerRegistryServer.Tests.ps1 +++ b/test/PublishPSResourceTests/PublishPSResourceContainerRegistryServer.Tests.ps1 @@ -97,6 +97,9 @@ Describe "Test Publish-PSResource" -tags 'CI' { # Path to specifically to that invalid test scripts folder $script:testScriptsFolderPath = Join-Path $script:testFilesFolderPath -ChildPath "testScripts" + + # Path to specifically to that invalid test nupkgs folder + $script:testNupkgsFolderPath = Join-Path $script:testFilesFolderPath -ChildPath "testNupkgs" } AfterEach { if(!(Test-Path $script:PublishModuleBase)) @@ -511,6 +514,42 @@ Describe "Test Publish-PSResource" -tags 'CI' { $results[0].Name | Should -Be $script:PublishModuleName $results[0].Version | Should -Be $version } + + It "Publish a package given NupkgPath to a package with .psd1" { + $packageName = "temp-testmodule-nupkgpath" + $version = "1.0.0.0" + $nupkgPath = Join-Path -Path $script:testNupkgsFolderPath -ChildPath $packageName + Publish-PSResource -NupkgPath $nupkgPath -Repository $ACRRepoName + + $results = Find-PSResource -Name $packageName -Repository $ACRRepoName + $results | Should -Not -BeNullOrEmpty + $results[0].Name | Should -Be $packageName + $results[0].Version | Should -Be $version + } + + It "Publish a package given NupkgPath to a package with .ps1" { + $packageName = "temp-testscript-nupkgpath" + $version = "1.0.0.0" + $nupkgPath = Join-Path -Path $script:testNupkgsFolderPath -ChildPath $packageName + Publish-PSResource -NupkgPath $nupkgPath -Repository $ACRRepoName + + $results = Find-PSResource -Name $packageName -Repository $ACRRepoName + $results | Should -Not -BeNullOrEmpty + $results[0].Name | Should -Be $packageName + $results[0].Version | Should -Be $version + } + + It "Publish a package given NupkgPath to a package with .nuspec" { + $packageName = "temp-testnupkg-nupkgpath" + $version = "1.0.0.0" + $nupkgPath = Join-Path -Path $script:testNupkgsFolderPath -ChildPath $packageName + Publish-PSResource -NupkgPath $nupkgPath -Repository $ACRRepoName + + $results = Find-PSResource -Name $packageName -Repository $ACRRepoName + $results | Should -Not -BeNullOrEmpty + $results[0].Name | Should -Be $packageName + $results[0].Version | Should -Be $version + } } Describe 'Test Publish-PSResource for MAR Repository' -tags 'CI' { diff --git a/test/testFiles/testNupkgs/temp-testmodule-nupkgpath.1.0.0.nupkg b/test/testFiles/testNupkgs/temp-testmodule-nupkgpath.1.0.0.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..a0f7d11d86d7c2aab04394d18fa26ff462815058 GIT binary patch literal 3393 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 qx8A= Date: Fri, 20 Dec 2024 13:23:20 -0500 Subject: [PATCH 07/18] fix nupkgPath path in the test --- .../PublishPSResourceContainerRegistryServer.Tests.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/PublishPSResourceTests/PublishPSResourceContainerRegistryServer.Tests.ps1 b/test/PublishPSResourceTests/PublishPSResourceContainerRegistryServer.Tests.ps1 index 0de6769d6..12e3c0eae 100644 --- a/test/PublishPSResourceTests/PublishPSResourceContainerRegistryServer.Tests.ps1 +++ b/test/PublishPSResourceTests/PublishPSResourceContainerRegistryServer.Tests.ps1 @@ -516,7 +516,7 @@ Describe "Test Publish-PSResource" -tags 'CI' { } It "Publish a package given NupkgPath to a package with .psd1" { - $packageName = "temp-testmodule-nupkgpath" + $packageName = "temp-testmodule-nupkgpath.nupkg" $version = "1.0.0.0" $nupkgPath = Join-Path -Path $script:testNupkgsFolderPath -ChildPath $packageName Publish-PSResource -NupkgPath $nupkgPath -Repository $ACRRepoName @@ -528,7 +528,7 @@ Describe "Test Publish-PSResource" -tags 'CI' { } It "Publish a package given NupkgPath to a package with .ps1" { - $packageName = "temp-testscript-nupkgpath" + $packageName = "temp-testscript-nupkgpath.nupkg" $version = "1.0.0.0" $nupkgPath = Join-Path -Path $script:testNupkgsFolderPath -ChildPath $packageName Publish-PSResource -NupkgPath $nupkgPath -Repository $ACRRepoName @@ -540,7 +540,7 @@ Describe "Test Publish-PSResource" -tags 'CI' { } It "Publish a package given NupkgPath to a package with .nuspec" { - $packageName = "temp-testnupkg-nupkgpath" + $packageName = "temp-testnupkg-nupkgpath.nupkg" $version = "1.0.0.0" $nupkgPath = Join-Path -Path $script:testNupkgsFolderPath -ChildPath $packageName Publish-PSResource -NupkgPath $nupkgPath -Repository $ACRRepoName From 2909df91c9f8897f2c23006bfb1d0f4e2cb22aec Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Fri, 20 Dec 2024 13:36:18 -0500 Subject: [PATCH 08/18] fix nupkgPath path in the test again --- .../PublishPSResourceContainerRegistryServer.Tests.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/PublishPSResourceTests/PublishPSResourceContainerRegistryServer.Tests.ps1 b/test/PublishPSResourceTests/PublishPSResourceContainerRegistryServer.Tests.ps1 index 12e3c0eae..32472676a 100644 --- a/test/PublishPSResourceTests/PublishPSResourceContainerRegistryServer.Tests.ps1 +++ b/test/PublishPSResourceTests/PublishPSResourceContainerRegistryServer.Tests.ps1 @@ -516,7 +516,7 @@ Describe "Test Publish-PSResource" -tags 'CI' { } It "Publish a package given NupkgPath to a package with .psd1" { - $packageName = "temp-testmodule-nupkgpath.nupkg" + $packageName = "temp-testmodule-nupkgpath.1.0.0.nupkg" $version = "1.0.0.0" $nupkgPath = Join-Path -Path $script:testNupkgsFolderPath -ChildPath $packageName Publish-PSResource -NupkgPath $nupkgPath -Repository $ACRRepoName @@ -528,7 +528,7 @@ Describe "Test Publish-PSResource" -tags 'CI' { } It "Publish a package given NupkgPath to a package with .ps1" { - $packageName = "temp-testscript-nupkgpath.nupkg" + $packageName = "temp-testscript-nupkgpath.1.0.0.nupkg" $version = "1.0.0.0" $nupkgPath = Join-Path -Path $script:testNupkgsFolderPath -ChildPath $packageName Publish-PSResource -NupkgPath $nupkgPath -Repository $ACRRepoName @@ -540,7 +540,7 @@ Describe "Test Publish-PSResource" -tags 'CI' { } It "Publish a package given NupkgPath to a package with .nuspec" { - $packageName = "temp-testnupkg-nupkgpath.nupkg" + $packageName = "temp-testnupkg-nupkgpath.1.0.0.nupkg" $version = "1.0.0.0" $nupkgPath = Join-Path -Path $script:testNupkgsFolderPath -ChildPath $packageName Publish-PSResource -NupkgPath $nupkgPath -Repository $ACRRepoName From d063072535a4adbf68f33f72e0d2d811b5b6c723 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Fri, 20 Dec 2024 14:17:31 -0500 Subject: [PATCH 09/18] fix package name passed to Find-PSResource --- ...ublishPSResourceContainerRegistryServer.Tests.ps1 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/PublishPSResourceTests/PublishPSResourceContainerRegistryServer.Tests.ps1 b/test/PublishPSResourceTests/PublishPSResourceContainerRegistryServer.Tests.ps1 index 32472676a..a808cdb5d 100644 --- a/test/PublishPSResourceTests/PublishPSResourceContainerRegistryServer.Tests.ps1 +++ b/test/PublishPSResourceTests/PublishPSResourceContainerRegistryServer.Tests.ps1 @@ -516,9 +516,9 @@ Describe "Test Publish-PSResource" -tags 'CI' { } It "Publish a package given NupkgPath to a package with .psd1" { - $packageName = "temp-testmodule-nupkgpath.1.0.0.nupkg" + $packageName = "temp-testmodule-nupkgpath" $version = "1.0.0.0" - $nupkgPath = Join-Path -Path $script:testNupkgsFolderPath -ChildPath $packageName + $nupkgPath = Join-Path -Path $script:testNupkgsFolderPath -ChildPath "$packageName.1.0.0.nupkg" Publish-PSResource -NupkgPath $nupkgPath -Repository $ACRRepoName $results = Find-PSResource -Name $packageName -Repository $ACRRepoName @@ -528,9 +528,9 @@ Describe "Test Publish-PSResource" -tags 'CI' { } It "Publish a package given NupkgPath to a package with .ps1" { - $packageName = "temp-testscript-nupkgpath.1.0.0.nupkg" + $packageName = "temp-testscript-nupkgpath" $version = "1.0.0.0" - $nupkgPath = Join-Path -Path $script:testNupkgsFolderPath -ChildPath $packageName + $nupkgPath = Join-Path -Path $script:testNupkgsFolderPath -ChildPath "$packageName.1.0.0.nupkg" Publish-PSResource -NupkgPath $nupkgPath -Repository $ACRRepoName $results = Find-PSResource -Name $packageName -Repository $ACRRepoName @@ -540,9 +540,9 @@ Describe "Test Publish-PSResource" -tags 'CI' { } It "Publish a package given NupkgPath to a package with .nuspec" { - $packageName = "temp-testnupkg-nupkgpath.1.0.0.nupkg" + $packageName = "temp-testnupkg-nupkgpath" $version = "1.0.0.0" - $nupkgPath = Join-Path -Path $script:testNupkgsFolderPath -ChildPath $packageName + $nupkgPath = Join-Path -Path $script:testNupkgsFolderPath -ChildPath "$packageName.1.0.0.nupkg" Publish-PSResource -NupkgPath $nupkgPath -Repository $ACRRepoName $results = Find-PSResource -Name $packageName -Repository $ACRRepoName From 13e48c20b42929f736fa2e83fe471759871361e4 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Fri, 3 Jan 2025 11:41:23 -0500 Subject: [PATCH 10/18] correctly parse out metadata during Find (fix casing of properties expected) and update nupkg with nuspec with copyright --- src/code/ContainerRegistryServerAPICalls.cs | 4 ++-- src/code/PSResourceInfo.cs | 19 +++++++++--------- .../temp-testnupkg-nupkgpath.1.0.0.nupkg | Bin 2046 -> 2067 bytes 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/code/ContainerRegistryServerAPICalls.cs b/src/code/ContainerRegistryServerAPICalls.cs index 35a29cf2d..42fda0d1c 100644 --- a/src/code/ContainerRegistryServerAPICalls.cs +++ b/src/code/ContainerRegistryServerAPICalls.cs @@ -649,9 +649,9 @@ internal Hashtable GetContainerRegistryMetadata(string packageName, string exact pkgVersionString += $"-{pkgPrereleaseLabelElement.ToString()}"; } } - else if (rootDom.TryGetProperty("Version", out pkgVersionElement)) + else if (rootDom.TryGetProperty("Version", out pkgVersionElement) || rootDom.TryGetProperty("version", out pkgVersionElement)) { - // script metadata will have "Version" property + // script metadata will have "Version" property, but nupk only based .nuspec will have lowercase "version" property and JsonElement.TryGetProperty() is case sensitive pkgVersionString = pkgVersionElement.ToString(); } else diff --git a/src/code/PSResourceInfo.cs b/src/code/PSResourceInfo.cs index 0e14f6ce9..4d7cd79ba 100644 --- a/src/code/PSResourceInfo.cs +++ b/src/code/PSResourceInfo.cs @@ -836,7 +836,8 @@ public static bool TryConvertFromContainerRegistryJson( // Version // For scripts (i.e with "Version" property) the version can contain prerelease label - if (rootDom.TryGetProperty("Version", out JsonElement scriptVersionElement)) + // For nupkg only based packages the .nuspec's metadata attributes will be lowercase + if (rootDom.TryGetProperty("Version", out JsonElement scriptVersionElement) || rootDom.TryGetProperty("version", out scriptVersionElement)) { versionValue = scriptVersionElement.ToString(); pkgVersion = ParseHttpVersion(versionValue, out string prereleaseLabel); @@ -883,25 +884,25 @@ public static bool TryConvertFromContainerRegistryJson( metadata["NormalizedVersion"] = parsedNormalizedVersion.ToNormalizedString(); // License Url - if (rootDom.TryGetProperty("LicenseUrl", out JsonElement licenseUrlElement)) + if (rootDom.TryGetProperty("LicenseUrl", out JsonElement licenseUrlElement) || rootDom.TryGetProperty("licenseUrl", out licenseUrlElement)) { metadata["LicenseUrl"] = ParseHttpUrl(licenseUrlElement.ToString()) as Uri; } // Project Url - if (rootDom.TryGetProperty("ProjectUrl", out JsonElement projectUrlElement)) + if (rootDom.TryGetProperty("ProjectUrl", out JsonElement projectUrlElement) || rootDom.TryGetProperty("projectUrl", out projectUrlElement)) { metadata["ProjectUrl"] = ParseHttpUrl(projectUrlElement.ToString()) as Uri; } // Icon Url - if (rootDom.TryGetProperty("IconUrl", out JsonElement iconUrlElement)) + if (rootDom.TryGetProperty("IconUrl", out JsonElement iconUrlElement) || rootDom.TryGetProperty("iconUrl", out iconUrlElement)) { metadata["IconUrl"] = ParseHttpUrl(iconUrlElement.ToString()) as Uri; } // Tags - if (rootDom.TryGetProperty("Tags", out JsonElement tagsElement)) + if (rootDom.TryGetProperty("Tags", out JsonElement tagsElement) || rootDom.TryGetProperty("tags", out tagsElement)) { string[] pkgTags = Utils.EmptyStrArray; if (tagsElement.ValueKind == JsonValueKind.Array) @@ -937,7 +938,7 @@ public static bool TryConvertFromContainerRegistryJson( } // Author - if (rootDom.TryGetProperty("Authors", out JsonElement authorsElement)) + if (rootDom.TryGetProperty("Authors", out JsonElement authorsElement) || rootDom.TryGetProperty("authors", out authorsElement)) { metadata["Authors"] = authorsElement.ToString(); @@ -948,19 +949,19 @@ public static bool TryConvertFromContainerRegistryJson( } // Copyright - if (rootDom.TryGetProperty("Copyright", out JsonElement copyrightElement)) + if (rootDom.TryGetProperty("Copyright", out JsonElement copyrightElement) || rootDom.TryGetProperty("copyright", out copyrightElement)) { metadata["Copyright"] = copyrightElement.ToString(); } // Description - if (rootDom.TryGetProperty("Description", out JsonElement descriptiontElement)) + if (rootDom.TryGetProperty("Description", out JsonElement descriptiontElement) || rootDom.TryGetProperty("description", out descriptiontElement)) { metadata["Description"] = descriptiontElement.ToString(); } // ReleaseNotes - if (rootDom.TryGetProperty("ReleaseNotes", out JsonElement releaseNotesElement)) + if (rootDom.TryGetProperty("ReleaseNotes", out JsonElement releaseNotesElement) || rootDom.TryGetProperty("releaseNotes", out releaseNotesElement)) { metadata["ReleaseNotes"] = releaseNotesElement.ToString(); } diff --git a/test/testFiles/testNupkgs/temp-testnupkg-nupkgpath.1.0.0.nupkg b/test/testFiles/testNupkgs/temp-testnupkg-nupkgpath.1.0.0.nupkg index fe6affa1cc24c737a0208f531709669d38116aa7..370ba0068365dbe59e33e257998293abd01a9269 100644 GIT binary patch delta 1040 zcmeyzKUttYz?+#xgn@y9gFz@pIm-C%erH)m1_m}J1_o}RXnav>PO-ioh@3j{Y}R1| zftL5J`1oOSo_b5Ge(!|~0wC%aYy!;yn|ax9}p zeclxVfqlv!`4-Q4u;F8#zv!o3PPU2{xjKvb*wW3+d~=fhPrch*_+VlM>zgZ@f*ocVLh?!3G!ufvTN)E#M5xEyO` z)@Hd!SSiz4cv;ydt6xw2?_}9`rstIjg#SM5_-1{5>+E2KyYqtYrx-I>3MTjWcu&o~ zt-Vb1%?zR4mNtC5pYon?>*5KEk_~xkd3&!&c4Xk3n?GiVShf34tJ1vYr|R;{?zV^g zTD9pf_FfZ_n5$NL$Z(>_|D&txYSJbx&z+N!R!-k6JbU-#uYR6?8A0(l`6HXuWOHUU7EqR$oXGqe z!bo7TQZP@mFflT=u(V80u{23CHA^x~GB8ZFNH#MxO-wX0FxoStjSP=n!=9Xgi$3y$$DYHN?5`MKmXV6Pt(&wq*3S){ zKIM;mVec=Wd6U^{6j>OP8L7B&j`rlLSsQYNlFDaRn(^5Pt#`O})}i%?YS-Vt zCw{$&x37D(`?JX*?$mFFGP9j`=QlL2xovK>u=ZHvf(y*@((04$ zX&$|HvE`26y=Nyrs;upuT=i6py>zp^%$0v(tuyO|Z+<&d8+?Z0i%XL&*SgS^wfQZ} zwg@M27FWrYy`CK~CyaH?7ONGS#oMaau1j?-6caa==3$Jt`5F~#J$1s%+i#3*E4&+D z?%g_trCGK3&_vJG{~v|g?_*M!?sB~CoTjiov&pl=eb9WuAQX1 zQZ+teF>B|Bu*`o(Rb{EMAMSQHA7}j=(bV1|d3upX_SUaIgr9kw_#)BW{nNx>_!;*R z;fVG`g*MJ=Ciw(OKCQ}wM+L8BXH7q0u6On3v67Q@1xZ_e{a!D=;K6}sobAk0p1ZBy z8kg^t+vjy%S>?0zWIbjV7Er36T*mwx!YF02Qb@HhvNTIEGfzu4Of)f0G`BEMO-nMd zFf>dyGc&U^Ox%2)WjiA$Jhx2lXETro@eq;Dz#tFII|$%9`5v1OqvT|5b~%VOzU)$r s!ILxCl_1 Date: Fri, 3 Jan 2025 12:22:08 -0500 Subject: [PATCH 11/18] fix version in test --- .../PublishPSResourceContainerRegistryServer.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/PublishPSResourceTests/PublishPSResourceContainerRegistryServer.Tests.ps1 b/test/PublishPSResourceTests/PublishPSResourceContainerRegistryServer.Tests.ps1 index a808cdb5d..af57385a1 100644 --- a/test/PublishPSResourceTests/PublishPSResourceContainerRegistryServer.Tests.ps1 +++ b/test/PublishPSResourceTests/PublishPSResourceContainerRegistryServer.Tests.ps1 @@ -541,7 +541,7 @@ Describe "Test Publish-PSResource" -tags 'CI' { It "Publish a package given NupkgPath to a package with .nuspec" { $packageName = "temp-testnupkg-nupkgpath" - $version = "1.0.0.0" + $version = "1.0.0" $nupkgPath = Join-Path -Path $script:testNupkgsFolderPath -ChildPath "$packageName.1.0.0.nupkg" Publish-PSResource -NupkgPath $nupkgPath -Repository $ACRRepoName From 9c676de409df2b7005c33510c804f1c2c56b05bd Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 7 Jan 2025 14:56:46 -0500 Subject: [PATCH 12/18] Update src/code/ContainerRegistryServerAPICalls.cs Co-authored-by: Aditya Patwardhan --- src/code/ContainerRegistryServerAPICalls.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/code/ContainerRegistryServerAPICalls.cs b/src/code/ContainerRegistryServerAPICalls.cs index 42fda0d1c..2a3144457 100644 --- a/src/code/ContainerRegistryServerAPICalls.cs +++ b/src/code/ContainerRegistryServerAPICalls.cs @@ -651,7 +651,7 @@ internal Hashtable GetContainerRegistryMetadata(string packageName, string exact } else if (rootDom.TryGetProperty("Version", out pkgVersionElement) || rootDom.TryGetProperty("version", out pkgVersionElement)) { - // script metadata will have "Version" property, but nupk only based .nuspec will have lowercase "version" property and JsonElement.TryGetProperty() is case sensitive + // script metadata will have "Version" property, but nupkg only based .nuspec will have lowercase "version" property and JsonElement.TryGetProperty() is case sensitive pkgVersionString = pkgVersionElement.ToString(); } else From 1980bff6329cb379a6f1b43337668c034833e4c8 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 7 Jan 2025 14:57:00 -0500 Subject: [PATCH 13/18] Update src/code/ContainerRegistryServerAPICalls.cs Co-authored-by: Aditya Patwardhan --- src/code/ContainerRegistryServerAPICalls.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/code/ContainerRegistryServerAPICalls.cs b/src/code/ContainerRegistryServerAPICalls.cs index 2a3144457..4f31cd176 100644 --- a/src/code/ContainerRegistryServerAPICalls.cs +++ b/src/code/ContainerRegistryServerAPICalls.cs @@ -1115,7 +1115,6 @@ private static Collection> GetDefaultHeaders(string #endregion #region Publish Methods - /// /// Helper method that publishes a package to the container registry. /// This gets called from Publish-PSResource. From 5c5628d141d30732f81cbf95912cc5222fe3c3ef Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 7 Jan 2025 15:00:17 -0500 Subject: [PATCH 14/18] Update src/code/ContainerRegistryServerAPICalls.cs Co-authored-by: Aditya Patwardhan --- src/code/ContainerRegistryServerAPICalls.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/code/ContainerRegistryServerAPICalls.cs b/src/code/ContainerRegistryServerAPICalls.cs index 4f31cd176..d9175c0b0 100644 --- a/src/code/ContainerRegistryServerAPICalls.cs +++ b/src/code/ContainerRegistryServerAPICalls.cs @@ -1134,7 +1134,7 @@ internal bool PushNupkgContainerRegistry( _cmdletPassedIn.WriteDebug("In ContainerRegistryServerAPICalls::PushNupkgContainerRegistry()"); // if isNupkgPathSpecified, then we need to publish the original .nupkg file, as it may be signed - string fullNupkgFile = !isNupkgPathSpecified ? System.IO.Path.Combine(outputNupkgDir, packageName + "." + packageVersion.ToNormalizedString() + ".nupkg") : originalNupkgPath; + string fullNupkgFile = isNupkgPathSpecified ? originalNupkgPath : System.IO.Path.Combine(outputNupkgDir, packageName + "." + packageVersion.ToNormalizedString() + ".nupkg"); string pkgNameForUpload = string.IsNullOrEmpty(modulePrefix) ? packageName : modulePrefix + "/" + packageName; string packageNameLowercase = pkgNameForUpload.ToLower(); From e7c0cb773dc3c477e7e482e7a1846604f0011907 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 7 Jan 2025 15:00:43 -0500 Subject: [PATCH 15/18] Update src/code/PublishHelper.cs Co-authored-by: Aditya Patwardhan --- src/code/PublishHelper.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/code/PublishHelper.cs b/src/code/PublishHelper.cs index 6509d4e2f..85c1fb7de 100644 --- a/src/code/PublishHelper.cs +++ b/src/code/PublishHelper.cs @@ -433,7 +433,6 @@ internal void PushResource(string Repository, string modulePrefix, bool SkipDepe return; } } - } string repositoryUri = repository.Uri.AbsoluteUri; From 2d389f99831f53027f0c618945c961a9f58275a9 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 7 Jan 2025 15:44:49 -0500 Subject: [PATCH 16/18] populate out ErrorRecord in additional places --- src/code/PublishHelper.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/code/PublishHelper.cs b/src/code/PublishHelper.cs index 85c1fb7de..544529210 100644 --- a/src/code/PublishHelper.cs +++ b/src/code/PublishHelper.cs @@ -1286,11 +1286,11 @@ private string CopyNupkgFileToTempPath(string nupkgFilePath, out ErrorRecord err } catch (Exception e) { - _cmdletPassedIn.WriteError(new ErrorRecord( + errRecord = new ErrorRecord( new ArgumentException($"Error moving .nupkg at -NupkgPath to temp nupkg dir path '{outputNupkgDir}' due to: '{e.Message}'."), "ErrorMovingNupkg", ErrorCategory.NotSpecified, - this)); + this); // exit process record return destinationFilePath; @@ -1330,6 +1330,12 @@ private void GetPackageInfoFromNupkg(string nupkgFilePath, out ErrorRecord errRe if (!NuGetVersion.TryParse(version, out NuGetVersion nugetVersion)) { + errRecord = new ErrorRecord( + new ArgumentException($"Error parsing version '{version}' into NuGetVersion instance."), + "ErrorParsingNuGetVersion", + ErrorCategory.NotSpecified, + this); + return; } From 7a4f691c3d1d2b302dbba680ee6ee318711400cf Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Wed, 8 Jan 2025 12:42:42 -0500 Subject: [PATCH 17/18] delete outputDir when it has been created --- src/code/PublishHelper.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/code/PublishHelper.cs b/src/code/PublishHelper.cs index 544529210..66daea84e 100644 --- a/src/code/PublishHelper.cs +++ b/src/code/PublishHelper.cs @@ -455,7 +455,7 @@ internal void PushResource(string Repository, string modulePrefix, bool SkipDepe GetPackageInfoFromNupkg(nupkgFilePath: copiedNupkgFilePath, errRecord: out ErrorRecord pkgInfoErrRecord); if (pkgInfoErrRecord != null) { - _cmdletPassedIn.WriteError(copyErrRecord); + _cmdletPassedIn.WriteError(pkgInfoErrRecord); return; } } @@ -492,7 +492,8 @@ internal void PushResource(string Repository, string modulePrefix, bool SkipDepe } finally { - if (!_isNupkgPathSpecified) + // For scenarios such as Publish-PSResource -NupkgPath -Repository , the outputNupkgDir will be set to NupkgPath path, and a temp outputDir folder will not have been created and thus doesn't need to attempt to be deleted + if (Directory.Exists(outputDir)) { _cmdletPassedIn.WriteVerbose(string.Format("Deleting temporary directory '{0}'", outputDir)); Utils.DeleteDirectory(outputDir); From 85d71f6d5d8e4fe73fce83eceadd3512dc5f8291 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Wed, 8 Jan 2025 12:57:23 -0500 Subject: [PATCH 18/18] add check for directory not existing --- src/code/Utils.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/code/Utils.cs b/src/code/Utils.cs index 4d062e107..d51ba0fdb 100644 --- a/src/code/Utils.cs +++ b/src/code/Utils.cs @@ -1584,6 +1584,11 @@ public static void DeleteDirectoryWithRestore(string dirPath) /// public static void DeleteDirectory(string dirPath) { + if (!Directory.Exists(dirPath)) + { + throw new Exception($"Path '{dirPath}' that was attempting to be deleted does not exist."); + } + // Remove read only file attributes first foreach (var dirFilePath in Directory.GetFiles(dirPath,"*",SearchOption.AllDirectories)) {