Fix typo on List documentation

Fix typo on List documentation

defmodule List do
  @moduledoc """
  Implements functions that only make sense for lists
  and cannot be part of the Enum protocol. In general,
  favor using the Enum API instead of List.

  A decision was taken to delegate most functions to
  Erlang's standard lib but following Elixir's convention
  of receiving the target (in this case, a list) as the
  first argument.
  """

  @doc """
  Given a list of lists, concatenates the sublists into a single list.

  ## Examples

      iex> List.concat([[1,[2],3], [4], [5,6]])
      [1,[2],3,4,5,6]

  """
  def concat(list) when is_list(list) do
    :lists.append(list)
  end

  @doc """
  Concatenates the list on the right with the list on the left.

  This function produces the same result the `++` operator. The only difference
  is a minor optimization: when the first list contains only one element, we
  simply add it as a head to the second list.

  ## Examples

      iex> List.concat([1,2,3], [4,5,6])
      [1,2,3,4,5,6]

  """
  def concat(list, elements) when is_list(list) and is_list(elements) do
    list ++ elements
  end

  @doc """
  Deletes the given item from the list. Returns a list without the item.
  If the item occurs more than once in the list, just the first occurrence
  is removed.

  ## Examples

      iex> List.delete([1,2,3], 1)
      [2,3]

  """
  def delete(list, item) do
    :lists.delete(item, list)
  end

  @doc """
  Duplicates the given element n times in a list.

  ## Examples

      iex> List.duplicate("hello", 3)
      ["hello","hello","hello"]

      iex> List.duplicate([1,2], 2)
      [[1,2],[1,2]]
  """
  def duplicate(elem, n) do
    :lists.duplicate(n, elem)
  end

  @doc """
  Flattens the given `list` of nested lists. An optional
  tail can be given that will be added at the end of
  the flattened list.

  ## Examples

      iex> List.flatten([1,[[2],3]])
      [1,2,3]

      iex> List.flatten([1,[[2],3]], [4,5])
      [1,2,3,4,5]

  """
  def flatten(list) do
    :lists.flatten(list)
  end

  def flatten(list, tail) do
    :lists.flatten(list, tail)
  end

  @doc """
  Folds (reduces) the given list to the left with
  a function. Requires an accumulator.

  ## Examples

      iex> List.foldl([5,5], 10, fn (x, acc) -> x + acc end)
      20

      iex> List.foldl([1,2,3,4], 0, fn (x, acc) -> x - acc end)
      2

  """
  def foldl(list, acc, function) when is_list(list) and is_function(function) do
    :lists.foldl(function, acc, list)
  end

  @doc """
  Folds (reduces) the given list to the right with
  a function. Requires an accumulator.

  ## Examples

      iex> List.foldr([1,2,3,4], 0, fn (x, acc) -> x - acc end)
      -2

  """
  def foldr(list, acc, function) when is_list(list) and is_function(function) do
    :lists.foldr(function, acc, list)
  end

  @doc """
  Returns the last element in `list` or nil if the `list` is empty.

  ## Examples

      iex> List.last([])
      nil
      iex> List.last([1])
      1
      iex> List.last([1, 2, 3])
      3

  """
  def last([]), do: nil

  def last(list) do
    :lists.last(list)
  end

  @doc """
  Receives a list of tuples and returns the first tuple
  where the item at position `position` matches with the
  given `item`.

  ## Examples

      iex> List.keyfind([a: 1, b: 2], :a, 0)
      { :a, 1 }

      iex> List.keyfind([a: 1, b: 2], 2, 1)
      { :b, 2 }

      iex> List.keyfind([a: 1, b: 2], :c, 0)
      nil

  """
  def keyfind(list, key, position, default // nil) do
    :lists.keyfind(key, position + 1, list) || default
  end

  @doc """
  Receives a list of tuples and returns true if there is
  a tuple where the item at position `position` matches
  with the given `item`.

  ## Examples

      iex> List.keymember?([a: 1, b: 2], :a, 0)
      true

      iex> List.keymember?([a: 1, b: 2], 2, 1)
      true

      iex> List.keymember?([a: 1, b: 2], :c, 0)
      false

  """
  def keymember?(list, key, position) do
    :lists.keymember(key, position + 1, list)
  end

  @doc """
  Receives a list of tuples and replaces the item
  identified by `key` at position `pos` if it exists.

  ## Examples

      iex> List.keyreplace([a: 1, b: 2], :a, 0, { :a, 3 })
      [a: 3, b: 2]

  """
  def keyreplace(list, key, position, new_tuple) do
    :lists.keyreplace(key, position + 1, list, new_tuple)
  end

  @doc """
  Receives a list of tuples and replaces the item
  identified by `key` at position `pos`. If the item
  does not exist, it is added to the end of the list.

  ## Examples

      iex> List.keystore([a: 1, b: 2], :a, 0, { :a, 3 })
      [a: 3, b: 2]

  """
  def keystore(list, key, position, new_tuple) do
    :lists.keystore(key, position + 1, list, new_tuple)
  end

  @doc """
  Receives a list of tuples and deletes the first tuple
  where the item at position `position` matches with the
  given `item`. Returns the new tuple.

  ## Examples

      iex> List.keydelete([a: 1, b: 2], :a, 0)
      [{ :b, 2 }]

      iex> List.keydelete([a: 1, b: 2], 2, 1)
      [{ :a, 1 }]

      iex> List.keydelete([a: 1, b: 2], :c, 0)
      [{ :a, 1 }, { :b, 2 }]

  """
  def keydelete(list, key, position) do
    :lists.keydelete(key, position + 1, list)
  end

  @doc """
  Wraps the argument in a list.
  If the argument is already a list, returns the list.
  If the argument is nil, returns an empty list.

  ## Examples

      iex> List.wrap([1,2,3])
      [1,2,3]

  """
  def wrap(list) when is_list(list) do
    list
  end

  def wrap(nil) do
    []
  end

  def wrap(other) do
    [other]
  end

  @doc """
  Zips corresponding elements from each list in `list_of_lists`.

  ## Examples

      iex> List.zip([[1, 2], [3, 4], [5, 6]])
      [{1, 3, 5}, {2, 4, 6}]

      iex> List.zip([[1, 2], [3], [5, 6]])
      [{1, 3, 5}]

  """
  def zip([]), do: []
  def zip(list_of_lists) when is_list(list_of_lists) do
    do_zip(list_of_lists, [])
  end

  @doc """
  Unzips the given list of lists or tuples into separate lists and returns a
  list of lists.

  ## Examples

      iex> List.unzip([{1, 2}, {3, 4}])
      [[1, 3], [2, 4]]

      iex> List.unzip([{1, :a, "apple"}, {2, :b, "banana"}, {3, :c}])
      [[1, 2, 3], [:a, :b, :c]]

  """
  def unzip(list) when is_list(list) do
    :lists.map tuple_to_list(&1), zip(list)
  end

  @doc """
  Returns a list with an inserted value at specified index. Note that the index
  is capped at the list length and that negative indicies wraps around at the
  end of the list.

  ## Examples

      iex> List.insert_at([1, 2, 3, 4], 2, 0)
      [1, 2, 0, 3, 4]

      iex> List.insert_at([1, 2, 3], 10, 0)
      [1, 2, 3, 0]

      iex> List.insert_at([1, 2, 3], -1, 0)
      [1, 2, 0, 3]

  """
  def insert_at(list, index, value) do
    if index < 0 do
      do_insert_at(list, length(list) + index, value)
    else
      do_insert_at(list, index, value)
    end
  end

  ## Helpers

  # insert_at

  defp do_insert_at([], _index, value) do
    [ value ]
  end

  defp do_insert_at(list, index, value) when index <= 0 do
    [ value | list ]
  end

  defp do_insert_at([h|t], index, value) do
    [ h | do_insert_at(t, index - 1, value) ]
  end

  # zip

  defp do_zip(list, acc) do
    converter = fn x, acc -> do_zip_each(to_list(x), acc) end
    {mlist, heads} = :lists.mapfoldl converter, [], list

    case heads do
      nil -> :lists.reverse acc
      _   -> do_zip mlist, [list_to_tuple(:lists.reverse(heads))|acc]
    end
  end

  defp do_zip_each(_, nil) do
    { nil, nil }
  end

  defp do_zip_each([h|t], acc) do
    { t, [h|acc] }
  end

  defp do_zip_each([], _) do
    { nil, nil }
  end

  defp to_list(tuple) when is_tuple(tuple), do: tuple_to_list(tuple)
  defp to_list(list)  when is_list(list),   do: list
end

defmodule List do
  @moduledoc """
  Implements functions that only make sense for lists
  and cannot be part of the Enum protocol. In general,
  favor using the Enum API instead of List.

  A decision was taken to delegate most functions to
  Erlang's standard lib but following Elixir's convention
  of receiving the target (in this case, a list) as the
  first argument.
  """

  @doc """
  Given a list of lists, concatenates the sublists into a single list.

  ## Examples

      iex> List.concat([[1,[2],3], [4], [5,6]])
      [1,[2],3,4,5,6]

  """
  def concat(list) when is_list(list) do
    :lists.append(list)
  end

  @doc """
  Concatenates the list on the right with the list on the left.

  This function produces the same result the `++` operator. The only difference
  is a minor optimization: when the first list contains only one element, we
  simply add it as a head to the second list.

  ## Examples

      iex> List.concat([1,2,3], [4,5,6])
      [1,2,3,4,5,6]

  """
  def concat(list, elements) when is_list(list) and is_list(elements) do
    list ++ elements
  end

  @doc """
  Deletes the given item from the list. Returns a list without the item.
  If the item occurs more than once in the list, just the first occurrence
  is removed.

  ## Examples

      iex> List.delete([1,2,3], 1)
      [2,3]

  """
  def delete(list, item) do
    :lists.delete(item, list)
  end

  @doc """
  Duplicates the given element n times in a list.

  ## Examples

      iex> List.duplicate("hello", 3)
      ["hello","hello","hello"]

      iex> List.duplicate([1,2], 2)
      [[1,2],[1,2]]
  """
  def duplicate(elem, n) do
    :lists.duplicate(n, elem)
  end

  @doc """
  Flattens the given `list` of nested lists. An optional
  tail can be given that will be added at the end of
  the flattened list.

  ## Examples

      iex> List.flatten([1,[[2],3]])
      [1,2,3]

      iex> List.flatten([1,[[2],3]], [4,5])
      [1,2,3,4,5]

  """
  def flatten(list) do
    :lists.flatten(list)
  end

  def flatten(list, tail) do
    :lists.flatten(list, tail)
  end

  @doc """
  Folds (reduces) the given list to the left with
  a function. Requires an accumulator.

  ## Examples

      iex> List.foldl([5,5], 10, fn (x, acc) -> x + acc end)
      20

      iex> List.foldl([1,2,3,4], 0, fn (x, acc) -> x - acc end)
      2

  """
  def foldl(list, acc, function) when is_list(list) and is_function(function) do
    :lists.foldl(function, acc, list)
  end

  @doc """
  Folds (reduces) the given list to the right with
  a function. Requires an accumulator.

  ## Examples

      iex> List.foldr([1,2,3,4], 0, fn (x, acc) -> x - acc end)
      -2

  """
  def foldr(list, acc, function) when is_list(list) and is_function(function) do
    :lists.foldr(function, acc, list)
  end

  @doc """
  Returns the last element in `list` or nil if the `list` is empty.

  ## Examples

      iex> List.last([])
      nil
      iex> List.last([1])
      1
      iex> List.last([1, 2, 3])
      3

  """
  def last([]), do: nil

  def last(list) do
    :lists.last(list)
  end

  @doc """
  Receives a list of tuples and returns the first tuple
  where the item at position `position` matches with the
  given `item`.

  ## Examples

      iex> List.keyfind([a: 1, b: 2], :a, 0)
      { :a, 1 }

      iex> List.keyfind([a: 1, b: 2], 2, 1)
      { :b, 2 }

      iex> List.keyfind([a: 1, b: 2], :c, 0)
      nil

  """
  def keyfind(list, key, position, default // nil) do
    :lists.keyfind(key, position + 1, list) || default
  end

  @doc """
  Receives a list of tuples and returns true if there is
  a tuple where the item at position `posistion` matches
  with the given `item`.

  ## Examples

      iex> List.keymember?([a: 1, b: 2], :a, 0)
      true

      iex> List.keymember?([a: 1, b: 2], 2, 1)
      true

      iex> List.keymember?([a: 1, b: 2], :c, 0)
      false

  """
  def keymember?(list, key, position) do
    :lists.keymember(key, position + 1, list)
  end

  @doc """
  Receives a list of tuples and replaces the item
  identified by `key` at position `pos` if it exists.

  ## Examples

      iex> List.keyreplace([a: 1, b: 2], :a, 0, { :a, 3 })
      [a: 3, b: 2]

  """
  def keyreplace(list, key, position, new_tuple) do
    :lists.keyreplace(key, position + 1, list, new_tuple)
  end

  @doc """
  Receives a list of tuples and replaces the item
  identified by `key` at position `pos`. If the item
  does not exist, it is added to the end of the list.

  ## Examples

      iex> List.keystore([a: 1, b: 2], :a, 0, { :a, 3 })
      [a: 3, b: 2]

  """
  def keystore(list, key, position, new_tuple) do
    :lists.keystore(key, position + 1, list, new_tuple)
  end

  @doc """
  Receives a list of tuples and deletes the first tuple
  where the item at position `posistion` matches with the
  given `item`. Returns the new tuple.

  ## Examples

      iex> List.keydelete([a: 1, b: 2], :a, 0)
      [{ :b, 2 }]

      iex> List.keydelete([a: 1, b: 2], 2, 1)
      [{ :a, 1 }]

      iex> List.keydelete([a: 1, b: 2], :c, 0)
      [{ :a, 1 }, { :b, 2 }]

  """
  def keydelete(list, key, position) do
    :lists.keydelete(key, position + 1, list)
  end

  @doc """
  Wraps the argument in a list.
  If the argument is already a list, returns the list.
  If the argument is nil, returns an empty list.

  ## Examples

      iex> List.wrap([1,2,3])
      [1,2,3]

  """
  def wrap(list) when is_list(list) do
    list
  end

  def wrap(nil) do
    []
  end

  def wrap(other) do
    [other]
  end

  @doc """
  Zips corresponding elements from each list in `list_of_lists`.

  ## Examples

      iex> List.zip([[1, 2], [3, 4], [5, 6]])
      [{1, 3, 5}, {2, 4, 6}]

      iex> List.zip([[1, 2], [3], [5, 6]])
      [{1, 3, 5}]

  """
  def zip([]), do: []
  def zip(list_of_lists) when is_list(list_of_lists) do
    do_zip(list_of_lists, [])
  end

  @doc """
  Unzips the given list of lists or tuples into separate lists and returns a
  list of lists.

  ## Examples

      iex> List.unzip([{1, 2}, {3, 4}])
      [[1, 3], [2, 4]]

      iex> List.unzip([{1, :a, "apple"}, {2, :b, "banana"}, {3, :c}])
      [[1, 2, 3], [:a, :b, :c]]

  """
  def unzip(list) when is_list(list) do
    :lists.map tuple_to_list(&1), zip(list)
  end

  @doc """
  Returns a list with an inserted value at specified index. Note that the index
  is capped at the list length and that negative indicies wraps around at the
  end of the list.

  ## Examples

      iex> List.insert_at([1, 2, 3, 4], 2, 0)
      [1, 2, 0, 3, 4]

      iex> List.insert_at([1, 2, 3], 10, 0)
      [1, 2, 3, 0]

      iex> List.insert_at([1, 2, 3], -1, 0)
      [1, 2, 0, 3]

  """
  def insert_at(list, index, value) do
    if index < 0 do
      do_insert_at(list, length(list) + index, value)
    else
      do_insert_at(list, index, value)
    end
  end

  ## Helpers

  # insert_at

  defp do_insert_at([], _index, value) do
    [ value ]
  end

  defp do_insert_at(list, index, value) when index <= 0 do
    [ value | list ]
  end

  defp do_insert_at([h|t], index, value) do
    [ h | do_insert_at(t, index - 1, value) ]
  end

  # zip

  defp do_zip(list, acc) do
    converter = fn x, acc -> do_zip_each(to_list(x), acc) end
    {mlist, heads} = :lists.mapfoldl converter, [], list

    case heads do
      nil -> :lists.reverse acc
      _   -> do_zip mlist, [list_to_tuple(:lists.reverse(heads))|acc]
    end
  end

  defp do_zip_each(_, nil) do
    { nil, nil }
  end

  defp do_zip_each([h|t], acc) do
    { t, [h|acc] }
  end

  defp do_zip_each([], _) do
    { nil, nil }
  end

  defp to_list(tuple) when is_tuple(tuple), do: tuple_to_list(tuple)
  defp to_list(list)  when is_list(list),   do: list
end


Use new comment syntax to disable Credo

Use new comment syntax to disable Credo

defmodule Credo.Execution.Task do
  @type t :: module

  @callback call(exec :: Credo.Execution.t, opts :: Keyword.t) :: Credo.Execution.t

  defmacro __using__(_opts \\ []) do
    quote do
      @behaviour Credo.Execution.Task
      import Credo.Execution
      alias Credo.Execution

      def call(%Execution{halted: false} = exec, opts) do
        exec
      end

      def error(exec, _opts) do
        IO.warn "Execution halted during #{__MODULE__}!"
      end

      defoverridable call: 2
      defoverridable error: 2
    end
  end

  def run(exec, task, opts \\ [])
  def run(%Credo.Execution{halted: false} = exec, task, opts) do
    #require Logger
    #Logger.debug "Calling #{task} ..."

    case task.call(exec, opts) do
      %Credo.Execution{halted: false} = exec ->
        exec
      %Credo.Execution{halted: true} = exec ->
        task.error(exec, opts)
      value ->
        # TODO: improve message
        IO.warn "Expected task to return %Credo.Execution{}, got:"
        # credo:disable-for-next-line
        IO.inspect value

        value
    end
  end
  def run(exec, _task, _opts) do
    exec
  end
end

defmodule Credo.Execution.Task do
  @type t :: module

  @callback call(exec :: Credo.Execution.t, opts :: Keyword.t) :: Credo.Execution.t

  defmacro __using__(_opts \\ []) do
    quote do
      @behaviour Credo.Execution.Task
      import Credo.Execution
      alias Credo.Execution

      def call(%Execution{halted: false} = exec, opts) do
        exec
      end

      def error(exec, _opts) do
        IO.warn "Execution halted during #{__MODULE__}!"
      end

      defoverridable call: 2
      defoverridable error: 2
    end
  end

  def run(exec, task, opts \\ [])
  def run(%Credo.Execution{halted: false} = exec, task, opts) do
    #require Logger
    #Logger.debug "Calling #{task} ..."

    case task.call(exec, opts) do
      %Credo.Execution{halted: false} = exec ->
        exec
      %Credo.Execution{halted: true} = exec ->
        task.error(exec, opts)
      value ->
        # TODO: improve message
        IO.warn "Expected task to return %Credo.Execution{}, got:"
        IO.inspect value

        value
    end
  end
  def run(exec, _task, _opts) do
    exec
  end
end


Fix type of executable passed to Port.open in IEx.CLI.tty_works/0

Change the executable to a charlist instead of an atom

# IEx sets the Erlang user to be IEx.CLI via the command line.
# While this works most of the time, there are some problems
# that may happen depending on how the booting process goes.
# Those problems need to be manually tested in case changes are
# done to this file.
#
# 1. In some situations, printing something before the shell
#    starts becomes very slow. To verify this feature, just
#    get an existing project and run:
#
#      $ mix clean
#      $ iex -S mix
#
#    If the printing of data is slower than usual. This particular
#    bug has arisen;
#
# 2. In some situations, connecting to a remote node via --remsh
#    is not possible. This can be tested by starting two iex nodes:
#
#      $ iex --sname foo
#      $ iex --sname bar --remsh foo@localhost
#
# 3. When still using --remsh, we need to guarantee the arguments
#    are processed on the local node and not the remote one. For such,
#    one can replace the last line above by:
#
#      $ iex --sname bar --remsh foo@localhost -e IO.inspect node
#
#    And verify that the local node name is printed.
#
# 4. Finally, in some other circunstances, printing messages may become
#    borked. This can be verified with:
#
#      $ iex -e ":error_logger.info_msg("foo~nbar", [])"
#
# By the time those instructions have been written, all tests above pass.
defmodule IEx.CLI do
  @moduledoc false

  @doc """
  In order to work properly, IEx needs to be set as the
  proper `-user` when starting the Erlang VM and we do so
  by pointing exactly to this function.

  If possible, Elixir will start a tty (smart terminal)
  which makes all control commands available in tty
  available to the developer.

  In case `tty` is not available (for example, Windows),
  a dumb terminal version is started instead.
  """
  def start do
    if tty_works? do
      :user_drv.start([:"tty_sl -c -e", tty_args])
    else
      :user.start
      IO.puts "Warning: could not run smart terminal, falling back to dumb one"
      local_start()
    end
  end

  # Check if tty works. If it does not, we fall back to the
  # simple/dumb terminal. This is starting the linked in
  # driver twice, it would be nice and appropriate if we had
  # to do it just once.
  defp tty_works? do
    try do
      port = Port.open { :spawn, 'tty_sl -c -e' }, [:eof]
      Port.close(port)
    catch
      _, _ -> false
    end
  end

  defp tty_args do
    if remote = get_remsh(:init.get_plain_arguments) do
      if is_alive do
        case :rpc.call remote, :code, :ensure_loaded, [IEx] do
          { :badrpc, reason } ->
            abort "Could not contact remote node #{remote}, reason: #{inspect reason}. Aborting..."
          { :module, IEx } ->
            { remote, :erlang, :apply, [remote_start_function, []] }
          _ ->
            abort "Could not find IEx on remote node #{remote}. Aborting..."
        end
      else
        abort "In order to use --remsh, you need to name the current node using --name or --sname. Aborting..."
      end
    else
      { :erlang, :apply, [local_start_function, []] }
    end
  end

  def local_start do
    IEx.start(config(), fn -> :elixir.start_cli end)
  end

  defp local_start_function do
    &local_start/0
  end

  defp remote_start_function do
    ref    = make_ref
    config = config()

    parent = spawn_link fn ->
      receive do
        { :begin, ^ref, other } ->
          :elixir.start_cli
          other <- { :done, ref }
      end
    end

    fn ->
      IEx.start(config, fn ->
        parent <- { :begin, ref, self }
        receive do: ({ :done, ^ref } -> :ok)
      end)
    end
  end

  defp config do
    [dot_iex_path: find_dot_iex(:init.get_plain_arguments)]
  end

  defp abort(msg) do
    function = fn ->
      IO.puts(:stderr, msg)
      System.halt(1)
    end
    { :erlang, :apply, [function, []] }
  end

  defp find_dot_iex(['--dot-iex', h|_]), do: String.from_char_list!(h)
  defp find_dot_iex([_|t]), do: find_dot_iex(t)
  defp find_dot_iex([]), do: nil

  defp get_remsh(['--remsh', h|_]), do: list_to_atom(h)
  defp get_remsh([_|t]), do: get_remsh(t)
  defp get_remsh([]), do: nil
end

# IEx sets the Erlang user to be IEx.CLI via the command line.
# While this works most of the time, there are some problems
# that may happen depending on how the booting process goes.
# Those problems need to be manually tested in case changes are
# done to this file.
#
# 1. In some situations, printing something before the shell
#    starts becomes very slow. To verify this feature, just
#    get an existing project and run:
#
#      $ mix clean
#      $ iex -S mix
#
#    If the printing of data is slower than usual. This particular
#    bug has arisen;
#
# 2. In some situations, connecting to a remote node via --remsh
#    is not possible. This can be tested by starting two iex nodes:
#
#      $ iex --sname foo
#      $ iex --sname bar --remsh foo@localhost
#
# 3. When still using --remsh, we need to guarantee the arguments
#    are processed on the local node and not the remote one. For such,
#    one can replace the last line above by:
#
#      $ iex --sname bar --remsh foo@localhost -e IO.inspect node
#
#    And verify that the local node name is printed.
#
# 4. Finally, in some other circunstances, printing messages may become
#    borked. This can be verified with:
#
#      $ iex -e ":error_logger.info_msg("foo~nbar", [])"
#
# By the time those instructions have been written, all tests above pass.
defmodule IEx.CLI do
  @moduledoc false

  @doc """
  In order to work properly, IEx needs to be set as the
  proper `-user` when starting the Erlang VM and we do so
  by pointing exactly to this function.

  If possible, Elixir will start a tty (smart terminal)
  which makes all control commands available in tty
  available to the developer.

  In case `tty` is not available (for example, Windows),
  a dumb terminal version is started instead.
  """
  def start do
    if tty_works? do
      :user_drv.start([:"tty_sl -c -e", tty_args])
    else
      :user.start
      IO.puts "Warning: could not run smart terminal, falling back to dumb one"
      local_start()
    end
  end

  # Check if tty works. If it does not, we fall back to the
  # simple/dumb terminal. This is starting the linked in
  # driver twice, it would be nice and appropriate if we had
  # to do it just once.
  defp tty_works? do
    try do
      port = Port.open { :spawn, :"tty_sl -c -e" }, [:eof]
      Port.close(port)
    catch
      _, _ -> false
    end
  end

  defp tty_args do
    if remote = get_remsh(:init.get_plain_arguments) do
      if is_alive do
        case :rpc.call remote, :code, :ensure_loaded, [IEx] do
          { :badrpc, reason } ->
            abort "Could not contact remote node #{remote}, reason: #{inspect reason}. Aborting..."
          { :module, IEx } ->
            { remote, :erlang, :apply, [remote_start_function, []] }
          _ ->
            abort "Could not find IEx on remote node #{remote}. Aborting..."
        end
      else
        abort "In order to use --remsh, you need to name the current node using --name or --sname. Aborting..."
      end
    else
      { :erlang, :apply, [local_start_function, []] }
    end
  end

  def local_start do
    IEx.start(config(), fn -> :elixir.start_cli end)
  end

  defp local_start_function do
    &local_start/0
  end

  defp remote_start_function do
    ref    = make_ref
    config = config()

    parent = spawn_link fn ->
      receive do
        { :begin, ^ref, other } ->
          :elixir.start_cli
          other <- { :done, ref }
      end
    end

    fn ->
      IEx.start(config, fn ->
        parent <- { :begin, ref, self }
        receive do: ({ :done, ^ref } -> :ok)
      end)
    end
  end

  defp config do
    [dot_iex_path: find_dot_iex(:init.get_plain_arguments)]
  end

  defp abort(msg) do
    function = fn ->
      IO.puts(:stderr, msg)
      System.halt(1)
    end
    { :erlang, :apply, [function, []] }
  end

  defp find_dot_iex(['--dot-iex', h|_]), do: String.from_char_list!(h)
  defp find_dot_iex([_|t]), do: find_dot_iex(t)
  defp find_dot_iex([]), do: nil

  defp get_remsh(['--remsh', h|_]), do: list_to_atom(h)
  defp get_remsh([_|t]), do: get_remsh(t)
  defp get_remsh([]), do: nil
end


Fixed reading .mix/config.exs

Fixed reading .mix/config.exs

defmodule Mix.CLI do
  @moduledoc false

  @doc """
  Runs Mix according to the command line arguments.
  """
  def main(args \\ System.argv) do
    Mix.Local.append_archives
    Mix.Local.append_paths

    case check_for_shortcuts(args) do
      :help ->
        proceed(["help"])
      :version ->
        display_version()
      nil ->
        proceed(args)
    end
  end

  defp proceed(args) do
    Mix.Tasks.Local.Hex.maybe_update()
    load_dot_config()
    args = load_mixfile(args)
    {task, args} = get_task(args)
    change_env(task)
    run_task(task, args)
  end

  defp load_mixfile(args) do
    file = System.get_env("MIX_EXS") || "mix.exs"
    if File.regular?(file) do
      Code.load_file(file)
    end
    args
  end

  defp get_task(["-" <> _|_]) do
    Mix.shell.error "** (Mix) Cannot implicitly pass flags to default mix task, " <>
                    "please invoke instead: mix #{Mix.Project.config[:default_task]}"
    exit(1)
  end

  defp get_task([h|t]) do
    {h, t}
  end

  defp get_task([]) do
    {Mix.Project.config[:default_task], []}
  end

  defp run_task(name, args) do
    try do
      if Mix.Project.get do
        Mix.Task.run "loadconfig"
        Mix.Task.run "deps.loadpaths", ["--no-deps-check"]
        Mix.Task.run "loadpaths", ["--no-elixir-version-check"]
        Mix.Task.reenable "deps.loadpaths"
        Mix.Task.reenable "loadpaths"
      end

      # If the task is not available, let's try to
      # compile the repository and then run it again.
      cond do
        Mix.Task.get(name) ->
          Mix.Task.run(name, args)
        Mix.Project.get ->
          Mix.Task.run("compile")
          Mix.Task.run(name, args)
        true ->
          # Raise no task error
          Mix.Task.get!(name)
      end
    rescue
      # We only rescue exceptions in the mix namespace, all
      # others pass through and will explode on the users face
      exception ->
        stacktrace = System.stacktrace

        cond do
          Map.get(exception, :mix_error, false) ->
            # IO.write :stderr, "warning: setting mix_error: true in Mix exceptions is deprecated, " <>
            #                   "please define a `:mix` field and use Mix.raise to raise them"
            Mix.shell.error "** (Mix) #{Exception.message(exception)}"

          info = Map.get(exception, :mix) ->
            mod = exception.__struct__ |> Module.split() |> Enum.at(0, "Mix")
            Mix.shell.error "** (#{mod})#{show_mix_info(info)} #{Exception.message(exception)}"

          true ->
            reraise exception, stacktrace
        end

        exit(1)
    end
  end

  defp show_mix_info({:project, proj}), do: " [#{inspect proj}]"
  defp show_mix_info({:app, app}),      do: " [#{app}]"
  defp show_mix_info(:none),            do: ""

  defp change_env(task) do
    if nil?(System.get_env("MIX_ENV")) &&
       (env = Mix.Project.config[:preferred_cli_env][task]) do
      Mix.env(env)
      if project = Mix.Project.pop do
        {project, _config, file} = project
        Mix.Project.push project, file
      end
    end
  end

  defp load_dot_config do
    path = Path.expand("~/.mix/config.exs")
    if File.regular?(path) do
      path
      |> Mix.Config.read!()
      |> Mix.Config.persist()
    end
  end

  defp display_version() do
    IO.puts "Elixir #{System.version}"
  end

  # Check for --help or --version in the args
  defp check_for_shortcuts([first_arg|_]) when first_arg in
      ["--help", "-h", "-help"], do: :help

  defp check_for_shortcuts([first_arg|_]) when first_arg in
      ["--version", "-v"], do: :version

  defp check_for_shortcuts(_), do: nil
end

defmodule Mix.CLI do
  @moduledoc false

  @doc """
  Runs Mix according to the command line arguments.
  """
  def main(args \\ System.argv) do
    Mix.Local.append_archives
    Mix.Local.append_paths

    case check_for_shortcuts(args) do
      :help ->
        proceed(["help"])
      :version ->
        display_version()
      nil ->
        proceed(args)
    end
  end

  defp proceed(args) do
    Mix.Tasks.Local.Hex.maybe_update()
    load_dot_config()
    args = load_mixfile(args)
    {task, args} = get_task(args)
    change_env(task)
    run_task(task, args)
  end

  defp load_mixfile(args) do
    file = System.get_env("MIX_EXS") || "mix.exs"
    if File.regular?(file) do
      Code.load_file(file)
    end
    args
  end

  defp get_task(["-" <> _|_]) do
    Mix.shell.error "** (Mix) Cannot implicitly pass flags to default mix task, " <>
                    "please invoke instead: mix #{Mix.Project.config[:default_task]}"
    exit(1)
  end

  defp get_task([h|t]) do
    {h, t}
  end

  defp get_task([]) do
    {Mix.Project.config[:default_task], []}
  end

  defp run_task(name, args) do
    try do
      if Mix.Project.get do
        Mix.Task.run "loadconfig"
        Mix.Task.run "deps.loadpaths", ["--no-deps-check"]
        Mix.Task.run "loadpaths", ["--no-elixir-version-check"]
        Mix.Task.reenable "deps.loadpaths"
        Mix.Task.reenable "loadpaths"
      end

      # If the task is not available, let's try to
      # compile the repository and then run it again.
      cond do
        Mix.Task.get(name) ->
          Mix.Task.run(name, args)
        Mix.Project.get ->
          Mix.Task.run("compile")
          Mix.Task.run(name, args)
        true ->
          # Raise no task error
          Mix.Task.get!(name)
      end
    rescue
      # We only rescue exceptions in the mix namespace, all
      # others pass through and will explode on the users face
      exception ->
        stacktrace = System.stacktrace

        cond do
          Map.get(exception, :mix_error, false) ->
            # IO.write :stderr, "warning: setting mix_error: true in Mix exceptions is deprecated, " <>
            #                   "please define a `:mix` field and use Mix.raise to raise them"
            Mix.shell.error "** (Mix) #{Exception.message(exception)}"

          info = Map.get(exception, :mix) ->
            mod = exception.__struct__ |> Module.split() |> Enum.at(0, "Mix")
            Mix.shell.error "** (#{mod})#{show_mix_info(info)} #{Exception.message(exception)}"

          true ->
            reraise exception, stacktrace
        end

        exit(1)
    end
  end

  defp show_mix_info({:project, proj}), do: " [#{inspect proj}]"
  defp show_mix_info({:app, app}),      do: " [#{app}]"
  defp show_mix_info(:none),            do: ""

  defp change_env(task) do
    if nil?(System.get_env("MIX_ENV")) &&
       (env = Mix.Project.config[:preferred_cli_env][task]) do
      Mix.env(env)
      if project = Mix.Project.pop do
        {project, _config, file} = project
        Mix.Project.push project, file
      end
    end
  end

  defp load_dot_config do
    path = Path.expand("~/.mix/config.exs")
    if File.regular?(path) do
      path
      |> Mix.Config.read()
      |> Mix.Config.persist()
    end
  end

  defp display_version() do
    IO.puts "Elixir #{System.version}"
  end

  # Check for --help or --version in the args
  defp check_for_shortcuts([first_arg|_]) when first_arg in
      ["--help", "-h", "-help"], do: :help

  defp check_for_shortcuts([first_arg|_]) when first_arg in
      ["--version", "-v"], do: :version

  defp check_for_shortcuts(_), do: nil
end


Remove unecessary new lines

Remove unecessary new lines

defmodule HTTParrot.Supervisor do
  use Supervisor

  def start_link do
    :supervisor.start_link({:local, __MODULE__}, __MODULE__, [])
  end

  def init([]) do
    children = []
    supervise children, strategy: :one_for_one
  end
end


Update tests (implicit `return` statement)

defmodule FarmbotOS.LuaTest do
  use ExUnit.Case
  use Mimic
  setup :verify_on_exit!
  alias FarmbotOS.Lua

  @tag :capture_log
  test "evaluates Lua" do
    assert Lua.eval_assertion("Returns 'true'", "return true")
    {:error, message1} = Lua.eval_assertion("Returns 'true'", "-1")

    assert message1 == "bad return value from expression evaluation"

    {:error, error} = Lua.eval_assertion("random error", "return (1/0)")
    assert error == :badarith
  end

  test "assertion logs" do
    # Hmmm
    expect(FarmbotCore.LogExecutor, :execute, 1, fn log ->
      assert log.level == "assertion"
      assert log.message == "this is an assertion"
      assert log.meta == %{assertion_passed: true, assertion_type: :assertion}
    end)

    Lua.log_assertion(true, :assertion, "this is an assertion")
  end
end

defmodule FarmbotOS.LuaTest do
  use ExUnit.Case
  use Mimic
  setup :verify_on_exit!
  alias FarmbotOS.Lua

  @tag :capture_log
  test "evaluates Lua" do
    assert Lua.eval_assertion("Returns 'true'", "return true")
    {:error, message1} = Lua.eval_assertion("Returns 'true'", "-1")

    assert message1 ==
             "failed to parse expression (line:1): syntax error before: '-'"

    {:error, error} = Lua.eval_assertion("random error", "return (1/0)")
    assert error == :badarith
  end

  test "assertion logs" do
    # Hmmm
    expect(FarmbotCore.LogExecutor, :execute, 1, fn log ->
      assert log.level == "assertion"
      assert log.message == "this is an assertion"
      assert log.meta == %{assertion_passed: true, assertion_type: :assertion}
    end)

    Lua.log_assertion(true, :assertion, "this is an assertion")
  end
end


Removed non-dev dependency

Removed non-dev dependency

# Copyright 2016 Apcera Inc. All rights reserved.
defmodule Nats.Mixfile do
  use Mix.Project

  @name "Nats"
  @git_url "https://github.com/nats-io/elixir-nats"
  @nats_io_url "https://nats.io/"
  @home_url @git_url
  @doc_url "https://nats-io.github.com/elixir-nats/"
  @description "NATS framework for Elixir"

  @version "0.1.5"

  def project do
    [app: :nats,
     version: @version,
     elixir: "~> 1.2",
     description: @description,
     package: package,
     source_url: @git_url,
     homepage_url: @home_url,
     deps: deps,
     name: @name,
     docs: [extras: ["README.md"], main: "readme",
            source_url: @git_url],
     test_coverage: [tool: ExCoveralls],
     preferred_cli_env: ["coveralls": :test, "coveralls.detail":
                         :test, "coveralls.post": :test]]
  end

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

  defp deps do
    [{:exrm, "~> 0.18.8", only: :dev},
     {:excoveralls, "~> 0.4.5", only: :test},
     {:benchfella, "~> 0.3.1", only: :dev},
     {:earmark, "~> 0.2.1", only: :dev},
     {:ex_doc, "~> 0.11.4", only: :dev}]
  end

  defp package do
    [
      name: "natsio",
      files: ~w(lib src bench mix.exs LICENSE README.md),
      maintainers: ["camros", "nats.io", "Apcera"],
      licenses: ["MIT"],
      links: %{"GitHub" => @git_url,
               "Docs" => @doc_url,
               "Nats.io" => @nats_io_url}
    ]
  end
end

# Copyright 2016 Apcera Inc. All rights reserved.
defmodule Nats.Mixfile do
  use Mix.Project

  @name "Nats"
  @git_url "https://github.com/nats-io/elixir-nats"
  @nats_io_url "https://nats.io/"
  @home_url @git_url
  @doc_url "https://nats-io.github.com/elixir-nats/"
  @description "NATS framework for Elixir"

  @version "0.1.5"

  def project do
    [app: :nats,
     version: @version,
     elixir: "~> 1.2",
     description: @description,
     package: package,
     source_url: @git_url,
     homepage_url: @home_url,
     deps: deps,
     name: @name,
     docs: [extras: ["README.md"], main: "readme",
            source_url: @git_url],
     test_coverage: [tool: ExCoveralls],
     preferred_cli_env: ["coveralls": :test, "coveralls.detail":
                         :test, "coveralls.post": :test]]
  end

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

  defp deps do
    [{:exrm, "~> 0.18.8", only: :dev},
     {:excoveralls, "~> 0.4.5", only: :test},
     {:benchfella, "~> 0.3.1"}, #only: :dev},
     {:earmark, "~> 0.2.1", only: :dev},
     {:ex_doc, "~> 0.11.4", only: :dev}]
  end

  defp package do
    [
      name: "natsio",
      files: ~w(lib src bench mix.exs LICENSE README.md),
      maintainers: ["camros", "nats.io", "Apcera"],
      licenses: ["MIT"],
      links: %{"GitHub" => @git_url,
               "Docs" => @doc_url,
               "Nats.io" => @nats_io_url}
    ]
  end
end


Update earmark dep to add only: :dev

Update earmark dep to add only: :dev

Problems compile on elixir 1.1.1 so added only: :dev to earmark dep

defmodule ExAdmin.Mixfile do
  use Mix.Project

  def project do
    [app: :ex_admin,
     version: "0.3.2",
     elixir: "~> 1.0",
     elixirc_paths: elixirc_paths(Mix.env),
     compilers: [:phoenix] ++ Mix.compilers,
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     name: "ExAdmin",
     docs: [extras: ["README.md"]],
     deps: deps]
  end

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

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

  defp deps do
    [
      {:phoenix, "~> 1.0.2", override: true},
      {:ecto, "~> 1.0.3", override: true },
      {:phoenix_ecto, "~> 1.1"},
      {:cowboy, "~> 1.0"},
      {:mariaex, ">= 0.0.0"},
      {:phoenix_html, "~> 2.1", override: true},
      {:phoenix_live_reload, "~> 1.0", only: :dev},
      {:factory_girl_elixir, "~> 0.1.1"},
      {:pavlov, "~> 0.1.2", only: :test},
      {:inflex, github: "smpallen99/inflex"},
      {:ex_form, github: "smpallen99/ex_form"},
      {:xain, github: "smpallen99/xain", override: true},
      {:scrivener, "~> 0.10.0"},
      {:csvlixir, "~> 1.0.0"},
      {:exactor, "~>1.0.0"},
      {:ex_doc, "~>0.10.0", only: :dev},
      {:earmark, ">= 0.0.0", only: :dev},
    ]
  end
end

defmodule ExAdmin.Mixfile do
  use Mix.Project

  def project do
    [app: :ex_admin,
     version: "0.3.2",
     elixir: "~> 1.0",
     elixirc_paths: elixirc_paths(Mix.env),
     compilers: [:phoenix] ++ Mix.compilers,
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     name: "ExAdmin",
     docs: [extras: ["README.md"]],
     deps: deps]
  end

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

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

  defp deps do
    [
      {:phoenix, "~> 1.0.2", override: true},
      {:ecto, "~> 1.0.3", override: true },
      {:phoenix_ecto, "~> 1.1"},
      {:cowboy, "~> 1.0"},
      {:mariaex, ">= 0.0.0"},
      {:phoenix_html, "~> 2.1", override: true},
      {:phoenix_live_reload, "~> 1.0", only: :dev},
      {:factory_girl_elixir, "~> 0.1.1"},
      {:pavlov, "~> 0.1.2", only: :test},
      {:inflex, github: "smpallen99/inflex"},
      {:ex_form, github: "smpallen99/ex_form"},
      {:xain, github: "smpallen99/xain", override: true},
      {:scrivener, "~> 0.10.0"},
      {:csvlixir, "~> 1.0.0"},
      {:exactor, "~>1.0.0"},
      {:ex_doc, "~>0.10.0", only: :dev},
      {:earmark, ">= 0.0.0"},
    ]
  end
end


Do not include ex_doc or earmark in package deps

defmodule Conform.Mixfile do
  use Mix.Project

  @compile_peg_task "tasks/compile.peg.exs"
  @do_peg_compile?  File.exists?(@compile_peg_task)
  if @do_peg_compile? do
    Code.eval_file @compile_peg_task
  end

  def project do
    [app: :conform,
     version: "1.0.0-rc6",
     elixir: "~> 1.0",
     escript: [main_module: Conform],
     compilers: compilers(@do_peg_compile?),
     description: description,
     package: package,
     deps: deps(@do_peg_compile?)]
  end

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

  defp compilers(true), do: [:peg, :erlang, :elixir, :app]
  defp compilers(_),    do: nil

  defp deps(true) do
    [{:neotoma, "~> 1.7.3"},
     {:ex_doc, "~> 0.10", only: [:docs, :dev]},
     {:earmark, "> 0.0.0", only: [:docs, :dev]}] ++ core_deps()
  end
  defp deps(_), do: core_deps()

  defp core_deps(), do: [
    {:exrm, "~> 1.0.0-rc5", optional: true},
  ]

  defp description, do: "Easy release configuration for Elixir apps."
  defp package do
    [ files: ["lib", "src", "priv", "mix.exs", "README.md", "LICENSE"],
      maintainers: ["Paul Schoenfelder"],
      licenses: ["MIT"],
      links: %{ "GitHub": "https://github.com/bitwalker/conform" } ]
  end
end

defmodule Conform.Mixfile do
  use Mix.Project

  @compile_peg_task "tasks/compile.peg.exs"
  @do_peg_compile?  File.exists?(@compile_peg_task)
  if @do_peg_compile? do
    Code.eval_file @compile_peg_task
  end

  def project do
    [app: :conform,
     version: "1.0.0-rc6",
     elixir: "~> 1.0",
     escript: [main_module: Conform],
     compilers: compilers(@do_peg_compile?),
     description: description,
     package: package,
     deps: deps(@do_peg_compile?)]
  end

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

  defp compilers(true), do: [:peg, :erlang, :elixir, :app]
  defp compilers(_),    do: nil

  defp deps(true), do: [{:neotoma, "~> 1.7.3"}] ++ core_deps()
  defp deps(_),    do: core_deps()

  defp core_deps(), do: [
    {:exrm, "~> 1.0.0-rc5", optional: true},
    {:ex_doc, "~> 0.7", only: [:docs, :dev]},
    {:earmark, "~> 0.1", only: [:docs, :dev]}
  ]

  defp description, do: "Easy release configuration for Elixir apps."
  defp package do
    [ files: ["lib", "src", "priv", "mix.exs", "README.md", "LICENSE"],
      maintainers: ["Paul Schoenfelder"],
      licenses: ["MIT"],
      links: %{ "GitHub": "https://github.com/bitwalker/conform" } ]
  end
end


Bump version to 0.8.3

Bump version to 0.8.3

defmodule Credo.Mixfile do
  use Mix.Project

  def project do
    [
      app: :credo,
      version: "0.8.3",
      elixir: "~> 1.1",
      escript: [main_module: Credo.CLI],
      build_embedded: Mix.env == :prod,
      start_permanent: Mix.env == :prod,
      deps: deps(),
      test_coverage: [tool: Coverex.Task],
      name: "Credo",
      description: "A static code analysis tool with a focus on code consistency and teaching.",
      package: package()
    ]
  end

  defp package do
    [
      files: [".credo.exs", ".template.check.ex", "lib", "mix.exs",
              "README.md", "LICENSE"],
      maintainers: ["René Föhring"],
      licenses: ["MIT"],
      links: %{"GitHub" => "https://github.com/rrrene/credo"},
    ]
  end

  def application do
    [mod: {Credo, []}, applications: [:bunt, :logger, :inets]]
  end

  defp deps do
    [
      {:bunt, "~> 0.2.0"},
      {:inch_ex, "~> 0.5.3", only: [:dev, :test]},
      {:coverex, "~> 1.4.9", only: :test}
    ]
  end
end

defmodule Credo.Mixfile do
  use Mix.Project

  def project do
    [
      app: :credo,
      version: "0.8.2",
      elixir: "~> 1.1",
      escript: [main_module: Credo.CLI],
      build_embedded: Mix.env == :prod,
      start_permanent: Mix.env == :prod,
      deps: deps(),
      test_coverage: [tool: Coverex.Task],
      name: "Credo",
      description: "A static code analysis tool with a focus on code consistency and teaching.",
      package: package()
    ]
  end

  defp package do
    [
      files: [".credo.exs", ".template.check.ex", "lib", "mix.exs",
              "README.md", "LICENSE"],
      maintainers: ["René Föhring"],
      licenses: ["MIT"],
      links: %{"GitHub" => "https://github.com/rrrene/credo"},
    ]
  end

  def application do
    [mod: {Credo, []}, applications: [:bunt, :logger, :inets]]
  end

  defp deps do
    [
      {:bunt, "~> 0.2.0"},
      {:inch_ex, "~> 0.5.3", only: [:dev, :test]},
      {:coverex, "~> 1.4.9", only: :test}
    ]
  end
end


Bump version number

Bump version number

defmodule Vutuv.Mixfile do
  use Mix.Project

  def project do
    [app: :vutuv,
     version: "1.2.53",
     elixir: "~> 1.4.0",
     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: {Vutuv, []},
     applications: [:phoenix,
                    :phoenix_pubsub,
                    :phoenix_html,
                    :cowboy,
                    :logger,
                    :gettext,
                    :phoenix_ecto,
                    :ex_machina,
                    :phoenix_html_simplified_helpers,
                    :bamboo,
                    :bamboo_smtp,
                    :mariaex,
                    :httpoison,
                    :slugger,
                    :timex_ecto,
                    :word_smith,
                    :arc,
                    :arc_ecto,
                    :quantum]]
  end

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

  # Specifies your project dependencies.
  #
  # Type `mix help deps` for examples and options.
  defp deps do
    [{:ecto, "~> 2.0.1", override: true},
     {:bamboo, "~> 0.6"},
     {:bamboo_smtp, "~> 1.1.0"},
     {:phoenix, "~> 1.2.0"},
     {:phoenix_ecto, "~> 3.0.0-rc"},
     {:phoenix_html, "~> 2.8"},
     {:phoenix_live_reload, "~> 1.0", only: :dev},
     {:gettext, "~> 0.12.1"},
     {:cowboy, "~> 1.0"},
     {:arc, "~> 0.5.3"},
     {:arc_ecto, "~> 0.4.2"},
     {:ex_machina, "~> 1.0"},
     {:phoenix_html_simplified_helpers, "~> 0.6.0"},
     {:mariaex, ">= 0.0.0"},
     {:word_smith, "~> 0.1.0"},
     {:slugger, "~> 0.1.0"},
     {:httpoison, "~> 0.9.0"},
     {:distillery, "~> 0.10"},
     {:quantum, ">= 1.8.1"}]
  end

  # Aliases are shortcut 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 Vutuv.Mixfile do
  use Mix.Project

  def project do
    [app: :vutuv,
     version: "1.2.52",
     elixir: "~> 1.4.0",
     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: {Vutuv, []},
     applications: [:phoenix,
                    :phoenix_pubsub,
                    :phoenix_html,
                    :cowboy,
                    :logger,
                    :gettext,
                    :phoenix_ecto,
                    :ex_machina,
                    :phoenix_html_simplified_helpers,
                    :bamboo,
                    :bamboo_smtp,
                    :mariaex,
                    :httpoison,
                    :slugger,
                    :timex_ecto,
                    :word_smith,
                    :arc,
                    :arc_ecto,
                    :quantum]]
  end

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

  # Specifies your project dependencies.
  #
  # Type `mix help deps` for examples and options.
  defp deps do
    [{:ecto, "~> 2.0.1", override: true},
     {:bamboo, "~> 0.6"},
     {:bamboo_smtp, "~> 1.1.0"},
     {:phoenix, "~> 1.2.0"},
     {:phoenix_ecto, "~> 3.0.0-rc"},
     {:phoenix_html, "~> 2.8"},
     {:phoenix_live_reload, "~> 1.0", only: :dev},
     {:gettext, "~> 0.12.1"},
     {:cowboy, "~> 1.0"},
     {:arc, "~> 0.5.3"},
     {:arc_ecto, "~> 0.4.2"},
     {:ex_machina, "~> 1.0"},
     {:phoenix_html_simplified_helpers, "~> 0.6.0"},
     {:mariaex, ">= 0.0.0"},
     {:word_smith, "~> 0.1.0"},
     {:slugger, "~> 0.1.0"},
     {:httpoison, "~> 0.9.0"},
     {:distillery, "~> 0.10"},
     {:quantum, ">= 1.8.1"}]
  end

  # Aliases are shortcut 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


Bump version number

Bump version number

defmodule Vutuv.Mixfile do
  use Mix.Project

  def project do
    [app: :vutuv,
     version: "1.2.28",
     elixir: "~> 1.0",
     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: {Vutuv, []},
     applications: [:phoenix,
                    :phoenix_pubsub,
                    :phoenix_html,
                    :cowboy,
                    :logger,
                    :gettext,
                    :phoenix_ecto,
                    :ex_machina,
                    :phoenix_html_simplified_helpers,
                    :bamboo,
                    :bamboo_smtp,
                    :mariaex,
                    :httpoison,
                    :slugger,
                    :timex_ecto,
                    :word_smith,
                    :arc,
                    :arc_ecto]]
  end

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

  # Specifies your project dependencies.
  #
  # Type `mix help deps` for examples and options.
  defp deps do
    [{:ecto, "~> 2.0.1", override: true},
     {:bamboo, "~> 0.6"},
     {:bamboo_smtp, "~> 1.1.0"},
     {:phoenix, "~> 1.2.0"},
     {:phoenix_ecto, "~> 3.0.0-rc"},
     {:phoenix_html, "~> 2.8"},
     {:phoenix_live_reload, "~> 1.0", only: :dev},
     {:gettext, "~> 0.12.1"},
     {:cowboy, "~> 1.0"},
     {:arc, "~> 0.5.3"},
     {:arc_ecto, "~> 0.4.2"},
     {:ex_machina, "~> 1.0"},
     {:phoenix_html_simplified_helpers, "~> 0.6.0"},
     {:mariaex, ">= 0.0.0"},
     {:word_smith, "~> 0.1.0"},
     {:slugger, "~> 0.1.0"},
     {:httpoison, "~> 0.9.0"},
     {:distillery, "~> 0.10"}]
  end

  # Aliases are shortcut 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 Vutuv.Mixfile do
  use Mix.Project

  def project do
    [app: :vutuv,
     version: "1.2.27",
     elixir: "~> 1.0",
     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: {Vutuv, []},
     applications: [:phoenix,
                    :phoenix_pubsub,
                    :phoenix_html,
                    :cowboy,
                    :logger,
                    :gettext,
                    :phoenix_ecto,
                    :ex_machina,
                    :phoenix_html_simplified_helpers,
                    :bamboo,
                    :bamboo_smtp,
                    :mariaex,
                    :httpoison,
                    :slugger,
                    :timex_ecto,
                    :word_smith,
                    :arc,
                    :arc_ecto]]
  end

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

  # Specifies your project dependencies.
  #
  # Type `mix help deps` for examples and options.
  defp deps do
    [{:ecto, "~> 2.0.1", override: true},
     {:bamboo, "~> 0.6"},
     {:bamboo_smtp, "~> 1.1.0"},
     {:phoenix, "~> 1.2.0"},
     {:phoenix_ecto, "~> 3.0.0-rc"},
     {:phoenix_html, "~> 2.8"},
     {:phoenix_live_reload, "~> 1.0", only: :dev},
     {:gettext, "~> 0.12.1"},
     {:cowboy, "~> 1.0"},
     {:arc, "~> 0.5.3"},
     {:arc_ecto, "~> 0.4.2"},
     {:ex_machina, "~> 1.0"},
     {:phoenix_html_simplified_helpers, "~> 0.6.0"},
     {:mariaex, ">= 0.0.0"},
     {:word_smith, "~> 0.1.0"},
     {:slugger, "~> 0.1.0"},
     {:httpoison, "~> 0.9.0"},
     {:distillery, "~> 0.10"}]
  end

  # Aliases are shortcut 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 talonframework

update talonframework

defmodule ExAdmin.Mixfile do
  use Mix.Project

  def project do
    [app: :ex_admin,
     version: "0.1.0",
     elixir: "~> 1.4",
     elixirc_paths: elixirc_paths(Mix.env),
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     deps: deps()]
  end

  def application do
    [extra_applications: [:logger],
     mod: {ExAdmin.Application, [:inflex]}]
  end

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

  defp deps do
    [
      {:inflex, "~> 1.7"},
      {:phoenix, "~> 1.3.0-rc"},
      {:phoenix_html, "~> 2.6"},
      {:phoenix_ecto, "~> 3.2"},
      {:scrivener_ecto, "~> 1.1"},
      {:postgrex, ">= 0.0.0", only: :test},
      {:phoenix_slime, github: "slime-lang/phoenix_slime"},
      {:ecto_ex_admin, github: "talonframework/ecto_ex_admin", only: :test},
      # {:ecto_ex_admin, path: "../ecto_ex_admin", only: :test},
    ]
  end
end

defmodule ExAdmin.Mixfile do
  use Mix.Project

  def project do
    [app: :ex_admin,
     version: "0.1.0",
     elixir: "~> 1.4",
     elixirc_paths: elixirc_paths(Mix.env),
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     deps: deps()]
  end

  def application do
    [extra_applications: [:logger],
     mod: {ExAdmin.Application, [:inflex]}]
  end

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

  defp deps do
    [
      {:inflex, "~> 1.7"},
      {:phoenix, "~> 1.3.0-rc"},
      {:phoenix_html, "~> 2.6"},
      {:phoenix_ecto, "~> 3.2"},
      {:scrivener_ecto, "~> 1.1"},
      {:postgrex, ">= 0.0.0", only: :test},
      {:phoenix_slime, github: "slime-lang/phoenix_slime"},
      {:ecto_ex_admin, github: "ex-admin/ecto_ex_admin", only: :test},
      # {:ecto_ex_admin, path: "../ecto_ex_admin", only: :test},
    ]
  end
end


Increment version [ci skip]

Increment version [ci skip]

defmodule Gateway.Mixfile do
  use Mix.Project

  @version "0.1.4"

  def project do
    [app: :gateway,
     description: "Add description to your package.",
     package: package(),
     version: @version,
     elixir: "~> 1.3",
     elixirc_paths: elixirc_paths(Mix.env),
     compilers: [] ++ 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, :confex, :cowboy, :plug, :postgrex, :ecto, :ecto_enum, :timex, :joken, :ex_json_schema,
                     :poison, :uuid, :httpoison, :ex_statsd],
      mod: {Gateway, []}
    ]
  end

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

  # 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, "~> 0.10.1"},
     {:confex, "~> 1.4"},
     {:plug, ">= 0.0.0"},
     {:cowboy, ">= 0.0.0"},
     {:postgrex, ">= 0.0.0", override: true},
     {:ecto, ">= 2.1.0-rc.2", override: true},
     {:ecto_enum, git: "https://github.com/gjaldon/ecto_enum", branch: "ecto-2.0", override: true},
     {:timex, "~> 3.0"},
     {:poison, "~> 2.0"},
     {:joken, "~> 1.3"},
     {:ex_json_schema, ">= 0.0.0"},
     {:httpoison, ">= 0.0.0"},
     {:uuid, ">= 0.0.0"},
     {:cassandra, ">= 1.0.0-beta"},
     {:httpoison, ">= 0.0.0"},
     {:ex_statsd, ">= 0.5.1"},
     {:faker, "~> 0.7.0", only: [:dev, :test]},
     {:dogma, "> 0.1.0", only: [:dev, :test]},
     {:benchfella, "~> 0.3", only: [:dev, :test]},
     {:ex_doc, ">= 0.0.0", only: [:dev, :test]},
     {:excoveralls, "~> 0.5", only: [:dev, :test]},
     {:credo, ">= 0.4.8", only: [:dev, :test]},
    ]
  end

  # Settings for publishing in Hex package manager:
  defp package do
    [contributors: ["Nebo #15"],
     maintainers: ["Nebo #15"],
     licenses: ["LISENSE.md"],
     links: %{github: "https://github.com/Nebo15/os.gateway"},
     files: ~w(lib LICENSE.md mix.exs README.md)]
  end

  defp aliases do
    ["ecto.setup": ["ecto.create --quiet",
                    "ecto.migrate",
                    "run priv/repos/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.3"

  def project do
    [app: :gateway,
     description: "Add description to your package.",
     package: package(),
     version: @version,
     elixir: "~> 1.3",
     elixirc_paths: elixirc_paths(Mix.env),
     compilers: [] ++ 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, :confex, :cowboy, :plug, :postgrex, :ecto, :ecto_enum, :timex, :joken, :ex_json_schema,
                     :poison, :uuid, :httpoison, :ex_statsd],
      mod: {Gateway, []}
    ]
  end

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

  # 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, "~> 0.10.1"},
     {:confex, "~> 1.4"},
     {:plug, ">= 0.0.0"},
     {:cowboy, ">= 0.0.0"},
     {:postgrex, ">= 0.0.0", override: true},
     {:ecto, ">= 2.1.0-rc.2", override: true},
     {:ecto_enum, git: "https://github.com/gjaldon/ecto_enum", branch: "ecto-2.0", override: true},
     {:timex, "~> 3.0"},
     {:poison, "~> 2.0"},
     {:joken, "~> 1.3"},
     {:ex_json_schema, ">= 0.0.0"},
     {:httpoison, ">= 0.0.0"},
     {:uuid, ">= 0.0.0"},
     {:cassandra, ">= 1.0.0-beta"},
     {:httpoison, ">= 0.0.0"},
     {:ex_statsd, ">= 0.5.1"},
     {:faker, "~> 0.7.0", only: [:dev, :test]},
     {:dogma, "> 0.1.0", only: [:dev, :test]},
     {:benchfella, "~> 0.3", only: [:dev, :test]},
     {:ex_doc, ">= 0.0.0", only: [:dev, :test]},
     {:excoveralls, "~> 0.5", only: [:dev, :test]},
     {:credo, ">= 0.4.8", only: [:dev, :test]},
    ]
  end

  # Settings for publishing in Hex package manager:
  defp package do
    [contributors: ["Nebo #15"],
     maintainers: ["Nebo #15"],
     licenses: ["LISENSE.md"],
     links: %{github: "https://github.com/Nebo15/os.gateway"},
     files: ~w(lib LICENSE.md mix.exs README.md)]
  end

  defp aliases do
    ["ecto.setup": ["ecto.create --quiet",
                    "ecto.migrate",
                    "run priv/repos/seeds.exs"],
     "ecto.reset": ["ecto.drop", "ecto.setup"],
     "test":       ["ecto.create --quiet",
                    "ecto.migrate",
                    "test"]]
  end
