Skip to content

Parsing of rebar3 unconstrained hex deps causes mix to crash itself #11062

@ferd

Description

@ferd
  • Elixir & Erlang/OTP versions (elixir --version):
Erlang/OTP 24 [erts-12.0.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [dtrace]
Elixir 1.12.1 (compiled with Erlang/OTP 24)
  • Operating system:

Darwin [...] 20.4.0 Darwin Kernel Version 20.4.0: Thu Apr 22 21:46:47 PDT 2021; root:xnu-7195.101.2~1/RELEASE_X86_64 x86_64

Current behavior

Fetching rebar3 dependencies with no version constraints in their transitive deps is parsed in a way where mix's own parsing causes it to fail.

I was trying with the following sample specification for dependencies:

  defp deps do
    [
      {:recon, ">= 0.0.0"},
      {:grpcbox, "~> 0.14.0", override: true},
      {:opentelemetry_api, git: "http://github.com/open-telemetry/opentelemetry-erlang", branch: "master", sparse: "apps/opentelemetry_api", override: true},
      {:opentelemetry, git: "http://github.com/open-telemetry/opentelemetry-erlang", branch: "master", sparse: "apps/opentelemetry", override: true},
      {:opentelemetry_exporter, git: "http://github.com/open-telemetry/opentelemetry-erlang", branch: "master", sparse: "apps/opentelemetry_exporter", override: true}
    ]
  end

This is interesting because I'm trying to get the master branch, which is defined in Erlang and has :opentelemetry as a subdirectory checkout: https://github.com/open-telemetry/opentelemetry-erlang/blob/master/apps/opentelemetry/rebar.config (the issue is gone on main, the new mainline branch, but still happens there with grpcbox as a dep), with no lockfile to further limit the dependency.

However, when this is parsed by mix, the content returns a nil version constraint:

defp parse_dep(app) when is_atom(app) do
{app, nil, override: true}
end

This is seen as invalid in the dep loader:

defp with_scm_and_app({app, req, opts} = original) when is_atom(app) and is_list(opts) do
if is_binary(req) or is_struct(req, Regex) do
with_scm_and_app(app, req, opts, original)
else
invalid_dep_format(original)
end
end

Expected behavior

The actual proper semantics would likely be to return it as {app, ">= 0.0.0", override: true}, which would match the intent behind rebar3's format, and avoid parsing dependencies in a ways that crashes itself.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions