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

Implement switch -h, --help to CLI #238

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
27 changes: 19 additions & 8 deletions lib/cli.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,26 @@ defmodule Onigumo.CLI do
}

def main(argv) do
parsed = OptionParser.parse(argv, aliases: [C: :working_dir], strict: [working_dir: :string])
parsed =
OptionParser.parse(
argv,
aliases: [h: :help, C: :working_dir],
strict: [help: :boolean, working_dir: :string]
)

with {switches, [component], []} <- parsed,
{:ok, module} <- Map.fetch(@components, String.to_atom(component)) do
working_dir = Keyword.get(switches, :working_dir, File.cwd!())
module.main(working_dir)
with {[help: true], [], []} <- parsed do
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am afraid this is not the right use case for with. It only collects a single value and the else part only contains a single branch. It’s just a pompous if/else. case might be more appropriate here. See #256.

case parsed:
  [help: true], [], []} ->
    usage_message()

  {switches, [component], []} ->{_, _, [_ | _]} ->
    usage_message()

  {_, argv, _} when length(argv) != 1usage_message()
end

usage_message()
else
{_, _, [_ | _]} -> usage_message()
{_, argv, _} when length(argv) != 1 -> usage_message()
:error -> usage_message()
_ ->
with {switches, [component], []} <- parsed,
{:ok, module} <- Map.fetch(@components, String.to_atom(component)) do
working_dir = Keyword.get(switches, :working_dir, File.cwd!())
module.main(working_dir)
else
{_, _, [_ | _]} -> usage_message()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unlike the other two patterns in this else clause, this one catches a case when any invalid switch is passed. It belongs more to the level where the help switch and the component run are matched.

case parsed do
  {[help: true], [], []} ->{switches, [component], []} ->{_, _, [_ | _]} →
    …
end

{_, argv, _} when length(argv) != 1 -> usage_message()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pattern is related to the component run, so it can belong here.

:error -> usage_message()
end
end
end

Expand All @@ -28,6 +38,7 @@ defmodule Onigumo.CLI do
COMPONENT\tOnigumo component to run, available: #{components}

OPTIONS:
-h, --help\t\tPrint this help
-C, --working-dir <dir>\tChange working dir to <dir> before running
""")
end
Expand Down
18 changes: 18 additions & 0 deletions test/onigumo_cli_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ defmodule OnigumoCLITest do
"-c"
]

@invalid_switch_combinations [
"--help -C invalid",
"-h --invalid",
"downloader -h"
]

@working_dir_switches [
"--working-dir",
"-C"
Expand All @@ -39,6 +45,12 @@ defmodule OnigumoCLITest do
end
end

for switches <- @invalid_switch_combinations do
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is one more user story of providing both a positional argument and the help switch. If ran in the ./onigumo downloader -h order, the -h switch is ignored.

This case is not tested and because it doesn’t work correctly, the test would fail. The expected result is a help message to be printed because of an invalid argument combination. The actual result is that the downloader is run.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that should be already tested but it is strange that github does not mark as as outdated. I suppose it because the line of code you mark is not changed but in text is mentioned case of test which is not added in your changes.

test("run invalid combination of switches #{inspect(switches)} ") do
assert usage_message_printed?(fn -> Onigumo.CLI.main([unquote(switches)]) end)
end
end

@tag :tmp_dir
test("run CLI with 'downloader' argument passing cwd", %{tmp_dir: tmp_dir}) do
expect(OnigumoDownloaderMock, :main, fn working_dir -> working_dir end)
Expand All @@ -60,6 +72,12 @@ defmodule OnigumoCLITest do
end
end

for switch <- ["-h", "--help"] do
test("run CLI with a #{inspect(switch)} switch") do
assert usage_message_printed?(fn -> Onigumo.CLI.main([unquote(switch)]) end)
end
end

defp usage_message_printed?(function) do
output = capture_io(function)
String.starts_with?(output, "Usage: onigumo ")
Expand Down
Loading