Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Aug 03 12:56
    rioka opened #67
  • Jun 22 21:36

    github-actions[bot] on v4.6.1

    (compare)

  • Jun 22 21:34

    jeremydmiller on master

    putting the docs at /oakton and… (compare)

  • Jun 22 17:30

    jeremydmiller on gh-pages

    Documentation Update for 4.0.0 (compare)

  • Jun 22 16:18
    jeremydmiller closed #57
  • Jun 22 16:18

    jeremydmiller on master

    last second doc updates for Vit… (compare)

  • Jun 22 16:16

    github-actions[bot] on v4.6.0

    (compare)

  • Jun 22 16:05

    jeremydmiller on gh-pages

    Documentation Update for 4.0.0 (compare)

  • Jun 22 15:51
    dependabot[bot] labeled #66
  • Jun 22 15:51
    dependabot[bot] opened #66
  • Jun 22 15:51

    dependabot[bot] on npm_and_yarn

    Bump shell-quote from 1.7.2 to … (compare)

  • Jun 22 15:51

    jeremydmiller on master

    little fix on resources setup c… (compare)

  • May 26 13:56

    github-actions[bot] on v4.5.1

    (compare)

  • May 26 13:51

    jeremydmiller on master

    overriding the log level will n… bump to 4.5.1 (compare)

  • Apr 14 15:19

    github-actions[bot] on v4.5.0

    (compare)

  • Apr 14 15:17

    jeremydmiller on master

    option to also clear state on a… (compare)

  • Apr 14 13:59

    github-actions[bot] on v4.4.0

    (compare)

  • Apr 14 13:54

    jeremydmiller on master

    new extension methods for rebui… (compare)

  • Apr 13 19:46

    github-actions[bot] on v4.3.1

    (compare)

  • Apr 13 19:43

    jeremydmiller on master

    changing the resources display … (compare)

Jeremy D. Miller
@jeremydmiller
Hey, just getting this started for anyone who may have questions about Oakton
Luke Foust
@lfoust_twitter
Just trying out the library. Works as expected ;) Does it have any support for using dependency injection? I would like my commands to be instantiated using DI
Vadym Kurachevskyi
@hmvs

Hey. Thanks for the library. It's really great. Wanted to ask is there any way how I can mark Flags as required?
For example I have a tool which migrate database.
it should have 3 required parameters:

string connectionString;
IEnumerable<string> paths;
IEnumerable<string> alwaysRun;

I would like to make this all parameters as flags. But can't find a way how I mark it as required. In case of making them all as arguments I don't get how I would pass them all.

Andy Davies
@Pondidum
@lfoust_twitter yes, it does.
static int Main(string[] args)
{
    var executor = CommandExecutor.For(_ =>
    {
        _.RegisterCommand<ScanCommand>();
        _.DefaultCommand = typeof(ScanCommand);
    }, new StructureMapCreator());

    return executor.Execute(args);
}

public class StructureMapCreator : ICommandCreator
{
    public IOaktonCommand Create(Type commandType)
    {
          return _container.GetInstance(commandType) as IOaktonCommand;
    }
}
Andy Davies
@Pondidum

@hmvs You can do this, but as far as I know, you need to use Arguments for the required parameters, and flags for options.

public class MigrateCommand : OaktonCommand<MigrateInput>
{
    public MigrateCommand()
    {
        // our first usage is just ConnectionString, and optionally the AlwaysRun flag
        Usage("Name is required, Option is optional")
            .Arguments(x => x.ConnectionString)    //required
            .ValidFlags(x => x.AlwaysRunFlag); //a flag

        // our second usage is ConnectionString and multiple paths, and optionally the AlwaysRun flag
        Usage("Name is required, Option is optional")
            .Arguments(x => x.ConnectionString, x => x.Paths)    //required
            .ValidFlags(x => x.AlwaysRunFlag); //a flag
    }

    public override bool Execute(MigrateInput input)
    {
        Console.WriteLine($"ConnectionString: {input.ConnectionString}");
        Console.WriteLine($"AlwaysRun: {input.AlwaysRunFlag}");

        Console.WriteLine("Paths:");
        foreach (var path in (input.Paths ?? Enumerable.Empty<string>()))
        {
            Console.WriteLine($"  - {path}");
        }

        return true;
    }
}

public class MigrateInput
{
    public string ConnectionString { get; set; }
    public IEnumerable<string> Paths { get; set; }
    public bool AlwaysRunFlag { get; set; }
}

There are docs on arguments and flags here:
https://jasperfx.github.io/oakton/documentation/arguments/
https://jasperfx.github.io/oakton/documentation/flags/

