Last active
September 18, 2023 17:42
-
-
Save baronfel/bf84929a8e9eea793090d870b601b2df to your computer and use it in GitHub Desktop.
System.CommandLine Flag variant
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module CliFlag | |
open System | |
open System.CommandLine | |
open System.CommandLine.Parsing | |
type CliFlag<'t> = | |
inherit CliOption<'t> | |
val private enabledFlagName: string | |
val private disabledFlagName: string | |
val private defaultValue: 't | |
val private enabledValue: 't | |
val private disabledValue: 't | |
new(flagName: string, enabledValue: 't, disabledValue: 't, defaultValue: 't) as this = | |
ArgumentNullException.ThrowIfNullOrWhiteSpace(flagName, nameof (flagName)) | |
if | |
flagName.StartsWith("-") | |
|| flagName.StartsWith("--") | |
then | |
let e = | |
ArgumentException("Flag name must not start with '-' or '--'", nameof (flagName)) | |
raise e | |
{ inherit CliOption<'t>(null, [||]) | |
enabledFlagName = flagName | |
disabledFlagName = flagName | |
enabledValue = enabledValue | |
disabledValue = disabledValue | |
defaultValue = defaultValue } // dummy branch, will never be hit | |
else | |
let tfn = "--" + flagName | |
let ffn = "--no-" + flagName | |
{ inherit CliOption<'t>(tfn, [| ffn |], Arity = ArgumentArity.Zero, CustomParser = this.Parse) | |
enabledFlagName = tfn | |
disabledFlagName = ffn | |
enabledValue = enabledValue | |
disabledValue = disabledValue | |
defaultValue = defaultValue } | |
abstract member Parse: r: ArgumentResult -> 't | |
default x.Parse(r: ArgumentResult) : 't = | |
let parent = r.Parent :?> OptionResult | |
match parent.IdentifierToken.Value with | |
| s when s = x.enabledFlagName -> x.enabledValue | |
| s when s = x.disabledFlagName -> x.disabledValue | |
| s -> failwith $"Unexpected flag name %s{s}" | |
type CliFlag(name, defaultValue) = | |
inherit CliFlag<bool>(name, true, false, defaultValue) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Flags | |
open System | |
open System.CommandLine | |
open System.CommandLine.Parsing | |
let selfContained = CliFlag("self-contained", defaultValue = false) | |
let private isCiEnvironment () = | |
Environment.GetEnvironmentVariable("CI") = "true" | |
let private shellSaysWeAreInteractive () = true | |
let private detectInteractiveState () = | |
not Console.IsInputRedirected | |
|| not (isCiEnvironment ()) | |
|| shellSaysWeAreInteractive () | |
let interactive = | |
{ new CliFlag("interactive", defaultValue = true) with | |
member x.Parse(r: ArgumentResult) = | |
// how should we probe for shell state here? | |
if (r.Parent :?> OptionResult).Implicit then | |
detectInteractiveState () | |
else | |
true } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment