Fixed typo in perceived_complexity.ex

Fixed typo in perceived_complexity.ex

defmodule Credo.Check.Refactor.PerceivedComplexity do
  @moduledoc """
  Cyclomatic complexity is a software complexity metric closely correlated with
  coding errors.

  If a function feels like it's gotten too complex, it more often than not also
  has a high CC value. So, if anything, this is useful to convince team members
  and bosses of a need to refactor parts of the code based on "objective"
  metrics.
  """

  @explanation [
    check: @moduledoc,
    params: [
      max_complexity: "The maximum cyclomatic complexity a function should have."
    ]
  ]
  @default_params [max_complexity: 9]

  @def_ops [:def, :defp, :defmacro]
  # these have two outcomes: it succeeds or does not
  @double_condition_ops [:if, :unless, :for, :try, :and, :or, :&&, :||]
  # these can have multiple outcomes as they are defined in their do blocks
  @multiple_condition_ops [:case, :cond]
  @op_complexity_map [
    def: 1,
    defp: 1,
    defmacro: 1,
    if: 1,
    unless: 1,
    for: 1,
    try: 1,
    and: 1,
    or: 1,
    &&: 1,
    ||: 1,
    case: 0.3,
    cond: 1,
  ]

  alias Credo.Check.CodeHelper
  alias Credo.SourceFile

  use Credo.Check

  @doc false
  def run(%SourceFile{ast: ast} = source_file, params \\ []) do
    issue_meta = IssueMeta.for(source_file, params)
    max_complexity = Params.get(params, :max_complexity, @default_params)

    Credo.Code.prewalk(ast, &traverse(&1, &2, issue_meta, max_complexity))
  end

  # exception for `__using__` macros
  defp traverse({:defmacro, _, [{:__using__, _, _}, _]} = ast, issues, _, _) do
    {ast, issues}
  end
  for op <- @def_ops do
    defp traverse({unquote(op), meta, arguments} = ast, issues, issue_meta, max_complexity) when is_list(arguments) do
      complexity =
        ast
        |> complexity_for
        |> round

      if complexity > max_complexity do
        fun_name = CodeHelper.def_name(ast)

        {ast, issues ++ [issue_for(issue_meta, meta[:line], fun_name, max_complexity, complexity)]}
      else
        {ast, issues}
      end
    end
  end
  defp traverse(ast, issues, _source_file, _max_complexity) do
    {ast, issues}
  end

  @doc """
  Returns the Cyclomatic Complexity score for the block inside the given AST,
  which is expected to represent a function or macro definition.

      iex> {:def, [line: 1],
      ...>   [
      ...>     {:first_fun, [line: 1], nil},
      ...>     [do: {:=, [line: 2], [{:x, [line: 2], nil}, 1]}]
      ...>   ]
      ...> } |> Credo.Check.Refactor.CyclomaticComplexity.complexity_for
      1.0
  """
  def complexity_for({_def_op, _meta, _arguments} = ast) do
    Credo.Code.prewalk(ast, &traverse_complexity/2, 0)
  end

  for op <- @def_ops do
    defp traverse_complexity({unquote(op) = op, _meta, arguments} = ast, complexity) when is_list(arguments) do
      {ast, complexity + @op_complexity_map[op]}
    end
  end

  for op <- @double_condition_ops do
    defp traverse_complexity({unquote(op) = op, _meta, arguments} = ast, complexity) when is_list(arguments) do
      {ast, complexity + @op_complexity_map[op]}
    end
  end

  for op <- @multiple_condition_ops do
    defp traverse_complexity({unquote(op), _meta, nil} = ast, complexity) do
      {ast, complexity}
    end
    defp traverse_complexity({unquote(op) = op, _meta, arguments} = ast, complexity) when is_list(arguments) do
      block_cc =
        arguments
        |> CodeHelper.do_block_for!
        |> do_block_complexity(op)

      {ast, complexity + block_cc}
    end
  end
  defp traverse_complexity(ast, complexity) do
    {ast, complexity}
  end

  defp do_block_complexity(nil, _), do: 0
  defp do_block_complexity(block, op) do
    count =
      block
      |> List.wrap
      |> Enum.count

    count * @op_complexity_map[op]
  end

  def issue_for(issue_meta, line_no, trigger, max_value, actual_value) do
    format_issue issue_meta,
      message: "Function is too complex (CC is #{actual_value}, max is #{max_value}).",
      trigger: trigger,
      line_no: line_no,
      severity: Severity.compute(actual_value, max_value)
  end
end

defmodule Credo.Check.Refactor.PerceivedComplexity do
  @moduledoc """
  Cyclomatic complexity is a software complexity metric closely correlated with
  coding errors.

  If a function feels like it's gotten too complex, it more often than not also
  has a high CC value. So, if anything, this is useful to convince team members
  and bosses of a need to refactor parts of the code based on "objective"
  metrics.
  """

  @explanation [
    check: @moduledoc,
    params: [
      max_complexity: "The maximum cyclomatic complexity a function should have."
    ]
  ]
  @default_params [max_complexity: 9]

  @def_ops [:def, :defp, :defmacro]
  # these have two outcomes: it succeds or does not
  @double_condition_ops [:if, :unless, :for, :try, :and, :or, :&&, :||]
  # these can have multiple outcomes as they are defined in their do blocks
  @multiple_condition_ops [:case, :cond]
  @op_complexity_map [
    def: 1,
    defp: 1,
    defmacro: 1,
    if: 1,
    unless: 1,
    for: 1,
    try: 1,
    and: 1,
    or: 1,
    &&: 1,
    ||: 1,
    case: 0.3,
    cond: 1,
  ]

  alias Credo.Check.CodeHelper
  alias Credo.SourceFile

  use Credo.Check

  @doc false
  def run(%SourceFile{ast: ast} = source_file, params \\ []) do
    issue_meta = IssueMeta.for(source_file, params)
    max_complexity = Params.get(params, :max_complexity, @default_params)

    Credo.Code.prewalk(ast, &traverse(&1, &2, issue_meta, max_complexity))
  end

  # exception for `__using__` macros
  defp traverse({:defmacro, _, [{:__using__, _, _}, _]} = ast, issues, _, _) do
    {ast, issues}
  end
  for op <- @def_ops do
    defp traverse({unquote(op), meta, arguments} = ast, issues, issue_meta, max_complexity) when is_list(arguments) do
      complexity =
        ast
        |> complexity_for
        |> round

      if complexity > max_complexity do
        fun_name = CodeHelper.def_name(ast)

        {ast, issues ++ [issue_for(issue_meta, meta[:line], fun_name, max_complexity, complexity)]}
      else
        {ast, issues}
      end
    end
  end
  defp traverse(ast, issues, _source_file, _max_complexity) do
    {ast, issues}
  end

  @doc """
  Returns the Cyclomatic Complexity score for the block inside the given AST,
  which is expected to represent a function or macro definition.

      iex> {:def, [line: 1],
      ...>   [
      ...>     {:first_fun, [line: 1], nil},
      ...>     [do: {:=, [line: 2], [{:x, [line: 2], nil}, 1]}]
      ...>   ]
      ...> } |> Credo.Check.Refactor.CyclomaticComplexity.complexity_for
      1.0
  """
  def complexity_for({_def_op, _meta, _arguments} = ast) do
    Credo.Code.prewalk(ast, &traverse_complexity/2, 0)
  end

  for op <- @def_ops do
    defp traverse_complexity({unquote(op) = op, _meta, arguments} = ast, complexity) when is_list(arguments) do
      {ast, complexity + @op_complexity_map[op]}
    end
  end

  for op <- @double_condition_ops do
    defp traverse_complexity({unquote(op) = op, _meta, arguments} = ast, complexity) when is_list(arguments) do
      {ast, complexity + @op_complexity_map[op]}
    end
  end

  for op <- @multiple_condition_ops do
    defp traverse_complexity({unquote(op), _meta, nil} = ast, complexity) do
      {ast, complexity}
    end
    defp traverse_complexity({unquote(op) = op, _meta, arguments} = ast, complexity) when is_list(arguments) do
      block_cc =
        arguments
        |> CodeHelper.do_block_for!
        |> do_block_complexity(op)

      {ast, complexity + block_cc}
    end
  end
  defp traverse_complexity(ast, complexity) do
    {ast, complexity}
  end

  defp do_block_complexity(nil, _), do: 0
  defp do_block_complexity(block, op) do
    count =
      block
      |> List.wrap
      |> Enum.count

    count * @op_complexity_map[op]
  end

  def issue_for(issue_meta, line_no, trigger, max_value, actual_value) do
    format_issue issue_meta,
      message: "Function is too complex (CC is #{actual_value}, max is #{max_value}).",
      trigger: trigger,
      line_no: line_no,
      severity: Severity.compute(actual_value, max_value)
  end
end


Add test case for auto sync channel error handlers

defmodule AutoSyncChannelTest do
  require Helpers
  use ExUnit.Case, async: false
  use Mimic
  alias FarmbotExt.AMQP.AutoSyncChannel

  alias FarmbotExt.{
    AMQP.ConnectionWorker,
    API.Preloader,
    JWT
  }

  setup :verify_on_exit!
  setup :set_mimic_global

  @fake_jwt "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJhZ" <>
              "G1pbkBhZG1pbi5jb20iLCJpYXQiOjE1MDIxMjcxMTcsImp0a" <>
              "SI6IjlhZjY2NzJmLTY5NmEtNDhlMy04ODVkLWJiZjEyZDlhY" <>
              "ThjMiIsImlzcyI6Ii8vbG9jYWxob3N0OjMwMDAiLCJleHAiO" <>
              "jE1MDU1ODMxMTcsIm1xdHQiOiJsb2NhbGhvc3QiLCJvc191c" <>
              "GRhdGVfc2VydmVyIjoiaHR0cHM6Ly9hcGkuZ2l0aHViLmNvb" <>
              "S9yZXBvcy9mYXJtYm90L2Zhcm1ib3Rfb3MvcmVsZWFzZXMvb" <>
              "GF0ZXN0IiwiZndfdXBkYXRlX3NlcnZlciI6Imh0dHBzOi8vY" <>
              "XBpLmdpdGh1Yi5jb20vcmVwb3MvRmFybUJvdC9mYXJtYm90L" <>
              "WFyZHVpbm8tZmlybXdhcmUvcmVsZWFzZXMvbGF0ZXN0IiwiY" <>
              "m90IjoiZGV2aWNlXzE1In0.XidSeTKp01ngtkHzKD_zklMVr" <>
              "9ZUHX-U_VDlwCSmNA8ahOHxkwCtx8a3o_McBWvOYZN8RRzQV" <>
              "LlHJugHq1Vvw2KiUktK_1ABQ4-RuwxOyOBqqc11-6H_GbkM8" <>
              "dyzqRaWDnpTqHzkHGxanoWVTTgGx2i_MZLr8FPZ8prnRdwC1" <>
              "x9zZ6xY7BtMPtHW0ddvMtXU8ZVF4CWJwKSaM0Q2pTxI9GRqr" <>
              "p5Y8UjaKufif7bBPOUbkEHLNOiaux4MQr-OWAC8TrYMyFHzt" <>
              "eXTEVkqw7rved84ogw6EKBSFCVqwRA-NKWLpPMV_q7fRwiEG" <>
              "Wj7R-KZqRweALXuvCLF765E6-ENxA"

  def generate_pid do
    apply_default_mocks()
    jwt = JWT.decode!(@fake_jwt)
    {:ok, pid} = AutoSyncChannel.start_link([jwt: jwt], [])
    pid
  end

  def apply_default_mocks do
    ok1 = fn _ -> :whatever end
    stub(FarmbotExt.API.EagerLoader.Supervisor, :drop_all_cache, fn -> :ok end)
    stub(ConnectionWorker, :close_channel, ok1)

    stub(ConnectionWorker, :maybe_connect_autosync, fn _ ->
      %{conn: %{fake_conn: true}, chan: %{fake_chan: true}}
    end)
  end

  def ensure_response_to(msg) do
    # Not much to check here other than matching clauses.
    # AMQP lib handles most all of this.
    expect(Preloader, :preload_all, 1, fn -> :ok end)
    pid = generate_pid()
    send(pid, msg)
    Helpers.wait_for(pid)
  end

  test "basic_cancel", do: ensure_response_to({:basic_cancel, :anything})
  test "basic_cancel_ok", do: ensure_response_to({:basic_cancel_ok, :anything})
  test "basic_consume_ok", do: ensure_response_to({:basic_consume_ok, :anything})

  test "init / terminate - auto_sync enabled" do
    expect(Preloader, :preload_all, 1, fn -> :ok end)
    expect(FarmbotCore.BotState, :set_sync_status, 1, fn "synced" -> :ok end)

    expect(FarmbotCore.Leds, :green, 2, fn
      :solid ->
        :ok

      :really_fast_blink ->
        :ok
    end)

    pid = generate_pid()
    assert %{chan: nil, conn: nil, preloaded: true} == AutoSyncChannel.network_status(pid)
    GenServer.stop(pid, :normal)
  end

  test "init / terminate - preload error" do
    expect(Preloader, :preload_all, 1, fn -> {:error, "part of a test"} end)
    expect(FarmbotCore.BotState, :set_sync_status, 1, fn "sync_error" -> :ok end)

    pid = generate_pid()
    assert %{chan: nil, conn: nil, preloaded: false} == AutoSyncChannel.network_status(pid)
    GenServer.stop(pid, :normal)
  end

  test "delivery of auto sync messages" do
    expect(Preloader, :preload_all, 1, fn -> :ok end)

    expect(ConnectionWorker, :rpc_reply, 1, fn chan, device, label ->
      assert chan == %{fake_chan: true}
      assert device == "device_15"
      assert label == "thisismylabelinatestsuite"
      :ok
    end)

    key = "bot.device_15.sync.Device.46"

    {:ok, payload} =
      FarmbotCore.JSON.encode(%{
        "id" => 46,
        "args" => %{
          "label" => "thisismylabelinatestsuite"
        },
        "body" => %{name: "This is my bot"}
      })

    pid = generate_pid()
    # We need the process to be preloaded for these tests to work:
    %{preloaded: true} = AutoSyncChannel.network_status(pid)
    send(pid, {:basic_deliver, payload, %{routing_key: key}})

    expect(FarmbotExt.AMQP.AutoSyncAssetHandler, :handle_asset, fn kind, id, body ->
      assert kind == "Device"
      assert id == 46
      assert body == %{"name" => "This is my bot"}
      :ok
    end)

    Helpers.wait_for(pid)
    Process.sleep(1000)
  end
