[ANN] CondaPkg.jl: Add Conda dependencies to your Julia project

Conda is a cross-platform package manager, originally used to manage the Anaconda Python distribution, but also handles non-Python packages too.

CondaPkg.jl is a bit like Pkg but for managing Conda dependencies.

This provides an convenient means to add binary dependencies to your Julia project. It can be used as an alternative to artifacts, JLL packages or manual downloading. It is particularly useful for Python dependencies.

Example

To declare dependencies, you simply create a CondaPkg.toml file in your Julia project, such as:

[deps]
perl = "5.*"

Alternatively, we provide interactive functions to add and remove dependencies, such as:

CondaPkg.add("perl", version="5.*")

Now you can run programs in the environment like so:

CondaPkg.withenv() do
    run(`perl -e 'print("Hello world!\n")'`)
end

Features

  • Automatically resolves your Conda dependencies.
  • Uses a different Conda environment for each Julia environment, so avoiding version conflicts.
  • Also handles Pip dependencies, and maybe more kinds in the future.
  • Behind the scenes we use MicroMamba, the new fast reimplementation of Conda. Installation of this is managed by the new MicroMamba.jl package.
19 Likes

What’s the syntax for specifying version bounds in CondaPkg.toml ?

There are examples in the README: GitHub - cjdoris/CondaPkg.jl: Add Conda dependencies to your Julia project

1 Like

Thanks, I had seen that. It shows only examples with <=, ==, <. To be concrete, I have two questions:

  1. ~, ^ (as defined in Pkg) are not supported by CondaPkg?

  2. If I write:

[deps]
pyarrow = "6.0"

what does it mean? Is it automatically equivalent to >=6.0, <7? How does it treat leading 0. versions?

I don’t know the answer to that myself, so I went digging. CondaPkg dependencies are stored in an object of type CondaPkg.PkgSpec or CondaPkg.PipPkgSpec, and the version validation is done by the following lines:

is_valid_version(ver) = occursin(r"^\s*($|[!<>=0-9])", ver) && is_valid_string(ver; allow_glob=true)

normalise_version(ver) = strip(ver)

validate_version(ver) =
    if is_valid_version(ver)
        normalise_version(ver)
    else
        error("invalid version: $(repr(ver))")
    end
is_valid_pip_version(ver) = occursin(r"^\s*($|[~!<>=@])", ver) && !occursin(";", ver)

normalise_pip_version(ver) = strip(ver)

validate_pip_version(ver) =
    if is_valid_pip_version(ver)
        normalise_pip_version(ver)
    else
        error("invalid pip version: $(repr(ver))")
    end

Source: CondaPkg.jl/src/spec.jl at main · cjdoris/CondaPkg.jl · GitHub

CondaPkg uses the Conda version syntax for Conda dependencies (and pip syntax for pip dependencies).

In short, it supports <, <=, >, >= and == ranges, , means “and” and | means “or”.

A “naked” version like 6.0 means 6.0.*, equivalent to >=6.0,<6.1.

It doesn’t directly support anything like Julia’s SemVer ranges. You just have to build them like >=6.0,<7.

2 Likes