Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions fixtures/example/deps.nix
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,20 @@ let
in
drv;

daisyui = stdenv.mkDerivation {
name = "daisyui";
src = fetchFromGitHub {
owner = "saadeghi";
repo = "daisyui";
rev = "22ecff57f2c391b80a75617325748cf4d13fdf47";
hash = "sha256-I2LI9VYVxQcvoMDgDWmvNyQToS1rFm12V167YxqDs24=";
};
buildPhase = ''
mkdir $out
ln -sv $src $out/src
'';
};

db_connection =
let
version = "2.10.2";
Expand Down
7 changes: 7 additions & 0 deletions fixtures/example/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ defmodule Example.MixProject do
[
{:bandit, github: "mtrudel/bandit", ref: "1.4.2", override: true},
{:brod, "~> 3.16"},
{:daisyui,
github: "saadeghi/daisyui",
tag: "v5.5.20",
sparse: "packages/bundle",
app: false,
compile: false,
depth: 1},
{:deps_nix, path: "../..", only: [:dev]},
{:eventstore, "~> 1.4"},
{:ex_heroicons, "~> 3.1"},
Expand Down
1 change: 1 addition & 0 deletions fixtures/example/mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"cldr_utils": {:hex, :cldr_utils, "2.29.7", "2189bc0117efe91c684558e79174b45eb43135595b7d1fe9b57f53917be195c1", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.5", [hex: :certifi, repo: "hexpm", optional: true]}, {:decimal, "~> 1.9 or ~> 2.0 or ~> 3.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "4bddcd597fee34e2d2829ae9ef62bcfef8d97ae5f6b75f0c6ee37a3db31aa73a"},
"crc32cer": {:hex, :crc32cer, "0.1.8", "c6c2275c5fb60a95f4935d414f30b50ee9cfed494081c9b36ebb02edfc2f48db", [:rebar3], [], "hexpm", "251499085482920deb6c9b7aadabf9fb4c432f96add97ab42aee4501e5b6f591"},
"ctx": {:hex, :ctx, "0.6.0", "8ff88b70e6400c4df90142e7f130625b82086077a45364a78d208ed3ed53c7fe", [:rebar3], [], "hexpm", "a14ed2d1b67723dbebbe423b28d7615eb0bdcba6ff28f2d1f1b0a7e1d4aa5fc2"},
"daisyui": {:git, "https://github.com/saadeghi/daisyui.git", "22ecff57f2c391b80a75617325748cf4d13fdf47", [tag: "v5.5.20", sparse: "packages/bundle", depth: 1]},
"db_connection": {:hex, :db_connection, "2.10.2", "ae391e803a5adff104da913c2fc1c0c14a37f8b10001dcef568796e1fb7bf95c", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "510b14482330f1af6490a2fa0efd8d4f1435d1529b165647df22ac0f2df0fa93"},
"decimal": {:hex, :decimal, "3.1.1", "430d87b04011ce6cbd4fd205be758311a81f87d552d40904abd00f015935b1d0", [:mix], [], "hexpm", "c5f25f2ced74a0587d03e6023f595db8e924c9d3922c8c8ffd9edfc4498cf1f6"},
"digital_token": {:hex, :digital_token, "2.0.0", "fb3c74411790994895c4a61387ab322b64a682995ef2f54a4627c92d46be5d62", [:mix], [], "hexpm", "cbd2fff52770284a8251540a4b4e529e9738c6fe052d7f3c3428eb5c817385cd"},
Expand Down
7 changes: 3 additions & 4 deletions lib/deps_nix.ex
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,10 @@ defmodule DepsNix do
end
end

# Fetch-only deps become plain source derivations, but that only works for
# git checkouts; anything else with `app: false, compile: false` is dropped.
defp unwanted(dep) do
dep.app != :heroicons &&
Enum.all?([:app, :compile], fn opt ->
Keyword.fetch(dep.opts, opt) == {:ok, false}
end)
dep.scm != Mix.SCM.Git && Packages.fetch_only?(dep)
end

defp add_output(%Options{} = options, parsed_args) do
Expand Down
15 changes: 10 additions & 5 deletions lib/deps_nix/derivation.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ defmodule DepsNix.Derivation do
DepsNix.FetchFromGitHub.t()
| DepsNix.FetchGit.t()
| DepsNix.FetchHex.t(),
beam_deps: list(atom())
beam_deps: list(atom()),
fetch_only: boolean()
}

@enforce_keys [
Expand All @@ -30,15 +31,17 @@ defmodule DepsNix.Derivation do
:name,
:version,
:src,
:beam_deps
:beam_deps,
fetch_only: false
]