end

defmodule AutoSyncChannelTest do
  require Helpers
  use ExUnit.Case, async: false
  use Mimic
  alias FarmbotExt.AMQP.AutoSyncChannel

  alias FarmbotExt.{
    AMQP.ConnectionWorker,
    API.Preloader,
    JWT
  }

  setup :verify_on_exit!
  setup :set_mimic_global

  @fake_jwt "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJhZ" <>
              "G1pbkBhZG1pbi5jb20iLCJpYXQiOjE1MDIxMjcxMTcsImp0a" <>
              "SI6IjlhZjY2NzJmLTY5NmEtNDhlMy04ODVkLWJiZjEyZDlhY" <>
              "ThjMiIsImlzcyI6Ii8vbG9jYWxob3N0OjMwMDAiLCJleHAiO" <>
              "jE1MDU1ODMxMTcsIm1xdHQiOiJsb2NhbGhvc3QiLCJvc191c" <>
              "GRhdGVfc2VydmVyIjoiaHR0cHM6Ly9hcGkuZ2l0aHViLmNvb" <>
              "S9yZXBvcy9mYXJtYm90L2Zhcm1ib3Rfb3MvcmVsZWFzZXMvb" <>
              "GF0ZXN0IiwiZndfdXBkYXRlX3NlcnZlciI6Imh0dHBzOi8vY" <>
              "XBpLmdpdGh1Yi5jb20vcmVwb3MvRmFybUJvdC9mYXJtYm90L" <>
              "WFyZHVpbm8tZmlybXdhcmUvcmVsZWFzZXMvbGF0ZXN0IiwiY" <>
              "m90IjoiZGV2aWNlXzE1In0.XidSeTKp01ngtkHzKD_zklMVr" <>
              "9ZUHX-U_VDlwCSmNA8ahOHxkwCtx8a3o_McBWvOYZN8RRzQV" <>
              "LlHJugHq1Vvw2KiUktK_1ABQ4-RuwxOyOBqqc11-6H_GbkM8" <>
              "dyzqRaWDnpTqHzkHGxanoWVTTgGx2i_MZLr8FPZ8prnRdwC1" <>
              "x9zZ6xY7BtMPtHW0ddvMtXU8ZVF4CWJwKSaM0Q2pTxI9GRqr" <>
              "p5Y8UjaKufif7bBPOUbkEHLNOiaux4MQr-OWAC8TrYMyFHzt" <>
              "eXTEVkqw7rved84ogw6EKBSFCVqwRA-NKWLpPMV_q7fRwiEG" <>
              "Wj7R-KZqRweALXuvCLF765E6-ENxA"

  def generate_pid do
    apply_default_mocks()
    jwt = JWT.decode!(@fake_jwt)
    {:ok, pid} = AutoSyncChannel.start_link([jwt: jwt], [])
    pid
  end

  def apply_default_mocks do
    ok1 = fn _ -> :whatever end
    stub(FarmbotExt.API.EagerLoader.Supervisor, :drop_all_cache, fn -> :ok end)
    stub(ConnectionWorker, :close_channel, ok1)

    stub(ConnectionWorker, :maybe_connect_autosync, fn _ ->
      %{conn: %{fake_conn: true}, chan: %{fake_chan: true}}
    end)
  end

  def ensure_response_to(msg) do
    # Not much to check here other than matching clauses.
    # AMQP lib handles most all of this.
    expect(Preloader, :preload_all, 1, fn -> :ok end)
    pid = generate_pid()
    send(pid, msg)
    Helpers.wait_for(pid)
  end

  test "basic_cancel", do: ensure_response_to({:basic_cancel, :anything})
  test "basic_cancel_ok", do: ensure_response_to({:basic_cancel_ok, :anything})
  test "basic_consume_ok", do: ensure_response_to({:basic_consume_ok, :anything})

  test "init / terminate - auto_sync enabled" do
    expect(Preloader, :preload_all, 1, fn -> :ok end)
    expect(FarmbotCore.BotState, :set_sync_status, 1, fn "synced" -> :ok end)

    expect(FarmbotCore.Leds, :green, 2, fn
      :solid ->
        :ok

      :really_fast_blink ->
        :ok
    end)

    pid = generate_pid()
    assert %{chan: nil, conn: nil, preloaded: true} == AutoSyncChannel.network_status(pid)
    GenServer.stop(pid, :normal)
  end

  test "delivery of auto sync messages" do
    expect(Preloader, :preload_all, 1, fn -> :ok end)

    expect(ConnectionWorker, :rpc_reply, 1, fn chan, device, label ->
      assert chan == %{fake_chan: true}
      assert device == "device_15"
      assert label == "thisismylabelinatestsuite"
      :ok
    end)

    key = "bot.device_15.sync.Device.46"

    {:ok, payload} =
      FarmbotCore.JSON.encode(%{
        "id" => 46,
        "args" => %{
          "label" => "thisismylabelinatestsuite"
        },
        "body" => %{name: "This is my bot"}
      })

    pid = generate_pid()
    # We need the process to be preloaded for these tests to work:
    %{preloaded: true} = AutoSyncChannel.network_status(pid)
    send(pid, {:basic_deliver, payload, %{routing_key: key}})

    expect(FarmbotExt.AMQP.AutoSyncAssetHandler, :handle_asset, fn kind, id, body ->
      assert kind == "Device"
      assert id == 46
      assert body == %{"name" => "This is my bot"}
      :ok
    end)

    Helpers.wait_for(pid)
    Process.sleep(1000)
  end
end


Update language for eef slack invite flash message (#283)

* Update language for eef slack invite flash message

 - The intent of this change is set more reasonable expectations around
 how long it could take to process a slack invite for eef slack

Co-authored-by: Paulo F. Oliveira <b16e465d96888ebec7724d89408104847e41662a@gmail.com>

Co-authored-by: Paulo F. Oliveira <b16e465d96888ebec7724d89408104847e41662a@gmail.com>

defmodule ErlefWeb.Members.SlackInviteController do
  use ErlefWeb, :controller

  alias Erlef.Accounts
  alias Erlef.Accounts.Member
  alias Erlef.Admins

  def new(conn, _) do
    render(conn, "new.html")
  end

  def create(conn, _) do
    member = conn.assigns.current_user
    process(conn, member)
  end

  defp process(conn, %Member{has_requested_slack_invite: false} = member) do
    with {:ok, member} <- set_slack_invite_requested(member),
         {:ok, _} <- Admins.notify(:new_slack_invite, %{member: member}) do
      conn
      |> put_flash(:info, success_msg())
      |> redirect(to: Routes.members_profile_path(conn, :show))
    else
      _ ->
        conn
        |> put_flash(:error, "An unknown error occured.")
        |> redirect(to: Routes.members_profile_path(conn, :show))
    end
  end

  defp process(conn, _member) do
    conn
    |> put_flash(:error, "You have already requested an invite to Erlef slack.")
    |> redirect(to: Routes.members_profile_path(conn, :show))
  end

  defp success_msg do
    """
    Your Slack invitation request was successfully created.
    Note: there are humans behind this process and as such it can take up
    to 24 hours to process it.
    """
  end

  defp set_slack_invite_requested(member) do
    attrs = %{has_requested_slack_invite: true, requested_slack_invite_at: DateTime.utc_now()}
    Accounts.update_member(member, attrs)
  end
end

defmodule ErlefWeb.Members.SlackInviteController do
  use ErlefWeb, :controller

  alias Erlef.Accounts
  alias Erlef.Accounts.Member
  alias Erlef.Admins

  def new(conn, _) do
    render(conn, "new.html")
  end

  def create(conn, _) do
    member = conn.assigns.current_user
    process(conn, member)
  end

  defp process(conn, %Member{has_requested_slack_invite: false} = member) do
    with {:ok, member} <- set_slack_invite_requested(member),
         {:ok, _} <- Admins.notify(:new_slack_invite, %{member: member}) do
      conn
      |> put_flash(:info, success_msg())
      |> redirect(to: Routes.members_profile_path(conn, :show))
    else
      _ ->
        conn
        |> put_flash(:error, "An unknown error occured.")
        |> redirect(to: Routes.members_profile_path(conn, :show))
    end
  end

  defp process(conn, _member) do
    conn
    |> put_flash(:error, "You have already requested an invite to Erlef slack.")
    |> redirect(to: Routes.members_profile_path(conn, :show))
  end

  defp success_msg do
    """
    Your slack invite request was successfully created.
    An administrator will process your request as soon as possible.
    """
  end

  defp set_slack_invite_requested(member) do
    attrs = %{has_requested_slack_invite: true, requested_slack_invite_at: DateTime.utc_now()}
    Accounts.update_member(member, attrs)
  end
end


version 0.11.12

version 0.11.12

defmodule Wwwtech.MixProject do
  use Mix.Project

  def project do
    [
      app: :wwwtech,
      version: "0.11.12",
      elixir: "~> 1.7",
      elixirc_paths: elixirc_paths(Mix.env()),
      compilers: [:phoenix, :gettext] ++ Mix.compilers(),
      start_permanent: Mix.env() == :prod,
      aliases: aliases(),
      deps: deps()
    ]
  end

  # Configuration for the OTP application.
  #
  # Type `mix help compile.app` for more information.
  def application do
    [
      mod: {Wwwtech.Application, []},
      extra_applications: [:logger, :runtime_tools, :os_mon]
    ]
  end

  # Specifies which paths to compile per environment.
  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_), do: ["lib"]

  # Specifies your project dependencies.
  #
  # Type `mix help deps` for examples and options.
  defp deps do
    [
      {:phoenix, "~> 1.5.0"},
      {:phoenix_pubsub, "~> 2.0"},
      {:phoenix_ecto, "~> 4.0"},
      {:ecto_sql, "~> 3.1"},
      {:postgrex, ">= 0.0.0"},
      {:phoenix_html, "~> 2.11"},
      {:phoenix_live_reload, "~> 1.2", only: :dev},
      {:gettext, "~> 0.11"},
      {:jason, "~> 1.0"},
      {:plug_cowboy, "~> 2.1"},
      {:argon2_elixir, "~> 2.0"},
      {:timex, "~> 3.5"},
      {:earmark, "~> 1.4"},
      {:xml_builder, "~> 2.1"},
      {:exexif, "~> 0.0.5"},
      {:mogrify, "~> 0.8.0"},
      {:microformats2, "~> 0.1"},
      {:webmentions, "~> 0.3"},
      {:floki, "~> 0.23"},
      {:swoosh, "~> 1.3"},
      {:gen_smtp, "~> 1.1"},
      {:phoenix_swoosh, "~> 0.3"},
      {:appsignal_phoenix, "~> 2.0.0"},
      {:tesla, "~> 1.3"},
      {:hackney, "~> 1.15"},
      {:phoenix_live_dashboard, "~> 0.1"},
      {:telemetry_poller, "~> 0.4"},
      {:telemetry_metrics, "~> 0.4"},
      {:gh_webhook_plug, "~> 0.0.5"}
    ]
  end

  # Aliases are shortcuts or tasks specific to the current project.
  # For example, to create, migrate and run the seeds file at once:
  #
  #     $ mix ecto.setup
  #
  # See the documentation for `Mix` for more info on aliases.
  defp aliases do
    [
      "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
      "ecto.reset": ["ecto.drop", "ecto.setup"],
      test: ["ecto.create --quiet", "ecto.migrate", "test"],
      build: "cmd ./.build/build",
      deploy: "cmd ./.build/deploy"
    ]
  end
end