Vadym Kurachevskyi
@hmvs
@Pondidum thanks. But alwaysrun it's also requred array of paths. So I have one required string and two required arrays.
Andy Davies
@Pondidum

@hmvs the closest I can get to what you are after is this:

public class MigrateCommand : OaktonCommand<MigrateInput>
{
    public MigrateCommand()
    {
        Usage("Migrate things")
            .Arguments(x => x.ConnectionString)
            .ValidFlags(x => x.PathsFlag, x => x.AlwaysRunFlag);
    }

    public override bool Execute(MigrateInput input)
    {
        if (input.PathsFlag == null || input.PathsFlag.Any() == false)
        {
            ConsoleWriter.Write(ConsoleColor.Red, "You must specify the Paths flag");
            return false;
        }

        if (input.AlwaysRunFlag == null || input.AlwaysRunFlag.Any() == false)
        {
            ConsoleWriter.Write(ConsoleColor.Red, "You must specify the AlwaysRun flag");
            return false;
        }

        Console.WriteLine($"ConnectionString: {input.ConnectionString}");

        Console.WriteLine("Paths:");
        foreach (var path in (input.PathsFlag ?? Enumerable.Empty<string>()))
            Console.WriteLine($"  - {path}");

        Console.WriteLine("Always:");
        foreach (var path in (input.AlwaysRunFlag ?? Enumerable.Empty<string>()))
            Console.WriteLine($"  - {path}");

        return true;
    }
}

public class MigrateInput
{
    public string ConnectionString { get; set; }
    public IEnumerable<string> PathsFlag { get; set; }
    public IEnumerable<string> AlwaysRunFlag { get; set; }
}

usage:

dotnet run -- localhost --paths /d/dev/tmp/1.sql /d/dev/tmp/2.sql --always-run /d/dev/tmp/3.sql
Vadym Kurachevskyi
@hmvs
Thanks. @Pondidum. Though I think we need to make mandatory flags
Andy Davies
@Pondidum
I'd me more inclined for named arguments, I feel that flags are by nature optional, although I haven't run into needing multiple enumerable arguments so it's not been a problem for me
Jeremy D. Miller
@jeremydmiller
@hmvs If it’s mandatory, just use an argument. There’s nothing stopping you from validating the command line input in the commands for that matter and throwing an explanatory exception if flag values are missing
Mo Zaatar ﮼محمدزعتر﮼
@MZaatar_twitter
Hello, anyone has any idea how could I pass a default flag (without adding -- in front of it). Example:
My current command is myExe --option1 "option1" --option2 "option2"
What I want to achieve is be able to run something like
myExe "option1" --option2 "option2"
myExe --option1 "option1" --option2 "option2"
Andy Davies
@Pondidum

You can achive something like what you are after...but it's not entirely pleasant. It involves using an argument and a flag, and specifying usages so that you either can use "argument + flag" or "flag + flag":

    public class TestInput
    {
        public string One { get; set; }
        public string OneFlag { get; set; }
        public string TwoFlag { get; set; }
    }

    public class TestCommand : OaktonCommand<TestInput>
    {
        public TestCommand()
        {
            Usage("default flag").Arguments(x => x.One).ValidFlags(x => x.TwoFlag);
            Usage("do it yourself flag").ValidFlags(x => x.OneFlag, x => x.TwoFlag);
        }

        public override bool Execute(TestInput input)
        {
            Console.WriteLine($"1: {input.One ?? input.OneFlag}");
            Console.WriteLine($"2: {input.TwoFlag}");

            return true;
        }
    }

Example usage:

# working usages:
dotnet OaktonTesting.dll test --one wat --two is
dotnet OaktonTesting.dll test wat --two is

# throws an error, as this is not a valid usage:
dotnet OaktonTesting.dll test omg --one wat --two is
Mo Zaatar ﮼محمدزعتر﮼
@MZaatar_twitter
Hey @Pondidum thanks for your reply. That was my guess but I thought that there is an easier one
Will implement it anyway as I want it :)
Mohamed Bareche
@neoexa
This message was deleted

Hello i have an opts file where i defined some flags, when running my command the program appends the flags this way
mytool -u MyUserName -p ~~HeMan2345 somecommand
instead of

mytool somecommand -u MyUserName -p ~~HeMan2345
which gives me an error : -u is not a command

Any tips ?! Thanks

Jeremy D. Miller
@jeremydmiller
It’s a bug if anything
Mohamed Bareche
@neoexa
@jeremydmiller Ok, i'll look more into it (i'll keep you updated)
Yehuda Makarov
@yehudamakarov

Hey guys. great library! thank you!