def new(dep, opts) do
struct!(
__MODULE__,
[
name: dep.app,
beam_deps: Enum.map(dep.deps, & &1.app)
beam_deps: Enum.map(dep.deps, & &1.app),
fetch_only: DepsNix.Packages.fetch_only?(dep)
]
|> Keyword.merge(opts)
)
Expand Down Expand Up @@ -196,10 +199,12 @@ defmodule DepsNix.Derivation do
"""
end

def to_string(%DepsNix.Derivation{name: :heroicons} = drv) do
# Fetch-only deps aren't BEAM packages; expose the bare checkout so
# consumers can symlink ${pkg}/src into deps/.
def to_string(%DepsNix.Derivation{fetch_only: true} = drv) do
"""
#{drv.name} = stdenv.mkDerivation {
name = "heroicons";
name = "#{drv.name}";
src = #{drv.src |> Kernel.to_string() |> Util.indent(from: 1)}
buildPhase = ''
mkdir $out
Expand Down
10 changes: 10 additions & 0 deletions lib/deps_nix/packages.ex
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ defmodule DepsNix.Packages do
Enum.filter(packages, &("#{&1.app}" in permitted_names))
end

@doc """
Deps declared with `app: false, compile: false` are plain source checkouts
(e.g. asset repos like heroicons or daisyui) rather than BEAM packages.
"""
def fetch_only?(%Mix.Dep{} = dep) do
Enum.all?([:app, :compile], fn opt ->
Keyword.fetch(dep.opts, opt) == {:ok, false}
end)
end

def reject_paths(deps) do
deps
|> Enum.reject(fn dep ->
Expand Down
35 changes: 33 additions & 2 deletions test/deps_nix/special_treatment_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ defmodule DepsNix.SpecialTreatmentTest do
alias DepsNix.FetchFromGitHub
alias DepsNix.FetchHex

test "heroicons needs a nested GitHub fetch" do
test "fetch-only deps like heroicons or daisyui get a nested GitHub fetch" do
# the src dir is expected by mixRelease, which symlinks deps into place
assert %Derivation{
builder: "buildMix",
Expand All @@ -19,7 +19,8 @@ defmodule DepsNix.SpecialTreatmentTest do
hash: "sha256-4yRqfY8r2Ar9Fr45ikD/8jK+H3g4veEHfXa9BorLxXg="
},
beam_deps: [],
app_config_path: "foo"
app_config_path: "foo",
fetch_only: true
}
|> to_string() == """
heroicons = stdenv.mkDerivation {
Expand All @@ -36,6 +37,36 @@ defmodule DepsNix.SpecialTreatmentTest do
'';
};
"""

assert %Derivation{
builder: "buildMix",
name: :daisyui,
version: nil,
src: %FetchFromGitHub{
owner: "saadeghi",
repo: "daisyui",
rev: "4dbf88f9dd80e0917b7d366b0f4e28ec33ba6b52",
hash: "sha256-4yRqfY8r2Ar9Fr45ikD/8jK+H3g4veEHfXa9BorLxXg="
},
beam_deps: [],
app_config_path: "foo",
fetch_only: true
}
|> to_string() == """
daisyui = stdenv.mkDerivation {
name = "daisyui";
src = fetchFromGitHub {
owner = "saadeghi";
repo = "daisyui";
rev = "4dbf88f9dd80e0917b7d366b0f4e28ec33ba6b52";
hash = "sha256-4yRqfY8r2Ar9Fr45ikD/8jK+H3g4veEHfXa9BorLxXg=";
};
buildPhase = ''
mkdir $out
ln -sv $src $out/src
'';
};
"""
end

test "ex_heroicons symlinks the required heroicons into place" do
Expand Down
27 changes: 19 additions & 8 deletions test/deps_nix_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -166,17 +166,28 @@ defmodule DepsNixTest do
assert output(%DepsNix.Options{}, &stub_converger/1) =~ "with self;\n {\n \n };"
end

test "creates a special fetcher derivation for heroicons, which is included in new Phoenix apps" do
dep = dep(name: :heroicons, dep_opts: [app: false, compile: false]) |> pick()
converger = fn [env: :prod] -> [dep] end
nix = output(%DepsNix.Options{envs: %{"prod" => :all}}, converger)
property "creates fetch-only derivations for git deps marked app: false and compile: false" do
check all dep <-
dep(
name: :an_asset_dep,
scm: Mix.SCM.Git,
dep_opts: [app: false, compile: false]
) do
converger = fn [env: :prod] -> [dep] end
nix = output(%DepsNix.Options{envs: %{"prod" => :all}}, converger)

assert Regex.scan(~r(heroicons), nix) |> length() >= 1,
"Couldn't find special-cased heroicons fetcher in #{nix}"
assert nix =~ "an_asset_dep = stdenv.mkDerivation",
"Couldn't find fetch-only fetcher for #{dep.app} in #{nix}"
end
end

property "doesn't create derivations marked both app: false and compile: false" do
check all dep <- dep(name: :not_a_mix_dep, dep_opts: [app: false, compile: false]) do
property "doesn't create derivations for non-git deps marked both app: false and compile: false" do
check all dep <-
dep(
name: :not_a_mix_dep,
scm: Mix.SCM.Hex,
dep_opts: [app: false, compile: false]
) do
converger = fn [env: :prod] -> [dep] end
nix = output(%DepsNix.Options{envs: %{"prod" => :all}}, converger)

Expand Down
Loading