Skip to content

Commit

Permalink
Merge branch 'main' of github.com:zoedsoupe/nexus
Browse files Browse the repository at this point in the history
* 'main' of github.com:zoedsoupe/nexus:
  DSL refactor and Flags (options) parsing (#21)
  • Loading branch information
zoedsoupe committed Nov 17, 2024
2 parents 4253df3 + 13fab22 commit 5691f85
Show file tree
Hide file tree
Showing 19 changed files with 1,371 additions and 598 deletions.
14 changes: 12 additions & 2 deletions .formatter.exs
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
local_without_parens = [
defcommand: 2,
subcommand: 2,
value: 2,
flag: 2,
short: 1,
description: 1
]

[
import_deps: [:nimble_parsec],
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"],
export: [locals_without_parens: [defcommand: 2]],
locals_without_parens: [defcommand: 2]
export: [locals_without_parens: local_without_parens],
locals_without_parens: local_without_parens
]
31 changes: 10 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,33 +21,22 @@ An `Elixir` library to write command line apps in a cleaner and elegant way!

## Example

```elixir dark
```elixir
defmodule MyCLI do
use Nexus
@moduledoc "This will be used into as help"

defcommand :ping, type: :null, doc: "Answers 'pong'"
defcommand :fizzbuzz, type: :integer, required: true, doc: "Plays fizzbuzz"
defcommand :mode, type: {:enum, ~w[fast slow]a}, required: true, doc: "Defines the command mode"
use Nexus.CLI

@impl Nexus.CLI
# no input as type == :null
def handle_input(:ping), do: IO.puts("pong")
defcommand :fizzbuzz do
description "Plays fizzbuzz - this will also be used as help"

@impl Nexus.CLI
# input can be named to anything
@spec handle_input(atom, input) :: :ok
when input: Nexus.Command.Input.t()
def handle_input(:fizzbuzz, %{value: value}) do
cond do
rem(value, 3) == 0 -> IO.puts("fizz")
rem(value, 5) == 0 -> IO.puts("buzz")
rem(value, 3) == 0 and rem(value, 5) == 0 -> IO.puts("fizzbuzz")
true -> IO.puts value
end
value :integer, required: true
end

def handle_input(:mode, %{value: :fast), do: IO.puts "Hare"
def handle_input(:mode, %{value: :slow), do: IO.puts "Tortoise"
@impl Nexus.CLI
def handle_input(:fizzbuzz, %{args: [input]}) do
# plays fizzbuzz
end
end
```

Expand Down
37 changes: 27 additions & 10 deletions examples/escript/example.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,34 @@ defmodule Escript.Example do
from the `main/1` escript funciton, as can seen below.
"""

use Nexus
use Nexus.CLI

defcommand :foo, required: true, type: :string, doc: "Command that receives a string as argument and prints it."
defcommand :fizzbuzz, type: {:enum, ~w(fizz buzz)a}, doc: "Fizz bUZZ", required: true
defcommand :foo do
description "Command that receives a string as argument and prints it."

defcommand :foo_bar, type: :null, doc: "Teste" do
defcommand :foo, default: "hello", doc: "Hello"
defcommand :bar, default: "hello", doc: "Hello"
value :string, required: true
end

defcommand :fizzbuzz do
description "Fizz bUZZ"

value {:enum, ~w(fizz buzz)a}, required: true
end

defcommand :foo_bar do
description "Teste"

subcommand :foo do
description "hello"

value :string, required: false, default: "hello"
end

subcommand :bar do
description "hello"

value :string, required: false, default: "hello"
end
end

@impl true
Expand Down Expand Up @@ -49,8 +69,5 @@ defmodule Escript.Example do
:ok
end

Nexus.help()
Nexus.parse()

defdelegate main(args), to: __MODULE__, as: :run
# defdelegate main(args), to: __MODULE__, as: :run
end
127 changes: 127 additions & 0 deletions examples/file_management.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
defmodule MyCLI do
@moduledoc """
MyCLI provides file operations such as copy, move, and delete using the Nexus.CLI DSL.
"""

use Nexus.CLI, otp_app: :nexus_cli

defcommand :file do
description "Performs file operations such as copy, move, and delete."

subcommand :copy do
description "Copies files from source to destination."

value :string, required: true, as: :source
value :string, required: true, as: :dest

flag :level do
value :integer, required: false
end

flag :verbose do
short :v
description "Enables verbose output."
end

flag :recursive do
short :rc
description "Copies directories recursively."
end
end

subcommand :move do
description "Moves files from source to destination."

value :string, required: true, as: :source
value :string, required: true, as: :dest

flag :force do
short :f
description "Forces the move without confirmation."
end

flag :verbose do
short :v
description "Enables verbose output."
end
end

subcommand :delete do
description "Deletes specified files or directories."

value {:list, :string}, required: true, as: :targets

flag :force do
short :f
description "Forces deletion without confirmation."
end

flag :recursive do
short :rc
description "Deletes directories recursively."
end

flag :verbose do
short :v
description "Enables verbose output."
end
end
end

@impl Nexus.CLI
def handle_input([:file, :copy], %{args: args, flags: flags}) do
if flags.verbose do
IO.puts("Copying from #{args.source} to #{args.dest}")
end

if flags.recursive do
IO.puts("Recursive copy enabled")
end

# Implement actual copy logic here
IO.puts("Copied #{args.source} to #{args.dest}")
:ok
end

def handle_input([:file, :move], %{args: args, flags: flags}) do
if flags.verbose do
IO.puts("Moving from #{args.source} to #{args.dest}")
end

if flags.force do
IO.puts("Force move enabled")
end

# Implement actual move logic here
IO.puts("Moved #{args.source} to #{args.dest}")
:ok
end

def handle_input([:file, :delete], %{args: args, flags: flags}) do
if flags.verbose do
IO.puts("Deleting targets: #{Enum.join(args.targets, ", ")}")
end

if flags.recursive do
IO.puts("Recursive delete enabled")
end

if flags.force do
IO.puts("Force delete enabled")
end

# Implement actual delete logic here
Enum.each(args.targets, fn target ->
IO.puts("Deleted #{target}")
end)

:ok
end

def handle_input(command, input) do
IO.puts("Unknown command or invalid parameters")
IO.inspect(command, label: "CMD")
IO.inspect(input, label: "INPUT")
:error
end
end
Loading

0 comments on commit 5691f85

Please sign in to comment.