Skip to content

Recipes

Practical workflows that combine ixt features. Each recipe shows the commands, the resulting state, and what the ixt.toml looks like if you want to commit it.


🔀 Side-by-side versions of the same tool

Use case. You want to keep ruff at the latest version for everyday work, but also pin ruff==0.5.7 for a legacy project — both reachable from your shell, no juggling.

ixt tool install ruff                                                # exposed as `ruff`
ixt tool install ruff==0.5.7 --slot ruff-old --bare                  # env only, no shim yet
ixt tool config ruff-old expose ruff:ruff-old                        # exposed as `ruff-old`

After this:

$ ixt tool list
  ruff.pypi           0.13.0   [python]  bins: ruff
  ruff-old.ruff.pypi  0.5.7    [python]  bins: ruff-old (-> ruff)

The output shows the two separate names involved:

  • Installed idruff-old.ruff.pypi is the slotted install of the ruff package.
  • After the bin name — the shim ruff-old on PATH points at the ruff binary inside the env.

ixt tool info ruff-old resolves the id prefix and shows the exact id:

$ ixt tool info ruff-old
  ruff
  Id:       ruff-old.ruff.pypi
  Backend:  python
  Package:  ruff
  Spec:     ruff==0.5.7
  ...
  Exposed:
    ruff-old -> /.../envs/ruff-old.ruff.pypi/bin/ruff
Flag / command Role
--slot ruff-old Side-by-side slot. The installed id becomes ruff-old.ruff.pypi; the package being installed is still ruff.
--bare Skip the default __main__ shim. Without it, install would try to expose ruff, collide with the first install, and warn conflict: already exists.
ixt tool config ruff-old expose ruff:ruff-old Renames the exposed shim. Rule orig:alias takes the binary ruff from the env and links it as ruff-old on PATH.

Skipping the rename step

ixt tool install ruff==0.5.7 --slot ruff-old --bare installs the env but leaves it unreachable from PATH (bins: (none) in ixt tool list). Run ixt tool config ruff-old expose ruff:ruff-old to fix it.

Persisting the layout in ixt.toml

Add --save on the install and the toml round-trips through ixt tool export / ixt tool apply. Config steps (expose, inject, …) don't touch ixt.toml — capture them with ixt tool export > ixt.toml once you're happy with the layout:

ixt tool install ruff --save
ixt tool install ruff==0.5.7 --slot ruff-old --bare --save
ixt tool config ruff-old expose ruff:ruff-old
ixt tool export > ixt.toml    # snapshot current state
# ixt.toml
[tools]
"@pypi:ruff" = {}
ruff-old = { install = "@pypi:ruff", version = "==0.5.7", expose = ["ruff:ruff-old"] }

The install = "@pypi:ruff" field tells apply which package to install for the ruff-old slot.