Skip to content

Instantly share code, notes, and snippets.

@igaray
Last active June 30, 2017 15:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save igaray/66f6037ccb86500d471a1bff2b4d8213 to your computer and use it in GitHub Desktop.
Save igaray/66f6037ccb86500d471a1bff2b4d8213 to your computer and use it in GitHub Desktop.
beamba2017

Elixir Tooling

Custom ExUnit Console Formatter

Custom Mix Tasks

  • elixir/lib/mix/lib/mix/tasks
  • elixir/lib/mix/lib/mix/utils.ex
    • camelize/1
    • can_write/ 1
    • command_to_module/1/2
    • command_to_module_name/1
    • compiling_n/
    • extract_files/2
    • extract_stale/2
    • last_modified/1
    • mix_home/0
    • mix_paths/0
    • module_name_to_command/1
    • print_tree/2,3
    • proxy_config/1
    • read_path/1
    • stale/2
    • symlink_or_copy/2
    • underscore/1
    • write_dot_graph~/4,5

Umbrella Tasks

"Your umbrella projects do not have code. That's because the applications in the umbrella are meant to work regardless if they are inside the umbrella or not. If you want to have a task that is shared across multiple applications, you should define it inside a regular application in the umbrella, like any other, and have the other applications that use the task depend on it, like you would for any other piece of code." -- Jose Valim

defmodule Mix.Tasks.Umbrella.Run do
    use Mix.Task

    @shortdoc "Runs a task for a single app in an umbrella"

    @switches [apps: :keep]
    @recursive true

    def run(args) do
        if (length args) == 0 do
            Mix.raise "Task not provided"
        end

        {opts, _files} = OptionParser.parse! args
        config = Mix.Project.config
        app = Atom.to_string config[:app]
        apps = opts[:apps] |> String.split(",")

        if Enum.member?(apps, app) do
            [task, "--apps", _ | task_args] = args
            Mix.Task.run(task, task_args)
        end
    end
end

Generator

  • import Mix.Generator
  • Macro: create_directory
  • Macro: create_file
  • Macro: embed_text
  • Macro: embed_template
    defp generate(_opts) do
        create_directory "scripts"
        create_file "scripts/manifest.config", manifest_text()
        create_file "scripts/game.exs", game_script_text()
    end

    embed_text :manifest, """
    "area.exs".
    "game.exs".
    "group.exs".
    "player.exs".
    """

    embed_text :game_script, """
    defmodule PGS.Game do

        def profile(type) do
            try do
                Sys.Log.debug("PGS.Game.profile(\#{inspect type})")
                :ok
            rescue
                error -> {:error, error}
            end
        end
    """"

create_file "config/config.exs", config_umbrella_template(assigns)

embed_template :config_umbrella, ~S"""
  # This file is responsible for configuring your application
  # and its dependencies with the aid of the Mix.Config module.
  use Mix.Config
  import_config "../apps/*/config/config.exs"

  # Sample configuration (overrides the imported configuration above):
  #
  #     config :logger, :console,
  #       level: :info,
  #       format: "$date $time [$level] $metadata$message\n",
  #       metadata: [:user_id]
  """

  embed_template :lib, """
  defmodule <%= @mod %> do
  end
  """
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment