Packages

A Mix Task to upload Distillery releases to GitHub.

Current section

Files

Jump to
duckduck lib duck_duck cli.ex
Raw

lib/duck_duck/cli.ex

defmodule DuckDuck.CLI do
@moduledoc """
Command line interface for uploading release artifacts.
"""
import DuckDuck
alias Mix.Project
alias DuckDuck.Effects
@switches [tag: :string, file: :string, yes: :boolean]
@aliases [t: :tag, f: :file, y: :yes]
@effects Application.get_env(:duckduck, :effects_client, Effects)
def parse!(argv) do
{parsed, _rest} =
OptionParser.parse!(argv, switches: @switches, aliases: @aliases)
Map.new(parsed)
end
# fill in missing values
def resolve!(%{tag: _tag, file: _file} = opts), do: opts
def resolve!(%{file: _file} = opts),
do: Map.put(opts, :tag, @effects.get_tag())
def resolve!(%{tag: tag} = opts) do
app_name = Keyword.fetch!(Project.config(), :app)
file =
case @effects.release_files(app_name, tag, @effects.build_path()) do
[file] ->
file
[] ->
fail("No local release files found for #{tag}!")
[_ | _] ->
fail("Found too many local release files for #{tag}")
end
Map.put(opts, :file, file)
end
def resolve!(opts) do
opts
|> Map.put(:tag, @effects.get_tag())
|> resolve!()
end
def confirm!(%{yes: true} = opts), do: opts
def confirm!(%{file: file, tag: tag} = opts) do
"I want to upload #{file} to tag #{tag}.\nIs this ok? [Y/n] "
|> IO.gets()
|> String.trim()
|> String.downcase()
|> case do
"" ->
Map.put(opts, :yes, true)
"y" <> _ ->
Map.put(opts, :yes, true)
_ ->
fail("Aborting!")
end
end
def run!(%{tag: tag, file: file, yes: true}) do
@effects.start_http_client()
owner = Application.fetch_env!(:duckduck, :owner)
repo = Application.fetch_env!(:duckduck, :repo)
api_token = @effects.read_api_token()
unless valid_token?(api_token, owner, repo) do
fail("GitHub doesn't think this token is valid!")
end
upload_url = find_upload_url(api_token, owner, repo, tag)
upload(file, api_token, upload_url)
end
end