end


Adds `:build_embedded` and `:start_permanent` options (#15)

* Adds `:build_embedded` and `:start_permanent` options

Changes:
1. Modified `project/0` function
2. Bumped `credo` version, see https://github.com/rrrene/credo/issues/210

Closes #14

* Tries to fix `credo` issue on elixir->1.2

defmodule Recaptcha.Mixfile do
  use Mix.Project

  def project do
    [
      app: :recaptcha,
      version: "2.1.1",
      elixir: "~> 1.2",
      description: description(),
      deps: deps(),
      package: package(),

      build_embedded: Mix.env == :prod,
      start_permanent: Mix.env == :prod,

      # Test coverage:
      test_coverage: [tool: ExCoveralls],
      preferred_cli_env: [
        "coveralls": :test,
        "coveralls.detail": :test,
        "coveralls.post": :test,
        "coveralls.html": :test,
      ],
   ]
  end

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

  defp description do
    """
    A simple reCaptcha package for Elixir applications, provides verification
    and templates for rendering forms with the reCaptcha widget
    """
  end

  defp deps do
    [
      {:httpoison, "~> 0.9.0"},
      {:poison, "~> 1.5 or ~> 2.0"},
      {:credo, "~> 0.6", only: [:dev, :test]},
      {:ex_doc, ">= 0.0.0", only: :dev},
      {:excoveralls, "~> 0.5", only: :test},
    ]
  end

  defp package do
    [files: ["lib", "mix.exs", "README.md", "LICENSE"],
     maintainers: ["Samuel Seay", "Nikita Sobolev", "Michael JustMikey"],
     licenses: ["MIT"],
     links: %{"GitHub" => "https://github.com/samueljseay/recaptcha"}]
  end
end

defmodule Recaptcha.Mixfile do
  use Mix.Project

  def project do
    [
      app: :recaptcha,
      version: "2.1.1",
      elixir: "~> 1.2",
      description: description(),
      deps: deps(),
      package: package(),

      # Test coverage:
      test_coverage: [tool: ExCoveralls],
      preferred_cli_env: [
        "coveralls": :test,
        "coveralls.detail": :test,
        "coveralls.post": :test,
        "coveralls.html": :test,
      ],
   ]
  end

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

  defp description do
    """
    A simple reCaptcha package for Elixir applications, provides verification
    and templates for rendering forms with the reCaptcha widget
    """
  end

  defp deps do
    [
      {:httpoison, "~> 0.9.0"},
      {:poison, "~> 1.5 or ~> 2.0"},
      {:credo, "~> 0.6", only: [:dev, :test]},
      {:ex_doc, ">= 0.0.0", only: :dev},
      {:excoveralls, "~> 0.5", only: :test},
    ]
  end

  defp package do
    [files: ["lib", "mix.exs", "README.md", "LICENSE"],
     maintainers: ["Samuel Seay"],
     licenses: ["MIT"],
     links: %{"GitHub" => "https://github.com/samueljseay/recaptcha"}]
  end
end


Bump to 1.0.0-rc.1

Bump to 1.0.0-rc.1

unless Code.ensure_loaded?(Appsignal.Agent) do
  {_, _} = Code.eval_file("agent.ex")
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} ->
        :ok = Mix.Appsignal.Helper.ensure_downloaded(arch)
        :ok = Mix.Appsignal.Helper.compile
      {: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
    end
  end
end

defmodule Appsignal.Mixfile do
  use Mix.Project
  @agent_version Appsignal.Agent.version

  def project do
    [app: :appsignal,
     version: "1.0.0-rc.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: [logo: "logo.png", extras: ["Roadmap.md"]],
     agent_version: @agent_version
    ]
  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.ex"],
      maintainers: ["Arjan Scherpenisse", "Jeff Kreeftmeijer", "Tom de Bruijn"],
      licenses: ["MIT"],
      links: %{"GitHub" => "https://github.com/appsignal/appsignal-elixir"}}
  end

  def application do
    [mod: {Appsignal, []},
     applications: [:logger, :decorator, :httpoison]]
  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
    [
      {:httpoison, "~> 0.11"},
      {:decorator, "~> 1.0"},
      {:phoenix, "~> 1.2.0", optional: true, only: [:prod, :test_phoenix]},
      {:mock, "~> 0.2.1", only: [:test, :test_phoenix, :test_no_nif]},
      {:bypass, "~> 0.5", only: [:test, :test_phoenix, :test_no_nif]},
      {:ex_doc, "~> 0.12", only: :dev}
    ]
  end
