Why doesn't the Elixir core team accept `mix deps.add` proposals?

I’d love to see this addressed in the vein suggested by @dorgan. Something like:

$ mix hex.latest tesla jason
{tesla: "~> 1.4.0"},
{json: "~> 1.1"},

Basically do a similar job to mix hex.outdated, but for packages yet-to-be-added.

11 Likes

You mean just outputting the tuples to be manually copy/pasted into the mix.exs file? That’s a very good idea :slight_smile: and possibly one that could be acceptable in the core, as it is up to the user where to place the dependencies.

3 Likes

Maybe that could be wrapped by elixir-ls, so that for example typing add-dep tesla jason in IDE would paste the proper snippet straight to the code. What do you think @axelson?

1 Like

There’s already mix hex.info package, but that doesn’t do interdependency resolution.

5 Likes

It is a bit tedious to go look for the latest version of a library each time one adds a dependency.

True. What else would you propose ? The most simplest thing that came to mind is using the latest version. Obviously, if you and the latest package use different elixir versions, things would get a bit out of hand.

If adding mix deps.add means you have to list your dependencies in a separate file or have to structure them in a special way, then it’s not a good solution. One feature in the language shouldn’t limit other features.

As @LostKobrakai already said mix hex.info shows the configuration you can copy-paste into mix.exs:

> mix hex.info jason
A blazing fast JSON parser and generator in pure Elixir.

Config: {:jason, "~> 1.2"}
Releases: 1.2.2, 1.2.1, 1.2.0, 1.1.2, 1.1.1, 1.1.0, 1.0.1, 1.0.0, ...

Licenses: Apache-2.0
Links:
  GitHub: https://github.com/michalmuskala/jason

The single extra step of pasting the dependency config into mix.exs is not worth losing the flexibility of being able to configure dependencies using code.

14 Likes

I personally think the hex.latest task working like @stefanchrobot outlined would be the best way: simple, versatile, solving the problem without over-engineering it or without imposing restrictions to the user. It could be initially implemented as a library, and proposed for the core.

Basically, if I want to add the latest version of library foo and bar to my project, I would run:

$ mix hex.latest foo bar

Which would not modify anything in my code, but rather just output the latest versions in a tuple format that can be directly copy/pasted in the mix.exs:

{:foo, "~> 1.2.3"},
{:bar, "~> 3.2.1"}
1 Like

Ooooh actually I didn’t realize that mix hex.info already outputs the latest version as a tuple that can be copy/pasted in the dependencies. Well, that’s already good enough I guess :slight_smile:

It might be interesting to implement something similar, but with inter-dependency resolution, working like suggested by @stefanchrobot. After all, getting the current dependencies/versions of a project is rather easy: it’s updating that is hard, so it should be left to the developer. I personally feel it would be still better to implement it as a library though, at least to start.

Something like:

$ mix deps.add foo bar
Resolving dependencies... DONE
Copy-paste the following into your mix.exs:

{:foo, "~> 1.2.3"},
{:bar, "~> 3.2.1"}
1 Like

True. I manually list out my dependencies, so I didn’t consider the option of heavily using code to configure my dependencies. Maybe we should just leave things as is? (I like the way doorgan is proposing to solving the problem though)

I thing though, either make it do not output any additional text like Copy-paste the following into your mix.exs or output that to the stderr instead of stdout. That will allow editors to provide functionality of adding dependencies much easier. For example for Vim it would be:

:read !mix hex.add foo bar

Also, such command should be IMHO named hex.add not deps.add to accustom any other package manager that can be created/added later by the user.

4 Likes

That would be perfect with a trailing comma.

If the elixir parser can be augmented to ignore the last trailing comma in a list literal like what Perl does, we can just blindly copy/paste the line.

1 Like

You can put something like like this into your lib/mix/tasks/hex_latest.ex and then just do mix hex.latest jason | pbcopy for example.

4 Likes

Today I learned that mix hex.info <package> exists.

:man_facepalming:

I really should go read a bit more.

4 Likes

Awesome work putting this together, man. :heart:

I did roughly the same with a shell script incantation:

mix hex.info ecto_sql | grep 'Config:' | sed 's/.*{\(.*\)}[^}]*/{\1},/'

Which yields:

{:ecto_sql, "~> 3.6"},

One can easily alias this in their shell startup file like I just did in my ~/.zshrc:

function _mix_hex_latest() {
    mix hex.info $1 | grep 'Config:' | sed 's/.*{\(.*\)}[^}]*/{\1},/'
}

alias mix_hex_latest='_mix_hex_latest'
6 Likes

The parser is already capable of doing this. The trailing comma is required so we can paste anywhere.

1 Like

Maybe an additional flag could do it?

mix hex.info jason --config

And it would just output

{:jason, "~> 1.2"}
6 Likes

Supporting a deps.json wouldn’t be that hard.

Most people (?) are using a single deps/0 function now that just returns a list of tuples.

It’d be easy enough to parse a JSON file and return a list of ‘deps’ tuples. Your tool’s README could just document how users would modify their deps/0 function to included the parsed JSON output, e.g. something like:

  defp deps do
    [
      # Fixed/static/hard-coded deps (if any) ...
    ]
    ++ function_or_something_with_parsed_deps_json_data()
  end

Personally, I don’t like npm-style ‘add deps’ CLI commands – I much prefer maintaining deps ‘manually’ as-is the current convention.

1 Like

Been writing elixir daily for 5 years and did not know there were any mix hex tasks… Just discovered mix hex.search as well (doesn’t give you a tuple but does give you the latest version number).

2 Likes

You can also do:

$ curl --silent https://hex.pm/api/packages/jason | jq -r '.configs."mix.exs"'
{:jason, "~> 1.2"}

which is what mix hex.info does under the hood :slight_smile:

8 Likes