defmodule Wwwtech.MixProject do
  use Mix.Project

  def project do
    [
      app: :wwwtech,
      version: "0.11.11",
      elixir: "~> 1.7",
      elixirc_paths: elixirc_paths(Mix.env()),
      compilers: [:phoenix, :gettext] ++ Mix.compilers(),
      start_permanent: Mix.env() == :prod,
      aliases: aliases(),
      deps: deps()
    ]
  end

  # Configuration for the OTP application.
  #
  # Type `mix help compile.app` for more information.
  def application do
    [
      mod: {Wwwtech.Application, []},
      extra_applications: [:logger, :runtime_tools, :os_mon]
    ]
  end

  # Specifies which paths to compile per environment.
  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_), do: ["lib"]

  # Specifies your project dependencies.
  #
  # Type `mix help deps` for examples and options.
  defp deps do
    [
      {:phoenix, "~> 1.5.0"},
      {:phoenix_pubsub, "~> 2.0"},
      {:phoenix_ecto, "~> 4.0"},
      {:ecto_sql, "~> 3.1"},
      {:postgrex, ">= 0.0.0"},
      {:phoenix_html, "~> 2.11"},
      {:phoenix_live_reload, "~> 1.2", only: :dev},
      {:gettext, "~> 0.11"},
      {:jason, "~> 1.0"},
      {:plug_cowboy, "~> 2.1"},
      {:argon2_elixir, "~> 2.0"},
      {:timex, "~> 3.5"},
      {:earmark, "~> 1.4"},
      {:xml_builder, "~> 2.1"},
      {:exexif, "~> 0.0.5"},
      {:mogrify, "~> 0.8.0"},
      {:microformats2, "~> 0.1"},
      {:webmentions, "~> 0.3"},
      {:floki, "~> 0.23"},
      {:swoosh, "~> 1.3"},
      {:gen_smtp, "~> 1.1"},
      {:phoenix_swoosh, "~> 0.3"},
      {:appsignal_phoenix, "~> 2.0.0"},
      {:tesla, "~> 1.3"},
      {:hackney, "~> 1.15"},
      {:phoenix_live_dashboard, "~> 0.1"},
      {:telemetry_poller, "~> 0.4"},
      {:telemetry_metrics, "~> 0.4"},
      {:gh_webhook_plug, "~> 0.0.5"}
    ]
  end

  # Aliases are shortcuts or tasks specific to the current project.
  # For example, to create, migrate and run the seeds file at once:
  #
  #     $ mix ecto.setup
  #
  # See the documentation for `Mix` for more info on aliases.
  defp aliases do
    [
      "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
      "ecto.reset": ["ecto.drop", "ecto.setup"],
      test: ["ecto.create --quiet", "ecto.migrate", "test"],
      build: "cmd ./.build/build",
      deploy: "cmd ./.build/deploy"
    ]
  end
end


Seems as good a time as any for v0.0.2

Seems as good a time as any for v0.0.2

defmodule Dogma.Mixfile do
  use Mix.Project

  @version "0.0.2"

  def project do
    [
      app: :dogma,
      version: @version,
      elixir: "~> 1.0",
      deps: deps,
      test_coverage: [tool: ExCoveralls],

      name: "Dogma",
      source_url: "https://github.com/lpil/dogma",
      description: "A code style linter for Elixir, powered by shame.",
      package: [
        contributors: ["Louis Pilfold"],
        licenses: ["MIT"],
        links: %{ "GitHub" => "https://github.com/lpil/dogma" },
        files: ~w(mix.exs lib README.md LICENCE)
      ]
    ]
  end

  def application do
    [applications: [:logger]]
  end

  defp deps do
    [
      {:shouldi, only: :test},
      {:excoveralls, only: [:dev,:test]},
      {:mix_test_watch, "~> 0.1.1", only: :dev},
    ]
  end
end

defmodule Dogma.Mixfile do
  use Mix.Project

  @version "0.0.1"

  def project do
    [
      app: :dogma,
      version: @version,
      elixir: "~> 1.0",
      deps: deps,
      test_coverage: [tool: ExCoveralls],

      name: "Dogma",
      source_url: "https://github.com/lpil/dogma",
      description: "A code style linter for Elixir, powered by shame.",
      package: [
        contributors: ["Louis Pilfold"],
        licenses: ["MIT"],
        links: %{ "GitHub" => "https://github.com/lpil/dogma" },
        files: ~w(mix.exs lib README.md LICENCE)
      ]
    ]
  end

  def application do
    [applications: [:logger]]
  end

  defp deps do
    [
      {:shouldi, only: :test},
      {:excoveralls, only: [:dev,:test]},
      {:mix_test_watch, "~> 0.1.1", only: :dev},
    ]
  end
end


Update mix.exs

Update mix.exs

Revert Elixir to safer 1.7

defmodule DistilleryPackager.Mixfile do
  use Mix.Project

  def project do
    [app: :distillery_packager,
     version: "1.0.7",
     elixir: "~> 1.7",
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     description: description(),
     test_coverage: [tool: ExCoveralls],
     preferred_cli_env: [
       coveralls: :test,
       "coveralls.detail": :test,
       "coveralls.post": :test],
     package: package(),
     deps: deps()]
  end

  # Configuration for the OTP application
  #
  # Type "mix help compile.app" for more information
  def application do
    # Specify extra applications you'll use from Erlang/Elixir
    [extra_applications: [:logger]]
  end

  # Dependencies can be Hex packages:
  #
  #   {:my_dep, "~> 0.3.0"}
  #
  # Or git/path repositories:
  #
  #   {:my_dep, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
  #
  # Type "mix help deps" for more examples and options
  defp deps do
    [
      {:distillery,  "~> 2.1"},
      {:vex,         "~> 0.8"},
      {:timex,       "~> 3.6"},
      {:ex_doc,      "~> 0.21", only: :dev},
      {:credo,       "~> 1.1", only: [:dev, :test], runtime: false},
      {:dogma,       "~> 0.1", only: [:dev, :test], runtime: false},
      {:faker,       "~> 0.12", only: :test},
      {:excoveralls, "~> 0.11", only: :test},
    ]
  end

  defp description do
    """
    Elixir lib for creating Debian and RPM packages with Distillery.
    """
  end

  defp package do
    [name: :distillery_packager,
     files: ["lib", "mix.exs", "README*", "LICENSE*", "templates"],
     maintainers: ["18Months Dev Team <info@18months.it>"],
     licenses: ["MIT"],
     links: %{"GitHub" => "https://github.com/18Months/distillery_packager",
              "Docs" => "https://hexdocs.pm/distillery_packager"}]
  end
end

defmodule DistilleryPackager.Mixfile do
  use Mix.Project

  def project do
    [app: :distillery_packager,
     version: "1.0.7",
     elixir: "~> 1.9",
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     description: description(),
     test_coverage: [tool: ExCoveralls],
     preferred_cli_env: [
       coveralls: :test,
       "coveralls.detail": :test,
       "coveralls.post": :test],
     package: package(),
     deps: deps()]
  end

  # Configuration for the OTP application
  #
  # Type "mix help compile.app" for more information
  def application do
    # Specify extra applications you'll use from Erlang/Elixir
    [extra_applications: [:logger]]
  end

  # Dependencies can be Hex packages:
  #
  #   {:my_dep, "~> 0.3.0"}
  #
  # Or git/path repositories:
  #
  #   {:my_dep, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
  #
  # Type "mix help deps" for more examples and options
  defp deps do
    [
      {:distillery,  "~> 2.1"},
      {:vex,         "~> 0.8"},
      {:timex,       "~> 3.6"},
      {:ex_doc,      "~> 0.21", only: :dev},
      {:credo,       "~> 1.1", only: [:dev, :test], runtime: false},
      {:dogma,       "~> 0.1", only: [:dev, :test], runtime: false},
      {:faker,       "~> 0.12", only: :test},
      {:excoveralls, "~> 0.11", only: :test},
    ]
  end

  defp description do
    """
    Elixir lib for creating Debian and RPM packages with Distillery.
    """
  end

  defp package do
    [name: :distillery_packager,
     files: ["lib", "mix.exs", "README*", "LICENSE*", "templates"],
     maintainers: ["18Months Dev Team <info@18months.it>"],
     licenses: ["MIT"],
     links: %{"GitHub" => "https://github.com/18Months/distillery_packager",
              "Docs" => "https://hexdocs.pm/distillery_packager"}]
  end
end


Increment version [ci skip]

Increment version [ci skip]

defmodule Gateway.Mixfile do
  use Mix.Project

  @version "0.1.1"

  def project do
    [app: :gateway_api,
     version: @version,
     elixir: "~> 1.3",
     elixirc_paths: elixirc_paths(Mix.env),
     compilers: [:phoenix] ++ Mix.compilers,
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     aliases: aliases(),
     deps: deps(),
     test_coverage: [tool: ExCoveralls],
     preferred_cli_env: [coveralls: :test],
     docs: [source_ref: "v#\{@version\}", main: "readme", extras: ["README.md"]]]
  end

  # Configuration for the OTP application
  #
  # Type "mix help compile.app" for more information
  def application do
    [applications: [:logger, :phoenix, :phoenix_ecto, :cowboy, :httpoison, :poison, :corsica,
                    :ecto, :postgrex, :timex, :credit_card, :confex, :eview],
     mod: {Gateway, []}]
  end

  # Specifies which paths to compile per environment.
  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_),     do: ["lib"]

  # Dependencies can be Hex packages:
  #
  #   {:mydep, "~> 0.3.0"}
  #
  # Or git/path repositories:
  #
  #   {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"}
  #
  # To depend on another app inside the umbrella:
  #
  #   {:myapp, in_umbrella: true}
  #
  # Type "mix help deps" for more examples and options
  defp deps do
    [{:distillery, "~> 1.0"},
     {:phoenix, "~> 1.2"},
     {:phoenix_ecto, "3.1.0"},
     {:ecto, "2.1.0"},
     {:postgrex, "~> 0.13.0"},
     {:confex, "~> 1.4"},
     {:eview, "~> 0.8.0"},
     {:cowboy, "~> 1.0"},
     {:poison, "~> 3.0", override: true}, # TODO: Update when Phoenix 1.3 will be released
     {:httpoison, "~> 0.10"},
     {:credit_card, "~> 1.0"},
     {:timex, "~> 3.0"},
     {:corsica, "~> 0.5"},
     {:excoveralls, "~> 0.5", only: [:dev, :test]},
     {:dogma, "> 0.1.0", only: [:dev, :test]},
     {:credo, ">= 0.4.12", only: [:dev, :test]}]
  end

  # Aliases are shortcuts or tasks specific to the current project.
  # For example, to create, migrate and run the seeds file at once:
  #
  #     $ mix ecto.setup
  #
  # See the documentation for `Mix` for more info on aliases.
  defp aliases do
    ["ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
     "ecto.reset": ["ecto.drop", "ecto.setup"],
     "test":       ["ecto.create --quiet", "ecto.migrate", "test"]]
  end
end

defmodule Gateway.Mixfile do
  use Mix.Project

  @version "0.1.0"

  def project do
    [app: :gateway_api,
     version: @version,
     elixir: "~> 1.3",
     elixirc_paths: elixirc_paths(Mix.env),
     compilers: [:phoenix] ++ Mix.compilers,
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     aliases: aliases(),
     deps: deps(),
     test_coverage: [tool: ExCoveralls],
     preferred_cli_env: [coveralls: :test],
     docs: [source_ref: "v#\{@version\}", main: "readme", extras: ["README.md"]]]
  end

  # Configuration for the OTP application
  #
  # Type "mix help compile.app" for more information
  def application do
    [applications: [:logger, :phoenix, :phoenix_ecto, :cowboy, :httpoison, :poison, :corsica,
                    :ecto, :postgrex, :timex, :credit_card, :confex, :eview],
     mod: {Gateway, []}]
  end

  # Specifies which paths to compile per environment.
  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_),     do: ["lib"]

  # Dependencies can be Hex packages:
  #
  #   {:mydep, "~> 0.3.0"}
  #
  # Or git/path repositories:
  #
  #   {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"}
  #
  # To depend on another app inside the umbrella:
  #
  #   {:myapp, in_umbrella: true}
  #
  # Type "mix help deps" for more examples and options
  defp deps do
    [{:distillery, "~> 1.0"},
     {:phoenix, "~> 1.2"},
     {:phoenix_ecto, "3.1.0"},
     {:ecto, "2.1.0"},
     {:postgrex, "~> 0.13.0"},
     {:confex, "~> 1.4"},
     {:eview, "~> 0.8.0"},
     {:cowboy, "~> 1.0"},
     {:poison, "~> 3.0", override: true}, # TODO: Update when Phoenix 1.3 will be released
     {:httpoison, "~> 0.10"},
     {:credit_card, "~> 1.0"},
     {:timex, "~> 3.0"},
     {:corsica, "~> 0.5"},
     {:excoveralls, "~> 0.5", only: [:dev, :test]},
     {:dogma, "> 0.1.0", only: [:dev, :test]},
     {:credo, ">= 0.4.12", only: [:dev, :test]}]
  end

  # Aliases are shortcuts or tasks specific to the current project.
  # For example, to create, migrate and run the seeds file at once:
  #
  #     $ mix ecto.setup
  #
  # See the documentation for `Mix` for more info on aliases.
  defp aliases do
    ["ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
     "ecto.reset": ["ecto.drop", "ecto.setup"],
     "test":       ["ecto.create --quiet", "ecto.migrate", "test"]]
  end
end


version bump d(⌒ー⌒)