end

unless Code.ensure_loaded?(Appsignal.Agent) do
  {_, _} = Code.eval_file("agent.ex")
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} ->
        :ok = Mix.Appsignal.Helper.ensure_downloaded(arch)
        :ok = Mix.Appsignal.Helper.compile
      {: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
    end
  end
end

defmodule Appsignal.Mixfile do
  use Mix.Project
  @agent_version Appsignal.Agent.version

  def project do
    [app: :appsignal,
     version: "0.13.0",
     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: [logo: "logo.png", extras: ["Roadmap.md"]],
     agent_version: @agent_version
    ]
  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.ex"],
      maintainers: ["Arjan Scherpenisse", "Jeff Kreeftmeijer", "Tom de Bruijn"],
      licenses: ["MIT"],
      links: %{"GitHub" => "https://github.com/appsignal/appsignal-elixir"}}
  end

  def application do
    [mod: {Appsignal, []},
     applications: [:logger, :decorator, :httpoison]]
  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
    [
      {:httpoison, "~> 0.11"},
      {:decorator, "~> 1.0"},
      {:phoenix, "~> 1.2.0", optional: true, only: [:prod, :test_phoenix]},
      {:mock, "~> 0.2.1", only: [:test, :test_phoenix, :test_no_nif]},
      {:bypass, "~> 0.5", only: [:test, :test_phoenix, :test_no_nif]},
      {:ex_doc, "~> 0.12", only: :dev}
    ]
  end
