defmodule PhaseDB.Client.CLI do alias PhaseDB.Client.Session require PhaseDB.Client @moduledoc """ Implements the command line interface for the `phase_db_cli` escript. """ @switches [ version: :boolean, help: :boolean ] @aliases [ v: :version, h: :help ] @valid_schemes ~w| ws wss | def go %{help: true} do IO.puts version IO.write """ usage: phase_db_cli [options] uri: The URI of the phaseDB server you are connecting to. Defaults to "%{PhaseDB.Client.default_uri}". options: -v --version Display the phaseDB CLI version and exit -h --help This message """ end def go %{version: true} do IO.puts version end def go %{uri: uri} do Session.create uri end def main(args) do args |> parse_args |> go end def parse_args args do case OptionParser.parse args, switches: @switches, aliases: @aliases do {opts, [], _} -> opts |> Dict.put(:uri, PhaseDB.Client.default_uri) |> Enum.into(%{}) {opts, [uri], _} -> opts |> Dict.put(:uri, validate_uri(uri)) |> Enum.into(%{}) {_, uris, _} -> halt_with_error "Invalid arguments: #{inspect uris}" end end defp validate_uri(uri) when is_binary(uri) do validate_uri URI.parse(uri) end defp validate_uri(%{scheme: scheme, path: path}=uri) do errors = [] errors = if Enum.member? @valid_schemes, scheme do errors else [ ~s|Invalid URI: Scheme must be one of #{inspect @valid_schemes}]| | errors ] end errors = case path do nil -> errors "/" -> errors _ -> [ ~s|Invalid URI: Path must be "/"| | errors ] end if Enum.any? errors do halt_with_error Enum.join(errors, "\n\t") else URI.to_string uri end end def version do {:ok, version} = :application.get_key :phasedb_client, :vsn "PhaseDB CLI version #{version}" end def halt_with_error message do IO.write :stderr, "Error: #{message}" System.halt 1 end end