version bump d(⌒ー⌒)

defmodule Glasnost.Mixfile do
  use Mix.Project

  def project do
    [app: :glasnost,
     version: "0.10.0",
     elixir: "~> 1.4",
     elixirc_paths: elixirc_paths(Mix.env),
     compilers: [:phoenix, :gettext] ++ Mix.compilers,
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     aliases: aliases(),
     deps: deps()]
  end

  # Configuration for the OTP application.
  #
  # Type `mix help compile.app` for more information.
  def application do
    [mod: {Glasnost.Application, []},
     extra_applications: [:logger, :ex_golos]]
  end

  # Specifies which paths to compile per environment.
  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_),     do: ["lib"]

  # Specifies your project dependencies.
  #
  # Type `mix help deps` for examples and options.
  defp deps do
    [{:phoenix, "1.3.0-rc.1", override: true},
     {:phoenix_pubsub, "~> 1.0"},
     {:phoenix_ecto, "~> 3.2"},
     {:postgrex, ">= 0.0.0"},
     {:phoenix_html, "~> 2.6"},
     {:phoenix_live_reload, "~> 1.0", only: :dev},
     {:gettext, "~> 0.11"},
     {:ex_golos, ">= 0.5.0"},
     {:steemex, ">= 0.0.0"},
     {:expug, ">= 0.0.0"},
     {:phoenix_expug, ">= 0.0.0"},
     {:calendar, ">= 0.16.0"},
     {:ecto_mnesia, "~> 0.7.1"},
     {:distillery, ">= 0.0.0"},
     {:httpoison, ">= 0.0.0"},
     {:hound, ">= 0.0.0"},
     {:con_cache, "~> 0.12.0"},
     {:cowboy, "~> 1.0"},
     {:floki, ">= 0.0.0"},
     {:credo, ">= 0.0.0", only: :dev},
     {:earmark, ">= 0.0.0"}]
  end

  # Aliases are shortcuts or tasks specific to the current project.
  # For example, to create, migrate and run the seeds file at once:
  #
  #     $ mix ecto.setup
  #
  # See the documentation for `Mix` for more info on aliases.
  defp aliases do
    ["ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
     "ecto.reset": ["ecto.drop", "ecto.setup"],
     "test": ["ecto.create --quiet", "ecto.migrate", "test"]]
  end
end

defmodule Glasnost.Mixfile do
  use Mix.Project

  def project do
    [app: :glasnost,
     version: "0.9.0",
     elixir: "~> 1.4",
     elixirc_paths: elixirc_paths(Mix.env),
     compilers: [:phoenix, :gettext] ++ Mix.compilers,
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     aliases: aliases(),
     deps: deps()]
  end

  # Configuration for the OTP application.
  #
  # Type `mix help compile.app` for more information.
  def application do
    [mod: {Glasnost.Application, []},
     extra_applications: [:logger, :ex_golos]]
  end

  # Specifies which paths to compile per environment.
  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_),     do: ["lib"]

  # Specifies your project dependencies.
  #
  # Type `mix help deps` for examples and options.
  defp deps do
    [{:phoenix, "1.3.0-rc.1", override: true},
     {:phoenix_pubsub, "~> 1.0"},
     {:phoenix_ecto, "~> 3.2"},
     {:postgrex, ">= 0.0.0"},
     {:phoenix_html, "~> 2.6"},
     {:phoenix_live_reload, "~> 1.0", only: :dev},
     {:gettext, "~> 0.11"},
     {:ex_golos, ">= 0.5.0"},
     {:steemex, ">= 0.0.0"},
     {:expug, ">= 0.0.0"},
     {:phoenix_expug, ">= 0.0.0"},
     {:calendar, ">= 0.16.0"},
     {:ecto_mnesia, "~> 0.7.1"},
     {:distillery, ">= 0.0.0"},
     {:httpoison, ">= 0.0.0"},
     {:hound, ">= 0.0.0"},
     {:con_cache, "~> 0.12.0"},
     {:cowboy, "~> 1.0"},
     {:floki, ">= 0.0.0"},
     {:credo, ">= 0.0.0", only: :dev},
     {:earmark, ">= 0.0.0"}]
  end

  # Aliases are shortcuts or tasks specific to the current project.
  # For example, to create, migrate and run the seeds file at once:
  #
  #     $ mix ecto.setup
  #
  # See the documentation for `Mix` for more info on aliases.
  defp aliases do
    ["ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
     "ecto.reset": ["ecto.drop", "ecto.setup"],
     "test": ["ecto.create --quiet", "ecto.migrate", "test"]]
  end
end


Update version

Update version

defmodule Xema.Mixfile do
  use Mix.Project

  def project do
    [
      app: :xema,
      version: "0.13.3",
      elixir: "~> 1.7",
      build_embedded: Mix.env() == :prod,
      start_permanent: Mix.env() == :prod,
      deps: deps(),
      description: description(),
      package: package(),
      elixirc_paths: elixirc_paths(Mix.env()),
      source_url: "https://github.com/hrzndhrn/xema",
      aliases: aliases(),

      # Coveralls
      test_coverage: [tool: ExCoveralls],
      preferred_cli_env: [
        carp: :test,
        coveralls: :test,
        "coveralls.detail": :test,
        "coveralls.post": :test,
        "coveralls.travis": :test,
        "coveralls.html": :test,
        "gen.test_suite": :test
      ],

      # Docs
      docs: [
        extras: [
          "docs/readme.md",
          "docs/usage.md",
          "docs/cast.md",
          "docs/loader.md",
          "docs/examples.md",
          "docs/unsupported.md",
          "CHANGELOG.md"
        ],
        main: "readme"
      ],

      # Dialyzer
      dialyzer: [
        ignore_warnings: ".dialyzer_ignore.exs",
        plt_add_apps: [:decimal],
        plt_file: {:no_warn, "test/support/plts/dialyzer.plt"}
      ]
    ]
  end

  defp description() do
    "A schema validator inspired by JSON Schema."
  end

  def application do
    [extra_applications: [:logger], env: [loader: Xema.NoLoader]]
  end

  defp deps do
    [
      {:benchee, "~> 1.0", only: :dev, runtime: false},
      {:conv_case, "~> 0.2.2"},
      {:cowboy, "== 2.7.0", only: :test},
      {:credo, "~> 1.1", only: [:dev, :test], runtime: false},
      {:decimal, "~> 2.0", optional: true},
      {:dialyxir, "~> 1.0", only: :dev, runtime: false},
      {:elixir_uuid, "~> 1.2", only: [:dev, :test]},
      {:ex_doc, "~> 0.19", only: :dev, runtime: false},
      {:excoveralls, "~> 0.10", only: :test},
      {:jason, "~> 1.1", only: [:dev, :test]},
      {:httpoison, "== 1.6.2", only: :test}
    ]
  end

  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_), do: ["lib"]

  defp aliases do
    [carp: "test --seed 0 --max-failures 1 --trace"]
  end

  defp package do
    [
      maintainers: ["Marcus Kruse"],
      licenses: ["MIT"],
      links: %{"GitHub" => "https://github.com/hrzndhrn/xema"},
      files: [
        "lib",
        "mix.exs",
        "README*",
        "LICENSE*",
        "docs/readme.md",
        "docs/usage.md",
        "docs/loader.md",
        "docs/unsupported.md"
      ]
    ]
  end
end

defmodule Xema.Mixfile do
  use Mix.Project

  def project do
    [
      app: :xema,
      version: "0.13.2",
      elixir: "~> 1.7",
      build_embedded: Mix.env() == :prod,
      start_permanent: Mix.env() == :prod,
      deps: deps(),
      description: description(),
      package: package(),
      elixirc_paths: elixirc_paths(Mix.env()),
      source_url: "https://github.com/hrzndhrn/xema",
      aliases: aliases(),

      # Coveralls
      test_coverage: [tool: ExCoveralls],
      preferred_cli_env: [
        carp: :test,
        coveralls: :test,
        "coveralls.detail": :test,
        "coveralls.post": :test,
        "coveralls.travis": :test,
        "coveralls.html": :test,
        "gen.test_suite": :test
      ],

      # Docs
      docs: [
        extras: [
          "docs/readme.md",
          "docs/usage.md",
          "docs/cast.md",
          "docs/loader.md",
          "docs/examples.md",
          "docs/unsupported.md",
          "CHANGELOG.md"
        ],
        main: "readme"
      ],

      # Dialyzer
      dialyzer: [
        ignore_warnings: ".dialyzer_ignore.exs",
        plt_add_apps: [:decimal],
        plt_file: {:no_warn, "test/support/plts/dialyzer.plt"}
      ]
    ]
  end

  defp description() do
    "A schema validator inspired by JSON Schema."
  end

  def application do
    [extra_applications: [:logger], env: [loader: Xema.NoLoader]]
  end

  defp deps do
    [
      {:benchee, "~> 1.0", only: :dev, runtime: false},
      {:conv_case, "~> 0.2.2"},
      {:cowboy, "== 2.7.0", only: :test},
      {:credo, "~> 1.1", only: [:dev, :test], runtime: false},
      {:decimal, "~> 2.0", optional: true},
      {:dialyxir, "~> 1.0", only: :dev, runtime: false},
      {:elixir_uuid, "~> 1.2", only: [:dev, :test]},
      {:ex_doc, "~> 0.19", only: :dev, runtime: false},
      {:excoveralls, "~> 0.10", only: :test},
      {:jason, "~> 1.1", only: [:dev, :test]},
      {:httpoison, "== 1.6.2", only: :test}
    ]
  end

  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_), do: ["lib"]

  defp aliases do
    [carp: "test --seed 0 --max-failures 1 --trace"]
  end

  defp package do
    [
      maintainers: ["Marcus Kruse"],
      licenses: ["MIT"],
      links: %{"GitHub" => "https://github.com/hrzndhrn/xema"},
      files: [
        "lib",
        "mix.exs",
        "README*",
        "LICENSE*",
        "docs/readme.md",
        "docs/usage.md",
        "docs/loader.md",
        "docs/unsupported.md"
      ]
    ]
  end
end


Bump version to `0.3.0`

Bump version to `0.3.0`

defmodule Pixie.Mixfile do
  use Mix.Project

  def project do
    [
      app:               :pixie,
      version:           "0.3.0",
      elixir:            "~> 1.0",
      build_embedded:    Mix.env == :prod,
      start_permanent:   Mix.env == :prod,
      deps:              deps,
      preferred_cli_env: [espec: :test],
      package:           package,
      description:       description,
      source_url:        "https://github.com/messagerocket/pixie"
    ]
  end

  defp package do
    [
      maintainers: ["James Harton"],
      licenses: ["MIT"],
      links: %{
        "bitbucket"     => "https://bitbucket.org/messagerocket/pixie",
        "messagerocket" => "https://messagerocket.co/",
        "github"        => "https://github.com/messagerocket/pixie"
      }
    ]
  end

  defp description do
    """
    Bayeux compatible server written in Elixir.
    """
  end

  def application do
    [
      applications: [:logger, :crypto, :cowboy, :plug, :gproc, :con_cache, :tzdata],
      mod: {Pixie, []}
    ]
  end

  defp deps do
    [
      {:cowboy,        "~> 1.0.2", optional: true},
      {:poison,        "~> 1.4.0"},
      {:secure_random, "~> 0.1"},
      {:ex_minimatch,  "~> 0.0.1"},
      {:timex,         "~> 0.19.2"},
      {:espec,         "~> 0.7.0", only: :test},
      {:plug,          "~> 1.0.0"},
      {:exredis,       "~> 0.2.0", optional: true},
      {:poolboy,       "~> 1.5.1"},
      {:ex_doc,        "~> 0.8.4", optional: true},
      {:gproc,         "~> 0.3.1"},
      {:con_cache,     "~> 0.9.0"}
    ]
  end
end

defmodule Pixie.Mixfile do
  use Mix.Project

  def project do
    [
      app:               :pixie,
      version:           "0.2.3",
      elixir:            "~> 1.0",
      build_embedded:    Mix.env == :prod,
      start_permanent:   Mix.env == :prod,
      deps:              deps,
      preferred_cli_env: [espec: :test],
      package:           package,
      description:       description,
      source_url:        "https://github.com/messagerocket/pixie"
    ]
  end

  defp package do
    [
      maintainers: ["James Harton"],
      licenses: ["MIT"],
      links: %{
        "bitbucket"     => "https://bitbucket.org/messagerocket/pixie",
        "messagerocket" => "https://messagerocket.co/",
        "github"        => "https://github.com/messagerocket/pixie"
      }
    ]
  end

  defp description do
    """
    Bayeux compatible server written in Elixir.
    """
  end

  def application do
    [
      applications: [:logger, :crypto, :cowboy, :plug, :gproc, :con_cache, :tzdata],
      mod: {Pixie, []}
    ]
  end

  defp deps do
    [
      {:cowboy,        "~> 1.0.2", optional: true},
      {:poison,        "~> 1.4.0"},
      {:secure_random, "~> 0.1"},
      {:ex_minimatch,  "~> 0.0.1"},
      {:timex,         "~> 0.19.2"},
      {:espec,         "~> 0.7.0", only: :test},
      {:plug,          "~> 1.0.0"},
      {:exredis,       "~> 0.2.0", optional: true},
      {:poolboy,       "~> 1.5.1"},
      {:ex_doc,        "~> 0.8.4", optional: true},
      {:gproc,         "~> 0.3.1"},
      {:con_cache,     "~> 0.9.0"}
    ]
  end
