You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The leo update command downloads the latest release archive from GitHub and attempts to install it by replacing the running leo binary in-place. While the original goal was for convenience, this adds subtle complexity and conflates leos role with package management.
1. Conflicts with package managers and immutable environments
leo update attempts to replace the binary at std::env::current_exe() but does not update any external package manager's metadata.
As an example: for cargo install users, ~/.cargo/.crates.toml still records the old version after leo update runs - cargo install --list disagrees with leo --version, and a subsequent cargo install leo-lang may silently downgrade Leo if the registry lags the GitHub release.
The problem is worse with system package managers and immutable or security-conscious environments. On NixOS (and any Nix-managed install), the binary lives in the read-only /nix/store - leo update will simply fail with a permission error. The same applies to Guix, Docker images with read-only layers, Flatpak, Snap with strict confinement, and any environment where executables are managed externally. In these cases leo update is not just redundant, it's broken and will almost certainly lead to confusing user bug reports.
2. Creates yet another install path
To get leo in the first place, users already need to either:
use their package manager of choice (e.g. cargo, nix, etc) or
download the github release to somewhere on their $PATH.
leo update while potentially slightly fewer characters to type, is yet another install path that users need to consider the behaviour of. E.g. without digging deeper its unclear to the user if this replaces the existing executable, or installs new versions in a new location, whether or not it modifies their PATH, and if so what the resulting PATH priority is, whether or not it will conflict with their package manager, and so on.
It also lacks many features already supported by proper package managers e.g. version selection, rollback, checksum/signature verification for security, system dependency management, backup mirrors, etc. While addressing these is feasible, it leads us down the path of writing yet-another package manager when many mature options already exist.
Proposed path
Remove the leo update subcommand and its implementation in crates/leo/src/cli/helpers/updater.rs.
Keep the existing check_for_updates() mechanism that prints a notice when a newer version is available - this provides the discoverability benefit without mutation. On new version availability, recommend users install the new version the same way they installed leo initially.
Remove the self_update and self-replace dependencies.
Ensure clear, easily accessible release binaries that real package managers can consume. [Proposal] Independent release cadence for workspace crates #29189 will help here - each binary crate gets its own tagged GitHub release with cross-platform artifacts, making it straightforward for tools like Homebrew, Nix, and other existing package managers to track and distribute Leo tooling through their native upgrade mechanisms.
Update docs to point users to cargo install leo-lang leo-fmt or GitHub releases as the canonical upgrade method (it's already introduced for installation anyway).
Optional: Voluntariliy add leo to popular downstream package-sets like AUR, nixpkgs, brew, etc. Once integrated, most mature package managers have automated methods of picking up new versions of binaries from github releases as long as basic conventions are followed like naming and version consistency.
Motivation
The
leo updatecommand downloads the latest release archive from GitHub and attempts to install it by replacing the runningleobinary in-place. While the original goal was for convenience, this adds subtle complexity and conflatesleos role with package management.1. Conflicts with package managers and immutable environments
leo updateattempts to replace the binary atstd::env::current_exe()but does not update any external package manager's metadata.As an example: for
cargo installusers,~/.cargo/.crates.tomlstill records the old version afterleo updateruns -cargo install --listdisagrees withleo --version, and a subsequentcargo install leo-langmay silently downgrade Leo if the registry lags the GitHub release.The problem is worse with system package managers and immutable or security-conscious environments. On NixOS (and any Nix-managed install), the binary lives in the read-only
/nix/store-leo updatewill simply fail with a permission error. The same applies to Guix, Docker images with read-only layers, Flatpak, Snap with strict confinement, and any environment where executables are managed externally. In these casesleo updateis not just redundant, it's broken and will almost certainly lead to confusing user bug reports.2. Creates yet another install path
To get
leoin the first place, users already need to either:cargo,nix, etc) or$PATH.leo updatewhile potentially slightly fewer characters to type, is yet another install path that users need to consider the behaviour of. E.g. without digging deeper its unclear to the user if this replaces the existing executable, or installs new versions in a new location, whether or not it modifies their PATH, and if so what the resulting PATH priority is, whether or not it will conflict with their package manager, and so on.It also lacks many features already supported by proper package managers e.g. version selection, rollback, checksum/signature verification for security, system dependency management, backup mirrors, etc. While addressing these is feasible, it leads us down the path of writing yet-another package manager when many mature options already exist.
Proposed path
leo updatesubcommand and its implementation incrates/leo/src/cli/helpers/updater.rs.check_for_updates()mechanism that prints a notice when a newer version is available - this provides the discoverability benefit without mutation. On new version availability, recommend users install the new version the same way they installed leo initially.self_updateandself-replacedependencies.cargo install leo-lang leo-fmtor GitHub releases as the canonical upgrade method (it's already introduced for installation anyway).