end


Remove mix file comments

Remove mix file comments

defmodule Rprel.Mixfile do
  use Mix.Project

  def project do
    [app: :rprel,
     version: "1.0.0",
     elixir: "~> 1.2",
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     escript: [main_module: Rprel.CLI],
     deps: deps]
  end

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

  defp deps do
    [{:poison, "~>2.0"},
     {:httpoison, "~> 0.8"},
     {:uri_template, "~>1.0"},
     {:bypass, "~> 0.1", only: :test},
     {:mix_test_watch, "~> 0.2", only: :dev},
     {:timex, "~> 2.1.6"}]
  end
end

defmodule Rprel.Mixfile do
  use Mix.Project

  def project do
    [app: :rprel,
     version: "1.0.0",
     elixir: "~> 1.2",
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     escript: [main_module: Rprel.CLI],
     deps: deps]
  end

  # Configuration for the OTP application
  #
  # Type "mix help compile.app" for more information
  def application do
    [applications: [:logger, :httpoison]]
  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
    [{:poison, "~>2.0"},
     {:httpoison, "~> 0.8"},
     {:uri_template, "~>1.0"},
     {:bypass, "~> 0.1", only: :test},
     {:mix_test_watch, "~> 0.2", only: :dev},
     {:timex, "~> 2.1.6"}]
  end
