Skip to content

Commit

Permalink
Merge pull request #2 from TheFirstAvenger/mb-deps-resolution-change
Browse files Browse the repository at this point in the history
Mb deps resolution change
  • Loading branch information
TheFirstAvenger committed Feb 7, 2019
2 parents 8bd140b + 5a37495 commit e7b45c3
Show file tree
Hide file tree
Showing 11 changed files with 46 additions and 64 deletions.
5 changes: 1 addition & 4 deletions .dialyzer_ignore.exs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
[
~r/Function :httpc\.request\/4 does not exist\./,
# https://github.com/elixir-lang/elixir/issues/8631
~r/Function with_deps\/0 has no local return/,
~r/Function with_deps\/1 has no local return/
~r/Function :httpc\.request\/4 does not exist\./
]
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
language: elixir
elixir:
- 1.8
- 1.8.1
otp_release:
- 21.0
env:
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Next

* Change dependency checking to use regex
* Clear dialyzer ignores fixed in elixir 1.8.1
* Change format of IO questions

## 0.1.2

* Add self version checking
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Ironman

[![Build Status](https://travis-ci.com/TheFirstAvenger/ironman.svg?branch=master)](https://travis-ci.com/TheFirstAvenger/ironman)
[![Coverage Status](https://coveralls.io/repos/github/TheFirstAvenger/ironman/badge.svg?branch=master)](https://coveralls.io/github/TheFirstAvenger/ironman?branch=master)
[![Project license](https://img.shields.io/hexpm/l/ironman.svg)](https://unlicense.org/)
[![Hex.pm package](https://img.shields.io/hexpm/v/ironman.svg)](https://hex.pm/packages/ironman)
[![Hex.pm downloads](https://img.shields.io/hexpm/dt/ironman.svg)](https://hex.pm/packages/ironman)

`mix new` is like Tony Stark: Awesome and can do great things, but not bulletproof. When he suits up, however, his vulnerabilities are covered. Similarly, the Ironman project takes an elixir project (existing or newly created) and configures it in a way that protects it from getting in a bad state. It does this by adding dependencies for best practices such as `:credo` and `:dialyxir`, adding ci configuration for these tools, setting run configuration such as `warnings_as_errors`, etc...

Each step of suiting up is confirmed with the end user before changing, and can be rejected individually.
Expand Down
5 changes: 1 addition & 4 deletions lib/ironman/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,14 @@ defmodule Ironman.Config do
"""
@type t :: %__MODULE__{
mix_exs: String.t(),
deps: list(),
changed: boolean()
}
defstruct mix_exs: nil,
deps: nil,
changed: false

def new!() do
%__MODULE__{
mix_exs: File.read!("mix.exs"),
deps: Mix.Project.config()[:deps]
mix_exs: File.read!("mix.exs")
}
end
end
1 change: 1 addition & 0 deletions lib/ironman/runner.ex
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ defmodule Ironman.Runner do
def run_check(%Config{} = config, :excoveralls),
do: config |> SimpleDep.run(:excoveralls, only: :test) |> unwrap(:excoveralls)

@spec unwrap({atom(), Config.t()} | {:error, any()}, atom()) :: Config.t()
def unwrap({:no, config}, _check), do: config
def unwrap({:yes, config}, _check), do: config
def unwrap({:up_to_date, config}, _check), do: config
Expand Down
2 changes: 1 addition & 1 deletion lib/ironman/utils.ex
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ defmodule Ironman.Utils do

@spec ask(String.t(), function(), function(), function()) :: any()
def ask(q, yes, no, other) do
case IIO.get("#{q} Yn\n") do
case IIO.get("#{q} [Yn] ") do
x when x in ["Y\n", "y\n", "\n"] -> yes.()
x when x in ["N\n", "n\n"] -> no.()
_ -> other.()
Expand Down
39 changes: 8 additions & 31 deletions lib/ironman/utils/deps.ex
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,13 @@ defmodule Ironman.Utils.Deps do
end

@spec get_configured_version(Config.t(), dep()) :: String.t() | nil
def get_configured_version(%Config{deps: deps}, dep) do
deps
|> Enum.find(fn d -> elem(d, 0) == dep end)
def get_configured_version(%Config{mix_exs: mix_exs}, dep) do
"defp deps do.*?\\[.*?{:#{dep}, \"(.*?)\""
|> Regex.compile!("s")
|> Regex.run(mix_exs)
|> case do
nil -> nil
d -> elem(d, 1)
[_, version] -> version
_ -> nil
end
end

Expand Down Expand Up @@ -82,7 +83,7 @@ defmodule Ironman.Utils.Deps do
"defp deps do\n [{:#{dep}, \"#{new_version}\"#{dep_opts_str}},"
)

{:yes, %Config{config | mix_exs: mix_exs, changed: true} |> add_dep_to_state(dep, dep_opts, new_version)}
{:yes, %Config{config | mix_exs: mix_exs, changed: true}}
end

defp dep_opts_to_str(dep_opts) do
Expand Down Expand Up @@ -118,31 +119,7 @@ defmodule Ironman.Utils.Deps do
regex = Regex.compile!("{:#{dep}, \"~>.*?\"")
mix_exs = Regex.replace(regex, mix_exs, "{:#{dep}, \"#{new_version}\"")

{:yes, %Config{config | mix_exs: mix_exs, changed: true} |> update_deps_state(dep, new_version)}
end

@spec update_deps_state(Ironman.Config.t(), dep(), String.t()) :: Ironman.Config.t()
def update_deps_state(%Config{deps: deps} = config, dep, new_version) do
deps =
Enum.map(deps, fn d ->
case elem(d, 0) do
^dep -> d |> Tuple.delete_at(1) |> Tuple.insert_at(1, new_version)
_ -> d
end
end)

%Config{config | deps: deps}
end

@spec add_dep_to_state(Ironman.Config.t(), dep(), keyword(), String.t()) :: Ironman.Config.t()
def add_dep_to_state(%Config{deps: deps} = config, dep, dep_opts, new_version) do
new_dep =
case dep_opts do
[] -> {dep, new_version}
_ -> {dep, new_version, dep_opts}
end

%Config{config | deps: [new_dep | deps]}
{:yes, %Config{config | mix_exs: mix_exs, changed: true}}
end

@spec skip_upgrade(Config.t(), any()) :: {:no, Config.t()}
Expand Down
18 changes: 9 additions & 9 deletions test/ironman/checks/simple_dep_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ defmodule Ironman.Checks.SimpleDepTest do
describe "out of date" do
test "updates when y pressed" do
MoxHelpers.expect_dep_http(:ex_doc, "1.2.3")
MoxHelpers.expect_io("Upgrade ex_doc from ~> 1.2.2 to 1.2.3? Yn\n", "y")
MoxHelpers.expect_io("Upgrade ex_doc from ~> 1.2.2 to 1.2.3? [Yn] ", "y")

%Config{mix_exs: mix_exs} = config = MixBuilder.with_deps(ex_doc: "~> 1.2.2")
assert "~> 1.2.2" == Deps.get_configured_version(config, :ex_doc)
Expand All @@ -30,7 +30,7 @@ defmodule Ironman.Checks.SimpleDepTest do

test "doesn't update when n pressed" do
MoxHelpers.expect_dep_http(:ex_doc, "1.2.3")
MoxHelpers.expect_io("Upgrade ex_doc from ~> 1.2.2 to 1.2.3? Yn\n", "n")
MoxHelpers.expect_io("Upgrade ex_doc from ~> 1.2.2 to 1.2.3? [Yn] ", "n")

%Config{mix_exs: mix_exs} = config = MixBuilder.with_deps(ex_doc: "~> 1.2.2")
assert "~> 1.2.2" == Deps.get_configured_version(config, :ex_doc)
Expand All @@ -42,9 +42,9 @@ defmodule Ironman.Checks.SimpleDepTest do

test "multiple" do
MoxHelpers.expect_dep_http(:ex_doc, "1.2.3")
MoxHelpers.expect_io("Upgrade ex_doc from ~> 1.2.2 to 1.2.3? Yn\n", "y")
MoxHelpers.expect_io("Upgrade ex_doc from ~> 1.2.2 to 1.2.3? [Yn] ", "y")
MoxHelpers.expect_dep_http(:earmark, "2.3.6")
MoxHelpers.expect_io("Upgrade earmark from ~> 2.3.4 to 2.3.6? Yn\n", "y")
MoxHelpers.expect_io("Upgrade earmark from ~> 2.3.4 to 2.3.6? [Yn] ", "y")

%Config{mix_exs: mix_exs} = config = MixBuilder.with_deps(ex_doc: "~> 1.2.2", earmark: "~> 2.3.4")

Expand All @@ -65,7 +65,7 @@ defmodule Ironman.Checks.SimpleDepTest do
describe "missing" do
test "updates when y pressed" do
MoxHelpers.expect_dep_http(:ex_doc, "1.2.3")
MoxHelpers.expect_io("Install ex_doc 1.2.3? Yn\n", "y")
MoxHelpers.expect_io("Install ex_doc 1.2.3? [Yn] ", "y")

%Config{mix_exs: mix_exs} = config = MixBuilder.with_deps()
assert nil == Deps.get_configured_version(config, :ex_doc)
Expand All @@ -77,7 +77,7 @@ defmodule Ironman.Checks.SimpleDepTest do

test "doesn't update when n pressed" do
MoxHelpers.expect_dep_http(:ex_doc, "1.2.3")
MoxHelpers.expect_io("Install ex_doc 1.2.3? Yn\n", "n")
MoxHelpers.expect_io("Install ex_doc 1.2.3? [Yn] ", "n")

%Config{mix_exs: mix_exs} = config = MixBuilder.with_deps()
assert nil == Deps.get_configured_version(config, :ex_doc)
Expand All @@ -90,9 +90,9 @@ defmodule Ironman.Checks.SimpleDepTest do

test "multiple" do
MoxHelpers.expect_dep_http(:ex_doc, "1.2.3")
MoxHelpers.expect_io("Install ex_doc 1.2.3? Yn\n", "y")
MoxHelpers.expect_io("Install ex_doc 1.2.3? [Yn] ", "y")
MoxHelpers.expect_dep_http(:earmark, "2.3.6")
MoxHelpers.expect_io("Install earmark 2.3.6? Yn\n", "y")
MoxHelpers.expect_io("Install earmark 2.3.6? [Yn] ", "y")

%Config{mix_exs: mix_exs} = config = MixBuilder.with_deps()

Expand All @@ -111,7 +111,7 @@ defmodule Ironman.Checks.SimpleDepTest do

test "Sets dep_opts" do
MoxHelpers.expect_dep_http(:ex_doc, "1.2.3")
MoxHelpers.expect_io("Install ex_doc 1.2.3? Yn\n", "y")
MoxHelpers.expect_io("Install ex_doc 1.2.3? [Yn] ", "y")

%Config{mix_exs: mix_exs} = config = MixBuilder.with_deps()
assert nil == Deps.get_configured_version(config, :ex_doc)
Expand Down
4 changes: 2 additions & 2 deletions test/ironman/utils_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ defmodule Ironman.UtilsTest do

test "Upgrade when out of date" do
MoxHelpers.expect_dep_http(:ironman, "0.0.0")
MoxHelpers.expect_io("Ironman is out of date. Upgrade? Yn\n", "y")
MoxHelpers.expect_io("Ironman is out of date. Upgrade? [Yn] ", "y")
MoxHelpers.expect_cmd(["mix", "archive.install", "hex", "ironman", "--force"])
assert :exit == Utils.check_self_version()
end

test "Dont upgrade when out of date and n pressed" do
MoxHelpers.expect_dep_http(:ironman, "0.0.0")
MoxHelpers.expect_io("Ironman is out of date. Upgrade? Yn\n", "n")
MoxHelpers.expect_io("Ironman is out of date. Upgrade? [Yn] ", "n")
MoxHelpers.expect_cmd("hi")
assert :declined == Utils.check_self_version()
end
Expand Down
22 changes: 10 additions & 12 deletions test/support/mix_builder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ defmodule Ironman.Test.Helpers.MixBuilder do
alias Ironman.Config

def with_deps(deps \\ []) when is_list(deps) do
mix_exs =
"""
defmodule Test.MixProject do
mix_exs = """
defmodule Test.MixProject do
use Mix.Project
def project do
Expand All @@ -22,21 +21,20 @@ defmodule Ironman.Test.Helpers.MixBuilder do
defp deps do
#{mix_string(deps)}
end
end
"""
|> Code.format_string!()
|> List.wrap()
|> IO.iodata_to_binary()
end
"""

%Config{mix_exs: mix_exs, deps: deps}
%Config{mix_exs: mix_exs}
end

@spec mix_string(list()) :: String.t()
def mix_string(deps) do
deps
|> Enum.map(fn {dep, ver} -> "{:#{dep}, \"#{ver}\"}" end)
|> Enum.join(",")
|> Enum.map(fn {dep, ver} -> " {:#{dep}, \"#{ver}\"}" end)
|> Enum.join(",\n")
|> wrap_brackets()
end

defp wrap_brackets(str), do: "[ #{str} ]"
defp wrap_brackets(""), do: "[]"
defp wrap_brackets(str), do: "[\n#{str}\n ]"
end

0 comments on commit e7b45c3

Please sign in to comment.