Packages
github_issues
0.4.4
0.4.71
0.4.70
0.4.69
0.4.68
0.4.66
0.4.65
0.4.64
0.4.63
0.4.62
0.4.61
0.4.60
0.4.59
0.4.58
0.4.56
0.4.55
0.4.54
0.4.53
0.4.52
0.4.51
0.4.50
0.4.48
0.4.47
0.4.46
0.4.45
0.4.44
0.4.43
0.4.42
0.4.41
0.4.40
0.4.39
0.4.38
0.4.37
0.4.36
0.4.35
0.4.34
0.4.33
0.4.32
0.4.31
0.4.30
0.4.29
0.4.28
0.4.27
0.4.26
0.4.25
0.4.24
0.4.23
0.4.22
0.4.21
0.4.20
0.4.19
0.4.18
0.4.17
0.4.16
0.4.15
0.4.14
0.4.13
0.4.12
0.4.11
0.4.10
0.4.9
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.24
0.3.23
0.3.22
0.3.21
0.3.20
0.3.19
0.3.18
0.3.17
0.3.16
0.3.15
0.3.14
0.3.13
0.3.12
0.3.11
0.3.10
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.0
0.2.5
0.2.3
0.2.2
0.2.0
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
0.1.4
0.1.2
0.1.1
0.1.0
Writes GitHub Issues to "stdio" in a table with borders and colors.
Current section
Files
Jump to
Current section
Files
lib/github/issues/cli.ex
# ┌───────────────────────────────────────────────────────────┐
# │ Inspired by the book "Programming Elixir" by Dave Thomas. │
# └───────────────────────────────────────────────────────────┘
defmodule GitHub.Issues.CLI do
@moduledoc """
Parses the command line and generates a table of
the first or last _n_ issues of a GitHub project.
"""
use PersistConfig
alias GitHub.Issues
alias GitHub.Issues.Help
alias IO.ANSI.Table
alias IO.ANSI.Table.Style
require Logger
@type bell :: boolean
@type count :: integer
@type parsed :: {user, project, count, bell, Style.t()} | :help
@type project :: String.t()
@type user :: String.t()
@aliases Application.get_env(@app, :aliases)
@async Application.get_env(:io_ansi_table, :async)
@count Application.get_env(@app, :default_count)
@strict Application.get_env(@app, :strict)
@switches Application.get_env(@app, :default_switches)
@doc """
Parses and processes `argv` (command line arguments).
## Parameters
- `argv` - command line arguments (list)
"""
@dialyzer {:nowarn_function, main: 1}
@spec main([String.t()]) :: :ok | no_return
def main(argv) do
with {user, project, count, bell, style} <- parse(argv),
{:ok, issues} <- Issues.fetch(user, project) do
Table.format(issues, count: count, bell: bell, style: style)
# Ensure table has printed before returning...
Process.sleep((@async && 2000) || 0)
else
:help -> Help.show_help()
{:error, text} -> log_error(text)
any -> log_error("unknown: #{inspect(any)}")
end
end
@doc """
Parses `argv` (command line arguments).
`argv` can be ["-h"] or ["--help"], which returns :help. Otherwise
it contains a user name, project name, and optionally the number
of issues to format (the first _n_ ones). To format the last _n_
issues, specify switch `--last` which will return a negative count.
To ring the bell, specify switch `--bell`. To apply a specific
table style, use switch `--table-style`.
Returns either a tuple of {user, project, count, bell, table_style}
or :help if `--help` was specified.
## Parameters
- `argv` - command line arguments (list)
## Switches
- `-h` or `--help` - for help
- `-l` or `--last` - to format the last _n_ issues
- `-b` or `--bell` - to ring the bell
- `-t` or `--table-style` - to apply a specific table style
## Table styles
#{Style.texts("\s\s- `&arg`&filler - ¬e\n")}
## Examples
iex> alias GitHub.Issues.CLI
iex> CLI.parse(["-h"])
:help
iex> alias GitHub.Issues.CLI
iex> CLI.parse(["user", "project", "99"])
{"user", "project", 99, false, :medium}
iex> alias GitHub.Issues.CLI
iex> CLI.parse(["user", "project", "88", "--last", "--bell"])
{"user", "project", -88, true, :medium}
iex> alias GitHub.Issues.CLI
iex> CLI.parse(["user", "project", "6", "--table-style", "dark"])
{"user", "project", 6, false, :dark}
"""
@spec parse([String.t()]) :: parsed
def parse(argv) do
argv
|> OptionParser.parse(strict: @strict, aliases: @aliases)
|> to_parsed()
end
## Private functions
@spec log_error(String.t()) :: no_return
defp log_error(text) do
Logger.error("Error fetching from GitHub - #{text}")
# Ensure message logged before exiting...
Process.sleep(1000)
System.halt(2)
end
@spec to_parsed({Keyword.t(), [String.t()], [tuple]}) :: parsed
defp to_parsed({switches, args, []}) do
with {user, project, count} <- to_tuple(args),
%{help: false, last: last, bell: bell, table_style: table_style} <-
Map.merge(Map.new(@switches), Map.new(switches)),
{:ok, style} <- Style.from_switch_arg(table_style),
do: {user, project, (last && -count) || count, bell, style},
else: (_ -> :help)
end
defp to_parsed(_), do: :help
@spec to_tuple([String.t()]) :: {user, project, non_neg_integer} | :error
defp to_tuple([user, project, count]) do
with {int, ""} when int >= 0 <- Integer.parse(count),
do: {user, project, int},
else: (_ -> :error)
end
defp to_tuple([user, project]), do: {user, project, @count}
defp to_tuple(_), do: :error
end