end


Update elixir version

Update elixir version

defmodule Rotor.Mixfile do
  use Mix.Project

  def project do
    [app: :rotor,
     version: "0.1.5",
     elixir: ">= 0.13.3",
     description: description,
     package: package,
     deps: deps]
  end

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

  defp description do
    """
    Rotor is a build system for Elixir projects. Use it to compile things, run commands or do anything that requires being run when files change.
    """
  end

  defp package do
    [
      contributors: ["Akash Manohar J"],
      links: %{ "GitHub" => "https://github.com/HashNuke/rotor" }
    ]
  end

  # Dependencies can be hex.pm packages:
  #
  #   {:mydep, "~> 0.3.0"}
  #
  # Or git/path repositories:
  #
  #   {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1"}
  #
  # Type `mix help deps` for more examples and options
  defp deps do
    []
  end
end

defmodule Rotor.Mixfile do
  use Mix.Project

  def project do
    [app: :rotor,
     version: "0.1.5",
     elixir: "~> 0.13.3",
     description: description,
     package: package,
     deps: deps]
  end

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

  defp description do
    """
    Rotor is a build system for Elixir projects. Use it to compile things, run commands or do anything that requires being run when files change.
    """
  end

  defp package do
    [
      contributors: ["Akash Manohar J"],
      links: %{ "GitHub" => "https://github.com/HashNuke/rotor" }
    ]
  end

  # Dependencies can be hex.pm packages:
  #
  #   {:mydep, "~> 0.3.0"}
  #
  # Or git/path repositories:
  #
  #   {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1"}
  #
  # Type `mix help deps` for more examples and options
  defp deps do
    []
  end
