Depos

Dependency notes for Elixir

The deps function in mix.exs lists the packages a project needs and the versions it accepts. It does not say why a package is there, which Phoenix or Ecto upgrade it is waiting for, or what to run after it moves.

Depos keeps a note for each dependency in .depos/mix/DEPENDENCY-NOTES.md, beside mix.exs, and shows it on the dependency's tuple. The apps of an umbrella project can share one notes file at the umbrella root.

The deps function of mix.exs in VS Code: filled marks and the first line of the note for the dependencies that have one, hollow marks before tesla and oban, which have none
mix.exs in VS Code.

What Depos reads

  • Manifest: mix.exs
  • Notes file: .depos/mix/DEPENDENCY-NOTES.md
  • Section heading: the dependency application atom: ## phoenix, ## ecto_sql

Depos reads literal dependency tuples in def/defp deps or an inline deps: [...] list, including Hex, Git, path and umbrella dependencies. Static only and targets options are shown as scopes; dynamically assembled lists are not run or guessed.

Depos never runs Mix or project code, so it needs no Elixir or Erlang installation.

Example

defp deps do
  [
    {:phoenix, "~> 1.7.14"},
    {:ecto_sql, "~> 3.12"},
    {:postgrex, ">= 0.0.0"},
    {:credo, "~> 1.7", only: [:dev, :test], runtime: false}
  ]
end

.depos/mix/DEPENDENCY-NOTES.md:

## ecto_sql

Database layer; migrations are in priv/repo/migrations.

### Agent notes

- purpose: SQL adapters and migrations for the Postgres repo
- bump-with: postgrex
- verify: `mix test` and `mix ecto.migrate` on an empty database
- verified: 3.12.1

The heading is the dependency's application atom without the colon: {:ecto_sql, "~> 3.12"} is ## ecto_sql. Credo's only: [:dev, :test] shows as its scope.

Comments in mix.exs

defp deps do
  [
    # phoenix: hold on 1.7 until the LiveView upgrade lands
    {:phoenix, "~> 1.7.14"},
    {:ecto_sql, "~> 3.12"} # migrations are in priv/repo/migrations
  ]
end

mix.exs is Elixir code: # starts a comment that runs to the end of the line. Neither Mix nor Hex adds or removes a dependency in it: mix deps.get and mix deps.update write only mix.lock.

Pinning a version

"~> 1.7.14" accepts >= 1.7.14 and < 1.8.0, and "~> 1.7" accepts >= 1.7.0 and < 2.0.0. A version with no operator means that version only: {:phoenix, "1.7.14"} is the same as "== 1.7.14". Every operator except ~> needs all three parts of a version.

mix.lock records the version and checksum of each Hex package and the commit of each Git one, and mix deps.get fetches exactly that. mix deps.update phoenix unlocks phoenix and the packages it depends on; mix deps.unlock phoenix followed by mix deps.get moves phoenix alone. Why a dependency is held where it is goes in its note, as constraint:.

For AI coding agents

An agent reads a dependency's section before it adds, upgrades or removes it, and logs what it did under ### Agent notes. See the rules agents follow.