Packages

A CLI tool to manage package dependencies

Current section

Files

Jump to
wand lib cli commands upgrade.ex
Raw

lib/cli/commands/upgrade.ex

defmodule Wand.CLI.Commands.Upgrade do
alias Wand.CLI.Display
@behaviour Wand.CLI.Command
@banner """
# Upgrade
Upgrade dependencies in your wand.json file
### Usage
```
wand upgrade
wand upgrade poison ex_doc --latest
```
## Options
```
--compile Run mix compile after adding (default: **true**)
--download Run mix deps.get after adding (default: **true**)
--latest Upgrade to the latest version, ignoring wand.json restrictions
```
The following flags are additionally allowed if `--latest` is passed in:
```
--exact After updating, set the version in wand.json with ^ semantics
--tilde After updating, set the version in wand.json with ~> semantics
```
"""
@moduledoc """
#{@banner}
By default, upgrade will respect the restrictions set in your wand.json file. Meaning,
if your requirement is `>= 3.2.0 and < 4.0.0`, and the latest version in hex is `3.7.3`, wand will update the lower bound of wand.json to `3.7.3`, but leave the upper bound alone.
If you want to update the upper bound, you need to use the --latest flag. The latest flag will always grab the newest (non pre) version in hex, and set that as the new lower bound. The upper bound is set to the next major version, unless you pass in the `--exact` or `--tilde` flags to override this behavior.
Wand prefers setting versions by the caret semantic. That means that the lower bound is the exact version specified, and the upper bound is the next major version. If the version is less than 1.0.0, the upper bound becomes the next minor version, and so forth.
"""
defmodule Options do
@moduledoc false
defstruct mode: :caret,
download: true,
compile: true,
latest: false
end
@doc false
def help(:banner), do: Display.print(@banner)
@doc false
def help(:verbose), do: Display.print(@moduledoc)
@doc false
def help({:invalid_flag, flag}) do
"""
#{flag} is invalid.
Allowed flags are --compile, --download, --exact, --latest, and --tilde.
See wand help upgrade --verbose for more information
"""
|> Display.print()
end
@doc false
def validate(args) do
{switches, [_ | commands], errors} = OptionParser.parse(args, strict: get_flags(args))
case Wand.CLI.Command.parse_errors(errors) do
:ok -> {:ok, parse(commands, switches)}
error -> error
end
end
@doc false
def execute(args), do: Wand.CLI.Commands.Upgrade.Execute.execute(args)
defp parse(commands, switches) do
download = Keyword.get(switches, :download, true)
compile = download and Keyword.get(switches, :compile, true)
options = %Options{
download: download,
compile: compile,
latest: Keyword.get(switches, :latest, false),
mode: get_mode(switches)
}
{get_packages(commands), options}
end
defp get_packages([]), do: :all
defp get_packages(commands), do: commands
defp get_mode(switches) do
cond do
Keyword.get(switches, :exact) -> :exact
Keyword.get(switches, :tilde) -> :tilde
true -> %Options{}.mode
end
end
defp get_flags(args) do
base_flags = [
compile: :boolean,
download: :boolean,
latest: :boolean
]
latest_flags = [
exact: :boolean,
tilde: :boolean
]
{switches, _commands, _errors} = OptionParser.parse(args)
case Keyword.get(switches, :latest) do
true -> latest_flags ++ base_flags
_ -> base_flags
end
end
end