Crate rattler_lock

source ·
Expand description

Definitions for a lock-file format that stores information about pinned dependencies from both the Conda and Pypi ecosystem.

The crate is structured in two API levels.

  1. The top level API accessible through the LockFile type that exposes high level access to the lock-file. This API is intended to be relatively stable and is the preferred way to interact with the lock-file.
  2. The *Data types. These are lower level types that expose more of the internal data structures used in the crate. These types are not intended to be stable and are subject to change over time. These types are used internally by the top level API. Also note that only a subset of the *Data types are exposed. See [crate::PyPiPackageData], [crate::CondaPackageData] for examples.

§Design goals

The goal of the lock-file format is:

  • To be complete. The lock-file should contain all the information needed to recreate environments even years after it was created. As long as the package data persists that a lock-file refers to, it should be possible to recreate the environment.
  • To be human readable. Although lock-files are not intended to be edited by hand, they should be relatively easy to read and understand. So that when a lock-file is checked into version control and someone looks at the diff, they can understand what changed.
  • To be easily parsable. It should be fairly straightforward to create a parser for the format so that it can be used in other tools.
  • To reduce diff size when the content changes. The order of content in the serialized lock-file should be fixed to ensure that the diff size is minimized when the content changes.
  • To be reproducible. Recreating the lock-file with the exact same input (including externally fetched data) should yield the same lock-file byte-for-byte.
  • To be statically verifiable. Given the specifications of the packages that went into a lock-file it should be possible to cheaply verify whether or not the specifications are still satisfied by the packages stored in the lock-file.
  • Backward compatible. Older version of lock-files should still be readable by never versions of this crate.

§Relation to conda-lock

Initially the lock-file format was based on conda-lock but over time significant changes have been made compared to the original conda-lock format. Conda-lock files (e.g. conda-lock.yml files) can still be parsed by this crate but the serialization format changed significantly. This means files created by this crate are not compatible with conda-lock.

Conda-lock stores a lot of metadata to be able to verify if the lock-file is still valid given the sources/inputs. For example conda-lock contains a content-hash which is a hash of all the input data of the lock-file. This crate approaches this differently by storing enough information in the lock-file to be able to verify if the lock-file still satisfies an input/source without requiring additional input (e.g. network requests) or expensive solves. We call this static satisfiability verification.

Conda-lock stores a custom partial representation of a rattler_conda_types::RepoDataRecord in the lock-file. This poses a problem when incrementally updating an environment. To only partially update packages in the lock-file without completely recreating it, the records stored in the lock-file need to be passed to the solver as “preferred” packages. Since rattler_conda_types::MatchSpec can match on any field present in a rattler_conda_types::PackageRecord we need to store all fields in the lock-file not just a subset. To that end this crate stores the full rattler_conda_types::PackageRecord in the lock-file. This allows completely recreating the record that was read from repodata when the lock-file was created which will allow a correct incremental update.

Conda-lock requires users to create multiple lock-files when they want to store multiple environments. This crate allows storing multiple environments for different platforms and with different channels in a single lock-file. This allows storing production- and test environments in a single file.

Structs§

  • The conda channel that was used for the dependency
  • Data related to a single locked conda package in an environment.
  • A locked conda dependency is just a PackageRecord with some additional information on where it came from. It is very similar to a RepoDataRecord, but it does not explicitly contain the channel name.
  • Information about a specific environment in the lock-file.
  • Represents a lock-file for both Conda packages and Pypi packages.
  • A struct to incrementally build a lock-file.
  • Defines the pypi indexes that were used during solving.
  • Data related to a single locked pypi package in an environment.
  • A pinned Pypi package
  • A helper struct to group package and environment data together.
  • Additional runtime configuration of a package. Multiple environments/platforms might refer to the same pypi package but with different extras enabled.
  • A struct that wraps the hashable part of a source package.

Enums§

Constants§

  • The name of the default environment in a LockFile. This is the environment name that is used when no explicit environment name is specified.