Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
zoedsoupe committed Nov 17, 2024
1 parent 5691f85 commit e490fa1
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 2 deletions.
1 change: 0 additions & 1 deletion examples/file_management.ex
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,5 @@ defmodule MyCLI do
IO.puts("Unknown command or invalid parameters")
IO.inspect(command, label: "CMD")
IO.inspect(input, label: "INPUT")
:error
end
end
80 changes: 80 additions & 0 deletions lib/nexus/cli.ex
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,24 @@ defmodule Nexus.CLI do
for c <- vsn, into: "", do: <<c>>
end

@impl Nexus.CLI
def handle_input(cmd, %{flags: %{help: true}}) do
ast = __nexus_cli_commands__()
display_help(ast, cmd)
{:error, 1, nil}
end

def handle_input(cmd, _input) do
ast = __nexus_cli_commands__()
command_path = Enum.reject(cmd, fn c -> c == :help end)
display_help(ast, command_path)
{:error, 1, nil}
end

def handle_input(_cmd, _input) do
{:error, 1, "Unknown command or invalid input"}
end

defoverridable version: 0
end
end
Expand Down Expand Up @@ -260,6 +278,7 @@ defmodule Nexus.CLI do
command
|> __process_command_arguments__()
|> V.validate_command()
|> __inject_help__()

existing_commands = Module.get_attribute(module, :cli_commands) || []

Expand All @@ -279,6 +298,7 @@ defmodule Nexus.CLI do
subcommand
|> __process_command_arguments__()
|> V.validate_command()
|> __inject_help__()

# Ensure no duplicate subcommand names within the parent
if Enum.any?(parent.subcommands, &(&1.name == subcommand.name)) do
Expand Down Expand Up @@ -380,6 +400,58 @@ defmodule Nexus.CLI do
end
end

defp __inject_help__(%Command{name: :help} = command) do
command
end

defp __inject_help__(%Command{} = command) do
command
|> ensure_help_subcommand()
|> ensure_help_flag()
|> inject_help_into_subcommands()
end

# Ensures that a command has the 'help' subcommand
defp ensure_help_subcommand(%Command{subcommands: subcommands} = command) do
if Enum.any?(subcommands, &(&1.name == :help)) do
command
else
help_subcommand = %Command{
name: :help,
description: "Displays help information for this command.",
subcommands: [],
flags: [],
args: []
}

%{command | subcommands: [help_subcommand | subcommands]}
end
end

# Ensures that a command has the '--help' and '-h' flags
defp ensure_help_flag(%Command{flags: flags} = command) do
if Enum.any?(flags, &(&1.name == :help)) do
command
else
help_flag = %Flag{
name: :help,
short: :h,
type: :boolean,
required: false,
default: false,
description: "Prints help information."
}

%{command | flags: [help_flag | flags]}
end
end

# Recursively injects help into all subcommands
defp inject_help_into_subcommands(%Command{subcommands: subcommands} = command) do
updated_subcommands = Enum.map(subcommands, &__inject_help__/1)
%{command | subcommands: updated_subcommands}
end

defmacro __before_compile__(env) do
commands = Module.get_attribute(env.module, :cli_commands)

Expand Down Expand Up @@ -427,6 +499,14 @@ defmodule Nexus.CLI do
else
module.handle_input([result.program | result.command], input)
end
|> case do
:ok ->
System.stop(0)

{:error, code, reason} ->
if reason, do: IO.puts(reason)

Check warning on line 507 in lib/nexus/cli.ex

View workflow job for this annotation

GitHub Actions / lint (1.17.0, 27)

Function body is nested too deep (max depth is 2, was 3).
System.stop(code)
end

{:error, errors} = err ->
Enum.each(errors, &IO.puts/1)
Expand Down
2 changes: 1 addition & 1 deletion lib/nexus/cli/help.ex
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ defmodule Nexus.CLI.Help do
defp get_subcommand(cmd, []), do: cmd

defp get_subcommand(cmd, [name | rest]) do
subcmd = Enum.find(cmd.subcommands, fn c -> c.name == String.to_atom(name) end)
subcmd = Enum.find(cmd.subcommands, &(&1.name == name))

if subcmd do
get_subcommand(subcmd, rest)
Expand Down

0 comments on commit e490fa1

Please sign in to comment.