mirror of https://github.com/mamba-org/mamba.git
Add MatchSpec doc and fix errors (#3224)
* Add missing spec doc * Add 2.0 changes to doc * Cleanup spec usage doc * Remove outdated documentation page * Fix doc link * Fix backticks in docs * Add rst pre-commit checks
This commit is contained in:
parent
fd42d8dd8e
commit
a00ef35675
|
@ -16,6 +16,12 @@ repos:
|
||||||
args: [--autofix]
|
args: [--autofix]
|
||||||
- id: debug-statements
|
- id: debug-statements
|
||||||
language_version: python3
|
language_version: python3
|
||||||
|
- repo: https://github.com/pre-commit/pygrep-hooks
|
||||||
|
rev: v1.9.0
|
||||||
|
hooks:
|
||||||
|
- id: rst-backticks
|
||||||
|
- id: rst-directive-colons
|
||||||
|
- id: rst-inline-touching-normal
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
rev: v0.1.6
|
rev: v0.1.6
|
||||||
hooks:
|
hooks:
|
||||||
|
|
|
@ -55,7 +55,7 @@ When a package gets installed, several steps are executed:
|
||||||
|
|
||||||
- the package is downloaded and placed into the ``$ROOT_PREFIX/pkgs`` folder
|
- the package is downloaded and placed into the ``$ROOT_PREFIX/pkgs`` folder
|
||||||
- the package is extracted
|
- the package is extracted
|
||||||
- the package is "linked" from the `pkgs` folder into the final destination
|
- the package is "linked" from the ``pkgs`` folder into the final destination
|
||||||
|
|
||||||
When the package is linked to the final destination (for example, some newly created environment), most files are "hard"-linked. That means, there is no copy of the file created. This saves a considerable amount of disk-space when re-using the same package in multiple environments.
|
When the package is linked to the final destination (for example, some newly created environment), most files are "hard"-linked. That means, there is no copy of the file created. This saves a considerable amount of disk-space when re-using the same package in multiple environments.
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,6 @@ If we want to install ``python 3.7.*`` we would prefer ``python 3.7 HASH_cpython
|
||||||
On conda-forge, we're building "variant packages" for numpy (and other packages requiring the C API of Python). This means for a given version of numpy, we'll end up with ~5 almost equivalent variant packages, for cpython 3.6, 3.7 and 3.8 as well as pypy 3.6 and 3.7.
|
On conda-forge, we're building "variant packages" for numpy (and other packages requiring the C API of Python). This means for a given version of numpy, we'll end up with ~5 almost equivalent variant packages, for cpython 3.6, 3.7 and 3.8 as well as pypy 3.6 and 3.7.
|
||||||
For this example the default is the cpython build of numpy. However, currently conda-forge does not apply the down-weigthing via track_feature on the terminal node (numpy), but only in some dependency package (such as python).
|
For this example the default is the cpython build of numpy. However, currently conda-forge does not apply the down-weigthing via track_feature on the terminal node (numpy), but only in some dependency package (such as python).
|
||||||
|
|
||||||
For the case where we want to simply install `numpy`, we need to find which numpy variant installs the highest python package. In this case libsolv would decide for ``numpy-1.20-cpython38``.
|
For the case where we want to simply install ``numpy``, we need to find which numpy variant installs the highest python package. In this case libsolv would decide for ``numpy-1.20-cpython38``.
|
||||||
|
|
||||||
If we install ``numpy python=3.7`` we have two potential variants: ``numpy-1.20-cpython37`` and ``numpy-1.20-pypy37``. In this case we need to inspect wether one of those two builds will require exclusively packages with a track_feature applied. And indeed, the ``pypy37`` package will have a requirement on ``python_abi 3.7 *pypy`` and **all** packages matching this requirement have a track_feature, so that it will be down-weighted.
|
If we install ``numpy python=3.7`` we have two potential variants: ``numpy-1.20-cpython37`` and ``numpy-1.20-pypy37``. In this case we need to inspect wether one of those two builds will require exclusively packages with a track_feature applied. And indeed, the ``pypy37`` package will have a requirement on ``python_abi 3.7 *pypy`` and **all** packages matching this requirement have a track_feature, so that it will be down-weighted.
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
=================
|
|
||||||
Mamba 2.0 Changes
|
Mamba 2.0 Changes
|
||||||
=================
|
=================
|
||||||
.. ...................... ..
|
.. ...................... ..
|
||||||
|
@ -9,11 +8,10 @@ Mamba 2.0 Changes
|
||||||
.. - OCI registries
|
.. - OCI registries
|
||||||
.. - Mirrors
|
.. - Mirrors
|
||||||
.. - Own implementation repodata.json
|
.. - Own implementation repodata.json
|
||||||
.. - Fully feature implementation of MatchSpec
|
|
||||||
|
|
||||||
|
|
||||||
Command Line Executables
|
Command Line Executables
|
||||||
========================
|
------------------------
|
||||||
Mamba (executable)
|
Mamba (executable)
|
||||||
******************
|
******************
|
||||||
``mamba``, previously a Python executable mixing ``libmambapy``, ``conda``, and code to bridge both
|
``mamba``, previously a Python executable mixing ``libmambapy``, ``conda``, and code to bridge both
|
||||||
|
@ -37,14 +35,14 @@ Breaking changes include:
|
||||||
- ``micromamba shell init`` root prefix parameter ``--prefix`` (``-p``) was renamed
|
- ``micromamba shell init`` root prefix parameter ``--prefix`` (``-p``) was renamed
|
||||||
``--root-prefix`` (``-r``).
|
``--root-prefix`` (``-r``).
|
||||||
Both options were supported in version ``1.5``.
|
Both options were supported in version ``1.5``.
|
||||||
- A new config `order_solver_request` (default true) can be used to order the dependencies passed
|
- A new config ``order_solver_request`` (default true) can be used to order the dependencies passed
|
||||||
to the solver, getting order independent solutions.
|
to the solver, getting order independent solutions.
|
||||||
|
|
||||||
.. TODO is micromamba executable renamed mamba?
|
.. TODO OCI and mirrors
|
||||||
|
|
||||||
|
|
||||||
Libraries
|
Libraries
|
||||||
=========
|
---------
|
||||||
Mamba (Python package)
|
Mamba (Python package)
|
||||||
**********************
|
**********************
|
||||||
In version 2.0, all tools are fully written in C++.
|
In version 2.0, all tools are fully written in C++.
|
||||||
|
@ -66,19 +64,21 @@ Changes inlcude:
|
||||||
``ChannelContext.make_conda_compatible`` (with ``Context.instance`` as argument in most cases)
|
``ChannelContext.make_conda_compatible`` (with ``Context.instance`` as argument in most cases)
|
||||||
and passed explicitly to a few functions.
|
and passed explicitly to a few functions.
|
||||||
- A new ``Context`` independent submodule ``libmambapy.specs`` has been introduced with:
|
- A new ``Context`` independent submodule ``libmambapy.specs`` has been introduced with:
|
||||||
|
|
||||||
- The redesign of the ``Channel`` and a new ``UnresolvedChannel`` used to describe unresolved
|
- The redesign of the ``Channel`` and a new ``UnresolvedChannel`` used to describe unresolved
|
||||||
channel strings.
|
channel strings.
|
||||||
A featureful ``libmambapy.specs.CondaURL`` is used to describe channel URLs.
|
A featureful ``libmambapy.specs.CondaURL`` is used to describe channel URLs.
|
||||||
- The redesign``MatchSpec``.
|
- The redesign of ``MatchSpec``.
|
||||||
The module also includes a platform enumeration, an implementation of ordered ``Version``,
|
The module also includes a platform enumeration, an implementation of ordered ``Version``,
|
||||||
and a ``VersionSpec`` to match versions.
|
and a ``VersionSpec`` to match versions.
|
||||||
- ``PackageInfo`` has been moved to this submodule.
|
- ``PackageInfo`` has been moved to this submodule.
|
||||||
Some attributes have been given a more explicit name ``fn`` > ``filename``,
|
Some attributes have been given a more explicit name ``fn`` > ``filename``,
|
||||||
``url`` > ``package_url``.
|
``url`` > ``package_url``.
|
||||||
|
|
||||||
- A new ``Context`` independent submodule ``libmambapy.solver`` has been introduced with the
|
- A new ``Context`` independent submodule ``libmambapy.solver`` has been introduced with the
|
||||||
changes below.
|
changes below.
|
||||||
A usage documentation page is available at
|
A usage documentation page is available at :ref:`mamba_usage_solver`.
|
||||||
https://mamba.readthedocs.io/en/latest/usage/solver.html
|
|
||||||
- The redesign of the ``Pool``, which is now available as ``libmambapy.solver.libsolv.Database``.
|
- The redesign of the ``Pool``, which is now available as ``libmambapy.solver.libsolv.Database``.
|
||||||
The new interfaces makes it easier to create repositories without using other ``libmambapy``
|
The new interfaces makes it easier to create repositories without using other ``libmambapy``
|
||||||
objects.
|
objects.
|
||||||
|
@ -89,13 +89,12 @@ Changes inlcude:
|
||||||
high-level free functions such as ``load_subdir_in_database`` and
|
high-level free functions such as ``load_subdir_in_database`` and
|
||||||
``load_installed_packages_in_database``.
|
``load_installed_packages_in_database``.
|
||||||
- The ``Solver`` has been moved to ``libmambapy.solver.libsolv.Solver``.
|
- The ``Solver`` has been moved to ``libmambapy.solver.libsolv.Solver``.
|
||||||
|
|
||||||
- All jobs, pins, and flags must be passed as a single ``libmambapy.solver.Request``.
|
- All jobs, pins, and flags must be passed as a single ``libmambapy.solver.Request``.
|
||||||
- The outcome of solving the request is either a ``libmambapy.solver.Solution`` or a
|
- The outcome of solving the request is either a ``libmambapy.solver.Solution`` or a
|
||||||
``libmambapy.solver.libsolv.Unsolvable`` state from which rich error messages can be
|
``libmambapy.solver.libsolv.Unsolvable`` state from which rich error messages can be
|
||||||
extracted.
|
extracted.
|
||||||
|
|
||||||
.. TODO include final decision for Channels as URLs.
|
|
||||||
|
|
||||||
For many changes, an exception throwing placeholder has ben kept to advise developpers on the new
|
For many changes, an exception throwing placeholder has ben kept to advise developpers on the new
|
||||||
direction to take.
|
direction to take.
|
||||||
|
|
||||||
|
@ -106,11 +105,14 @@ Due to the low usage of the C++ interface, all changes are not listed here.
|
||||||
The main changes are:
|
The main changes are:
|
||||||
|
|
||||||
- Refactoring and testing of a large number of utilities into a ``util::`` namespace,
|
- Refactoring and testing of a large number of utilities into a ``util::`` namespace,
|
||||||
- Creation of the ``specs::`` with:
|
- Creation of the ``specs::`` the items below.
|
||||||
- Implementations of ``Version`` and ``VersionSpec`` for matching versions,
|
A usage documentation (in Python) is available at :ref:`mamba_usage_specs`.
|
||||||
- A refactoring of a purely funcitonal ``Channel`` class,
|
|
||||||
- Implementaiton of a ``UnresolvedChannel`` to describe unresolved ``Channels``,
|
- Implementations of ``Version`` and ``VersionSpec`` for matching versions,
|
||||||
- A refactored implementation of ``MatchSpec`` using the components above.
|
- A refactoring of a purely funcitonal ``Channel`` class,
|
||||||
|
- Implementaiton of a ``UnresolvedChannel`` to describe unresolved ``Channels``,
|
||||||
|
- A refactored implementation of ``MatchSpec`` using the components above.
|
||||||
|
|
||||||
- A cleanup of ``ChannelContext`` for be a light proxy and parameter holder wrapping the
|
- A cleanup of ``ChannelContext`` for be a light proxy and parameter holder wrapping the
|
||||||
``specs::Channel``.
|
``specs::Channel``.
|
||||||
- A new ``repodata.json`` parser using `simdjson <https://simdjson.org/>`_.
|
- A new ``repodata.json`` parser using `simdjson <https://simdjson.org/>`_.
|
||||||
|
@ -118,15 +120,15 @@ The main changes are:
|
||||||
subnamespace and works independently of the ``Context``.
|
subnamespace and works independently of the ``Context``.
|
||||||
The ``solver::libsolv`` sub-namespace has also been added for full isolation of libsolv, and a
|
The ``solver::libsolv`` sub-namespace has also been added for full isolation of libsolv, and a
|
||||||
solver API without ``Context``.
|
solver API without ``Context``.
|
||||||
The ``solver`` API redesign includes:
|
The ``solver`` API redesign includes the items below.
|
||||||
- A refactoring of the ``MPool`` as a ``DataBase``, fully isolates libsolv, and simplifies
|
A usage documentation (in Python) is available at :ref:`mamba_usage_solver`.
|
||||||
repository creation.
|
|
||||||
- A refactoring and thinning of ``MRepo`` as a new ``RepoInfo``.
|
- A refactoring of the ``MPool`` as a ``DataBase``, fully isolates libsolv, and simplifies
|
||||||
- A solver ``Request`` with all requirements to solve is the new way to specify jobs.
|
repository creation.
|
||||||
- A refactoring of ``Solver``.
|
- A refactoring and thinning of ``MRepo`` as a new ``RepoInfo``.
|
||||||
- A solver outcome as either a ``Solution`` or an ``UnSolvable`` state.
|
- A solver ``Request`` with all requirements to solve is the new way to specify jobs.
|
||||||
A usage documentation (in Python) is available at
|
- A refactoring of ``Solver``.
|
||||||
https://mamba.readthedocs.io/en/latest/usage/solver.html
|
- A solver outcome as either a ``Solution`` or an ``UnSolvable`` state.
|
||||||
- Improved downloaders.
|
- Improved downloaders.
|
||||||
|
|
||||||
.. TODO OCI registry
|
.. TODO OCI registry
|
||||||
|
|
|
@ -28,7 +28,8 @@ Develop using Taskfile
|
||||||
======================
|
======================
|
||||||
|
|
||||||
Many development operations can be automated and chained using `Taskfile <https://taskfile.dev/>`_.
|
Many development operations can be automated and chained using `Taskfile <https://taskfile.dev/>`_.
|
||||||
You can follow the installation instructions there, or install it via `conda-forge`.
|
You can follow the installation instructions there, or install it via ``conda-forge``.
|
||||||
|
|
||||||
|
|
||||||
.. code:: bash
|
.. code:: bash
|
||||||
|
|
||||||
|
@ -63,15 +64,15 @@ At the time of writing, the following tasks are available:
|
||||||
* create-dev-env: Create a local development mamba environment with all needed dependencies
|
* create-dev-env: Create a local development mamba environment with all needed dependencies
|
||||||
* create-test-env: Create a local test environment with as a copy of the dev environment.
|
* create-test-env: Create a local test environment with as a copy of the dev environment.
|
||||||
* install-cpp: Install C++ targets into the test environment.
|
* install-cpp: Install C++ targets into the test environment.
|
||||||
* install-py: Install the `libmambapy` Python package inside the test environment.
|
* install-py: Install the ``libmambapy`` Python package inside the test environment.
|
||||||
* micromamba: Run the development `micromamba`.
|
* micromamba: Run the development ``micromamba``.
|
||||||
* pre-commit: Run linters and code formatters.
|
* pre-commit: Run linters and code formatters.
|
||||||
* reconfigure: Erase all CMake cache entries and run confiiguration again.
|
* reconfigure: Erase all CMake cache entries and run confiiguration again.
|
||||||
* stubgen: Regenerate libmambapy typing stubs.
|
* stubgen: Regenerate libmambapy typing stubs.
|
||||||
* test-docs: Test the documentation, for instance for dead links.
|
* test-docs: Test the documentation, for instance for dead links.
|
||||||
* test-libmamba: Run `libmamba` C++ based tests.
|
* test-libmamba: Run ``libmamba`` C++ based tests.
|
||||||
* test-libmambapy: Run `libmambapy` Python based unit tests.
|
* test-libmambapy: Run ``libmambapy`` Python based unit tests.
|
||||||
* test-micromamba: Run `micromamba` integration tests.
|
* test-micromamba: Run ``micromamba`` integration tests.
|
||||||
|
|
||||||
For instance to run ``libmamba`` tests, execute:
|
For instance to run ``libmamba`` tests, execute:
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,6 @@ You can try Mamba now by visiting the installation for
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
:hidden:
|
:hidden:
|
||||||
|
|
||||||
python_api
|
|
||||||
usage/specs
|
usage/specs
|
||||||
usage/solver
|
usage/solver
|
||||||
|
|
||||||
|
@ -75,3 +74,4 @@ You can try Mamba now by visiting the installation for
|
||||||
developer_zone/contributing
|
developer_zone/contributing
|
||||||
developer_zone/dev_environment
|
developer_zone/dev_environment
|
||||||
developer_zone/internals
|
developer_zone/internals
|
||||||
|
developer_zone/changes-2.0
|
||||||
|
|
|
@ -7,7 +7,7 @@ Mamba Installation
|
||||||
Fresh install (recommended)
|
Fresh install (recommended)
|
||||||
***************************
|
***************************
|
||||||
|
|
||||||
We recommend that you start with the `Miniforge distribution <https://github.com/conda-forge/miniforge>`_ >= `Miniforge3-22.3.1-0`.
|
We recommend that you start with the `Miniforge distribution <https://github.com/conda-forge/miniforge>`_ >= ``Miniforge3-22.3.1-0``.
|
||||||
If you need an older version of Mamba, please use the Mambaforge distribution.
|
If you need an older version of Mamba, please use the Mambaforge distribution.
|
||||||
Miniforge comes with the popular ``conda-forge`` channel preconfigured, but you can modify the configuration to use any channel you like.
|
Miniforge comes with the popular ``conda-forge`` channel preconfigured, but you can modify the configuration to use any channel you like.
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ After successful installation, you can use the mamba commands as described in :r
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
1. After installation, please :ref:`make sure <defaults_channels>` that you do not have the Anaconda default channels configured.
|
1. After installation, please :ref:`make sure <defaults_channels>` that you do not have the Anaconda default channels configured.
|
||||||
2. Do not install anything into the `base` environment as this might break your installation. See :ref:`here <base_packages>` for details.
|
2. Do not install anything into the ``base`` environment as this might break your installation. See :ref:`here <base_packages>` for details.
|
||||||
|
|
||||||
|
|
||||||
Existing ``conda`` install (not recommended)
|
Existing ``conda`` install (not recommended)
|
||||||
|
|
|
@ -1,138 +0,0 @@
|
||||||
=======================
|
|
||||||
Python API of ``mamba``
|
|
||||||
=======================
|
|
||||||
|
|
||||||
Using internal mamba APIs
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
The core of ``mamba`` is written in C++, but we expose the internals of mamba with a Python API
|
|
||||||
(using ``pybind11``).
|
|
||||||
|
|
||||||
You can import ``libmambapy`` containing the Python API using ``import libmambapy`` without having ``mamba`` installed.
|
|
||||||
|
|
||||||
These bindings expose the following objects (`boa`_ has a full example):
|
|
||||||
|
|
||||||
- ``Context``: a singleton configuration object. All global configuration goes through this. From Python you can use the context object like so:
|
|
||||||
|
|
||||||
.. code:: python
|
|
||||||
|
|
||||||
import libmambapy
|
|
||||||
|
|
||||||
ctx = libmambapy.Context.instance()
|
|
||||||
ctx.conda_prefix = "/home/wolfv/conda"
|
|
||||||
print(ctx.root_prefix)
|
|
||||||
|
|
||||||
|
|
||||||
Here is an example usage of ``libmambapy``:
|
|
||||||
|
|
||||||
.. code:: python
|
|
||||||
|
|
||||||
def get_index(
|
|
||||||
channel_urls=(),
|
|
||||||
prepend=True,
|
|
||||||
platform=None,
|
|
||||||
use_local=False,
|
|
||||||
use_cache=False,
|
|
||||||
unknown=None,
|
|
||||||
prefix=None,
|
|
||||||
repodata_fn="repodata.json",
|
|
||||||
):
|
|
||||||
check_allowlist(channel_urls)
|
|
||||||
|
|
||||||
dlist = libmambapy.DownloadTargetList()
|
|
||||||
|
|
||||||
index = []
|
|
||||||
for idx, url in enumerate(channel_urls):
|
|
||||||
channel = Channel(url)
|
|
||||||
|
|
||||||
full_url = channel.url(with_credentials=True) + "/" + repodata_fn
|
|
||||||
full_path_cache = os.path.join(
|
|
||||||
create_cache_dir(), cache_fn_url(full_url, repodata_fn)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Channels might not have a name.
|
|
||||||
if channel.name is None:
|
|
||||||
name_and_subdir = channel.subdir
|
|
||||||
else:
|
|
||||||
name_and_subdir = channel.name + "/" + channel.subdir
|
|
||||||
sd = libmambapy.SubdirData(name_and_subdir, full_url, full_path_cache)
|
|
||||||
|
|
||||||
index.append((sd, channel))
|
|
||||||
dlist.add(sd)
|
|
||||||
|
|
||||||
is_downloaded = dlist.download(libmambapy.MAMBA_DOWNLOAD_FAILFAST)
|
|
||||||
|
|
||||||
if not is_downloaded:
|
|
||||||
raise RuntimeError("Error downloading repodata.")
|
|
||||||
|
|
||||||
return index
|
|
||||||
|
|
||||||
|
|
||||||
class MambaSolver:
|
|
||||||
def __init__(self, prefix, channels, platform):
|
|
||||||
|
|
||||||
api_ctx = libmambapy.Context()
|
|
||||||
api_ctx.conda_prefix = prefix
|
|
||||||
|
|
||||||
self.channels = channels
|
|
||||||
self.platform = platform
|
|
||||||
self.index = get_index(channels, platform=platform)
|
|
||||||
self.local_index = []
|
|
||||||
self.pool = libmambapy.Pool()
|
|
||||||
self.repos = []
|
|
||||||
|
|
||||||
start_prio = len(channels)
|
|
||||||
priority = start_prio
|
|
||||||
subpriority = 0 # wrong! :)
|
|
||||||
for subdir, channel in self.index:
|
|
||||||
repo = libmambapy.Repo(
|
|
||||||
self.pool,
|
|
||||||
str(channel),
|
|
||||||
subdir.cache_path(),
|
|
||||||
channel.url(with_credentials=True),
|
|
||||||
)
|
|
||||||
repo.set_priority(start_prio, subpriority)
|
|
||||||
start_prio -= 1
|
|
||||||
self.repos.append(repo)
|
|
||||||
|
|
||||||
self.local_repos = {}
|
|
||||||
|
|
||||||
def solve(self, specs, prefix):
|
|
||||||
"""Solve given a set of specs.
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
specs : list of str
|
|
||||||
A list of package specs. You can use `conda.models.match_spec.MatchSpec`
|
|
||||||
to get them to the right form by calling
|
|
||||||
`MatchSpec(mypec).conda_build_form()`
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
solvable : bool
|
|
||||||
True if the set of specs has a solution, False otherwise.
|
|
||||||
"""
|
|
||||||
solver_options = [(libmambapy.SOLVER_FLAG_ALLOW_DOWNGRADE, 1)]
|
|
||||||
api_solver = libmambapy.Solver(self.pool, solver_options)
|
|
||||||
_specs = specs
|
|
||||||
|
|
||||||
api_solver.add_jobs(_specs, libmambapy.SOLVER_INSTALL)
|
|
||||||
success = api_solver.try_solve()
|
|
||||||
|
|
||||||
if not success:
|
|
||||||
error_string = "Mamba failed to solve:\n"
|
|
||||||
for s in _specs:
|
|
||||||
error_string += f" - {s}\n"
|
|
||||||
error_string += "\nwith channels:\n"
|
|
||||||
for c in self.channels:
|
|
||||||
error_string += f" - {c}\n"
|
|
||||||
pstring = api_solver.problems_to_str()
|
|
||||||
pstring = "\n".join([" " + l for l in pstring.split("\n")])
|
|
||||||
error_string += f"\nThe reported errors are:\n⇟{pstring}"
|
|
||||||
print(error_string)
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
package_cache = libmambapy.MultiPackageCache(pkgs_dirs)
|
|
||||||
|
|
||||||
t = libmambapy.Transaction(api_solver, package_cache)
|
|
||||||
return t
|
|
||||||
|
|
||||||
.. _boa: https://github.com/mamba-org/boa/blob/main/boa/core/solver.py
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
.. _mamba_usage_solver:
|
||||||
|
|
||||||
Solving Package Environments
|
Solving Package Environments
|
||||||
============================
|
============================
|
||||||
|
|
||||||
|
@ -30,7 +32,7 @@ This serves to resolve explicit channel requirements or channel priority.
|
||||||
As such, the database constructor takes a set of
|
As such, the database constructor takes a set of
|
||||||
:cpp:type:`ChannelResolveParams <mamba::specs::ChannelResolveParams>`
|
:cpp:type:`ChannelResolveParams <mamba::specs::ChannelResolveParams>`
|
||||||
to work with :cpp:type:`Channel <mamba::specs::Channel>` work with Channel data
|
to work with :cpp:type:`Channel <mamba::specs::Channel>` work with Channel data
|
||||||
internaly (see `the usage section on Channels <libmamba_usage_channel>`_ for more
|
internaly (see :ref:`the usage section on Channels <libmamba_usage_channel>` for more
|
||||||
information).
|
information).
|
||||||
|
|
||||||
The first way to add a repository is from a list of |PackageInfo| using
|
The first way to add a repository is from a list of |PackageInfo| using
|
||||||
|
|
|
@ -1,17 +1,29 @@
|
||||||
|
.. _mamba_usage_specs:
|
||||||
|
|
||||||
Describing Conda Objects
|
Describing Conda Objects
|
||||||
========================
|
========================
|
||||||
|
|
||||||
|
.. |CondaURL| replace:: :cpp:type:`CondaURL <mamba::specs::CondaURL>`
|
||||||
|
.. |UnresolvedChannel| replace:: :cpp:type:`UnresolvedChannel <mamba::specs::UnresolvedChannel>`
|
||||||
|
.. |Channel| replace:: :cpp:type:`Channel <mamba::specs::Channel>`
|
||||||
|
.. |Version| replace:: :cpp:type:`Version <mamba::specs::Version>`
|
||||||
|
.. |VersionSpec| replace:: :cpp:type:`VersionSpec <mamba::specs::VersionSpec>`
|
||||||
|
.. |BuildNumberSpec| replace:: :cpp:type:`BuildNumberSpec <mamba::specs::BuildNumberSpec>`
|
||||||
|
.. |GlobSpec| replace:: :cpp:type:`GlobSpec <mamba::specs::GlobSpec>`
|
||||||
|
.. |MatchSpec| replace:: :cpp:type:`MatchSpec <mamba::specs::MatchSpec>`
|
||||||
|
|
||||||
|
|
||||||
The :any:`libmambapy.specs <mamba::specs>` submodule contains object to *describe* abstraction in the Conda ecosystem.
|
The :any:`libmambapy.specs <mamba::specs>` submodule contains object to *describe* abstraction in the Conda ecosystem.
|
||||||
They are purely functional and do not have any observable impact on the user system.
|
They are purely functional and do not have any observable impact on the user system.
|
||||||
For instance :cpp:type:`libmambapy.specs.Channel <mamba::specs::Channel>` is used to describe a
|
For instance |Channel| is used to describe a channel but does not download any file.
|
||||||
channel but does not download any file.
|
|
||||||
|
|
||||||
CondaURL
|
CondaURL
|
||||||
--------
|
--------
|
||||||
The :cpp:type:`CondaURL <mamba::specs::CondaURL>` is a rich URL object that has additional
|
The |CondaURL| is a rich URL object that has additional capabilities for dealing with tokens,
|
||||||
capabilities for dealing with tokens, platforms, and packages.
|
platforms, and packages.
|
||||||
|
|
||||||
To parse a string into a ``CondaURL``, use ``CondaURL.parse`` as follows:
|
To parse a string into a |CondaURL| use :cpp:func:`CondaURL.parse <mamba::specs::CondaURL::parse>`
|
||||||
|
as follows:
|
||||||
|
|
||||||
.. code:: python
|
.. code:: python
|
||||||
|
|
||||||
|
@ -94,8 +106,8 @@ user-friendly string, but that may not be parsed back.
|
||||||
UnresolvedChannel
|
UnresolvedChannel
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
A :cpp:type:`UnresolvedChannel <mamba::specs::UnresolvedChannel>` is a lightweight object to represent
|
A |UnresolvedChannel| is a lightweight object to represent a channel string, as in passed in
|
||||||
a channel string, as in passed in the CLI or configuration.
|
the CLI or configuration.
|
||||||
Since channels rely heavily on configuration options, this type can be used as a placeholder for a
|
Since channels rely heavily on configuration options, this type can be used as a placeholder for a
|
||||||
channel that has not been fully "resolved" to a specific location.
|
channel that has not been fully "resolved" to a specific location.
|
||||||
It does minimal parsing and can detect the type of ressource (an unresolved name, a URL, a file)
|
It does minimal parsing and can detect the type of ressource (an unresolved name, a URL, a file)
|
||||||
|
@ -125,15 +137,14 @@ Dynamic platforms (as in not known by Mamba) can only be detected with the ``[]`
|
||||||
|
|
||||||
|
|
||||||
.. _libmamba_usage_channel:
|
.. _libmamba_usage_channel:
|
||||||
|
|
||||||
Channel
|
Channel
|
||||||
-------
|
-------
|
||||||
The :cpp:type:`Channel <mamba::specs::Channel>` are represented by a
|
The |Channel| are represented by a |CondaURL| and a set of platform filters.
|
||||||
:cpp:type:`CondaURL <mamba::specs::CondaURL>` and a set of platform filters.
|
|
||||||
A display name is also available, but is not considered a stable identifiaction form of the
|
A display name is also available, but is not considered a stable identifiaction form of the
|
||||||
channel, since it depends on the many configuration parameters, such as the channel alias.
|
channel, since it depends on the many configuration parameters, such as the channel alias.
|
||||||
|
|
||||||
We construct a :cpp:type:`Channel <mamba::specs::Channel>` by *resolving* a
|
We construct a |Channel| by *resolving* a |UnresolvedChannel|.
|
||||||
:cpp:type:`UnresolvedChannel <mamba::specs::UnresolvedChannel>`.
|
|
||||||
All parameters that influence this resolution must be provided explicitly.
|
All parameters that influence this resolution must be provided explicitly.
|
||||||
|
|
||||||
|
|
||||||
|
@ -197,13 +208,12 @@ This is because of custom multichannel, a single name can return mutliple channe
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Creating :cpp:type:`Channel <mamba::specs::Channel>` objects this way, while highly
|
Creating |Channel| objects this way, while highly customizable, can be very verbose.
|
||||||
customizable, can be very verbose.
|
|
||||||
In practice, one can create a ``ChannelContext`` with ``ChannelContext.make_simple`` or
|
In practice, one can create a ``ChannelContext`` with ``ChannelContext.make_simple`` or
|
||||||
``ChannelContext.make_conda_compatible`` to compute and hold all these parameters from a
|
``ChannelContext.make_conda_compatible`` to compute and hold all these parameters from a
|
||||||
``Context`` (itself getting its values from all the configuration sources).
|
``Context`` (itself getting its values from all the configuration sources).
|
||||||
``ChannelContext.make_channel`` can then directly construct a
|
``ChannelContext.make_channel`` can then directly construct a
|
||||||
:cpp:type:`Channel <mamba::specs::Channel>` from a string.
|
|Channel| from a string.
|
||||||
|
|
||||||
|
|
||||||
Version
|
Version
|
||||||
|
@ -240,7 +250,7 @@ so ``1.2``, ``1.2.0``, and ``1.2.0.0`` are all considered equal.
|
||||||
`calendar versioning <https://calver.org/>`_, or
|
`calendar versioning <https://calver.org/>`_, or
|
||||||
`PEP440 <https://peps.python.org/pep-0440/>`_.
|
`PEP440 <https://peps.python.org/pep-0440/>`_.
|
||||||
|
|
||||||
A :cpp:type:`Version <mamba::specs::Version>` can be created by parsing a string with
|
A |Version| can be created by parsing a string with
|
||||||
:cpp:func:`Version.parse <mamba::specs::Version::parse>`.
|
:cpp:func:`Version.parse <mamba::specs::Version::parse>`.
|
||||||
|
|
||||||
.. code:: python
|
.. code:: python
|
||||||
|
@ -268,16 +278,16 @@ A version spec is a way to describe a set of versions.
|
||||||
We have the following primitives:
|
We have the following primitives:
|
||||||
|
|
||||||
- ``*`` matches all versions (unrestricted).
|
- ``*`` matches all versions (unrestricted).
|
||||||
- ``==`` for **equal** states matches versions equal to the given one (a singleton).
|
- ``==`` for **equal** matches versions equal to the given one (a singleton).
|
||||||
For instance ``==1.2.4`` matches ``1.2.4`` only, and not ``1.2.4.1`` or ``1.2``.
|
For instance ``==1.2.4`` matches ``1.2.4`` only, and not ``1.2.4.1`` or ``1.2``.
|
||||||
Note that since ``1.2.4.0`` is the same as ``1.2.4``, this is also matched.
|
Note that since ``1.2.4.0`` is the same as ``1.2.4``, this is also matched.
|
||||||
- ``!=`` for ``not equal`` is the opposite, it matches all but the given version.
|
- ``!=`` for **not equal** is the opposite, it matches all but the given version.
|
||||||
For instance ``=!1.2.4`` matches ``1.2.5`` and ``1!1.2.4`` but not ``1.2.4``.
|
For instance ``=!1.2.4`` matches ``1.2.5`` and ``1!1.2.4`` but not ``1.2.4``.
|
||||||
- ``>`` for **greater** matches versions stricly greater than the current one, for instance
|
- ``>`` for **greater** matches versions stricly greater than the current one, for instance
|
||||||
``>1.2.4`` matches ``2.0.0``, ``1!1.0.0``, but not ``1.1.0`` or ``1.2.4``.
|
``>1.2.4`` matches ``2.0.0``, ``1!1.0.0``, but not ``1.1.0`` or ``1.2.4``.
|
||||||
- ``>=`` for **greater or equal**.
|
- ``>=`` for **greater or equal**.
|
||||||
- ``<`` for **less**.
|
- ``<`` for **less**.
|
||||||
- ``<-`` for **less or equal**.
|
- ``<=`` for **less or equal**.
|
||||||
- ``=`` for **starts with** matches versions that start with the same non zero parts of the version.
|
- ``=`` for **starts with** matches versions that start with the same non zero parts of the version.
|
||||||
For instance ``=1.7`` matches ``1.7.8``, and ``1.7.0alpha1`` (beware since this is smaller
|
For instance ``=1.7`` matches ``1.7.8``, and ``1.7.0alpha1`` (beware since this is smaller
|
||||||
than ``1.7.0``).
|
than ``1.7.0``).
|
||||||
|
@ -287,7 +297,7 @@ We have the following primitives:
|
||||||
For instance ``!=1.7.*`` matches ``1.8.3`` but not ``1.7.2``.
|
For instance ``!=1.7.*`` matches ``1.8.3`` but not ``1.7.2``.
|
||||||
- ``~=`` for **compatible with** matches versions that are greater or equal and starting with the
|
- ``~=`` for **compatible with** matches versions that are greater or equal and starting with the
|
||||||
all but the last parts specified, including zeros.
|
all but the last parts specified, including zeros.
|
||||||
For instance `~=2.0` matches ``2.0.0``, ``2.1.3``, but not ``3.0.1`` or ``2.0.0alpha``.
|
For instance ``~=2.0`` matches ``2.0.0``, ``2.1.3``, but not ``3.0.1`` or ``2.0.0alpha``.
|
||||||
|
|
||||||
All version spec can be combine using a boolean grammar where ``|`` means **or** and ``,`` means
|
All version spec can be combine using a boolean grammar where ``|`` means **or** and ``,`` means
|
||||||
**and**.
|
**and**.
|
||||||
|
@ -299,10 +309,10 @@ For instance, ``(>2.1.0,<3.0)|==2.0.1`` means:
|
||||||
- greater that ``2.1.0``
|
- greater that ``2.1.0``
|
||||||
- and less than ``3.0``.
|
- and less than ``3.0``.
|
||||||
|
|
||||||
To create a :cpp:type:`VersionSpec <mamba::specs::VersionSpec>` from a string, we parse it with
|
To create a |VersionSpec| from a string, we parse it with
|
||||||
:cpp:type:`VersionSpec.parse <mamba::specs::VersionSpec::parse>`.
|
:cpp:func:`VersionSpec.parse <mamba::specs::VersionSpec::parse>`.
|
||||||
To check if a given version matches a version spec, we use
|
To check if a given version matches a version spec, we use
|
||||||
:cpp:type:`VersionSpec.contains <mamba::specs::VersionSpec::contains>`.
|
:cpp:func:`VersionSpec.contains <mamba::specs::VersionSpec::contains>`.
|
||||||
|
|
||||||
.. code:: python
|
.. code:: python
|
||||||
|
|
||||||
|
@ -313,3 +323,111 @@ To check if a given version matches a version spec, we use
|
||||||
assert vs.contains(specs.Version.parse("2.4.0"))
|
assert vs.contains(specs.Version.parse("2.4.0"))
|
||||||
assert vs.contains(specs.Version.parse("2.0.1"))
|
assert vs.contains(specs.Version.parse("2.0.1"))
|
||||||
assert not vs.contains(specs.Version.parse("3.0.1"))
|
assert not vs.contains(specs.Version.parse("3.0.1"))
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
Single versions such as ``3.7`` are parsed by Conda and Mamba as ``==3.7``, which can seem
|
||||||
|
unintuitive.
|
||||||
|
As such, it is recommended to always specify an operator.
|
||||||
|
This mistake is especially likely when writing a match spec such as ``python 3.7``.
|
||||||
|
|
||||||
|
BuildNumberSpec
|
||||||
|
---------------
|
||||||
|
Similarily, a build number spec is a way to describe a set of build numbers.
|
||||||
|
It's much simpler than the |VersionSpec| in that it does not contain any boolean grammar
|
||||||
|
(the ``,`` and ``|`` operators).
|
||||||
|
|BuildNumberSpec| only contain primitives similar to that used in |VersionSpec|:
|
||||||
|
|
||||||
|
- ``*`` or ``=*`` matches all build numbers (unrestricted).
|
||||||
|
- ``=`` for **equal** matches build numbers equal to the given one (a singleton).
|
||||||
|
- ``!=`` for **not equal**.
|
||||||
|
- ``>`` for **greater** matches versions stricly greater than the current one.
|
||||||
|
- ``>=`` for **greater or equal**.
|
||||||
|
- ``<`` for **less**.
|
||||||
|
- ``<=`` for **less or equal**.
|
||||||
|
|
||||||
|
To create a |BuildNumberSpec| from a string, we parse it
|
||||||
|
with :cpp:func:`BuildNumberSpec.parse <mamba::specs::BuildNumberSpec::parse>`.
|
||||||
|
To check if a given build number matches a build number spec, we use
|
||||||
|
:cpp:func:`BuildNumberSpec.contains <mamba::specs::BuildNumberSpec::contains>`.
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
import libmambapy.specs as specs
|
||||||
|
|
||||||
|
bs = specs.BuildNumberSpec.parse(">2")
|
||||||
|
|
||||||
|
assert bs.contains(3)
|
||||||
|
assert not bs.contains(2)
|
||||||
|
|
||||||
|
Other Specs
|
||||||
|
-----------
|
||||||
|
The |GlobSpec| is used to match glob expressions on strings.
|
||||||
|
The only wildcard currently supported is ``*`` which stands for any string (0 or more characters).
|
||||||
|
The glob spec is used as the basis for the |MatchSpec| package name and build string.
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
import libmambapy.specs as specs
|
||||||
|
|
||||||
|
glob = specs.GlobSpec.parse("py*")
|
||||||
|
|
||||||
|
assert glob.contains("python")
|
||||||
|
assert glob.contains("pypy")
|
||||||
|
assert not vs.contains("rust-python")
|
||||||
|
|
||||||
|
MatchSpec
|
||||||
|
---------
|
||||||
|
Ultimately, the |MatchSpec| is the way to match on conda packages, that is a way to describe a
|
||||||
|
set of packages.
|
||||||
|
This is what is passed in a command line argument such as ``mamba install <match_spec>``.
|
||||||
|
|
||||||
|
Match specs have a complex string representation, which we can informally write as
|
||||||
|
``[[<channel>:]<namespace>:]<name>[<version>[=<build_string>]][[<attribute>=<value>, [...]]]``, or
|
||||||
|
with an example
|
||||||
|
``conda-forge:ns:python>=3.7=*cypthon[subdir="linux-64",fn=pkg.conda]``.
|
||||||
|
|
||||||
|
- ``<channel>``, here ``conda-forge`` describes an |UnresolvedChannel| of where the channel the
|
||||||
|
package should come from.
|
||||||
|
It accepts all values from an unresolved channel, such as ``conda-forge/label/micromamba_dev``,
|
||||||
|
URLs, local file path, and platforms filters in between brackets.
|
||||||
|
- ``<namespace>``, here ``ns`` is a future, not implemented, feature.
|
||||||
|
It is nonetheless parsed, and retrievable.
|
||||||
|
- ``<name>``, here ``python`` is the package name or glob expression and is the only mandatory
|
||||||
|
field.
|
||||||
|
- Following is the |VersionSpec| ``<version>`` or ``>=3.7`` here.
|
||||||
|
- When the version specification is written (but it could also be set to ``=*``), it can be
|
||||||
|
followed by a ``<build_string>`` glob specification, here ``*cpython``.
|
||||||
|
- Last, a bracket section of comma separated ``<attribute>`` = ``<value>``.
|
||||||
|
In the example, we have two attributes, ``subdir`` and ``fn``.
|
||||||
|
Attribute values support quaoting with ``"`` or ``'``.
|
||||||
|
As such, they can be useful to set previously mentioned field without ambiguity.
|
||||||
|
Valid attribute names are:
|
||||||
|
|
||||||
|
- ``channel``, similar to ``<channel>``.
|
||||||
|
- ``name``, similar to ``<name>``.
|
||||||
|
- ``version``, similar to ``<version>`` (can be useful to set version expression containing
|
||||||
|
parentheses and ``,`` and ``|`` operators).
|
||||||
|
- ``build``, similar to ``<build_string>``.
|
||||||
|
- ``build_number`` to set the |BuildNumberSpec|.
|
||||||
|
- ``subdir`` to select the channel subdirectory platform from which the package must come from.
|
||||||
|
- ``fn`` to select the filename the package must match.
|
||||||
|
- ``md5`` to specify the MD5 hash the package archive must have.
|
||||||
|
- ``sha256`` to specify the SHA256 hash the package archive must have.
|
||||||
|
- ``license`` to specify the license the package must have.
|
||||||
|
- ``track_features`` to specify a list of ``track_features`` specified at the package build time.
|
||||||
|
- ``optional`` to add the package as a constraint rather than a strict dependency.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
Specifying some value mulitple time, such as in ``python>=3.7[version="(=3.9|>3.11)"]``, or
|
||||||
|
``python[build="foo"][build="bar"]`` is undefined and subject to change in the future.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
When specifying a version in the attribute section, the first ``=`` is parsed as the attribute
|
||||||
|
assignment.
|
||||||
|
That is ``python[version=3.7]`` is equivalent to ``python 3.7``, which is equivalent to
|
||||||
|
``python==3.7`` (strong equality).
|
||||||
|
This is intuitively different from how we write ``python=3.7``, which we must write with
|
||||||
|
attributes as ``python[version="=3.7"]``.
|
||||||
|
|
|
@ -14,7 +14,7 @@ rely on a pure C++ implementation.
|
||||||
|
|
||||||
The configuration is parsed/read from multiple sources types:
|
The configuration is parsed/read from multiple sources types:
|
||||||
|
|
||||||
- **rc file**: a file using `YAML` syntax
|
- **rc file**: a file using ``YAML`` syntax
|
||||||
- **environment variable**: a key/value pair set prior to mamba execution
|
- **environment variable**: a key/value pair set prior to mamba execution
|
||||||
- **CLI**: a parsed argument/option from a CLI interface
|
- **CLI**: a parsed argument/option from a CLI interface
|
||||||
- **API**: a value set programmatically by a program relying on mamba
|
- **API**: a value set programmatically by a program relying on mamba
|
||||||
|
@ -26,7 +26,8 @@ The precedence order between those sources is:
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
`rc` file stands historically for `run commands` which could also translate to `runtime configuration`.
|
``rc`` file stands historically for ``run commands`` which could also translate to
|
||||||
|
``runtime configuration``.
|
||||||
It's a convenient way to persist configuration on the filesystem and use it as default.
|
It's a convenient way to persist configuration on the filesystem and use it as default.
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,9 +45,9 @@ Example:
|
||||||
|
|
||||||
Running ``micromamba install xtensor -c my-channel`` with 3 sources of configuration:
|
Running ``micromamba install xtensor -c my-channel`` with 3 sources of configuration:
|
||||||
|
|
||||||
- ``channels`` and ``always_yes`` set from rc file located at `~/.mambarc`
|
- ``channels`` and ``always_yes`` set from rc file located at ``~/.mambarc``.
|
||||||
- ``channels`` set from CLI using `-c` option
|
- ``channels`` set from CLI using ``-c`` option.
|
||||||
- ``always_yes`` set from environment variable using `MAMBA_ALWAYS_YES` env var
|
- ``always_yes`` set from environment variable using ``MAMBA_ALWAYS_YES`` env var
|
||||||
|
|
||||||
.. code::
|
.. code::
|
||||||
|
|
||||||
|
@ -60,7 +61,7 @@ Running ``micromamba install xtensor -c my-channel`` with 3 sources of configura
|
||||||
$ echo $MAMBA_ALWAYS_YES
|
$ echo $MAMBA_ALWAYS_YES
|
||||||
true
|
true
|
||||||
|
|
||||||
The resulting configuration written using `YAML` syntax is:
|
The resulting configuration written using ``YAML`` syntax is:
|
||||||
|
|
||||||
.. code::
|
.. code::
|
||||||
|
|
||||||
|
|
|
@ -99,8 +99,8 @@ While we make our best effort to keep backward compatibility, it is not impossib
|
||||||
breaks the current installation.
|
breaks the current installation.
|
||||||
The following actions can be tried:
|
The following actions can be tried:
|
||||||
|
|
||||||
- Reinitializing your shell with `micromamba shell reinit`.
|
- Reinitializing your shell with ``micromamba shell reinit``.
|
||||||
- Deleting the package cache (`"package cache"` entries in `micromamba info`)
|
- Deleting the package cache (``"package cache"`` entries in ``micromamba info``)
|
||||||
|
|
||||||
libmamba.so.2: undefined symbol ...
|
libmamba.so.2: undefined symbol ...
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
|
Loading…
Reference in New Issue