end


Only depend on credo in :dev

Only depend on credo in :dev

Credo breaks the CI build on Elixir ~> 1.3.0. Since we're not currently
using it in the test suite, we'll only depend on it in the :dev
environment for now.

defmodule Mix.Tasks.Compile.Appsignal do
  use Mix.Task

  def run(_args) do
    {_, _} = Code.eval_file("mix_helpers.exs")

    case Mix.Appsignal.Helper.verify_system_architecture() do
      {:ok, arch} ->
        case Mix.Appsignal.Helper.ensure_downloaded(arch) do
          :ok ->
            :ok = Mix.Appsignal.Helper.compile()
            :ok = Mix.Appsignal.Helper.store_architecture(arch)

          {:error, _reason} ->
            Mix.Shell.IO.error(
              "Failed to download AppSignal agent. AppSignal integration disabled!"
            )
        end

      {:error, {:unsupported, arch}} ->
        Mix.Shell.IO.error(
          "Unsupported target platform #{arch}, AppSignal integration " <>
            "disabled!\nPlease check " <>
            "http://docs.appsignal.com/support/operating-systems.html"
        )

        :ok = Mix.Appsignal.Helper.store_architecture(arch)

      {:error, {:unknown, {arch, platform}}} ->
        Mix.Shell.IO.error(
          "Unknown target platform #{arch} - #{platform}, AppSignal " <>
            "integration disabled!\nPlease check " <>
            "http://docs.appsignal.com/support/operating-systems.html"
        )

        :ok = Mix.Appsignal.Helper.store_architecture(arch)
    end
  end
end

defmodule Appsignal.Mixfile do
  use Mix.Project

  def project do
    [
      app: :appsignal,
      version: "1.9.1-beta.1",
      name: "AppSignal",
      description: description(),
      package: package(),
      source_url: "https://github.com/appsignal/appsignal-elixir",
      homepage_url: "https://appsignal.com",
      test_paths: test_paths(Mix.env()),
      elixir: "~> 1.0",
      compilers: compilers(Mix.env()),
      elixirc_paths: elixirc_paths(Mix.env()),
      deps: deps(),
      docs: [main: "Appsignal", logo: "logo.png"],
      dialyzer: [
        plt_add_deps: :transitive,
        plt_add_apps: [:mix],
        ignore_warnings: "dialyzer.ignore-warnings"
      ]
    ]
  end

  defp description do
    "Collects error and performance data from your Elixir applications and sends it to AppSignal"
  end

  defp package do
    %{
      files: [
        "lib",
        "c_src/*.[ch]",
        "mix.exs",
        "mix_helpers.exs",
        "*.md",
        "LICENSE",
        "Makefile",
        "agent.exs",
        "priv/cacert.pem"
      ],
      maintainers: ["Jeff Kreeftmeijer", "Tom de Bruijn"],
      licenses: ["MIT"],
      links: %{"GitHub" => "https://github.com/appsignal/appsignal-elixir"}
    }
  end

  def application do
    [mod: {Appsignal, []}, applications: [:logger, :decorator, :hackney, :poison]]
  end

  defp compilers(:test_phoenix), do: [:phoenix] ++ compilers(:prod)
  defp compilers(_), do: [:appsignal] ++ Mix.compilers()

  defp test_paths(:test_phoenix), do: ["test/appsignal", "test/mix", "test/phoenix"]
  defp test_paths(_), do: ["test/appsignal", "test/mix"]

  defp elixirc_paths(env) do
    case test?(env) do
      true -> ["lib", "test/support"]
      false -> ["lib"]
    end
  end

  defp test?(:test), do: true
  defp test?(:test_phoenix), do: true
  defp test?(:test_no_nif), do: true
  defp test?(_), do: false

  defp deps do
    poison_version =
      case Version.compare(System.version(), "1.6.0") do
        :lt -> ">= 1.3.0 and < 4.0.0"
        _ -> ">= 1.3.0"
      end

    [
      {:hackney, "~> 1.6"},
      {:poison, poison_version},
      {:decorator, "~> 1.2.3"},
      {:plug, ">= 1.1.0", optional: true},
      {:phoenix, ">= 1.2.0", optional: true, only: [:prod, :test_phoenix, :dev]},
      {:mock, "~> 0.3.0", only: [:test, :test_phoenix, :test_no_nif]},
      {:bypass, "~> 0.6.0", only: [:test, :test_phoenix, :test_no_nif]},
      {:plug_cowboy, "~> 1.0", only: [:test, :test_phoenix, :test_no_nif]},
      {:ex_doc, "~> 0.12", only: :dev, runtime: false},
      {:credo, "~> 1.0.0", only: :dev, runtime: false},
      {:dialyxir, "~> 0.5", only: [:dev], runtime: false}
    ]
  end
end

defmodule Mix.Tasks.Compile.Appsignal do
  use Mix.Task

  def run(_args) do
    {_, _} = Code.eval_file("mix_helpers.exs")

    case Mix.Appsignal.Helper.verify_system_architecture() do
      {:ok, arch} ->
        case Mix.Appsignal.Helper.ensure_downloaded(arch) do
          :ok ->
            :ok = Mix.Appsignal.Helper.compile()
            :ok = Mix.Appsignal.Helper.store_architecture(arch)

          {:error, _reason} ->
            Mix.Shell.IO.error(
              "Failed to download AppSignal agent. AppSignal integration disabled!"
            )
        end

      {:error, {:unsupported, arch}} ->
        Mix.Shell.IO.error(
          "Unsupported target platform #{arch}, AppSignal integration " <>
            "disabled!\nPlease check " <>
            "http://docs.appsignal.com/support/operating-systems.html"
        )

        :ok = Mix.Appsignal.Helper.store_architecture(arch)

      {:error, {:unknown, {arch, platform}}} ->
        Mix.Shell.IO.error(
          "Unknown target platform #{arch} - #{platform}, AppSignal " <>
            "integration disabled!\nPlease check " <>
            "http://docs.appsignal.com/support/operating-systems.html"
        )

        :ok = Mix.Appsignal.Helper.store_architecture(arch)
    end
  end
end

defmodule Appsignal.Mixfile do
  use Mix.Project

  def project do
    [
      app: :appsignal,
      version: "1.9.1-beta.1",
      name: "AppSignal",
      description: description(),
      package: package(),
      source_url: "https://github.com/appsignal/appsignal-elixir",
      homepage_url: "https://appsignal.com",
      test_paths: test_paths(Mix.env()),
      elixir: "~> 1.0",
      compilers: compilers(Mix.env()),
      elixirc_paths: elixirc_paths(Mix.env()),
      deps: deps(),
      docs: [main: "Appsignal", logo: "logo.png"],
      dialyzer: [
        plt_add_deps: :transitive,
        plt_add_apps: [:mix],
        ignore_warnings: "dialyzer.ignore-warnings"
      ]
    ]
  end

  defp description do
    "Collects error and performance data from your Elixir applications and sends it to AppSignal"
  end

  defp package do
    %{
      files: [
        "lib",
        "c_src/*.[ch]",
        "mix.exs",
        "mix_helpers.exs",
        "*.md",
        "LICENSE",
        "Makefile",
        "agent.exs",
        "priv/cacert.pem"
      ],
      maintainers: ["Jeff Kreeftmeijer", "Tom de Bruijn"],
      licenses: ["MIT"],
      links: %{"GitHub" => "https://github.com/appsignal/appsignal-elixir"}
    }
  end

  def application do
    [mod: {Appsignal, []}, applications: [:logger, :decorator, :hackney, :poison]]
  end

  defp compilers(:test_phoenix), do: [:phoenix] ++ compilers(:prod)
  defp compilers(_), do: [:appsignal] ++ Mix.compilers()

  defp test_paths(:test_phoenix), do: ["test/appsignal", "test/mix", "test/phoenix"]
  defp test_paths(_), do: ["test/appsignal", "test/mix"]

  defp elixirc_paths(env) do
    case test?(env) do
      true -> ["lib", "test/support"]
      false -> ["lib"]
    end
  end

  defp test?(:test), do: true
  defp test?(:test_phoenix), do: true
  defp test?(:test_no_nif), do: true
  defp test?(_), do: false

  defp deps do
    poison_version =
      case Version.compare(System.version(), "1.6.0") do
        :lt -> ">= 1.3.0 and < 4.0.0"
        _ -> ">= 1.3.0"
      end

    [
      {:hackney, "~> 1.6"},
      {:poison, poison_version},
      {:decorator, "~> 1.2.3"},
      {:plug, ">= 1.1.0", optional: true},
      {:phoenix, ">= 1.2.0", optional: true, only: [:prod, :test_phoenix, :dev]},
      {:mock, "~> 0.3.0", only: [:test, :test_phoenix, :test_no_nif]},
      {:bypass, "~> 0.6.0", only: [:test, :test_phoenix, :test_no_nif]},
      {:plug_cowboy, "~> 1.0", only: [:test, :test_phoenix, :test_no_nif]},
      {:ex_doc, "~> 0.12", only: :dev, runtime: false},
      {:credo, "~> 1.0.0", only: [:dev, :test], runtime: false},
      {:dialyxir, "~> 0.5", only: [:dev], runtime: false}
    ]
  end
end


fix compiler warning

fix compiler warning

defmodule Breadcrumble.Mixfile do
  use Mix.Project

  def project do
    [app: :breadcrumble,
     version: "1.0.2",
     elixir: "~> 1.0",
     description: "Elixir port of Breadcrumble library",
     package: [
       maintainers: ["Takayuki Matsubara"],
       licenses: ["MIT"],
       links: %{"GitHub" => "https://github.com/ma2gedev/breadcrumble_ex"}
     ],
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     deps: deps()]
  end

  # Configuration for the OTP application
  #
  # Type `mix help compile.app` for more information
  def application do
    [applications: [:logger]]
  end

  # Dependencies can be Hex packages:
  #
  #   {:mydep, "~> 0.3.0"}
  #
  # Or git/path repositories:
  #
  #   {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"}
  #
  # Type `mix help deps` for more examples and options
  defp deps do
    [{:plug, ">= 0.12.0 and < 2.0.0"},
     {:power_assert, "~> 0.0.1", only: :test}]
  end
end

defmodule Breadcrumble.Mixfile do
  use Mix.Project

  def project do
    [app: :breadcrumble,
     version: "1.0.2",
     elixir: "~> 1.0",
     description: "Elixir port of Breadcrumble library",
     package: [
       maintainers: ["Takayuki Matsubara"],
       licenses: ["MIT"],
       links: %{"GitHub" => "https://github.com/ma2gedev/breadcrumble_ex"}
     ],
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     deps: deps]
  end

  # Configuration for the OTP application
  #
  # Type `mix help compile.app` for more information
  def application do
    [applications: [:logger]]
  end

  # Dependencies can be Hex packages:
  #
  #   {:mydep, "~> 0.3.0"}
  #
  # Or git/path repositories:
  #
  #   {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"}
  #
  # Type `mix help deps` for more examples and options
  defp deps do
    [{:plug, ">= 0.12.0 and < 2.0.0"},
     {:power_assert, "~> 0.0.1", only: :test}]
  end
end


Add default env to coveralls.json

Add default env to coveralls.json

defmodule Guardian.DB.Mixfile do
  use Mix.Project

  @version "2.0.0"
  @source_url "https://github.com/ueberauth/guardian_db"

  def project do
    [
      name: "Guardian.DB",
      app: :guardian_db,
      version: @version,
      description: "DB tracking for token validity",
      elixir: "~> 1.4 or ~> 1.5",
      elixirc_paths: elixirc_paths(Mix.env()),
      package: package(),
      docs: docs(),
      build_embedded: Mix.env() == :prod,
      start_permanent: Mix.env() == :prod,
      aliases: aliases(),
      deps: deps(),
      test_coverage: [tool: ExCoveralls],
      preferred_cli_env: [
        coveralls: :test,
        "coveralls.html": :test,
        "coveralls.json": :test
      ]
    ]
  end

  def application do
    [extra_applications: [:logger]]
  end

  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_), do: ["lib"]

  defp deps do
    [
      {:guardian, "~> 1.0"},
      {:ecto, "~> 3.0"},
      {:ecto_sql, "~> 3.0.0"},
      {:postgrex, "~> 0.13", optional: true},

      # Tools
      {:dialyxir, ">= 0.0.0", only: [:dev], runtime: false},
      {:credo, ">= 0.0.0", only: [:dev, :test], runtime: false},
      {:excoveralls, ">= 0.0.0", only: [:test], runtime: false},
      {:ex_doc, ">= 0.0.0", only: [:dev], runtime: false},
      {:inch_ex, ">= 0.0.0", only: [:dev], runtime: false}
    ]
  end

  defp package do
    [
      maintainers: ["Daniel Neighman", "Sean Callan", "Sonny Scroggin"],
      licenses: ["MIT"],
      links: %{GitHub: @source_url},
      files: [
        "lib",
        "CHANGELOG.md",
        "LICENSE",
        "mix.exs",
        "README.md",
        "priv/templates"
      ]
    ]
  end

  defp docs do
    [
      main: "readme",
      homepage_url: @source_url,
      source_ref: "v#{@version}",
      source_url: @source_url,
      extras: ["README.md"]
    ]
  end

  defp aliases do
    [
      test: [
        "ecto.drop --quiet",
        "ecto.create --quiet",
        "guardian.db.gen.migration",
        "ecto.migrate",
        "test"
      ]
    ]
  end