end


Add package info

Add package info

defmodule CryptoExchanges.Mixfile do
  use Mix.Project

  def project do
    [
      app: :crypto_exchanges,
      version: "0.1.0",
      elixir: "~> 1.5",
      start_permanent: Mix.env == :prod,
      deps: deps(),
      package: package(),
      test_coverage: [tool: ExCoveralls],
      preferred_cli_env: [
        "coveralls": :test,
        "coveralls.detail": :test,
        "coveralls.post": :test,
        "coveralls.html": :test,
        "vcr": :test,
        "vcr.delete": :test,
        "vcr.check": :test,
        "vcr.show": :test
      ],
    ]
  end

  # Run "mix help compile.app" to learn about applications.
  def application do
    [
      extra_applications: [:logger]
    ]
  end

  # Run "mix help deps" to learn about dependencies.
  defp deps do
    [
      {:credo, ">= 0.0.0", only: [:dev, :test]},
      {:excoveralls, "~> 0.7", only: :test},
      {:exvcr, "~> 0.9", only: :test},
      {:httpoison, ">= 0.0.0"},
      {:mix_test_watch, "~> 0.3", only: :dev, runtime: false},
      {:poison, ">= 0.0.0"}
    ]
  end

  defp package do
    [
      maintainers: ["Sascha Brink"],
      licenses: ["MIT"],
      links: %{"GitHub" => "https://github.com/sbrink/crypto_exchanges_elixir"}
    ]
  end
