diff --git a/src/WingetCreateCLI/Commands/UpdateCommand.cs b/src/WingetCreateCLI/Commands/UpdateCommand.cs index b3d18e4f..2d06f340 100644 --- a/src/WingetCreateCLI/Commands/UpdateCommand.cs +++ b/src/WingetCreateCLI/Commands/UpdateCommand.cs @@ -290,7 +290,7 @@ public async Task UpdateManifestsAutonomously(Manifests manifests) // If the previous RelativeFilePath is not an exact match, check if there is a new suitable match in the archive. if (!File.Exists(Path.Combine(extractDirectory, nestedInstallerFile.RelativeFilePath))) { - string relativeFilePath = ObtainMatchingRelativeFilePath(nestedInstallerFile.RelativeFilePath, extractDirectory, packageFile); + string relativeFilePath = this.ObtainMatchingRelativeFilePath(nestedInstallerFile.RelativeFilePath, extractDirectory, packageFile); if (string.IsNullOrEmpty(relativeFilePath)) { return null; @@ -440,29 +440,6 @@ private static string ExtractArchiveAndRetrieveDirectoryPath(string packageFileP } } - private static string ObtainMatchingRelativeFilePath(string oldRelativeFilePath, string directory, string archiveName) - { - string fileName = Path.GetFileName(oldRelativeFilePath); - string[] matchingFiles = Directory.GetFiles(directory, fileName, SearchOption.AllDirectories); - - // If there is only one match in the archive, use that as the new relative file path. - if (matchingFiles.Length == 1) - { - string relativePath = matchingFiles.First().Replace(directory, string.Empty).TrimStart(Path.DirectorySeparatorChar); - return relativePath; - } - else if (matchingFiles.Length > 1) - { - Logger.ErrorLocalized(nameof(Resources.MultipleMatchingNestedInstallersFound_Error), fileName, Path.GetFileName(archiveName)); - return null; - } - else - { - Logger.ErrorLocalized(nameof(Resources.NestedInstallerFileNotFound_Error), oldRelativeFilePath); - return null; - } - } - private static Manifests ConvertSingletonToMultifileManifest(WingetCreateCore.Models.Singleton.SingletonManifest singletonManifest) { // Create automapping configuration @@ -622,6 +599,54 @@ private static void DisplayManifestsAsMenuSelection(Manifests manifests) } } + private string ObtainMatchingRelativeFilePath(string oldRelativeFilePath, string directory, string archiveName) + { + string fileName = Path.GetFileName(oldRelativeFilePath); + List matchingFiles = Directory.GetFiles(directory, fileName, SearchOption.AllDirectories) + .Select(filePath => filePath = Path.GetRelativePath(directory, filePath)) + .ToList(); + + // If there is only one match in the archive, use that as the new relative file path. + if (matchingFiles.Count == 1) + { + return matchingFiles.First(); + } + else if (matchingFiles.Count > 1) + { + if (this.Interactive) + { + Console.WriteLine(); + Logger.WarnLocalized(nameof(Resources.MultipleMatchingNestedInstallersFound_Warning), fileName, Path.GetFileName(archiveName)); + return Prompt.Select(Resources.SelectRelativeFilePath_Message, matchingFiles); + } + + Logger.ErrorLocalized(nameof(Resources.MultipleMatchingNestedInstallersFound_Error), fileName, Path.GetFileName(archiveName)); + return null; + } + else + { + if (this.Interactive) + { + List sameExtensionFiles = Directory.GetFiles(directory, $"*{Path.GetExtension(oldRelativeFilePath)}", SearchOption.AllDirectories) + .Select(filePath => filePath = Path.GetRelativePath(directory, filePath)) + .ToList(); + if (sameExtensionFiles.Count > 0) + { + Console.WriteLine(); + Logger.WarnLocalized(nameof(Resources.NestedInstallerFileNotFound_Warning), oldRelativeFilePath); + return Prompt.Select(Resources.SelectRelativeFilePath_Message, sameExtensionFiles); + } + else + { + return null; + } + } + + Logger.ErrorLocalized(nameof(Resources.NestedInstallerFileNotFound_Error), oldRelativeFilePath); + return null; + } + } + /// /// Parses the installer urls for any architecture or scope overrides. /// @@ -781,33 +806,25 @@ private async Task UpdateSingleInstallerInteractively(Installer installer) if (packageFile.IsZipFile()) { string extractDirectory = ExtractArchiveAndRetrieveDirectoryPath(packageFile); - string relativeFilePath = installer.NestedInstallerFiles.First().RelativeFilePath; - string pathToNestedInstaller = Path.Combine(extractDirectory, relativeFilePath); - if (File.Exists(pathToNestedInstaller)) - { - packageFile = pathToNestedInstaller; - } - else + bool isRelativePathNull = false; + + foreach (NestedInstallerFile nestedInstaller in installer.NestedInstallerFiles) { - relativeFilePath = ObtainMatchingRelativeFilePath(relativeFilePath, extractDirectory, packageFile); - if (relativeFilePath == null) + nestedInstaller.RelativeFilePath = this.ObtainMatchingRelativeFilePath(nestedInstaller.RelativeFilePath, extractDirectory, packageFile); + if (string.IsNullOrEmpty(nestedInstaller.RelativeFilePath)) { - continue; + isRelativePathNull = true; + break; } + } - pathToNestedInstaller = Path.Combine(extractDirectory, relativeFilePath); - packageFile = pathToNestedInstaller; - - // Update the relative file path for all nested installers. - foreach (NestedInstallerFile nestedInstaller in installer.NestedInstallerFiles) - { - nestedInstaller.RelativeFilePath = ObtainMatchingRelativeFilePath(nestedInstaller.RelativeFilePath, extractDirectory, packageFile); - if (string.IsNullOrEmpty(nestedInstaller.RelativeFilePath)) - { - continue; - } - } + if (isRelativePathNull) + { + Logger.ErrorLocalized(nameof(Resources.NestedInstallerTypeNotFound_Error)); + continue; } + + packageFile = Path.Combine(extractDirectory, installer.NestedInstallerFiles.First().RelativeFilePath); } if (!PackageParser.ParsePackageAndUpdateInstallerNode(installer, packageFile, url)) diff --git a/src/WingetCreateCLI/Properties/Resources.Designer.cs b/src/WingetCreateCLI/Properties/Resources.Designer.cs index 00f0fc72..45088def 100644 --- a/src/WingetCreateCLI/Properties/Resources.Designer.cs +++ b/src/WingetCreateCLI/Properties/Resources.Designer.cs @@ -1582,7 +1582,7 @@ public static string MultipleMatchedInstaller_Error { } /// - /// Looks up a localized string similar to Multiple matches found for "{0}" from {1}. + /// Looks up a localized string similar to Multiple matches found for "{0}" from {1}. Please use the interactive mode to update this package.. /// public static string MultipleMatchingNestedInstallersFound_Error { get { @@ -1590,6 +1590,15 @@ public static string MultipleMatchingNestedInstallersFound_Error { } } + /// + /// Looks up a localized string similar to Multiple matches found for "{0}" from {1}.. + /// + public static string MultipleMatchingNestedInstallersFound_Warning { + get { + return ResourceManager.GetString("MultipleMatchingNestedInstallersFound_Warning", resourceCulture); + } + } + /// /// Looks up a localized string similar to Multiple nested installer architectures were detected for following archive packages:. /// @@ -1618,7 +1627,7 @@ public static string Name_KeywordDescription { } /// - /// Looks up a localized string similar to Nested installer not found in zip archive: {0}. + /// Looks up a localized string similar to Nested installer not found in zip archive: {0}. Please use the interactive mode to update this package.. /// public static string NestedInstallerFileNotFound_Error { get { @@ -1626,6 +1635,15 @@ public static string NestedInstallerFileNotFound_Error { } } + /// + /// Looks up a localized string similar to Nested installer not found in zip archive: {0}. + /// + public static string NestedInstallerFileNotFound_Warning { + get { + return ResourceManager.GetString("NestedInstallerFileNotFound_Warning", resourceCulture); + } + } + /// /// Looks up a localized string similar to List of nested installer files contained inside an archive. /// @@ -1653,6 +1671,15 @@ public static string NestedInstallerType_KeywordDescription { } } + /// + /// Looks up a localized string similar to The zip archive does not contain a matching installer type with the old relative path.. + /// + public static string NestedInstallerTypeNotFound_Error { + get { + return ResourceManager.GetString("NestedInstallerTypeNotFound_Error", resourceCulture); + } + } + /// /// Looks up a localized string similar to Failed to connect to GitHub. Check your network connection.. /// @@ -2274,6 +2301,15 @@ public static string SelectPropertyToEdit_Message { } } + /// + /// Looks up a localized string similar to Select the new relative file path. + /// + public static string SelectRelativeFilePath_Message { + get { + return ResourceManager.GetString("SelectRelativeFilePath_Message", resourceCulture); + } + } + /// /// Looks up a localized string similar to Open settings. /// diff --git a/src/WingetCreateCLI/Properties/Resources.resx b/src/WingetCreateCLI/Properties/Resources.resx index 3479e3f4..702f2c58 100644 --- a/src/WingetCreateCLI/Properties/Resources.resx +++ b/src/WingetCreateCLI/Properties/Resources.resx @@ -964,7 +964,7 @@ {1} - will be replaced by the InstallerUrl - Nested installer not found in zip archive: {0} + Nested installer not found in zip archive: {0}. Please use the interactive mode to update this package. {0} - represents the relative file path of the nested installer file. @@ -1031,7 +1031,26 @@ The url of the hosted icon file - Multiple matches found for "{0}" from {1} + Multiple matches found for "{0}" from {1}. Please use the interactive mode to update this package. + {0} - will be replaced by the name of the nested installer file + +{1} - will be replaced by the name of the zip archive. + + + Multiple matches found for "{0}" from {1}. + {0} - will be replaced by the name of the nested installer file + +{1} - will be replaced by the name of the zip archive. + + + Nested installer not found in zip archive: {0} + {0} - represents the relative file path of the nested installer file. + + + The zip archive does not contain a matching installer type with the old relative path. + + + Select the new relative file path Display a manifest from the Windows Package Manager repository