Skip to content

Instantly share code, notes, and snippets.

@ivan
Last active September 26, 2016 17:08
Show Gist options
  • Select an option

  • Save ivan/b5740156c547460f676fcd4ce256be25 to your computer and use it in GitHub Desktop.

Select an option

Save ivan/b5740156c547460f676fcd4ce256be25 to your computer and use it in GitHub Desktop.
Hacking mix to globally map Hex dependencies to audited git repositories
# ~/.mix/depmapper.exs
defmodule Mix.DepMapper do
@repos_path "/ejail/code/erlang"
# The branch to check out. My workflow is to mark audited known-good
# commits with both a branch and timestamped tag using
# https://github.com/ludios/tagmyrebase
@default_branch "bien"
def mapdep(dep) do
#IO.puts("dep: #{inspect dep, pretty: true, width: 0}")
opts = Enum.into(dep.opts, %{})
if not Map.has_key?(opts, :hex) do
# TODO: convert other git, github deps as well
dep
else
dest = opts.dest
name = Atom.to_string(opts.hex)
git = Path.join(@repos_path, name)
if System.get_env("DEPMAPPER_DEBUG") do
IO.puts("[depmapper] Hex #{name} -> git #{git}")
end
opts = opts
|> Map.delete(:hex)
|> Map.put(:checkout, dest)
|> Map.put(:git, git)
|> Map.put(:branch, @default_branch)
dep
|> Map.put(:requirement, nil)
|> Map.put(:scm, Mix.SCM.Git)
|> Map.put(:opts, Enum.into(opts, []))
end
end
end
@ivan
Copy link
Author

ivan commented Sep 26, 2016

Requires a patch applied to https://github.com/elixir-lang/elixir:

From 28ca09a3170605d7b5f72e6f8483414f4e144955 Mon Sep 17 00:00:00 2001
From: Ivan Kozik <[email protected]>
Date: Mon, 26 Sep 2016 15:47:27 +0000
Subject: [PATCH] Add support for mapping dependencies using
 ~/.mix/depmapper.exs

This can be used to override dependencies globally (e.g. Hex package -> git repo),
without setting up overrides in each mix.exs.

---
 lib/mix/lib/mix/dep/loader.ex | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lib/mix/lib/mix/dep/loader.ex b/lib/mix/lib/mix/dep/loader.ex
index c2f1b39..bcc7b86 100644
--- a/lib/mix/lib/mix/dep/loader.ex
+++ b/lib/mix/lib/mix/dep/loader.ex
@@ -294,9 +294,17 @@ defmodule Mix.Dep.Loader do
   end

   defp mix_children(opts) do
+    depmapper_exs = Path.join(Mix.Utils.mix_home, "depmapper.exs")
+    mapdep = if File.exists?(depmapper_exs) do
+      Code.require_file(depmapper_exs)
+      &Mix.DepMapper.mapdep/1
+    else
+      &(&1)
+    end
     from = Path.absname("mix.exs")
     (Mix.Project.config[:deps] || [])
     |> Enum.map(&to_dep(&1, from))
+    |> Enum.map(&mapdep.(&1))
     |> partition_by_env(opts[:env])
     |> elem(0)
   end
-- 
2.9.3

@ivan
Copy link
Author

ivan commented Sep 26, 2016

depmapper.exs converts a Hex dependency like

dep: %Mix.Dep{app: :dialyxir,
  deps: [],
  extra: [],
  from: "/ejail/code/erlang/debpress/mix.exs",
  manager: nil,
  opts: [env: :prod,
   hex: :dialyxir,
   build: "/ejail/code/erlang/debpress/_build/dev/lib/dialyxir",
   dest: "/ejail/code/erlang/debpress/deps/dialyxir",
   only: :dev],
  requirement: "~> 0.3.5",
  scm: Hex.SCM,
  status: {:unavailable,
   "/ejail/code/erlang/debpress/deps/dialyxir"},
  top_level: false}

into a git dependency like

dep: %Mix.Dep{app: :dialyxir,
  deps: [],
  extra: [],
  from: "/ejail/code/erlang/debpress/mix.exs",
  manager: nil,
  opts: [env: :prod,
   checkout: "/ejail/code/erlang/debpress/deps/dialyxir",
   build: "/ejail/code/erlang/debpress/_build/dev/lib/dialyxir",
   dest: "/ejail/code/erlang/debpress/deps/dialyxir",
   git: "/ejail/code/erlang/dialyxir",
   branch: "bien",
   only: :dev],
  requirement: nil,
  scm: Mix.SCM.Git,
  status: {:unavailable,
   "/ejail/code/erlang/debpress/deps/dialyxir"},
  top_level: false}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment