From 793bad126150aed27180a37cb225edc7025de7df Mon Sep 17 00:00:00 2001 From: eevee <94960726+whoeevee@users.noreply.github.com> Date: Sun, 14 Sep 2025 01:59:57 +0300 Subject: [PATCH] migration to System.CommandLine 2.0.0-beta5+ --- Features/Command/IviRootCommand.cs | 197 +++++++++--------- .../Command/IviRootCommandParametersBinder.cs | 32 +-- Features/Command/IviRootCommandProcessor.cs | 4 +- Features/Command/LoggerFactoryBinder.cs | 17 -- Program.cs | 2 +- ivinject.csproj | 8 +- 6 files changed, 121 insertions(+), 139 deletions(-) delete mode 100644 Features/Command/LoggerFactoryBinder.cs diff --git a/Features/Command/IviRootCommand.cs b/Features/Command/IviRootCommand.cs index 120808f..6756b0a 100644 --- a/Features/Command/IviRootCommand.cs +++ b/Features/Command/IviRootCommand.cs @@ -12,138 +12,135 @@ internal class IviRootCommand : RootCommand var value = result.Tokens[0].Value; if (!RegularExpressions.ApplicationPackage().IsMatch(value)) - result.ErrorMessage = "The application package must be either an .app bundle or an .ipa$ archive."; + result.AddError("The application package must be either an .app bundle or an .ipa$ archive."); return value; } // - - private readonly Argument _targetArgument = new( - name: "target", - description: "The application package, either .app bundle or ipa$", - parse: ParseAppPackageResult - ); - - private readonly Argument _outputArgument = new( - name: "output", - description: "The output application package, either .app bundle or ipa$", - parse: ParseAppPackageResult - ); - - private readonly Option _overwriteOutputOption = new( - "--overwrite", - "Overwrite the output if it already exists" - ); - private readonly Option _compressionLevelOption = new( - "--compression-level", - description: "The compression level for ipa$ archive output", - getDefaultValue: () => CompressionLevel.Fastest - ); + private readonly Argument _targetArgument = new("target") + { + Description = "The application package, either .app bundle or ipa$", + CustomParser = ParseAppPackageResult + }; + + private readonly Argument _outputArgument = new("output") + { + Description = "The output application package, either .app bundle or ipa$", + CustomParser = ParseAppPackageResult + }; + + private readonly Option _overwriteOutputOption = new("--overwrite") + { + Description = "Overwrite the output if it already exists" + }; + + private readonly Option _compressionLevelOption = new("--compression-level") + { + Aliases = { "--level" }, + Description = "The compression level for ipa$ archive output", + DefaultValueFactory = _ => CompressionLevel.Fastest + }; // private readonly Option> _itemsOption = new("--items") { Description = "The entries to inject (Debian packages, Frameworks, and Bundles)", + Aliases = { "-i" }, AllowMultipleArgumentsPerToken = true }; - private readonly Option _provisioningProfileOption = new( - "--profile", - "Provisioning profile to extract entitlements, signing identity, and bundle ID" - ); + private readonly Option _provisioningProfileOption = new("--profile") + { + Aliases = { "-p" }, + Description = "Provisioning profile to extract entitlements, signing identity, and bundle ID" + }; + + private readonly Option _profileBundleIdOption = new("--profile-bundle-id") + { + Description = "Replace the bundle ID with the one in the provisioning profile" + }; + + private readonly Option _codesignIdentityOption = new("--sign") + { + Aliases = { "-s" }, + Description = "The identity for code signing (use \"-\" for ad hoc, a.k.a. fake signing)" + }; - private readonly Option _profileBundleIdOption = new( - "--profile-bundle-id", - "Replace the bundle ID with the one in the provisioning profile" - ); - - private readonly Option _codesignIdentityOption = new( - "--sign", - "The identity for code signing (use \"-\" for ad hoc, a.k.a. fake signing)" - ); - - private readonly Option _codesignEntitlementsOption = new( - "--entitlements", - "The file containing entitlements that will be written into main executables" - ); + private readonly Option _codesignEntitlementsOption = new("--entitlements") + { + Aliases = { "-e" }, + Description = "The file containing entitlements that will be written into main executables" + }; // - - private readonly Option _customBundleIdOption = new( - "--bundle-id", - "The custom identifier that will be applied to application bundles" - ); - - private readonly Option _enableDocumentsSupportOption = new( - "--enable-documents-support", - "Enables documents support (file sharing) for the application" - ); - - private readonly Option _removeSupportedDevicesOption = new( - "--remove-supported-devices", - "Removes supported devices property" - ); + + private readonly Option _customBundleIdOption = new("--bundle-id") + { + Aliases = { "-b" }, + Description = "The custom identifier that will be applied to application bundles" + }; + + private readonly Option _enableDocumentsSupportOption = new("--enable-documents-support") + { + Aliases = { "-d" }, + Description = "Enables documents support (file sharing) for the application" + }; + + private readonly Option _removeSupportedDevicesOption = new("--remove-supported-devices") + { + Aliases = { "-u" }, + Description = "Removes supported devices property" + }; private readonly Option> _directoriesToRemoveOption = new("--remove-directories") { + Aliases = { "-r" }, Description = "Directories to remove in the app package, e.g. PlugIns, Watch, AppClip", AllowMultipleArgumentsPerToken = true }; internal IviRootCommand() : base("The most demure iOS app injector and signer") { - _itemsOption.AddAlias("-i"); + Arguments.Add(_targetArgument); + Arguments.Add(_outputArgument); + Options.Add(_overwriteOutputOption); + Options.Add(_compressionLevelOption); - _provisioningProfileOption.AddAlias("-p"); - _codesignIdentityOption.AddAlias("-s"); - _codesignEntitlementsOption.AddAlias("-e"); - _compressionLevelOption.AddAlias("--level"); + Options.Add(_itemsOption); + Options.Add(_provisioningProfileOption); + Options.Add(_profileBundleIdOption); + Options.Add(_codesignIdentityOption); + Options.Add(_codesignEntitlementsOption); - _customBundleIdOption.AddAlias("-b"); - _enableDocumentsSupportOption.AddAlias("-d"); - _removeSupportedDevicesOption.AddAlias("-u"); - _directoriesToRemoveOption.AddAlias("-r"); + Options.Add(_customBundleIdOption); + Options.Add(_enableDocumentsSupportOption); + Options.Add(_removeSupportedDevicesOption); + Options.Add(_directoriesToRemoveOption); - AddArgument(_targetArgument); - AddArgument(_outputArgument); - AddOption(_overwriteOutputOption); - AddOption(_compressionLevelOption); - - AddOption(_itemsOption); - AddOption(_provisioningProfileOption); - AddOption(_profileBundleIdOption); - AddOption(_codesignIdentityOption); - AddOption(_codesignEntitlementsOption); - - AddOption(_customBundleIdOption); - AddOption(_enableDocumentsSupportOption); - AddOption(_removeSupportedDevicesOption); - AddOption(_directoriesToRemoveOption); - - this.SetHandler(async (iviParameters, loggerFactory) => + SetAction(async parseResult => { - var commandProcessor = new IviRootCommandProcessor(loggerFactory); + var binder = new IviRootCommandParametersBinder( + _targetArgument, + _outputArgument, + _overwriteOutputOption, + _compressionLevelOption, + _itemsOption, + _provisioningProfileOption, + _profileBundleIdOption, + _codesignIdentityOption, + _codesignEntitlementsOption, + _customBundleIdOption, + _enableDocumentsSupportOption, + _removeSupportedDevicesOption, + _directoriesToRemoveOption + ); + var iviParameters = binder.GetBoundValue(parseResult); + var commandProcessor = new IviRootCommandProcessor(); await commandProcessor.ProcessRootCommand(iviParameters); - }, - new IviRootCommandParametersBinder( - _targetArgument, - _outputArgument, - _overwriteOutputOption, - _compressionLevelOption, - _itemsOption, - _provisioningProfileOption, - _profileBundleIdOption, - _codesignIdentityOption, - _codesignEntitlementsOption, - _customBundleIdOption, - _enableDocumentsSupportOption, - _removeSupportedDevicesOption, - _directoriesToRemoveOption - ), - new LoggerFactoryBinder() + } ); } } \ No newline at end of file diff --git a/Features/Command/IviRootCommandParametersBinder.cs b/Features/Command/IviRootCommandParametersBinder.cs index 7b1fe97..a1afa86 100644 --- a/Features/Command/IviRootCommandParametersBinder.cs +++ b/Features/Command/IviRootCommandParametersBinder.cs @@ -1,5 +1,4 @@ using System.CommandLine; -using System.CommandLine.Binding; using System.IO.Compression; using ivinject.Features.Command.Models; using ivinject.Features.Injection.Models; @@ -20,38 +19,39 @@ internal class IviRootCommandParametersBinder( Option enableDocumentsSupportOption, Option removeSupportedDevicesOption, Option> directoriesToRemoveOption -) : BinderBase +) { - protected override IviParameters GetBoundValue(BindingContext bindingContext) + public IviParameters GetBoundValue(ParseResult parseResult) { var targetAppPackage = - bindingContext.ParseResult.GetValueForArgument(targetArgument); + parseResult.GetValue(targetArgument)!; var outputAppPackage = - bindingContext.ParseResult.GetValueForArgument(outputArgument); + parseResult.GetValue(outputArgument)!; + var overwriteOutput = - bindingContext.ParseResult.GetValueForOption(overwriteOutputOption); + parseResult.GetValue(overwriteOutputOption); var compressionLevel = - bindingContext.ParseResult.GetValueForOption(compressionLevelOption); + parseResult.GetValue(compressionLevelOption); var items = - bindingContext.ParseResult.GetValueForOption(itemsOption); + parseResult.GetValue(itemsOption); var provisioningProfile = - bindingContext.ParseResult.GetValueForOption(provisioningProfileOption); + parseResult.GetValue(provisioningProfileOption); var profileBundleId = - bindingContext.ParseResult.GetValueForOption(profileBundleIdOption); + parseResult.GetValue(profileBundleIdOption); var codesignIdentity = - bindingContext.ParseResult.GetValueForOption(codesignIdentityOption); + parseResult.GetValue(codesignIdentityOption); var codesignEntitlements = - bindingContext.ParseResult.GetValueForOption(codesignEntitlementsOption); + parseResult.GetValue(codesignEntitlementsOption); var customBundleId = - bindingContext.ParseResult.GetValueForOption(customBundleIdOption); + parseResult.GetValue(customBundleIdOption); var enableDocumentsSupport = - bindingContext.ParseResult.GetValueForOption(enableDocumentsSupportOption); + parseResult.GetValue(enableDocumentsSupportOption); var removeSupportedDevices = - bindingContext.ParseResult.GetValueForOption(removeSupportedDevicesOption); + parseResult.GetValue(removeSupportedDevicesOption); var directoriesToRemove = - bindingContext.ParseResult.GetValueForOption(directoriesToRemoveOption); + parseResult.GetValue(directoriesToRemoveOption); IviSigningInfo? signingInfo = null; IviPackagingInfo? packagingInfo = null; diff --git a/Features/Command/IviRootCommandProcessor.cs b/Features/Command/IviRootCommandProcessor.cs index 3f7beb9..91c8e01 100644 --- a/Features/Command/IviRootCommandProcessor.cs +++ b/Features/Command/IviRootCommandProcessor.cs @@ -16,8 +16,10 @@ internal class IviRootCommandProcessor private readonly InjectionManager _injectionManager; private readonly CodesigningManager _codesigningManager; - internal IviRootCommandProcessor(ILoggerFactory loggerFactory) + internal IviRootCommandProcessor() { + var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole()); + _logger = loggerFactory.CreateLogger("Main"); _packageManager = new PackageManager( loggerFactory.CreateLogger("PackageManager") diff --git a/Features/Command/LoggerFactoryBinder.cs b/Features/Command/LoggerFactoryBinder.cs deleted file mode 100644 index 37e8bed..0000000 --- a/Features/Command/LoggerFactoryBinder.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.CommandLine.Binding; -using Microsoft.Extensions.Logging; - -namespace ivinject.Features.Command; - -internal class LoggerFactoryBinder : BinderBase -{ - protected override ILoggerFactory GetBoundValue(BindingContext bindingContext) - => GetLoggerFactory(); - private static ILoggerFactory GetLoggerFactory() - { - var loggerFactory = LoggerFactory.Create(builder => - builder.AddConsole()); - - return loggerFactory; - } -} \ No newline at end of file diff --git a/Program.cs b/Program.cs index 7d2faa5..e1da664 100644 --- a/Program.cs +++ b/Program.cs @@ -9,6 +9,6 @@ internal static class Program private static async Task Main(string[] args) { - return await RootCommand.InvokeAsync(args); + return await RootCommand.Parse(args).InvokeAsync(); } } \ No newline at end of file diff --git a/ivinject.csproj b/ivinject.csproj index 1cef1e6..3513534 100644 --- a/ivinject.csproj +++ b/ivinject.csproj @@ -17,10 +17,10 @@ - - - - + + + +