From cc703cc860ad5ca29889b65ed932a0ba18213bcf Mon Sep 17 00:00:00 2001
From: Oleksii Holub <1935960+Tyrrrz@users.noreply.github.com>
Date: Thu, 26 Mar 2026 23:53:28 +0200
Subject: [PATCH] Migrate to CliFx v3 (#1516)
---
Directory.Packages.props | 7 ++-
.../Commands/Base/DiscordCommandBase.cs | 9 ++--
.../Commands/Base/ExportCommandBase.cs | 43 +++++++++----------
...s => ThreadInclusionModeInputConverter.cs} | 4 +-
...rter.cs => TruthyBooleanInputConverter.cs} | 4 +-
.../Commands/ExportAllCommand.cs | 12 +++---
.../Commands/ExportChannelsCommand.cs | 6 +--
.../Commands/ExportDirectMessagesCommand.cs | 4 +-
.../Commands/ExportGuildCommand.cs | 8 ++--
.../Commands/GetChannelsCommand.cs | 12 +++---
.../Commands/GetDirectChannelsCommand.cs | 4 +-
.../Commands/GetGuildsCommand.cs | 4 +-
.../Commands/GuideCommand.cs | 4 +-
.../DiscordChatExporter.Cli.csproj | 6 ---
DiscordChatExporter.Cli/Program.cs | 34 ++-------------
.../DiscordChatExporter.Gui.csproj | 6 ---
.../PublishMacOSBundle.csx | 16 +++----
17 files changed, 72 insertions(+), 111 deletions(-)
rename DiscordChatExporter.Cli/Commands/Converters/{ThreadInclusionModeBindingConverter.cs => ThreadInclusionModeInputConverter.cs} (86%)
rename DiscordChatExporter.Cli/Commands/Converters/{TruthyBooleanBindingConverter.cs => TruthyBooleanInputConverter.cs} (86%)
diff --git a/Directory.Packages.props b/Directory.Packages.props
index ebbc7454..45405453 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -10,7 +10,7 @@
-
+
@@ -26,7 +26,10 @@
-
+
diff --git a/DiscordChatExporter.Cli/Commands/Base/DiscordCommandBase.cs b/DiscordChatExporter.Cli/Commands/Base/DiscordCommandBase.cs
index 049d573a..55204343 100644
--- a/DiscordChatExporter.Cli/Commands/Base/DiscordCommandBase.cs
+++ b/DiscordChatExporter.Cli/Commands/Base/DiscordCommandBase.cs
@@ -2,7 +2,7 @@
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
using CliFx;
-using CliFx.Attributes;
+using CliFx.Binding;
using CliFx.Infrastructure;
using DiscordChatExporter.Core.Discord;
using DiscordChatExporter.Core.Utils;
@@ -17,23 +17,22 @@ public abstract class DiscordCommandBase : ICommand
EnvironmentVariable = "DISCORD_TOKEN",
Description = "Authentication token."
)]
- public required string Token { get; init; }
+ public required string Token { get; set; }
- [Obsolete("This option doesn't do anything. Kept for backwards compatibility.")]
[CommandOption(
"bot",
'b',
EnvironmentVariable = "DISCORD_TOKEN_BOT",
Description = "This option doesn't do anything. Kept for backwards compatibility."
)]
- public bool IsBotToken { get; init; } = false;
+ public bool IsBotToken { get; set; } = false;
[CommandOption(
"respect-rate-limits",
Description = "Whether to respect advisory rate limits. "
+ "If disabled, only hard rate limits (i.e. 429 responses) will be respected."
)]
- public bool ShouldRespectRateLimits { get; init; } = true;
+ public bool ShouldRespectRateLimits { get; set; } = true;
[field: AllowNull, MaybeNull]
protected DiscordClient Discord =>
diff --git a/DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs b/DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs
index 070c8e88..2b3c8400 100644
--- a/DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs
+++ b/DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs
@@ -5,8 +5,8 @@ using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
-using CliFx.Attributes;
-using CliFx.Exceptions;
+using CliFx;
+using CliFx.Binding;
using CliFx.Infrastructure;
using DiscordChatExporter.Cli.Commands.Converters;
using DiscordChatExporter.Cli.Commands.Shared;
@@ -37,23 +37,23 @@ public abstract class ExportCommandBase : DiscordCommandBase
get;
// Handle ~/ in paths on Unix systems
// https://github.com/Tyrrrz/DiscordChatExporter/pull/903
- init => field = Path.GetFullPath(value);
+ set => field = Path.GetFullPath(value);
} = Directory.GetCurrentDirectory();
[CommandOption("format", 'f', Description = "Export format.")]
- public ExportFormat ExportFormat { get; init; } = ExportFormat.HtmlDark;
+ public ExportFormat ExportFormat { get; set; } = ExportFormat.HtmlDark;
[CommandOption(
"after",
Description = "Only include messages sent after this date or message ID."
)]
- public Snowflake? After { get; init; }
+ public Snowflake? After { get; set; }
[CommandOption(
"before",
Description = "Only include messages sent before this date or message ID."
)]
- public Snowflake? Before { get; init; }
+ public Snowflake? Before { get; set; }
[CommandOption(
"partition",
@@ -61,51 +61,51 @@ public abstract class ExportCommandBase : DiscordCommandBase
Description = "Split the output into partitions, each limited to the specified "
+ "number of messages (e.g. '100') or file size (e.g. '10mb')."
)]
- public PartitionLimit PartitionLimit { get; init; } = PartitionLimit.Null;
+ public PartitionLimit PartitionLimit { get; set; } = PartitionLimit.Null;
[CommandOption(
"include-threads",
Description = "Which types of threads should be included.",
- Converter = typeof(ThreadInclusionModeBindingConverter)
+ Converter = typeof(ThreadInclusionModeInputConverter)
)]
- public ThreadInclusionMode ThreadInclusionMode { get; init; } = ThreadInclusionMode.None;
+ public ThreadInclusionMode ThreadInclusionMode { get; set; } = ThreadInclusionMode.None;
[CommandOption(
"filter",
Description = "Only include messages that satisfy this filter. "
+ "See the documentation for more info."
)]
- public MessageFilter MessageFilter { get; init; } = MessageFilter.Null;
+ public MessageFilter MessageFilter { get; set; } = MessageFilter.Null;
[CommandOption(
"parallel",
Description = "Limits how many channels can be exported in parallel."
)]
- public int ParallelLimit { get; init; } = 1;
+ public int ParallelLimit { get; set; } = 1;
[CommandOption(
"reverse",
Description = "Export messages in reverse chronological order (newest first)."
)]
- public bool IsReverseMessageOrder { get; init; }
+ public bool IsReverseMessageOrder { get; set; }
[CommandOption(
"markdown",
Description = "Process markdown, mentions, and other special tokens."
)]
- public bool ShouldFormatMarkdown { get; init; } = true;
+ public bool ShouldFormatMarkdown { get; set; } = true;
[CommandOption(
"media",
Description = "Download assets referenced by the export (user avatars, attached files, embedded images, etc.)."
)]
- public bool ShouldDownloadAssets { get; init; }
+ public bool ShouldDownloadAssets { get; set; }
[CommandOption(
"reuse-media",
Description = "Reuse previously downloaded assets to avoid redundant requests."
)]
- public bool ShouldReuseAssets { get; init; } = false;
+ public bool ShouldReuseAssets { get; set; } = false;
[CommandOption(
"media-dir",
@@ -117,34 +117,33 @@ public abstract class ExportCommandBase : DiscordCommandBase
get;
// Handle ~/ in paths on Unix systems
// https://github.com/Tyrrrz/DiscordChatExporter/pull/903
- init => field = value is not null ? Path.GetFullPath(value) : null;
+ set => field = value is not null ? Path.GetFullPath(value) : null;
}
- [Obsolete("This option doesn't do anything. Kept for backwards compatibility.")]
[CommandOption(
"dateformat",
Description = "This option doesn't do anything. Kept for backwards compatibility."
)]
- public string DateFormat { get; init; } = "MM/dd/yyyy h:mm tt";
+ public string DateFormat { get; set; } = "MM/dd/yyyy h:mm tt";
[CommandOption(
"locale",
Description = "Locale to use when formatting dates and numbers. "
+ "If not specified, the default system locale will be used."
)]
- public string? Locale { get; init; }
+ public string? Locale { get; set; }
[CommandOption("utc", Description = "Normalize all timestamps to UTC+0.")]
- public bool IsUtcNormalizationEnabled { get; init; } = false;
+ public bool IsUtcNormalizationEnabled { get; set; } = false;
[CommandOption(
"fuck-russia",
EnvironmentVariable = "FUCK_RUSSIA",
Description = "Don't print the Support Ukraine message to the console.",
// Use a converter to accept '1' as 'true' to reuse the existing environment variable
- Converter = typeof(TruthyBooleanBindingConverter)
+ Converter = typeof(TruthyBooleanInputConverter)
)]
- public bool IsUkraineSupportMessageDisabled { get; init; } = false;
+ public bool IsUkraineSupportMessageDisabled { get; set; } = false;
[field: AllowNull, MaybeNull]
protected ChannelExporter Exporter => field ??= new ChannelExporter(Discord);
diff --git a/DiscordChatExporter.Cli/Commands/Converters/ThreadInclusionModeBindingConverter.cs b/DiscordChatExporter.Cli/Commands/Converters/ThreadInclusionModeInputConverter.cs
similarity index 86%
rename from DiscordChatExporter.Cli/Commands/Converters/ThreadInclusionModeBindingConverter.cs
rename to DiscordChatExporter.Cli/Commands/Converters/ThreadInclusionModeInputConverter.cs
index 7857024f..716e2539 100644
--- a/DiscordChatExporter.Cli/Commands/Converters/ThreadInclusionModeBindingConverter.cs
+++ b/DiscordChatExporter.Cli/Commands/Converters/ThreadInclusionModeInputConverter.cs
@@ -1,10 +1,10 @@
using System;
-using CliFx.Extensibility;
+using CliFx.Activation;
using DiscordChatExporter.Cli.Commands.Shared;
namespace DiscordChatExporter.Cli.Commands.Converters;
-internal class ThreadInclusionModeBindingConverter : BindingConverter
+internal class ThreadInclusionModeInputConverter : ScalarInputConverter
{
public override ThreadInclusionMode Convert(string? rawValue)
{
diff --git a/DiscordChatExporter.Cli/Commands/Converters/TruthyBooleanBindingConverter.cs b/DiscordChatExporter.Cli/Commands/Converters/TruthyBooleanInputConverter.cs
similarity index 86%
rename from DiscordChatExporter.Cli/Commands/Converters/TruthyBooleanBindingConverter.cs
rename to DiscordChatExporter.Cli/Commands/Converters/TruthyBooleanInputConverter.cs
index 5f4abd20..33977b9c 100644
--- a/DiscordChatExporter.Cli/Commands/Converters/TruthyBooleanBindingConverter.cs
+++ b/DiscordChatExporter.Cli/Commands/Converters/TruthyBooleanInputConverter.cs
@@ -1,9 +1,9 @@
using System.Globalization;
-using CliFx.Extensibility;
+using CliFx.Activation;
namespace DiscordChatExporter.Cli.Commands.Converters;
-internal class TruthyBooleanBindingConverter : BindingConverter
+internal class TruthyBooleanInputConverter : ScalarInputConverter
{
public override bool Convert(string? rawValue)
{
diff --git a/DiscordChatExporter.Cli/Commands/ExportAllCommand.cs b/DiscordChatExporter.Cli/Commands/ExportAllCommand.cs
index 5d156e84..464ecf0a 100644
--- a/DiscordChatExporter.Cli/Commands/ExportAllCommand.cs
+++ b/DiscordChatExporter.Cli/Commands/ExportAllCommand.cs
@@ -2,7 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
-using CliFx.Attributes;
+using CliFx.Binding;
using CliFx.Infrastructure;
using DiscordChatExporter.Cli.Commands.Base;
using DiscordChatExporter.Cli.Utils.Extensions;
@@ -14,23 +14,23 @@ using Spectre.Console;
namespace DiscordChatExporter.Cli.Commands;
[Command("exportall", Description = "Exports all accessible channels.")]
-public class ExportAllCommand : ExportCommandBase
+public partial class ExportAllCommand : ExportCommandBase
{
[CommandOption("include-dm", Description = "Include direct message channels.")]
- public bool IncludeDirectChannels { get; init; } = true;
+ public bool IncludeDirectChannels { get; set; } = true;
[CommandOption("include-guilds", Description = "Include server channels.")]
- public bool IncludeGuildChannels { get; init; } = true;
+ public bool IncludeGuildChannels { get; set; } = true;
[CommandOption("include-vc", Description = "Include voice channels.")]
- public bool IncludeVoiceChannels { get; init; } = true;
+ public bool IncludeVoiceChannels { get; set; } = true;
[CommandOption(
"data-package",
Description = "Path to the personal data package (ZIP file) requested from Discord. "
+ "If provided, only channels referenced in the dump will be exported."
)]
- public string? DataPackageFilePath { get; init; }
+ public string? DataPackageFilePath { get; set; }
public override async ValueTask ExecuteAsync(IConsole console)
{
diff --git a/DiscordChatExporter.Cli/Commands/ExportChannelsCommand.cs b/DiscordChatExporter.Cli/Commands/ExportChannelsCommand.cs
index a0e1e94c..3e963cad 100644
--- a/DiscordChatExporter.Cli/Commands/ExportChannelsCommand.cs
+++ b/DiscordChatExporter.Cli/Commands/ExportChannelsCommand.cs
@@ -1,6 +1,6 @@
using System.Collections.Generic;
using System.Threading.Tasks;
-using CliFx.Attributes;
+using CliFx.Binding;
using CliFx.Infrastructure;
using DiscordChatExporter.Cli.Commands.Base;
using DiscordChatExporter.Core.Discord;
@@ -10,7 +10,7 @@ using DiscordChatExporter.Core.Utils.Extensions;
namespace DiscordChatExporter.Cli.Commands;
[Command("export", Description = "Exports one or multiple channels.")]
-public class ExportChannelsCommand : ExportCommandBase
+public partial class ExportChannelsCommand : ExportCommandBase
{
// TODO: change this to plural (breaking change)
[CommandOption(
@@ -19,7 +19,7 @@ public class ExportChannelsCommand : ExportCommandBase
Description = "Channel ID(s). "
+ "If provided with category ID(s), all channels inside those categories will be exported."
)]
- public required IReadOnlyList ChannelIds { get; init; }
+ public required IReadOnlyList ChannelIds { get; set; }
public override async ValueTask ExecuteAsync(IConsole console)
{
diff --git a/DiscordChatExporter.Cli/Commands/ExportDirectMessagesCommand.cs b/DiscordChatExporter.Cli/Commands/ExportDirectMessagesCommand.cs
index 69c80f79..39f41f40 100644
--- a/DiscordChatExporter.Cli/Commands/ExportDirectMessagesCommand.cs
+++ b/DiscordChatExporter.Cli/Commands/ExportDirectMessagesCommand.cs
@@ -1,5 +1,5 @@
using System.Threading.Tasks;
-using CliFx.Attributes;
+using CliFx.Binding;
using CliFx.Infrastructure;
using DiscordChatExporter.Cli.Commands.Base;
using DiscordChatExporter.Core.Discord.Data;
@@ -8,7 +8,7 @@ using DiscordChatExporter.Core.Utils.Extensions;
namespace DiscordChatExporter.Cli.Commands;
[Command("exportdm", Description = "Exports all direct message channels.")]
-public class ExportDirectMessagesCommand : ExportCommandBase
+public partial class ExportDirectMessagesCommand : ExportCommandBase
{
public override async ValueTask ExecuteAsync(IConsole console)
{
diff --git a/DiscordChatExporter.Cli/Commands/ExportGuildCommand.cs b/DiscordChatExporter.Cli/Commands/ExportGuildCommand.cs
index 90eb3d79..037d8c58 100644
--- a/DiscordChatExporter.Cli/Commands/ExportGuildCommand.cs
+++ b/DiscordChatExporter.Cli/Commands/ExportGuildCommand.cs
@@ -1,6 +1,6 @@
using System.Collections.Generic;
using System.Threading.Tasks;
-using CliFx.Attributes;
+using CliFx.Binding;
using CliFx.Infrastructure;
using DiscordChatExporter.Cli.Commands.Base;
using DiscordChatExporter.Cli.Utils.Extensions;
@@ -11,13 +11,13 @@ using Spectre.Console;
namespace DiscordChatExporter.Cli.Commands;
[Command("exportguild", Description = "Exports all channels within the specified server.")]
-public class ExportGuildCommand : ExportCommandBase
+public partial class ExportGuildCommand : ExportCommandBase
{
[CommandOption("guild", 'g', Description = "Server ID.")]
- public required Snowflake GuildId { get; init; }
+ public required Snowflake GuildId { get; set; }
[CommandOption("include-vc", Description = "Include voice channels.")]
- public bool IncludeVoiceChannels { get; init; } = true;
+ public bool IncludeVoiceChannels { get; set; } = true;
public override async ValueTask ExecuteAsync(IConsole console)
{
diff --git a/DiscordChatExporter.Cli/Commands/GetChannelsCommand.cs b/DiscordChatExporter.Cli/Commands/GetChannelsCommand.cs
index 60b152fe..b0116ed7 100644
--- a/DiscordChatExporter.Cli/Commands/GetChannelsCommand.cs
+++ b/DiscordChatExporter.Cli/Commands/GetChannelsCommand.cs
@@ -1,7 +1,7 @@
using System;
using System.Linq;
using System.Threading.Tasks;
-using CliFx.Attributes;
+using CliFx.Binding;
using CliFx.Infrastructure;
using DiscordChatExporter.Cli.Commands.Base;
using DiscordChatExporter.Cli.Commands.Converters;
@@ -12,20 +12,20 @@ using DiscordChatExporter.Core.Utils.Extensions;
namespace DiscordChatExporter.Cli.Commands;
[Command("channels", Description = "Get the list of channels in a server.")]
-public class GetChannelsCommand : DiscordCommandBase
+public partial class GetChannelsCommand : DiscordCommandBase
{
[CommandOption("guild", 'g', Description = "Server ID.")]
- public required Snowflake GuildId { get; init; }
+ public required Snowflake GuildId { get; set; }
[CommandOption("include-vc", Description = "Include voice channels.")]
- public bool IncludeVoiceChannels { get; init; } = true;
+ public bool IncludeVoiceChannels { get; set; } = true;
[CommandOption(
"include-threads",
Description = "Which types of threads should be included.",
- Converter = typeof(ThreadInclusionModeBindingConverter)
+ Converter = typeof(ThreadInclusionModeInputConverter)
)]
- public ThreadInclusionMode ThreadInclusionMode { get; init; } = ThreadInclusionMode.None;
+ public ThreadInclusionMode ThreadInclusionMode { get; set; } = ThreadInclusionMode.None;
public override async ValueTask ExecuteAsync(IConsole console)
{
diff --git a/DiscordChatExporter.Cli/Commands/GetDirectChannelsCommand.cs b/DiscordChatExporter.Cli/Commands/GetDirectChannelsCommand.cs
index daedf096..06ea69b1 100644
--- a/DiscordChatExporter.Cli/Commands/GetDirectChannelsCommand.cs
+++ b/DiscordChatExporter.Cli/Commands/GetDirectChannelsCommand.cs
@@ -1,7 +1,7 @@
using System;
using System.Linq;
using System.Threading.Tasks;
-using CliFx.Attributes;
+using CliFx.Binding;
using CliFx.Infrastructure;
using DiscordChatExporter.Cli.Commands.Base;
using DiscordChatExporter.Core.Discord.Data;
@@ -10,7 +10,7 @@ using DiscordChatExporter.Core.Utils.Extensions;
namespace DiscordChatExporter.Cli.Commands;
[Command("dm", Description = "Gets the list of all direct message channels.")]
-public class GetDirectChannelsCommand : DiscordCommandBase
+public partial class GetDirectChannelsCommand : DiscordCommandBase
{
public override async ValueTask ExecuteAsync(IConsole console)
{
diff --git a/DiscordChatExporter.Cli/Commands/GetGuildsCommand.cs b/DiscordChatExporter.Cli/Commands/GetGuildsCommand.cs
index 42642c41..6d8b5410 100644
--- a/DiscordChatExporter.Cli/Commands/GetGuildsCommand.cs
+++ b/DiscordChatExporter.Cli/Commands/GetGuildsCommand.cs
@@ -1,7 +1,7 @@
using System;
using System.Linq;
using System.Threading.Tasks;
-using CliFx.Attributes;
+using CliFx.Binding;
using CliFx.Infrastructure;
using DiscordChatExporter.Cli.Commands.Base;
using DiscordChatExporter.Core.Discord.Data;
@@ -10,7 +10,7 @@ using DiscordChatExporter.Core.Utils.Extensions;
namespace DiscordChatExporter.Cli.Commands;
[Command("guilds", Description = "Gets the list of accessible servers.")]
-public class GetGuildsCommand : DiscordCommandBase
+public partial class GetGuildsCommand : DiscordCommandBase
{
public override async ValueTask ExecuteAsync(IConsole console)
{
diff --git a/DiscordChatExporter.Cli/Commands/GuideCommand.cs b/DiscordChatExporter.Cli/Commands/GuideCommand.cs
index f4bd09cf..c0270c5d 100644
--- a/DiscordChatExporter.Cli/Commands/GuideCommand.cs
+++ b/DiscordChatExporter.Cli/Commands/GuideCommand.cs
@@ -1,13 +1,13 @@
using System;
using System.Threading.Tasks;
using CliFx;
-using CliFx.Attributes;
+using CliFx.Binding;
using CliFx.Infrastructure;
namespace DiscordChatExporter.Cli.Commands;
[Command("guide", Description = "Explains how to obtain the token, server or channel ID.")]
-public class GuideCommand : ICommand
+public partial class GuideCommand : ICommand
{
public ValueTask ExecuteAsync(IConsole console)
{
diff --git a/DiscordChatExporter.Cli/DiscordChatExporter.Cli.csproj b/DiscordChatExporter.Cli/DiscordChatExporter.Cli.csproj
index 6317bcca..9e4b02c8 100644
--- a/DiscordChatExporter.Cli/DiscordChatExporter.Cli.csproj
+++ b/DiscordChatExporter.Cli/DiscordChatExporter.Cli.csproj
@@ -6,12 +6,6 @@
false
-
-
- false
- false
-
-
diff --git a/DiscordChatExporter.Cli/Program.cs b/DiscordChatExporter.Cli/Program.cs
index 2dfa24ba..776d2e0b 100644
--- a/DiscordChatExporter.Cli/Program.cs
+++ b/DiscordChatExporter.Cli/Program.cs
@@ -1,41 +1,13 @@
-using System.Diagnostics.CodeAnalysis;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using CliFx;
-using DiscordChatExporter.Cli.Commands;
-using DiscordChatExporter.Cli.Commands.Converters;
-using DiscordChatExporter.Core.Exporting.Filtering;
-using DiscordChatExporter.Core.Exporting.Partitioning;
namespace DiscordChatExporter.Cli;
public static class Program
{
- // Explicit references because CliFx relies on reflection and we're publishing with trimming enabled
- [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ExportAllCommand))]
- [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ExportChannelsCommand))]
- [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ExportDirectMessagesCommand))]
- [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ExportGuildCommand))]
- [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(GetChannelsCommand))]
- [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(GetDirectChannelsCommand))]
- [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(GetGuildsCommand))]
- [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(GuideCommand))]
- [DynamicDependency(
- DynamicallyAccessedMemberTypes.All,
- typeof(ThreadInclusionModeBindingConverter)
- )]
- [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(TruthyBooleanBindingConverter))]
- [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(PartitionLimit))]
- [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(MessageFilter))]
public static async Task Main(string[] args) =>
- await new CliApplicationBuilder()
- .AddCommand()
- .AddCommand()
- .AddCommand()
- .AddCommand()
- .AddCommand()
- .AddCommand()
- .AddCommand()
- .AddCommand()
+ await new CommandLineApplicationBuilder()
+ .AddCommandsFromThisAssembly()
.Build()
.RunAsync(args);
}
diff --git a/DiscordChatExporter.Gui/DiscordChatExporter.Gui.csproj b/DiscordChatExporter.Gui/DiscordChatExporter.Gui.csproj
index b8950ea5..a35c363c 100644
--- a/DiscordChatExporter.Gui/DiscordChatExporter.Gui.csproj
+++ b/DiscordChatExporter.Gui/DiscordChatExporter.Gui.csproj
@@ -21,12 +21,6 @@
false
-
-
- false
- false
-
-
diff --git a/DiscordChatExporter.Gui/PublishMacOSBundle.csx b/DiscordChatExporter.Gui/PublishMacOSBundle.csx
index 080d5f24..3b2d7e80 100755
--- a/DiscordChatExporter.Gui/PublishMacOSBundle.csx
+++ b/DiscordChatExporter.Gui/PublishMacOSBundle.csx
@@ -2,16 +2,16 @@
#:package CliFx
using CliFx;
-using CliFx.Attributes;
+using CliFx.Binding;
using CliFx.Infrastructure;
-return await new CliApplicationBuilder()
- .AddCommand()
+return await new CommandLineApplicationBuilder()
+ .AddCommandsFromThisAssembly()
.Build()
.RunAsync(args);
[Command(Description = "Publishes the GUI app as a macOS .app bundle.")]
-public class PublishMacOSBundleCommand : ICommand
+public partial class PublishMacOSBundleCommand : ICommand
{
private const string BundleName = "DiscordChatExporter.app";
private const string AppName = "DiscordChatExporter";
@@ -21,16 +21,16 @@ public class PublishMacOSBundleCommand : ICommand
private const string AppIconName = "AppIcon";
[CommandOption("publish-dir", Description = "Path to the publish output directory.")]
- public required string PublishDirPath { get; init; }
+ public required string PublishDirPath { get; set; }
[CommandOption("icons-file", Description = "Path to the .icns icons file.")]
- public required string IconsFilePath { get; init; }
+ public required string IconsFilePath { get; set; }
[CommandOption("full-version", Description = "Full version string (e.g. '1.2.3.4').")]
- public required string FullVersion { get; init; }
+ public required string FullVersion { get; set; }
[CommandOption("short-version", Description = "Short version string (e.g. '1.2.3').")]
- public required string ShortVersion { get; init; }
+ public required string ShortVersion { get; set; }
public async ValueTask ExecuteAsync(IConsole console)
{