end

defmodule Guardian.DB.Mixfile do
  use Mix.Project

  @version "2.0.0"
  @source_url "https://github.com/ueberauth/guardian_db"

  def project do
    [
      name: "Guardian.DB",
      app: :guardian_db,
      version: @version,
      description: "DB tracking for token validity",
      elixir: "~> 1.4 or ~> 1.5",
      elixirc_paths: elixirc_paths(Mix.env()),
      package: package(),
      docs: docs(),
      build_embedded: Mix.env() == :prod,
      start_permanent: Mix.env() == :prod,
      aliases: aliases(),
      deps: deps(),
      test_coverage: [tool: ExCoveralls],
      preferred_cli_env: [
        coveralls: :test,
        "coveralls.html": :test
      ]
    ]
  end

  def application do
    [extra_applications: [:logger]]
  end

  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_), do: ["lib"]

  defp deps do
    [
      {:guardian, "~> 1.0"},
      {:ecto, "~> 3.0"},
      {:ecto_sql, "~> 3.0.0"},
      {:postgrex, "~> 0.13", optional: true},

      # Tools
      {:dialyxir, ">= 0.0.0", only: [:dev], runtime: false},
      {:credo, ">= 0.0.0", only: [:dev, :test], runtime: false},
      {:excoveralls, ">= 0.0.0", only: [:test], runtime: false},
      {:ex_doc, ">= 0.0.0", only: [:dev], runtime: false},
      {:inch_ex, ">= 0.0.0", only: [:dev], runtime: false}
    ]
  end

  defp package do
    [
      maintainers: ["Daniel Neighman", "Sean Callan", "Sonny Scroggin"],
      licenses: ["MIT"],
      links: %{GitHub: @source_url},
      files: [
        "lib",
        "CHANGELOG.md",
        "LICENSE",
        "mix.exs",
        "README.md",
        "priv/templates"
      ]
    ]
  end

  defp docs do
    [
      main: "readme",
      homepage_url: @source_url,
      source_ref: "v#{@version}",
      source_url: @source_url,
      extras: ["README.md"]
    ]
  end

  defp aliases do
    [
      test: [
        "ecto.drop --quiet",
        "ecto.create --quiet",
        "guardian.db.gen.migration",
        "ecto.migrate",
        "test"
      ]
    ]
  end
end


Fix mix deps

Fix mix deps

defmodule Elixre.Mixfile do
  use Mix.Project

  def project do
    [app: :elixre,
     version: "0.0.1",
     elixir: "~> 1.0",
     elixirc_paths: ["lib", "web"],
     compilers: [:phoenix] ++ Mix.compilers,
     deps: deps]
  end

  # Configuration for the OTP application
  #
  # Type `mix help compile.app` for more information
  def application do
    [
      mod: {Elixre, []},
      applications: applications(Mix.env),
   ]
  end

  defp applications(_) do
    ~w(phoenix cowboy logger)a
  end

  # Specifies your project dependencies
  #
  # Type `mix help deps` for examples and options
  defp deps do
    [
      # Web app framework
      {:phoenix, "~> 1.0"},
      # Our app renders HTML
      {:phoenix_html, "~> 1.0"},
      # Reload web code in development
      {:phoenix_live_reload, "~> 1.0", only: :dev},
      # Web server
      {:cowboy, "~> 1.0"},

      # Test framework
      {:shouldi, "~> 0.2", only: :test},
      # Code linter
      {:dogma, "~> 0.0", only: ~w(dev test)a},
      # Automatically run tests on file changes
      {:mix_test_watch, "~> 0.0", only: :dev},
    ]
  end
end

defmodule Elixre.Mixfile do
  use Mix.Project

  def project do
    [app: :elixre,
     version: "0.0.1",
     elixir: "~> 1.0",
     elixirc_paths: ["lib", "web"],
     compilers: [:phoenix] ++ Mix.compilers,
     deps: deps]
  end

  # Configuration for the OTP application
  #
  # Type `mix help compile.app` for more information
  def application do
    [
      mod: {Elixre, []},
      applications: applications(Mix.env),
   ]
  end

  defp applications(_) do
    ~w(phoenix cowboy logger)a
  end

  # Specifies your project dependencies
  #
  # Type `mix help deps` for examples and options
  defp deps do
    [
      # Web app framework
      {:phoenix, "~> 1.0"},
      # Our app renders HTML
      {:phoenix_html, "~> 1.0"},
      # Reload web code in development
      {:phoenix_live_reload, "~> 1.0", only: :dev},
      # Web server
      {:cowboy, "~> 1.0"},

      # Test framework
      {:shouldi, "~> 0.2", only: :test},
      # Code linter
      {:dogma, ">= 0.0", only: ~w(dev test)a},
      # Automatically run tests on file changes
      {:mix_test_watch, ">= 0.0", only: :dev},
    ]
  end
end


Use README as docs start page

Use README as docs start page

defmodule ParallelStream.Mixfile do
  use Mix.Project

  def project do
    [
      app: :parallel_stream,
      version: "1.1.0",
      elixir: "~> 1.5",
      deps: deps(),
      package: package(),
      docs: &docs/0,
      name: "Parallel Stream",
      consolidate_protocols: true,
      source_url: "https://github.com/beatrichartz/parallel_stream",
      description: "Parallel stream operations for Elixir",
      test_coverage: [tool: ExCoveralls],
      preferred_cli_env: [coveralls: :test, "coveralls.detail": :test, "coveralls.post": :test]
    ]
  end

  defp package do
    [
      maintainers: ["Beat Richartz"],
      licenses: ["MIT"],
      links: %{github: "https://github.com/beatrichartz/parallel_stream"}
    ]
  end

  defp deps do
    [
      {:excoveralls, "~> 0.5", only: :test},
      {:ex_doc, only: :dev},
      {:inch_ex, only: :dev},
      {:earmark, "1.4.15", only: :dev},
      {:benchfella, "~> 0.3.0", only: [:bench]}
    ]
  end

  defp docs do
    {ref, 0} = System.cmd("git", ["rev-parse", "--verify", "--quiet", "HEAD"])

    [
      source_ref: ref,
      extras: ["README.md"],
      main: "readme"
    ]
  end
end

defmodule ParallelStream.Mixfile do
  use Mix.Project

  def project do
    [
      app: :parallel_stream,
      version: "1.1.0",
      elixir: "~> 1.5",
      deps: deps(),
      package: package(),
      docs: &docs/0,
      name: "Parallel Stream",
      consolidate_protocols: true,
      source_url: "https://github.com/beatrichartz/parallel_stream",
      description: "Parallel stream operations for Elixir",
      test_coverage: [tool: ExCoveralls],
      preferred_cli_env: [coveralls: :test, "coveralls.detail": :test, "coveralls.post": :test]
    ]
  end

  defp package do
    [
      maintainers: ["Beat Richartz"],
      licenses: ["MIT"],
      links: %{github: "https://github.com/beatrichartz/parallel_stream"}
    ]
  end

  defp deps do
    [
      {:excoveralls, "~> 0.5", only: :test},
      {:ex_doc, only: :dev},
      {:inch_ex, only: :dev},
      {:earmark, "1.4.15", only: :dev},
      {:benchfella, "~> 0.3.0", only: [:bench]}
    ]
  end

  defp docs do
    {ref, 0} = System.cmd("git", ["rev-parse", "--verify", "--quiet", "HEAD"])

    [
      source_ref: ref,
      main: "overview"
    ]
  end
end


new version

new version

defmodule Coherence.Mixfile do
  use Mix.Project

  @version "0.0.4"
  def project do
    [ app: :coherence,
      version: @version,
      elixir: "~> 1.3",
      elixirc_paths: elixirc_paths(Mix.env),
      compilers: [:phoenix, :gettext] ++ Mix.compilers,
      build_embedded: Mix.env == :prod,
      start_permanent: Mix.env == :prod,
      docs: [extras: ["README.md"], main: "Coherence"],
      deps: deps,
      package: package,
      name: "Coherence",
      description: """
      A full featured, configurable authentication and user management system for Phoenix.
      """
    ]
  end

  # Configuration for the OTP application
  def application do
    [mod: {Coherence, []},
     applications: [:logger, :comeonin, :ecto, :uuid, :phoenix_swoosh,
                    :phoenix_timex, :timex_ecto, :tzdata]]
  end

  defp elixirc_paths(:test), do: ["lib", "web", "test/support"]
  defp elixirc_paths(_),     do: ["lib", "web"]

  defp deps do
    [
      {:ecto, "~> 2.0"},
      {:comeonin, "~> 2.4"},
      {:phoenix, "~> 1.1"},
      {:phoenix_html, "~> 2.4"},
      {:gettext, "~> 0.9"},
      {:uuid, "~> 1.0"},
      {:phoenix_swoosh, "~> 0.1.3"},
      {:phoenix_timex, "~> 1.0.0"},
      {:timex_ecto, "~> 1.1"},
      {:ex_doc, "== 0.11.5", only: :dev},
      {:earmark, "== 0.2.1", only: :dev, override: true},
      {:postgrex, ">= 0.0.0", only: :test},
    ]
  end

  defp package do
    [ maintainers: ["Stephen Pallen"],
      licenses: ["MIT"],
      links: %{ "Github" => "https://github.com/smpallen99/coherence" },
      files: ~w(lib priv web README.md mix.exs LICENSE)]
  end
end

defmodule Coherence.Mixfile do
  use Mix.Project

  @version "0.0.3"
  def project do
    [ app: :coherence,
      version: @version,
      elixir: "~> 1.3",
      elixirc_paths: elixirc_paths(Mix.env),
      compilers: [:phoenix, :gettext] ++ Mix.compilers,
      build_embedded: Mix.env == :prod,
      start_permanent: Mix.env == :prod,
      docs: [extras: ["README.md"], main: "Coherence"],
      deps: deps,
      package: package,
      name: "Coherence",
      description: """
      A full featured, configurable authentication and user management system for Phoenix.
      """
    ]
  end

  # Configuration for the OTP application
  def application do
    [mod: {Coherence, []},
     applications: [:logger, :comeonin, :ecto, :uuid, :phoenix_swoosh,
                    :phoenix_timex, :timex_ecto, :tzdata]]
  end

  defp elixirc_paths(:test), do: ["lib", "web", "test/support"]
  defp elixirc_paths(_),     do: ["lib", "web"]

  defp deps do
    [
      {:ecto, "~> 2.0"},
      {:comeonin, "~> 2.4"},
      {:phoenix, "~> 1.1"},
      {:phoenix_html, "~> 2.4"},
      {:gettext, "~> 0.9"},
      {:uuid, "~> 1.0"},
      {:phoenix_swoosh, "~> 0.1.3"},
      {:phoenix_timex, "~> 1.0.0"},
      {:timex_ecto, "~> 1.1"},
      {:ex_doc, "== 0.11.5", only: :dev},
      {:earmark, "== 0.2.1", only: :dev, override: true},
      {:postgrex, ">= 0.0.0", only: :test},
    ]
  end

  defp package do
    [ maintainers: ["Stephen Pallen"],
      licenses: ["MIT"],
      links: %{ "Github" => "https://github.com/smpallen99/coherence" },
      files: ~w(lib priv web README.md mix.exs LICENSE)]
  end
end


Remove comments

Remove comments

defmodule MogoChat.Mixfile do
  use Mix.Project

  def project do
    [ app: :mogo_chat,
      version: "0.0.1",
      build_per_environment: true,
      elixir: "~> 0.12.4",
      deps: deps ]
  end

  # Configuration for the OTP application
  def application do
    [
      applications: [:erlydtl, :bcrypt, :qdate, :jsex, :uuid],
      mod: { MogoChat, []}
    ]
  end

  defp deps do
    [
      {:phoenix, github: "phoenixframework/phoenix"},
      {:erlydtl, github: "erlydtl/erlydtl", tag: "0.9.0"},
      {:ecto, github: "elixir-lang/ecto"},
      {:postgrex, github: "ericmj/postgrex"},
      {:jsex, github: "talentdeficit/jsex"},
      {:qdate, github: "choptastic/qdate" },
      {:bcrypt, github: "irccloud/erlang-bcrypt"},
      {:uuid, github: "okeuday/uuid"}
    ]
  end
end

