Skip to content

Releases: Aviuz/ECF

ECF v1.0.6 - Hosted Services, User Secrets & .NET 9 support

21 Dec 17:47
Compare
Choose a tag to compare

Changelog:

  • added EasyConsoleFramework.HostedServices to enable hosting services in background
    • need additional nuget package to work
    • added to base package two configuration methods that can invoke user-defined function on start and on stop of ECF host
  • added UserSecrets when using AddConfiguration(...) on ECF builder
  • added references to .NET 9

ECF v1.0.3 - Dependencies version update patch

15 Oct 09:24
Compare
Choose a tag to compare

Changelog:

  • Bump Autofac from 8.0.0 to 8.1.0 in /source by @dependabot in #11
  • Bump Microsoft.NET.Test.Sdk from 17.11.0 to 17.11.1 in /source by @dependabot in #12
  • Bump xunit from 2.9.0 to 2.9.1 in /source by @dependabot in #13
  • Bump xunit from 2.9.1 to 2.9.2 in /source by @dependabot in #14
  • Bump System.Net.Http.Json from 8.0.0 to 8.0.1 in /source by @dependabot in #15
  • Bump Microsoft.Extensions.Http and Microsoft.Extensions.DependencyInjection in /source by @dependabot in #18

Full Changelog: ver/1.0.2...ver/1.0.3

ECF v1.0.2

29 Aug 11:12
Compare
Choose a tag to compare

Changelog:

  • fixed error message for command not found (using help command as default)

ECF v1.0.1 - Async commands, DevOps tasks and more

13 Aug 18:55
Compare
Choose a tag to compare

Note: Changes are backward compatible for standard usage scenarios (i.e. using ECFHostBuilder and CommandBase classes).

1. Linux users, I've got something for you major

  • problematic system32.CommandLineToArgW was rewritten to fully support Linux builds

2. ECF is now fully asynchronous major

  • added new base class AsyncCommandBase, which allow to utilize async behaviour
    • use CancellationToken for graceful interruption
    • CommandBase is now wrapping AsyncCommandBase to reflect old behavior
  • ICommand has new interface breaking change
    • definition of Execute changed to Task ExecuteAsync(CommandArguments args, CancellationToken cancellationToken)
    • definition ApplyArguments has been removed (it is still used internally inside AsyncCommandBase)
    • CancellationToken need to be handled for graceful interruption, for generic use I recommend putting cancellationToken.Register(() => Environment.Exit(1))
  • CTRL + C now tries to interrupt current command instead of interrupting whole program
    • For ICommand and AsyncCommandBase token will be cancelled. If token is not handled, command will run despite cancel signal.
    • For CommandBase this will invoke Environment.Exit(1)
    • Pressing CTRL + C twice will result in calling Environment.Exit(1) in any scenario
  • Updated BaseKit commands to new async behavior, including LoadScriptCommand, along with ScriptLoader.