Log.Information("Starting web host");
return CreateHostBuilder(args).RunOaktonCommands(args);
//CreateHostBuilder(args).Build().Run();
//return Task.FromResult(0);

anyone know why I lose my logs when i use the oakton commands instead? all I get is the one log before serilog is supposed to take over

bitbonk
@bitbonk
Hi, I have this super simple .NET Core static file server. Now I would like to feed in the settings for webroot and the listen port from from commandline args using Oakton. Oakton command line args should override what may have already been set by appsettings.json or appsettings.Development.json. Can this be done somehow?
public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(
                webBuilder =>
                {
                    // There are two problems with the following two lines.
                    // 1. Where do I get configuration instance from?
                    // 2. How do I merge them with Okaton commandline args?
                    webBuilder.UseWebRoot(configuration.GetValue<string>("MySection:webroot"));
                    webBuilder.UseUrls($"http://localhost:{configuration.GetValue<int>("MySection:port")}");

                    webBuilder.UseStartup<Startup>();
                });
}

public class Startup
{
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseDefaultFiles();
        app.UseStaticFiles();
    }
}
David Smith
@flipdoubt

Two quick questions:

  1. What does Oakton.AspNetCore provide that the Oakton package does not?
  2. Is there a simple way to replace the internal IConfiguration Preview?

Thanks for this library. It rocks.

Jeremy D. Miller
@jeremydmiller
Oakton.AspNetCore is obsolete and got completely folded into Oakton for the last big release
2.) I take pull requests ;)
And thanks!
David Smith
@flipdoubt
@jeremydmiller even if the pull request simply changes the access modifier from internal to public? Just curious as to why you went with internal.
Jeremy D. Miller
@jeremydmiller
I can’t say I ever thought about the configuration preview being swappable, so there was no reason to make it public
David Smith
@flipdoubt
When running my code on a machine without Visual Studio, I get an error with the following stack trace. I searched the docs but didn't find anything regarding "Microsoft.CodeAnalysis". How can I fix this issue?
[2021-05-03 16:05:42Z] [FTL] [<s:>] WebApp failed to start.
System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.CodeAnalysis, Version=2.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
File name: 'Microsoft.CodeAnalysis, Version=2.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
   at System.ModuleHandle.ResolveType(QCallModule module, Int32 typeToken, IntPtr* typeInstArgs, Int32 typeInstCount, IntPtr* methodInstArgs, Int32 methodInstCount, ObjectHandleOnStack type)
   at System.ModuleHandle.ResolveTypeHandleInternal(RuntimeModule module, Int32 typeToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
   at System.Reflection.RuntimeModule.ResolveType(Int32 metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
   at System.Reflection.CustomAttribute.FilterCustomAttributeRecord(MetadataToken caCtorToken, MetadataImport& scope, RuntimeModule decoratedModule, MetadataToken decoratedToken, RuntimeType attributeFilterType, Boolean mustBeInheritable, ListBuilder`1& derivedAttributes, RuntimeType& attributeType, IRuntimeMethodInfo& ctorWithParameters, Boolean& isVarArg)
   at System.Reflection.CustomAttribute.IsCustomAttributeDefined(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, RuntimeType attributeFilterType, Int32 attributeCtorToken, Boolean mustBeInheritable)
   at System.Reflection.CustomAttribute.IsDefined(RuntimeAssembly assembly, RuntimeType caType)
   at System.Reflection.RuntimeAssembly.IsDefined(Type attributeType, Boolean inherit)
   at System.Attribute.IsDefined(Assembly element, Type attributeType, Boolean inherit)
   at System.Reflection.CustomAttributeExtensions.IsDefined(Assembly element, Type attributeType)
   at Baseline.Reflection.ReflectionExtensions.HasAttribute[T](Assembly provider)
   at Oakton.CommandFactory.<>c.<RegisterCommandsFromExtensionAssemblies>b__30_0(Assembly a)
Jeremy D. Miller
@jeremydmiller
Can you try cleaning off your code first, then trying it from scratch? That just smells like dotnet restore not running cleanly from trash left behind
David Smith
@flipdoubt
This is a staging machine, so it should be cleaner than my local machine where it works without error. One thing I haven't considered, however, is that it is a Production build instead of Debug, which I never really tested locally. Are there any considerations when running in production? dotnet run ... doesn't even work without the project file.
David Smith
@flipdoubt
Am I being silly in that this should never be in a release build?
Jeremy D. Miller
@jeremydmiller
I don’t know about that, but this just feels like a run of the mill Nuget dependency issue. Could be something has an incompatible reference to that Nuget, and it is a common diamond dependency.