Current section
9 Versions
Jump to
Current section
9 Versions
Compare versions
7
files changed
+65
additions
-13
deletions
| @@ -40,9 +40,9 @@ defmodule MyCLI do | |
| 40 40 | when input: Nexus.Command.Input.t() |
| 41 41 | def handle_input(:fizzbuzz, %{value: value}) do |
| 42 42 | cond do |
| 43 | - rem(value, 3) -> IO.puts("fizz") |
| 44 | - rem(value, 5) -> IO.puts("buzz") |
| 45 | - rem(value, 3) and rem(value, 5) -> IO.puts("fizzbuzz") |
| 43 | + rem(value, 3) == 0 -> IO.puts("fizz") |
| 44 | + rem(value, 5) == 0 -> IO.puts("buzz") |
| 45 | + rem(value, 3) == 0 and rem(value, 5) == 0 -> IO.puts("fizzbuzz") |
| 46 46 | true -> IO.puts value |
| 47 47 | end |
| 48 48 | end |
| @@ -52,6 +52,8 @@ defmodule MyCLI do | |
| 52 52 | end |
| 53 53 | ``` |
| 54 54 | |
| 55 | + More different ways to use this library can be found on the [examples](./examples) folder |
| 56 | + |
| 55 57 | ## Why "Nexus" |
| 56 58 | |
| 57 59 | Nexus is a connection from two different worlds! This library connects the world of CLIs with the magic world of `Elixir`! |
| @@ -16,4 +16,4 @@ | |
| 16 16 | {<<"links">>,[{<<"GitHub">>,<<"https://github.com/zoedsoupe/nexus">>}]}. |
| 17 17 | {<<"name">>,<<"nexus_cli">>}. |
| 18 18 | {<<"requirements">>,[]}. |
| 19 | - {<<"version">>,<<"0.3.1">>}. |
| 19 | + {<<"version">>,<<"0.4.0">>}. |
| @@ -46,8 +46,9 @@ defmodule Nexus do | |
| 46 46 | defmacro __using__(_opts) do |
| 47 47 | quote do |
| 48 48 | Module.register_attribute(__MODULE__, :commands, accumulate: true) |
| 49 | + Module.register_attribute(__MODULE__, :subcommands, accumulate: true) |
| 49 50 | |
| 50 | - import Nexus, only: [defcommand: 2] |
| 51 | + import Nexus, only: [defcommand: 2, defcommand: 3] |
| 51 52 | require Nexus |
| 52 53 | |
| 53 54 | @behaviour Nexus.CLI |
| @@ -65,11 +66,33 @@ defmodule Nexus do | |
| 65 66 | """ |
| 66 67 | @spec defcommand(atom, keyword) :: Macro.t() |
| 67 68 | defmacro defcommand(cmd, opts) do |
| 68 | - quote do |
| 69 | + quote location: :keep do |
| 69 70 | @commands Nexus.__make_command__!(__MODULE__, unquote(cmd), unquote(opts)) |
| 70 71 | end |
| 71 72 | end |
| 72 73 | |
| 74 | + defmacro defcommand(cmd, opts, do: ast) do |
| 75 | + subcommands = build_subcommands(ast) |
| 76 | + |
| 77 | + quote location: :keep do |
| 78 | + @commands Nexus.__make_command__!( |
| 79 | + __MODULE__, |
| 80 | + unquote(cmd), |
| 81 | + Keyword.put(unquote(opts), :subcommands, unquote(subcommands)) |
| 82 | + ) |
| 83 | + end |
| 84 | + end |
| 85 | + |
| 86 | + defp build_subcommands({:__block__, _, subs}) do |
| 87 | + Enum.map(subs, &build_subcommands/1) |
| 88 | + end |
| 89 | + |
| 90 | + defp build_subcommands({:defcommand, _, [cmd, opts]}) do |
| 91 | + quote do |
| 92 | + Nexus.__make_command__!(__MODULE__, unquote(cmd), unquote(opts)) |
| 93 | + end |
| 94 | + end |
| 95 | + |
| 73 96 | @doc """ |
| 74 97 | Generates a default `help` command for your CLI. It uses the |
| 75 98 | optional `banner/0` callback from `Nexus.CLI` to complement |
| @@ -12,11 +12,18 @@ defmodule Nexus.Command do | |
| 12 12 | required: boolean, |
| 13 13 | name: atom, |
| 14 14 | default: term, |
| 15 | - doc: String.t() |
| 15 | + doc: String.t(), |
| 16 | + subcommands: [Nexus.Command.t()] |
| 16 17 | } |
| 17 18 | |
| 18 19 | @enforce_keys ~w(module type name)a |
| 19 | - defstruct module: nil, required: true, type: :string, name: nil, default: nil, doc: "" |
| 20 | + defstruct module: nil, |
| 21 | + required: true, |
| 22 | + type: :string, |
| 23 | + name: nil, |
| 24 | + default: nil, |
| 25 | + doc: "", |
| 26 | + subcommands: [] |
| 20 27 | |
| 21 28 | @spec parse!(keyword) :: Nexus.Command.t() |
| 22 29 | def parse!(attrs) do |
| @@ -4,10 +4,10 @@ defmodule Nexus.Command.Input do | |
| 4 4 | on commands dispatched |
| 5 5 | """ |
| 6 6 | |
| 7 | - @type t :: %__MODULE__{value: term, raw: binary} |
| 7 | + @type t :: %__MODULE__{value: term, raw: binary, subcommand: atom} |
| 8 8 | |
| 9 9 | @enforce_keys ~w(value raw)a |
| 10 | - defstruct value: nil, raw: nil |
| 10 | + defstruct value: nil, raw: nil, subcommand: nil |
| 11 11 | |
| 12 12 | @spec parse!(term, binary) :: Nexus.Command.Input.t() |
| 13 13 | def parse!(value, raw) do |
Loading more files…