3. Now ECF is more suitable for DevOps tasks with arrival of Default Commands major

  • this new approach is designed to modify ECF console application, to be used as a part of pipeline process, which does not support passing CLI arguments (or it's just really inconvenient)
    • yes, you've guessed it: I've encountered this scenario during one of my projects :)
    • the main advantage of this approach, in contrast to using simple console application, is that you can utilize IoC and already constructed ECF commands for those tasks
  • added ECFHostBuilder.UseSingleCommand<TCommand>(), which will enforce program to run only command you've specified (default command + no prompt mode + no commands in registry)
    • example configuration should looks like this
      await new ECFHostBuilder()
      #if ENV_build_for_very_annoying_devops
          .UseSingleCommand<Example.Commands.TestProgressBar_Asynchronous>()
      #else 
          .UseDefaultCommands()
      #endif
          .RunAsync(args);
      
  • added DefaultCommand option in InterfaceContext (not necessary when using UseSingleCommand)
    • note: keep in mind that command mapping comes first, so program.exe hello john will first check if command hello exits and tries to invoke it with args ["john"], if there is no such command it will invoke default command with args ["hello", "john"]
    • CommandArguments now have new property ExecutedAsDefaultCommand which will indicate if command was invoked via fallback mechanism: when no arguments were passed or when command name was not found by matching first argument
  • added DisablePrompting inside InterfaceContext (true when using UseSingleCommand), which will invoke default command, instead of prompt mode, when program started without arguments
  • removed not found message from core engine breaking change
    • NotFoundCommand was merged into HelpCommand, it now utilize ExecutedAsDefaultCommand to whenever display command not found or not
    • UseDefaultCommands() now sets HelpCommand as default command (if not set already)
    • if your ECF program does not invoke UseDefaultCommands() and you want to restore old NotFoundCommand behavior please set ctx.DefaultCommand = typeof(ECF.BaseKitCommands.HelpCommand) in your .Configure((ctx, services, _) => section

4. Help is now more helpful major

  • now every CommandBase and AsyncCommandBase will react to -h and --help with displaying help message (same as help commandname)
  • now command syntax, if not set by attribute, will be generated automatically based on argument bindings
  • some visual changes to reduce fuss and focus on actual help content

5. Other changes

  • added RequiredAttribute to use with [Argument]/[Parameter]/[Flag], which will prevent command from running if not set by user (CommandBase, AsyncCommandBase) major
  • added support for nullables in binded properties (CommandBase, AsyncCommandBase | [Argument], [Parameter], [Flag] )
  • added option for specifying StringComparison, defaults to StringComparison.InvariantCulture (CommandBase, AsyncCommandBase | [Argument], [Parameter], [Flag] )
  • new constructor for [Flag]s and [Paremeter]s major
    • [Flag(ShortName="f", LongName="flag")] => [Flag("-f --flag")]/[Flag("-f", "--flag")]
    • This will allow to change prefix aswell (eg. ~~tilde-flag)
  • added option to alter default behavior of ignoring values with prefixes (CommandBase, AsyncCommandBase | [Argument], [Parameter] )
    • by default all arguments and parameters with prefix - will be ignored
    • you can disable all prefixes by providing ForbiddenValuePrefixes = new string[0]
  • now all ECF exceptions inherit from ECFException which can help you managing exception better in your application
  • prefix from InterfaceContext now does not include space after, which can be added to maintain old behavior. (Marking this as breaking change because it can break some automated tests) breaking change
  • (advanced) AddECFCommandRegistry now uses configure Action inside extension method to register commands breaking change
    • New example for creating ICommandProcessor looks like this:
      public ICommandProcessor CreateDirectionCommandsProcessor(InterfaceContext interfaceContext)
      {
          // CommandProcessors hold IoC containers to maintain seperate collection of services        
      
          return new ServiceCollection()
              // when using alternative scope, we need to build command registry manually
              .AddECFCommandRegistry(interfaceContext, builder => builder
                  .RegisterCommands<DirectionCommandAttribute>(Assembly.GetExecutingAssembly()) // we can register all commands with  specified attribute in specified assembly
                  .RegisterCommands<CommandAttribute>(typeof(HelpCommand).Assembly) // this line will register basic commands as  HelpCommand, LoadCommand etc.
                  .Register<CommandAttribute>(typeof(ExitCommand)) // alternatively you can always register commands seperatly one by one
                  .Register(typeof(ExitCommand), "exit")) // or even register without attribute (it can cause issues with help command)
              .BuildAndCreateECFCommandProcessor(); // at the end we need to construct CommandProcesor which will process command  requests
      }

ECF v0.2.3 - AsyncCommandBase & auto syntax & .NET 8.0

28 Jul 09:27
Compare
Choose a tag to compare
  • Added AsyncCommandBase which is basically wrapper for ExecuteAsync().Wait() but it will be used in future if more sophisticated async management will be in place. For now I cannot see any benefit in propagating asynchronous behavior up to CommandProcessor. Maybe I will change my mind later.
  • Added auto-generated syntax when no [CmdSyntax(...)] is provided.
  • Added support for .NET 8