defmodule MogoChat.Mixfile do
  use Mix.Project

  def project do
    [ app: :mogo_chat,
      version: "0.0.1",
      build_per_environment: true,
      elixir: "~> 0.12.4",
      deps: deps ]
  end

  # Configuration for the OTP application
  def application do
    [
      applications: [:erlydtl, :bcrypt, :qdate, :jsex, :uuid],
      mod: { MogoChat, []}
    ]
  end

  # Returns the list of dependencies in the format:
  # { :foobar, git: "https://github.com/elixir-lang/foobar.git", tag: "0.1" }
  #
  # To specify particular versions, regardless of the tag, do:
  # { :barbat, "~> 0.1", github: "elixir-lang/barbat" }
  defp deps do
    [
      {:phoenix, github: "phoenixframework/phoenix"},
      {:erlydtl, github: "erlydtl/erlydtl", tag: "0.9.0"},
      {:ecto, github: "elixir-lang/ecto"},
      {:postgrex, github: "ericmj/postgrex"},
      {:jsex, github: "talentdeficit/jsex"},
      {:qdate, github: "choptastic/qdate" },
      {:bcrypt, github: "irccloud/erlang-bcrypt"},
      {:uuid, github: "okeuday/uuid"}
    ]
  end
end


Require Hound only in Test Env

Require Hound only in Test Env

defmodule ExAdmin.Mixfile do
  use Mix.Project

  @version "0.8.3-dev"

  def project do
    [ app: :ex_admin,
      version: @version,
      elixir: "~> 1.3",
      elixirc_paths: elixirc_paths(Mix.env),
      compilers: [:phoenix, :gettext] ++ Mix.compilers,
      build_embedded: Mix.env == :prod,
      start_permanent: Mix.env == :prod,
      name: "ExAdmin",
      docs: [extras: ["README.md"], main: "ExAdmin"],
      deps: deps(),
      package: package(),
      test_coverage: [tool: ExCoveralls],
      preferred_cli_env: ["coveralls": :test, "coveralls.detail": :test, "coveralls.post": :test, "coveralls.html": :test],
      description: """
      An Elixir Phoenix Auto Administration Package.
      """
    ]
  end

  def application do
    [ applications: applications(Mix.env)]
  end

  defp applications(:test) do
    [:plug, :cowboy | applications(:prod)]
  end
  defp applications(_) do
    [:gettext, :phoenix, :ecto, :inflex, :scrivener, :scrivener_ecto, :csvlixir, :logger, :ex_queb, :xain]
  end
  defp elixirc_paths(:test), do: ["lib", "web", "test/support"]
  defp elixirc_paths(_),     do: ["lib", "web"]

  defp deps do
    [
      {:decimal, "~> 1.0"},
      {:phoenix, "~> 1.2"},
      {:phoenix_html, "~> 2.6"},
      {:ecto, "~> 2.1"},
      {:phoenix_ecto, "~> 3.2"},
      {:postgrex, "~> 0.13", only: :test},
      {:floki, "~> 0.8", only: :test},
      {:cowboy, "~> 1.0"},
      {:phoenix_html, "~> 2.5"},
      {:inflex, "~> 1.7"},
      {:scrivener_ecto, "~> 1.1"},
      {:xain, "~> 0.6"},
      {:csvlixir, "~> 1.0.0"},
      {:exactor, "~> 2.2.0"},
      {:ex_doc, "~> 0.11", only: :dev},
      {:earmark, "~> 0.1", only: :dev},
      {:ex_queb, "~> 1.0"},
      {:excoveralls, "~> 0.5", only: :test},
      {:gettext, "~> 0.11"},
      {:hound, "~> 1.0", only: :test}
    ]
  end

  defp package do
    [ maintainers: ["Stephen Pallen", "Roman Smirnov"],
      licenses: ["MIT"],
      links: %{ "Github" => "https://github.com/smpallen99/ex_admin" },
      files: ~w(lib priv web README.md package.json mix.exs LICENSE brunch-config.js AdminLte-LICENSE)]
  end
end

defmodule ExAdmin.Mixfile do
  use Mix.Project

  @version "0.8.3-dev"

  def project do
    [ app: :ex_admin,
      version: @version,
      elixir: "~> 1.3",
      elixirc_paths: elixirc_paths(Mix.env),
      compilers: [:phoenix, :gettext] ++ Mix.compilers,
      build_embedded: Mix.env == :prod,
      start_permanent: Mix.env == :prod,
      name: "ExAdmin",
      docs: [extras: ["README.md"], main: "ExAdmin"],
      deps: deps(),
      package: package(),
      test_coverage: [tool: ExCoveralls],
      preferred_cli_env: ["coveralls": :test, "coveralls.detail": :test, "coveralls.post": :test, "coveralls.html": :test],
      description: """
      An Elixir Phoenix Auto Administration Package.
      """
    ]
  end

  def application do
    [ applications: applications(Mix.env)]
  end

  defp applications(:test) do
    [:plug, :cowboy | applications(:prod)]
  end
  defp applications(_) do
    [:gettext, :phoenix, :ecto, :inflex, :scrivener, :scrivener_ecto, :csvlixir, :logger, :ex_queb, :xain]
  end
  defp elixirc_paths(:test), do: ["lib", "web", "test/support"]
  defp elixirc_paths(_),     do: ["lib", "web"]

  defp deps do
    [
      {:decimal, "~> 1.0"},
      {:phoenix, "~> 1.2"},
      {:phoenix_html, "~> 2.6"},
      {:ecto, "~> 2.1"},
      {:phoenix_ecto, "~> 3.2"},
      {:postgrex, "~> 0.13", only: :test},
      {:floki, "~> 0.8", only: :test},
      {:cowboy, "~> 1.0"},
      {:phoenix_html, "~> 2.5"},
      {:inflex, "~> 1.7"},
      {:scrivener_ecto, "~> 1.1"},
      {:xain, "~> 0.6"},
      {:csvlixir, "~> 1.0.0"},
      {:exactor, "~> 2.2.0"},
      {:ex_doc, "~> 0.11", only: :dev},
      {:earmark, "~> 0.1", only: :dev},
      {:ex_queb, "~> 1.0"},
      {:excoveralls, "~> 0.5", only: :test},
      {:gettext, "~> 0.11"},
      {:hound, "~> 1.0"}
    ]
  end

  defp package do
    [ maintainers: ["Stephen Pallen", "Roman Smirnov"],
      licenses: ["MIT"],
      links: %{ "Github" => "https://github.com/smpallen99/ex_admin" },
      files: ~w(lib priv web README.md package.json mix.exs LICENSE brunch-config.js AdminLte-LICENSE)]
  end
end


[ex] Add more documentation for the IFSC module

defmodule Razorpay.IFSC do
  @moduledoc """
  Razorpay IFSC Validation Module

  Online validation (fetches details from ifsc.razorpay.com)

      iex> IFSC.get("KKBK0000261")
      {:ok,
       %Razorpay.IFSC{
         address: "JMD REGENT SQUARE,MEHRAULI GURGAON ROAD,OPPOSITE BRISTOL HOTEL,",
         bank: "Kotak Mahindra Bank",
         bank_code: "KKBK",
         branch: "GURGAON",
         city: "GURGAON",
         contact: "4131000",
         district: "GURGAON",
         ifsc: "KKBK0000261",
         rtgs: true,
         state: "HARYANA"
       }}

      iex> IFSC.get("foobar")
      {:error, :invalid_ifsc}

  Offline validation using the dataset in the package - please keep `ifsc` up to date if using this

  (Note that only the :bank, :bank_code and :ifsc fields are populated if using offline validation)

      iex> IFSC.validate("KKBK0000261")
      {:ok,
       %Razorpay.IFSC{
         address: nil,
         bank: "Kotak Mahindra Bank",
         bank_code: "KKBK",
         branch: nil,
         city: nil,
         contact: nil,
         district: nil,
         ifsc: "KKBK0000261",
         rtgs: nil,
         state: nil
       }}

       iex> IFSC.validate("foobar")
       {:error, :invalid_format}

       iex> IFSC.validate("AAAA0000000")
       {:error, :invalid_bank_code}

       iex(> IFSC.validate("HDFC0000000")
       {:error, :invalid_branch_code}

  """

  alias __MODULE__.Data

  @type t :: %__MODULE__{
    ifsc:      String.t,
    bank:      String.t | nil,
    bank_code: String.t | nil,
    branch:    String.t | nil,
    address:   String.t | nil,
    contact:   String.t | nil,
    city:      String.t | nil,
    district:  String.t | nil,
    state:     String.t | nil,
    rtgs:      boolean | nil,
  }

  @enforce_keys ~w(ifsc)a

  defstruct ~w(ifsc bank bank_code branch address contact city district state rtgs)a

  @doc """
  Fetch details about an IFSC code from the Razorpay IFSC API
  """
  @spec get(ifsc :: String.t) :: {:ok, ifsc :: __MODULE__.t} | {:error, reason :: :invalid_ifsc | any}
  def get(ifsc) do
    with {:ok, %HTTPoison.Response{status_code: 200, body: body}} <- Data.api(ifsc),
         {:ok, json} <- Poison.decode(body)
    do
      {:ok, %__MODULE__{
        ifsc: json["IFSC"],
        bank: json["BANK"],
        bank_code: json["BANKCODE"],
        branch: json["BRANCH"],
        address: json["ADDRESS"],
        contact: json["CONTACT"],
        city: json["CITY"],
        district: json["DISTRICT"],
        state: json["STATE"],
        rtgs: json["RTGS"],
      }}
    else
      {:ok, %HTTPoison.Response{status_code: 404}} ->
        {:error, :invalid_ifsc}
      {:error, %HTTPoison.Error{reason: reason}} ->
        {:error, reason}
    end
  end

  @doc """
  Perform offline validation and return the bank and bank codes
  """
  @spec validate(ifsc :: String.t) :: {:ok, ifsc :: __MODULE__.t} |
                                      {:error, reason :: :invalid_format | :invalid_bank_code | :invalid_branch_code | any}
  def validate(ifsc) do
    ifsc = String.upcase(ifsc)

    with :ok <- validate_format(ifsc),
         :ok <- validate_bank(ifsc),
         :ok <- validate_branch(ifsc)
    do
      {:ok, %__MODULE__{
        ifsc: ifsc,
        bank: bank_name(ifsc),
        bank_code: bank_code(ifsc, :sublet),
      }}
    end
  end

  defp validate_format(ifsc) do
    if String.length(ifsc) == 11 and String.at(ifsc, 4) == "0" do
      :ok
    else
      {:error, :invalid_format}
    end
  end

  defp validate_bank(ifsc) do
    with {:ok, bank_data} <- Data.bank() do
      if Map.has_key?(bank_data, bank_code(ifsc, :regular)) do
        :ok
      else
        {:error, :invalid_bank_code}
      end
    end
  end

  defp validate_branch(ifsc) do
    with {:ok, ifsc_data} <- Data.ifsc() do
      branches = ifsc_data[bank_code(ifsc, :regular)]
      if branches && Enum.member?(branches, branch_code(ifsc)) do
        :ok
      else
        {:error, :invalid_branch_code}
      end
    end
  end

  defp bank_code(ifsc, :sublet) do
    code = bank_code(ifsc, :regular)

    with {:ok, sublet_data} <- Data.sublet() do
      sublet_data[ifsc] || code
    else
      _ -> code
    end
  end
  defp bank_code(ifsc, :regular), do: String.slice(ifsc, 0..3)

  defp branch_code(ifsc) do
    code = String.slice(ifsc, 5..-1)

    if code =~ ~r/^(\d)+$/ do
      String.to_integer(code)
    else
      String.upcase(code)
    end
  end

  defp bank_name(ifsc) do
    with {:ok, bank_data} <- Data.bank() do
      bank_data[bank_code(ifsc, :sublet)]
    else
      _ -> nil
    end
  end
end