end

defmodule CryptoExchanges.Mixfile do
  use Mix.Project

  def project do
    [
      app: :crypto_exchanges,
      version: "0.1.0",
      elixir: "~> 1.5",
      start_permanent: Mix.env == :prod,
      deps: deps(),
      test_coverage: [tool: ExCoveralls],
      preferred_cli_env: [
        "coveralls": :test,
        "coveralls.detail": :test,
        "coveralls.post": :test,
        "coveralls.html": :test,
        "vcr": :test,
        "vcr.delete": :test,
        "vcr.check": :test,
        "vcr.show": :test
      ],
    ]
  end

  # Run "mix help compile.app" to learn about applications.
  def application do
    [
      extra_applications: [:logger]
    ]
  end

  # Run "mix help deps" to learn about dependencies.
  defp deps do
    [
      {:credo, ">= 0.0.0", only: [:dev, :test]},
      {:excoveralls, "~> 0.7", only: :test},
      {:exvcr, "~> 0.9", only: :test},
      {:httpoison, ">= 0.0.0"},
      {:mix_test_watch, "~> 0.3", only: :dev, runtime: false},
      {:poison, ">= 0.0.0"}
    ]
  end
end


0.3.0

defmodule Double.Mixfile do
  use Mix.Project
  @version "0.3.0"

  def project do
    [app: :double,
     version: @version,
     elixir: "~> 1.3",
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     description: description(),
     package: package(),
     deps: deps(),
     docs: [
       extras: ["README.md"],
       main: "readme",
       source_ref: "v#{@version}",
       source_url: "https://github.com/sonerdy/double",
     ]
   ]
  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
    [
      {:ex_doc, ">= 0.0.0", only: :dev},
      {:dialyxir, "~> 0.4", only: [:dev], runtime: false},
    ]
  end

  defp description do
    """
    Double is a simple library to help build injectable dependencies for your tests.
    It does NOT override behavior of existing modules or functions.
    """
  end

  defp package do
    [# These are the default files included in the package
     name: :double,
     files: ["lib", "mix.exs", "README*", "LICENSE*"],
     maintainers: ["Brandon Joyce"],
     licenses: ["MIT"],
     links: %{"GitHub" => "https://github.com/sonerdy/double",
      "Docs" => "https://github.com/sonerdy/double"}]
  end
end

defmodule Double.Mixfile do
  use Mix.Project
  @version "0.2.6"

  def project do
    [app: :double,
     version: @version,
     elixir: "~> 1.3",
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     description: description(),
     package: package(),
     deps: deps(),
     docs: [
       extras: ["README.md"],
       main: "readme",
       source_ref: "v#{@version}",
       source_url: "https://github.com/sonerdy/double",
     ]
   ]
  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
    [
      {:ex_doc, ">= 0.0.0", only: :dev},
      {:dialyxir, "~> 0.4", only: [:dev], runtime: false},
    ]
  end

  defp description do
    """
    Double is a simple library to help build injectable dependencies for your tests.
    It does NOT override behavior of existing modules or functions.
    """
  end

  defp package do
    [# These are the default files included in the package
     name: :double,
     files: ["lib", "mix.exs", "README*", "LICENSE*"],
     maintainers: ["Brandon Joyce"],
     licenses: ["MIT"],
     links: %{"GitHub" => "https://github.com/sonerdy/double",
      "Docs" => "https://github.com/sonerdy/double"}]
  end
end


Avoid confusing refute =

Avoid confusing refute =

Code.require_file "../../support/websocket_client.exs", __DIR__

defmodule Phoenix.Integration.WebSocketTest do
  use ExUnit.Case

  import RouterHelper, only: [capture_log: 1]

  alias Phoenix.Integration.WebsocketClient
  alias Phoenix.Socket.Message
  alias __MODULE__.Endpoint

  @port 5807

  Application.put_env(:phoenix, Endpoint, [
    https: false,
    http: [port: @port],
    secret_key_base: String.duplicate("abcdefgh", 8),
    debug_errors: false,
    server: true,
    pubsub: [adapter: Phoenix.PubSub.PG2, name: __MODULE__]
  ])

  defmodule RoomChannel do
    use Phoenix.Channel

    intercept ["new_msg"]

    def join(topic, message, socket) do
      Process.register(self, String.to_atom(topic))
      send(self, {:after_join, message})
      {:ok, socket}
    end

    def handle_info({:after_join, message}, socket) do
      broadcast socket, "user_entered", %{user: message["user"]}
      push socket, "joined", Map.merge(%{status: "connected"}, socket.assigns)
      {:noreply, socket}
    end

    def handle_in("new_msg", message, socket) do
      broadcast! socket, "new_msg", message
      {:noreply, socket}
    end

    def handle_in("boom", _message, _socket) do
      raise "boom"
    end

    def handle_out("new_msg", payload, socket) do
      push socket, "new_msg", Map.put(payload, "transport", inspect(socket.transport))
      {:noreply, socket}
    end

    def terminate(_reason, socket) do
      push socket, "you_left", %{message: "bye!"}
      :ok
    end
  end

  defmodule UserSocket do
    use Phoenix.Socket

    channel "rooms:*", RoomChannel

    transport :websocket, Phoenix.Transports.WebSocket,
      check_origin: ["//example.com"]

    def connect(%{"reject" => "true"}, _socket) do
      :error
    end

    def connect(params, socket) do
      Logger.disable(self())
      {:ok, assign(socket, :user_id, params["user_id"])}
    end

    def id(socket) do
      if id = socket.assigns.user_id, do: "user_sockets:#{id}"
    end
  end

  defmodule Endpoint do
    use Phoenix.Endpoint, otp_app: :phoenix

    socket "/ws", UserSocket
    socket "/ws/admin", UserSocket
  end

  setup_all do
    capture_log fn -> Endpoint.start_link() end
    :ok
  end

  test "endpoint handles mulitple mount segments" do
    {:ok, sock} = WebsocketClient.start_link(self, "ws://127.0.0.1:#{@port}/ws/admin/websocket")
    WebsocketClient.join(sock, "rooms:admin-lobby", %{})
    assert_receive %Message{event: "phx_reply",
                            payload: %{"response" => %{}, "status" => "ok"},
                            ref: "1", topic: "rooms:admin-lobby"}
  end

  test "join, leave, and event messages" do
    {:ok, sock} = WebsocketClient.start_link(self, "ws://127.0.0.1:#{@port}/ws/websocket")
    WebsocketClient.join(sock, "rooms:lobby1", %{})

    assert_receive %Message{event: "phx_reply",
                            payload: %{"response" => %{}, "status" => "ok"},
                            ref: "1", topic: "rooms:lobby1"}

    assert_receive %Message{event: "joined", payload: %{"status" => "connected",
                                                        "user_id" => nil}}
    assert_receive %Message{event: "user_entered",
                            payload: %{"user" => nil},
                            ref: nil, topic: "rooms:lobby1"}

    channel_pid = Process.whereis(:"rooms:lobby1")
    assert channel_pid
    assert Process.alive?(channel_pid)

    WebsocketClient.send_event(sock, "rooms:lobby1", "new_msg", %{body: "hi!"})
    assert_receive %Message{event: "new_msg", payload: %{"transport" => "Phoenix.Transports.WebSocket", "body" => "hi!"}}

    WebsocketClient.leave(sock, "rooms:lobby1", %{})
    assert_receive %Message{event: "you_left", payload: %{"message" => "bye!"}}
    assert_receive %Message{event: "phx_reply", payload: %{"status" => "ok"}}
    assert_receive %Message{event: "phx_close", payload: %{}}
    refute Process.alive?(channel_pid)

    WebsocketClient.send_event(sock, "rooms:lobby1", "new_msg", %{body: "Should ignore"})
    refute_receive %Message{event: "new_msg"}
    assert_receive %Message{event: "phx_reply", payload: %{"response" => %{"reason" => "unmatched topic"}}}

    WebsocketClient.send_event(sock, "rooms:lobby1", "new_msg", %{body: "Should ignore"})
    refute_receive %Message{event: "new_msg"}
  end

  test "sends phx_error if a channel server abnormally exits" do
    {:ok, sock} = WebsocketClient.start_link(self, "ws://127.0.0.1:#{@port}/ws/websocket")

    WebsocketClient.join(sock, "rooms:lobby", %{})
    assert_receive %Message{event: "phx_reply", ref: "1", payload: %{"response" => %{}, "status" => "ok"}}
    assert_receive %Message{event: "joined"}
    assert_receive %Message{event: "user_entered"}

    capture_log fn ->
      WebsocketClient.send_event(sock, "rooms:lobby", "boom", %{})
      assert_receive %Message{event: "phx_error", payload: %{}, topic: "rooms:lobby"}
    end
  end

  test "channels are terminated if transport normally exits" do
    {:ok, sock} = WebsocketClient.start_link(self, "ws://127.0.0.1:#{@port}/ws/websocket")

    WebsocketClient.join(sock, "rooms:lobby2", %{})
    assert_receive %Message{event: "phx_reply", ref: "1", payload: %{"response" => %{}, "status" => "ok"}}
    assert_receive %Message{event: "joined"}
    channel = Process.whereis(:"rooms:lobby2")
    assert channel
    Process.monitor(channel)
    WebsocketClient.close(sock)

    assert_receive {:DOWN, _, :process, ^channel, :shutdown}
  end

  test "refuses websocket events that haven't joined" do
    {:ok, sock} = WebsocketClient.start_link(self, "ws://127.0.0.1:#{@port}/ws/websocket")

    WebsocketClient.send_event(sock, "rooms:lobby", "new_msg", %{body: "hi!"})
    refute_receive %Message{event: "new_msg"}
    assert_receive %Message{event: "phx_reply", payload: %{"response" => %{"reason" => "unmatched topic"}}}

    WebsocketClient.send_event(sock, "rooms:lobby1", "new_msg", %{body: "Should ignore"})
    refute_receive %Message{event: "new_msg"}
 end

  test "refuses unallowed origins" do
    capture_log fn ->
      assert {:ok, _} =
        WebsocketClient.start_link(self, "ws://127.0.0.1:#{@port}/ws/websocket",
                                          [{"origin", "https://example.com"}])
      assert {:error, {403, _}} =
        WebsocketClient.start_link(self, "ws://127.0.0.1:#{@port}/ws/websocket",
                                         [{"origin", "http://notallowed.com"}])
    end
  end

  test "refuses connects that error with 403 response" do
    assert WebsocketClient.start_link(self, "ws://127.0.0.1:#{@port}/ws/websocket?reject=true") ==
           {:error, {403, "Forbidden"}}
  end

  test "shuts down when receiving disconnect broadcasts on socket's id" do
    {:ok, sock} = WebsocketClient.start_link(self, "ws://127.0.0.1:#{@port}/ws/websocket?user_id=1001")

    WebsocketClient.join(sock, "rooms:wsdisconnect1", %{})
    assert_receive %Message{topic: "rooms:wsdisconnect1", event: "phx_reply",
                            ref: "1", payload: %{"response" => %{}, "status" => "ok"}}
    WebsocketClient.join(sock, "rooms:wsdisconnect2", %{})
    assert_receive %Message{topic: "rooms:wsdisconnect2", event: "phx_reply",
                            ref: "2", payload: %{"response" => %{}, "status" => "ok"}}

    chan1 = Process.whereis(:"rooms:wsdisconnect1")
    assert chan1
    chan2 = Process.whereis(:"rooms:wsdisconnect2")
    assert chan2
    Process.monitor(sock)
    Process.monitor(chan1)
    Process.monitor(chan2)

    Endpoint.broadcast("user_sockets:1001", "disconnect", %{})

    assert_receive {:DOWN, _, :process, ^sock, :normal}
    assert_receive {:DOWN, _, :process, ^chan1, :shutdown}
    assert_receive {:DOWN, _, :process, ^chan2, :shutdown}
  end

  test "duplicate join event logs and ignores messages" do
    {:ok, sock} = WebsocketClient.start_link(self, "ws://127.0.0.1:#{@port}/ws/websocket?user_id=1001")
    WebsocketClient.join(sock, "rooms:joiner", %{})
    assert_receive %Message{topic: "rooms:joiner", event: "phx_reply",
                            ref: "1", payload: %{"response" => %{}, "status" => "ok"}}

    log = capture_log fn ->
      WebsocketClient.join(sock, "rooms:joiner", %{})
      assert_receive %Message{topic: "rooms:joiner", event: "phx_reply",
                              payload: %{"response" => %{"reason" => "already joined"},
                                         "status" => "error"}}
    end
    assert log =~ "Phoenix.Integration.WebSocketTest.RoomChannel received join event with topic \"rooms:joiner\" but channel already joined"
  end
