Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use-based command builder API #31

Merged
merged 9 commits into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 13 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ gleam add glint
1. create a new glint instance with `glint.new`
1. configure it with `glint.with_pretty_help` and other configuration functions
1. add commands with `glint.add`
1. create a new command with `glint.cmd`
1. create a new command with `glint.command`
1. assign that command any flags required
1. assign the command a custom description
1. run your cli with `glnt.run`, run with a function to handle command output with `glint.run_and_handle`
Expand Down Expand Up @@ -53,31 +53,26 @@ import argv
import glint
import glint/flag

/// the key for the caps flag
const caps = "caps"

/// a boolean flag with default False to control message capitalization.
///
fn caps_flag() -> flag.FlagBuilder(Bool) {
// this function returns the builder for the caps flag
fn caps_flag() -> flag.Builder(Bool) {
flag.bool()
|> flag.default(False)
|> flag.description("Capitalize the hello message")
}

/// the command function that will be executed
/// the glint command that will be executed
///
fn hello(input: glint.CommandInput) -> Nil {
let assert Ok(caps) = flag.get_bool(from: input.flags, for: caps)

let name =
case input.args {
fn hello() -> glint.Command(Nil) {
use <- glint.description("Prints Hello, <NAME>!")
use caps <- glint.flag("caps",caps_flag())
use _, args, flags <- glint.command()
let assert Ok(caps) = caps(flags)
let name = case args {
[] -> "Joe"
[name,..] -> name
}

}
let msg = "Hello, " <> name <> "!"


case caps {
True -> uppercase(msg)
False -> msg
Expand All @@ -93,16 +88,8 @@ pub fn main() {
// with pretty help enabled, using the built-in colours
|> glint.with_pretty_help(glint.default_pretty_help())
// with a root command that executes the `hello` function
|> glint.add(
// add the command to the root
at: [],
// create the command, add any flags
do: glint.command(hello)
// with flag `caps`
|> glint.flag(caps, caps_flag())
// with a short description
|> glint.description("Prints Hello, <NAME>!"),
)
|> glint.add(at: [], do: hello)
// execute given arguments from stdin
|> glint.run(argv.load().arguments)
}
```
1 change: 1 addition & 0 deletions examples/hello/gleam.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ gleam_stdlib = "~> 0.34 or ~> 1.0"
glint = { path = "../.." }
snag = "~> 0.2"
argv = "~> 1.0"
sheen = "~> 0.0"

[dev-dependencies]
gleeunit = "~> 1.0"
Expand Down
8 changes: 5 additions & 3 deletions examples/hello/manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ packages = [
{ name = "gleam_community_ansi", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_community_colour", "gleam_stdlib"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "FE79E08BF97009729259B6357EC058315B6FBB916FAD1C2FF9355115FEB0D3A4" },
{ name = "gleam_community_colour", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_community_colour", source = "hex", outer_checksum = "A49A5E3AE8B637A5ACBA80ECB9B1AFE89FD3D5351FF6410A42B84F666D40D7D5" },
{ name = "gleam_erlang", version = "0.24.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "26BDB52E61889F56A291CB34167315780EE4AA20961917314446542C90D1C1A0" },
{ name = "gleam_stdlib", version = "0.34.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "1FB8454D2991E9B4C0C804544D8A9AD0F6184725E20D63C3155F0AEB4230B016" },
{ name = "gleam_stdlib", version = "0.36.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "C0D14D807FEC6F8A08A7C9EF8DFDE6AE5C10E40E21325B2B29365965D82EB3D4" },
{ name = "gleescript", version = "1.0.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_erlang", "gleam_stdlib", "simplifile", "snag", "tom"], otp_app = "gleescript", source = "hex", outer_checksum = "F7C152E206167000420F90983E4D4A076703292AAC4335A9248BA46D380841AC" },
{ name = "gleeunit", version = "1.0.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "D364C87AFEB26BDB4FB8A5ABDE67D635DC9FA52D6AB68416044C35B096C6882D" },
{ name = "glint", version = "0.15.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_community_colour", "gleam_stdlib", "snag"], source = "local", path = "../.." },
{ name = "simplifile", version = "1.4.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "AAFCF154F69B237D269FF2764890F61ABC4A7EF2A592D44D67627B99694539D9" },
{ name = "glint", version = "0.18.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_community_colour", "gleam_stdlib", "snag"], source = "local", path = "../.." },
{ name = "sheen", version = "0.0.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "sheen", source = "hex", outer_checksum = "332920056C5C9CC904BC4AADFFAC87BEF910AC67AC2876D93F18DCB6C6A495BD" },
{ name = "simplifile", version = "1.5.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "EB9AA8E65E5C1E3E0FDCFC81BC363FD433CB122D7D062750FFDF24DE4AC40116" },
{ name = "snag", version = "0.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "snag", source = "hex", outer_checksum = "54D32E16E33655346AA3E66CBA7E191DE0A8793D2C05284E3EFB90AD2CE92BCC" },
{ name = "tom", version = "0.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "tom", source = "hex", outer_checksum = "0831C73E45405A2153091226BF98FB485ED16376988602CC01A5FD086B82D577" },
]
Expand All @@ -22,4 +23,5 @@ gleam_stdlib = { version = "~> 0.34 or ~> 1.0" }
gleescript = { version = "~> 1.0" }
gleeunit = { version = "~> 1.0" }
glint = { path = "../.." }
sheen = { version = "~> 0.0"}
snag = { version = "~> 0.2" }
60 changes: 19 additions & 41 deletions examples/hello/src/hello.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import gleam/io
import gleam/list
import gleam/string.{uppercase}
import gleam/dict
// external dep imports
import snag
// glint imports
Expand Down Expand Up @@ -56,7 +55,7 @@ pub const caps = "caps"

/// a boolean flag with default False to control message capitalization.
///
pub fn caps_flag() -> flag.FlagBuilder(Bool) {
pub fn caps_flag() -> flag.Builder(Bool) {
flag.bool()
|> flag.default(False)
|> flag.description("Capitalize the hello message")
Expand All @@ -68,7 +67,7 @@ pub const repeat = "repeat"
/// an int flag with default 1 to control how many times to repeat the message.
/// this flag has the `gtz` constraint applied to it.
///
pub fn repeat_flag() -> flag.FlagBuilder(Int) {
pub fn repeat_flag() -> flag.Builder(Int) {
flag.int()
|> flag.default(1)
|> flag.constraint(gtz)
Expand All @@ -87,48 +86,27 @@ fn gtz(n: Int) -> snag.Result(Nil) {
/// the command function that will be executed as the root command
///
pub fn hello_cmd() -> glint.Command(String) {
{
use input <- glint.command()

// the caps flag has a default value, so we can be sure it will always be present
let assert Ok(caps) = flag.get_bool(from: input.flags, for: caps)

// the repeat flag has a default value, so we can be sure it will always be present
let assert Ok(repeat) = flag.get_int(from: input.flags, for: repeat)

// call the hello function with all necessary inputs
// we can assert here because we have told glint that this command expects at least one argument
let assert [name, ..rest] = input.args
hello(name, rest, caps, repeat)
}
|> glint.description("Prints Hello, <names>!")
// with at least 1 unnamed argument
|> glint.unnamed_args(glint.MinArgs(1))
// register
use <- glint.description("Prints Hello, <names>!")
use <- glint.unnamed_args(glint.MinArgs(1))
use _, args, flags <- glint.command()
let assert Ok(caps) = flag.get_bool(flags, caps)
let assert Ok(repeat) = flag.get_int(flags, repeat)
let assert [name, ..rest] = args
hello(name, rest, caps, repeat)
}

/// the command function that will be executed as the "single" command
///
pub fn hello_single_cmd() -> glint.Command(String) {
{
use input <- glint.command()

// the caps flag has a default value, so we can be sure it will always be present
let assert Ok(caps) = flag.get_bool(from: input.flags, for: caps)

// the repeat flag has a default value, so we can be sure it will always be present
let assert Ok(repeat) = flag.get_int(from: input.flags, for: repeat)

// access named args directly
let assert Ok(name) = dict.get(input.named_args, "name")

// call the hello function with all necessary inputs
hello(name, [], caps, repeat)
}
|> glint.description("Prints Hello, <name>!")
// with a named arg called 'name'
|> glint.named_args(["name"])
// with no unnamed arguments
|> glint.unnamed_args(glint.EqArgs(0))
use <- glint.description("Prints Hello, <name>!")
use <- glint.unnamed_args(glint.EqArgs(0))
use name <- glint.named_arg("name")
use named_args, _, flags <- glint.command()
let assert Ok(caps) = flag.get_bool(flags, caps)
let assert Ok(repeat) = flag.get_int(flags, repeat)
let name = name(named_args)
hello(name, [], caps, repeat)
}

// the function that describes our cli structure
Expand All @@ -144,7 +122,7 @@ pub fn app() {
// with group level flags
// with flag `caps` for all commands (equivalent of using glint.global_flag)
|> glint.group_flag([], caps, caps_flag())
// with flag `repeat` for all commands (equivalent of using glint.global_flag)
// // with flag `repeat` for all commands (equivalent of using glint.global_flag)
|> glint.group_flag([], repeat, repeat_flag())
// with a root command that executes the `hello` function
|> glint.add(
Expand Down
Loading
Loading