defmodule Razorpay.IFSC do
  @moduledoc """
  Razorpay IFSC Validation Module
  """

  alias __MODULE__.Data

  @type t :: %__MODULE__{
    ifsc:      String.t,
    bank:      String.t | nil,
    bank_code: String.t | nil,
    branch:    String.t | nil,
    address:   String.t | nil,
    contact:   String.t | nil,
    city:      String.t | nil,
    district:  String.t | nil,
    state:     String.t | nil,
    rtgs:      boolean | nil,
  }

  @enforce_keys ~w(ifsc)a

  defstruct ~w(ifsc bank bank_code branch address contact city district state rtgs)a

  @doc """
  Fetch details about an IFSC code from the Razorpay IFSC API
  """
  @spec get(ifsc :: String.t) :: {:ok, ifsc :: __MODULE__.t} | {:error, reason :: :invalid_ifsc | any}
  def get(ifsc) do
    with {:ok, %HTTPoison.Response{status_code: 200, body: body}} <- Data.api(ifsc),
         {:ok, json} <- Poison.decode(body)
    do
      {:ok, %__MODULE__{
        ifsc: json["IFSC"],
        bank: json["BANK"],
        bank_code: json["BANKCODE"],
        branch: json["BRANCH"],
        address: json["ADDRESS"],
        contact: json["CONTACT"],
        city: json["CITY"],
        district: json["DISTRICT"],
        state: json["STATE"],
        rtgs: json["RTGS"],
      }}
    else
      {:ok, %HTTPoison.Response{status_code: 404}} ->
        {:error, :invalid_ifsc}
      {:error, %HTTPoison.Error{reason: reason}} ->
        {:error, reason}
    end
  end

  @doc """
  Perform offline validation and return the bank and bank codes
  """
  @spec validate(ifsc :: String.t) :: {:ok, ifsc :: __MODULE__.t} |
                                      {:error, reason :: :invalid_format | :invalid_bank_code | :invalid_branch_code | any}
  def validate(ifsc) do
    ifsc = String.upcase(ifsc)

    with :ok <- validate_format(ifsc),
         :ok <- validate_bank(ifsc),
         :ok <- validate_branch(ifsc)
    do
      {:ok, %__MODULE__{
        ifsc: ifsc,
        bank: bank_name(ifsc),
        bank_code: bank_code(ifsc, :sublet),
      }}
    end
  end

  defp validate_format(ifsc) do
    if String.length(ifsc) == 11 and String.at(ifsc, 4) == "0" do
      :ok
    else
      {:error, :invalid_format}
    end
  end

  defp validate_bank(ifsc) do
    with {:ok, bank_data} <- Data.bank() do
      if Map.has_key?(bank_data, bank_code(ifsc, :regular)) do
        :ok
      else
        {:error, :invalid_bank_code}
      end
    end
  end

  defp validate_branch(ifsc) do
    with {:ok, ifsc_data} <- Data.ifsc() do
      branches = ifsc_data[bank_code(ifsc, :regular)]
      if branches && Enum.member?(branches, branch_code(ifsc)) do
        :ok
      else
        {:error, :invalid_branch_code}
      end
    end
  end

  defp bank_code(ifsc, :sublet) do
    code = bank_code(ifsc, :regular)

    with {:ok, sublet_data} <- Data.sublet() do
      sublet_data[ifsc] || code
    else
      _ -> code
    end
  end
  defp bank_code(ifsc, :regular), do: String.slice(ifsc, 0..3)

  defp branch_code(ifsc) do
    code = String.slice(ifsc, 5..-1)

    if code =~ ~r/^(\d)+$/ do
      String.to_integer(code)
    else
      String.upcase(code)
    end
  end

  defp bank_name(ifsc) do
    with {:ok, bank_data} <- Data.bank() do
      bank_data[bank_code(ifsc, :sublet)]
    else
      _ -> nil
    end
  end
end


Delete old pin_binding code

Delete old pin_binding code

defmodule Farmbot.Target.PinBinding.AleHandler do
  @moduledoc "PinBinding handler that uses Elixir.Ale"

  use GenServer
  alias Circuits.GPIO
  @behaviour Farmbot.PinBinding.Handler

  # PinBinding.Handler Callbacks
  def start_link do
    GenServer.start_link(__MODULE__, [], name: __MODULE__)
  end

  def register_pin(num) do
    GenServer.call(__MODULE__, {:register_pin, num})
  end

  def unregister_pin(num) do
    GenServer.call(__MODULE__, {:unregister_pin, num})
  end

  # GenServer Callbacks

  defmodule State do
    @moduledoc false
    defstruct [:pins]
  end

  defmodule PinState do
    @moduledoc false
    defstruct [:pin, :state, :signal, :gpio]
  end

  def init([]) do
    {:ok, %State{pins: %{}}}
  end

  def handle_call({:register_pin, num}, _from, state) do
    with {:ok, out_gpio} <- GPIO.open(num, :output),
         :ok <- GPIO.write(out_gpio, 0),
         :ok <- GPIO.close(out_gpio),
         {:ok, gpio} <- GPIO.open(num, :input),
         :ok <- GPIO.set_interrupts(gpio, :both),
         new_pins <-
           Map.put(state.pins, num, %PinState{pin: num, gpio: gpio, state: nil, signal: :rising}) do
      {:reply, :ok, %{state | pins: new_pins}}
    else
      {:error, _} = err -> {:reply, err, state}
      err -> {:reply, {:error, err}, state}
    end
  end

  def handle_call({:unregister_pin, num}, _from, state) do
    case state.pins[num] do
      nil ->
        {:reply, :ok, state}

      %PinState{gpio: gpio} ->
        GPIO.close(gpio)
        {:reply, :ok, %{state | pins: Map.delete(state.pins, num)}}
    end
  end

  def handle_info({:gpio_interrupt, pin, signal}, state) do
    pin_state = state.pins[pin]
    new_state = %{state | pins: %{state.pins | pin => %{pin_state | state: signal}}}
    Farmbot.PinBinding.Manager.trigger(pin, signal)
    {:noreply, new_state}
  end
end


User.find convert user_id into the right type

if it's a string, convert into an int.

defmodule WhiteboardServer.User do

  def create( user_dict ) do
    sql = '''
      insert into users
      (
        created_at,
        first,
        last,
        email,
        password_hash,
        password_salt
      )
      values
      (
        now(),
        $1,
        $2,
        $3,
        md5( $4 || $5 ),
        $6
      )
      returning id
    '''

    result = query(
      sql,
      [
        HashDict.get(user_dict, :first, ""),
        HashDict.get(user_dict, :last, ""),
        HashDict.get(user_dict, :email, ""),
        HashDict.get(user_dict, :password, ""),
        "salt",
        "salt"
      ]
    )

    IO.puts "got back user: #{ inspect result }"

    case result do
      { :error, e } ->
        IO.puts "Got error: #{ inspect e }"
        { :error }
      { :ok, _count, _columns, rows } ->
        IO.puts "created user. yay!"
        { user_id } = hd(rows)
        { :ok, user_id }
    end
  end

  def find( nil ) do
    { :error }
  end

  def find( user_id ) when is_integer(user_id) do
    sql = '''
      select id, email, first, last from users where id = $1
    '''

    result = query( sql, [ user_id ] )

    case result do
      { :error, _ } ->
        { :error }
      { :ok, _columns, [{ id, email, first, last }]  } ->
        { :ok, [id: id, email: email, first: first, last: last] }
    end
  end

  def find( user_id ) when is_bitstring(user_id) do
    { id, _ } = Integer.parse(user_id)

    find id
  end

  def find_by_email( email ) do
    sql = '''
      select email, first, last from users where email = $1
    '''

    result = query( sql, [ email ] )

    case result do
      { :error, _ } ->
        { :error }
      { :ok, _columns, [{ id, email, first, last }]  } ->
        { :ok, [id: id, email: email, first: first, last: last] }
    end
  end

  def whiteboards( user_id ) do
    sql = '''
      select name, key from whiteboards where user_id = $1 and active
    '''

    result = query( sql, [ user_id ] )

    case result do
      { :error, error } ->
        IO.puts "Error fetching whiteboards: #{ inspect error }"
        { :error }
      { :ok, _columns, whiteboard_list } ->
        Enum.map whiteboard_list, fn({name, key}) ->
          [ name: name, key: key ]
        end
    end
  end

  def create_whiteboard( user_id, name ) do
    sql = '''
      insert into whiteboards
      (
        created_at,
        user_id,
        name,
        key
      )
      values
      (
        now(),
        $1,
        $2,
        md5( $3 || $4 || now() )
      )
      returning key
    '''

    result = query( sql, [ user_id, name, user_id, name ] )

    case result do
      { :error, error } ->
        IO.puts "Error creating whiteboard: #{ inspect error }"
        { :error }
      { :ok, 1, _columns, [ {key} ] } ->
        :gen_server.call( :board_store, { :create, key } )
        { :ok, key }
    end

  end

  def authenticate( email, password ) do
    sql = '''
      select id from users where email = $1 and password_hash = md5( $2 || password_salt )
    '''

    result = query( sql, [ email, password ] )

    case result do
      { :error, _ } ->
        { :error }
      { :ok, _columns, [] } ->
        { :not_found }
      { :ok, _columns, [{user_id}] } ->
        { :ok, user_id }
    end

  end

  defp query( sql, params ) do
    :gen_server.call( :database, { :equery, sql, params } )
  end

end

defmodule WhiteboardServer.User do

  def create( user_dict ) do
    sql = '''
      insert into users
      (
        created_at,
        first,
        last,
        email,
        password_hash,
        password_salt
      )
      values
      (
        now(),
        $1,
        $2,
        $3,
        md5( $4 || $5 ),
        $6
      )
      returning id
    '''

    result = query(
      sql,
      [
        HashDict.get(user_dict, :first, ""),
        HashDict.get(user_dict, :last, ""),
        HashDict.get(user_dict, :email, ""),
        HashDict.get(user_dict, :password, ""),
        "salt",
        "salt"
      ]
    )

    IO.puts "got back user: #{ inspect result }"

    case result do
      { :error, e } ->
        IO.puts "Got error: #{ inspect e }"
        { :error }
      { :ok, _count, _columns, rows } ->
        IO.puts "created user. yay!"
        { user_id } = hd(rows)
        { :ok, user_id }
    end
  end

  def find( nil ) do
    { :error }
  end

  def find( user_id ) do
    sql = '''
      select id, email, first, last from users where id = $1
    '''

    result = query( sql, [ user_id ] )

    case result do
      { :error, _ } ->
        { :error }
      { :ok, _columns, [{ id, email, first, last }]  } ->
        { :ok, [id: id, email: email, first: first, last: last] }
    end
  end

  def find_by_email( email ) do
    sql = '''
      select email, first, last from users where email = $1
    '''

    result = query( sql, [ email ] )

    case result do
      { :error, _ } ->
        { :error }
      { :ok, _columns, [{ id, email, first, last }]  } ->
        { :ok, [id: id, email: email, first: first, last: last] }
    end
  end

  def whiteboards( user_id ) do
    sql = '''
      select name, key from whiteboards where user_id = $1 and active
    '''

    result = query( sql, [ user_id ] )

    case result do
      { :error, error } ->
        IO.puts "Error fetching whiteboards: #{ inspect error }"
        { :error }
      { :ok, _columns, whiteboard_list } ->
        Enum.map whiteboard_list, fn({name, key}) ->
          [ name: name, key: key ]
        end
    end
  end

  def create_whiteboard( user_id, name ) do
    sql = '''
      insert into whiteboards
      (
        created_at,
        user_id,
        name,
        key
      )
      values
      (
        now(),
        $1,
        $2,
        md5( $3 || $4 || now() )
      )
      returning key
    '''

    result = query( sql, [ user_id, name, user_id, name ] )

    case result do
      { :error, error } ->
        IO.puts "Error creating whiteboard: #{ inspect error }"
        { :error }
      { :ok, 1, _columns, [ {key} ] } ->
        :gen_server.call( :board_store, { :create, key } )
        { :ok, key }
    end

  end

  def authenticate( email, password ) do
    sql = '''
      select id from users where email = $1 and password_hash = md5( $2 || password_salt )
    '''

    result = query( sql, [ email, password ] )

    case result do
      { :error, _ } ->
        { :error }
      { :ok, _columns, [] } ->
        { :not_found }
      { :ok, _columns, [{user_id}] } ->
        { :ok, user_id }
    end

  end

  defp query( sql, params ) do
    :gen_server.call( :database, { :equery, sql, params } )
  end

end


Add assertion for before state in voting end-to-end test

defmodule VotingTest do
  use RemoteRetro.IntegrationCase, async: false
  alias RemoteRetro.Idea

  import ShorterMaps

  describe "voting for an idea" do
    setup [:persist_idea_for_retro]

    @tag [
      retro_stage: "voting",
      idea: %Idea{category: "happy", body: "pacing well"},
    ]

    test "increments the idea's vote count across sessions", ~M{retro, session: session_one} do
      session_two = new_authenticated_browser_session()

      retro_path = "/retros/" <> retro.id
      session_one = visit(session_one, retro_path)
      session_two = visit(session_two, retro_path)

      # session one submits a vote for a particular idea
      # assert that the idea's vote count increments
      session_one_ideas_list_text = session_one |> find(Query.css(".happy.column")) |> Element.text()
      assert session_one_ideas_list_text =~ ~r/Vote\n0/ui

      session_one |> find(Query.css("button.ui.green.button")) |> Element.click

      session_one_ideas_list_text = session_one |> find(Query.css(".happy.column")) |> Element.text()
      assert session_one_ideas_list_text =~ ~r/Vote\n1/ui

      session_two_ideas_list_text = session_two |> find(Query.css(".happy.column")) |> Element.text()
      assert session_two_ideas_list_text =~ ~r/Vote\n1/ui
    end
  end
end

defmodule VotingTest do
  use RemoteRetro.IntegrationCase, async: false
  alias RemoteRetro.Idea

  import ShorterMaps

  describe "voting for an idea" do
    setup [:persist_idea_for_retro]

    @tag [
      retro_stage: "voting",
      idea: %Idea{category: "happy", body: "pacing well"},
    ]

    test "increments the idea's vote count across sessions", ~M{retro, session: session_one} do
      session_two = new_authenticated_browser_session()

      retro_path = "/retros/" <> retro.id
      session_one = visit(session_one, retro_path)
      session_two = visit(session_two, retro_path)

      # session one submits a vote for a particular idea
      # assert that the idea's vote count increments
      session_one |> find(Query.css("button.ui.green.button")) |> Element.click

      session_one_ideas_list_text = session_one |> find(Query.css(".happy.column")) |> Element.text()
      assert session_one_ideas_list_text =~ ~r/Vote\n1/ui

      session_two_ideas_list_text = session_two |> find(Query.css(".happy.column")) |> Element.text()
      assert session_two_ideas_list_text =~ ~r/Vote\n1/ui
    end
  end
end