end

Code.require_file "../../support/websocket_client.exs", __DIR__

defmodule Phoenix.Integration.WebSocketTest do
  use ExUnit.Case

  import RouterHelper, only: [capture_log: 1]

  alias Phoenix.Integration.WebsocketClient
  alias Phoenix.Socket.Message
  alias __MODULE__.Endpoint

  @port 5807

  Application.put_env(:phoenix, Endpoint, [
    https: false,
    http: [port: @port],
    secret_key_base: String.duplicate("abcdefgh", 8),
    debug_errors: false,
    server: true,
    pubsub: [adapter: Phoenix.PubSub.PG2, name: __MODULE__]
  ])

  defmodule RoomChannel do
    use Phoenix.Channel

    intercept ["new_msg"]

    def join(topic, message, socket) do
      Process.register(self, String.to_atom(topic))
      send(self, {:after_join, message})
      {:ok, socket}
    end

    def handle_info({:after_join, message}, socket) do
      broadcast socket, "user_entered", %{user: message["user"]}
      push socket, "joined", Map.merge(%{status: "connected"}, socket.assigns)
      {:noreply, socket}
    end

    def handle_in("new_msg", message, socket) do
      broadcast! socket, "new_msg", message
      {:noreply, socket}
    end

    def handle_in("boom", _message, _socket) do
      raise "boom"
    end

    def handle_out("new_msg", payload, socket) do
      push socket, "new_msg", Map.put(payload, "transport", inspect(socket.transport))
      {:noreply, socket}
    end

    def terminate(_reason, socket) do
      push socket, "you_left", %{message: "bye!"}
      :ok
    end
  end

  defmodule UserSocket do
    use Phoenix.Socket

    channel "rooms:*", RoomChannel

    transport :websocket, Phoenix.Transports.WebSocket,
      check_origin: ["//example.com"]

    def connect(%{"reject" => "true"}, _socket) do
      :error
    end

    def connect(params, socket) do
      Logger.disable(self())
      {:ok, assign(socket, :user_id, params["user_id"])}
    end

    def id(socket) do
      if id = socket.assigns.user_id, do: "user_sockets:#{id}"
    end
  end

  defmodule Endpoint do
    use Phoenix.Endpoint, otp_app: :phoenix

    socket "/ws", UserSocket
    socket "/ws/admin", UserSocket
  end

  setup_all do
    capture_log fn -> Endpoint.start_link() end
    :ok
  end

  test "endpoint handles mulitple mount segments" do
    {:ok, sock} = WebsocketClient.start_link(self, "ws://127.0.0.1:#{@port}/ws/admin/websocket")
    WebsocketClient.join(sock, "rooms:admin-lobby", %{})
    assert_receive %Message{event: "phx_reply",
                            payload: %{"response" => %{}, "status" => "ok"},
                            ref: "1", topic: "rooms:admin-lobby"}
  end

  test "join, leave, and event messages" do
    {:ok, sock} = WebsocketClient.start_link(self, "ws://127.0.0.1:#{@port}/ws/websocket")
    WebsocketClient.join(sock, "rooms:lobby1", %{})

    assert_receive %Message{event: "phx_reply",
                            payload: %{"response" => %{}, "status" => "ok"},
                            ref: "1", topic: "rooms:lobby1"}

    assert_receive %Message{event: "joined", payload: %{"status" => "connected",
                                                        "user_id" => nil}}
    assert_receive %Message{event: "user_entered",
                            payload: %{"user" => nil},
                            ref: nil, topic: "rooms:lobby1"}

    channel_pid = Process.whereis(:"rooms:lobby1")
    assert channel_pid
    assert Process.alive?(channel_pid)

    WebsocketClient.send_event(sock, "rooms:lobby1", "new_msg", %{body: "hi!"})
    assert_receive %Message{event: "new_msg", payload: %{"transport" => "Phoenix.Transports.WebSocket", "body" => "hi!"}}

    WebsocketClient.leave(sock, "rooms:lobby1", %{})
    assert_receive %Message{event: "you_left", payload: %{"message" => "bye!"}}
    assert_receive %Message{event: "phx_reply", payload: %{"status" => "ok"}}
    assert_receive %Message{event: "phx_close", payload: %{}}
    refute Process.alive?(channel_pid)

    WebsocketClient.send_event(sock, "rooms:lobby1", "new_msg", %{body: "Should ignore"})
    refute_receive %Message{event: "new_msg"}
    assert_receive %Message{event: "phx_reply", payload: %{"response" => %{"reason" => "unmatched topic"}}}

    WebsocketClient.send_event(sock, "rooms:lobby1", "new_msg", %{body: "Should ignore"})
    refute_receive %Message{event: "new_msg"}
  end

  test "sends phx_error if a channel server abnormally exits" do
    {:ok, sock} = WebsocketClient.start_link(self, "ws://127.0.0.1:#{@port}/ws/websocket")

    WebsocketClient.join(sock, "rooms:lobby", %{})
    assert_receive %Message{event: "phx_reply", ref: "1", payload: %{"response" => %{}, "status" => "ok"}}
    assert_receive %Message{event: "joined"}
    assert_receive %Message{event: "user_entered"}

    capture_log fn ->
      WebsocketClient.send_event(sock, "rooms:lobby", "boom", %{})
      assert_receive %Message{event: "phx_error", payload: %{}, topic: "rooms:lobby"}
    end
  end

  test "channels are terminated if transport normally exits" do
    {:ok, sock} = WebsocketClient.start_link(self, "ws://127.0.0.1:#{@port}/ws/websocket")

    WebsocketClient.join(sock, "rooms:lobby2", %{})
    assert_receive %Message{event: "phx_reply", ref: "1", payload: %{"response" => %{}, "status" => "ok"}}
    assert_receive %Message{event: "joined"}
    channel = Process.whereis(:"rooms:lobby2")
    assert channel
    Process.monitor(channel)
    WebsocketClient.close(sock)

    assert_receive {:DOWN, _, :process, ^channel, :shutdown}
  end

  test "refuses websocket events that haven't joined" do
    {:ok, sock} = WebsocketClient.start_link(self, "ws://127.0.0.1:#{@port}/ws/websocket")

    WebsocketClient.send_event(sock, "rooms:lobby", "new_msg", %{body: "hi!"})
    refute_receive %Message{event: "new_msg"}
    assert_receive %Message{event: "phx_reply", payload: %{"response" => %{"reason" => "unmatched topic"}}}

    WebsocketClient.send_event(sock, "rooms:lobby1", "new_msg", %{body: "Should ignore"})
    refute_receive %Message{event: "new_msg"}
 end

  test "refuses unallowed origins" do
    capture_log fn ->
      assert {:ok, _} = WebsocketClient.start_link(self, "ws://127.0.0.1:#{@port}/ws/websocket",
                                                   [{"origin", "https://example.com"}])
      refute {:ok, _} = WebsocketClient.start_link(self, "ws://127.0.0.1:#{@port}/ws/websocket",
                                                   [{"origin", "http://notallowed.com"}])
    end
  end

  test "refuses connects that error with 403 response" do
    assert WebsocketClient.start_link(self, "ws://127.0.0.1:#{@port}/ws/websocket?reject=true") ==
           {:error, {403, "Forbidden"}}
  end

  test "shuts down when receiving disconnect broadcasts on socket's id" do
    {:ok, sock} = WebsocketClient.start_link(self, "ws://127.0.0.1:#{@port}/ws/websocket?user_id=1001")

    WebsocketClient.join(sock, "rooms:wsdisconnect1", %{})
    assert_receive %Message{topic: "rooms:wsdisconnect1", event: "phx_reply",
                            ref: "1", payload: %{"response" => %{}, "status" => "ok"}}
    WebsocketClient.join(sock, "rooms:wsdisconnect2", %{})
    assert_receive %Message{topic: "rooms:wsdisconnect2", event: "phx_reply",
                            ref: "2", payload: %{"response" => %{}, "status" => "ok"}}

    chan1 = Process.whereis(:"rooms:wsdisconnect1")
    assert chan1
    chan2 = Process.whereis(:"rooms:wsdisconnect2")
    assert chan2
    Process.monitor(sock)
    Process.monitor(chan1)
    Process.monitor(chan2)

    Endpoint.broadcast("user_sockets:1001", "disconnect", %{})

    assert_receive {:DOWN, _, :process, ^sock, :normal}
    assert_receive {:DOWN, _, :process, ^chan1, :shutdown}
    assert_receive {:DOWN, _, :process, ^chan2, :shutdown}
  end

  test "duplicate join event logs and ignores messages" do
    {:ok, sock} = WebsocketClient.start_link(self, "ws://127.0.0.1:#{@port}/ws/websocket?user_id=1001")
    WebsocketClient.join(sock, "rooms:joiner", %{})
    assert_receive %Message{topic: "rooms:joiner", event: "phx_reply",
                            ref: "1", payload: %{"response" => %{}, "status" => "ok"}}

    log = capture_log fn ->
      WebsocketClient.join(sock, "rooms:joiner", %{})
      assert_receive %Message{topic: "rooms:joiner", event: "phx_reply",
                              payload: %{"response" => %{"reason" => "already joined"},
                                         "status" => "error"}}
    end
    assert log =~ "Phoenix.Integration.WebSocketTest.RoomChannel received join event with topic \"rooms:joiner\" but channel already joined"
  end
end