The Meson Build System
http://mesonbuild.com/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
3.9 KiB
96 lines
3.9 KiB
# SPDX-License-Identifier: Apache-2.0 |
|
# Copyright © 2022-2023 Intel Corporation |
|
|
|
"""Convert Cargo versions into Meson compatible ones.""" |
|
|
|
from __future__ import annotations |
|
import typing as T |
|
|
|
|
|
def convert(cargo_ver: str) -> T.List[str]: |
|
"""Convert a Cargo compatible version into a Meson compatible one. |
|
|
|
:param cargo_ver: The version, as Cargo specifies |
|
:return: A list of version constraints, as Meson understands them |
|
""" |
|
# Cleanup, just for safety |
|
cargo_ver = cargo_ver.strip() |
|
cargo_vers = [c.strip() for c in cargo_ver.split(',')] |
|
|
|
out: T.List[str] = [] |
|
|
|
for ver in cargo_vers: |
|
# This covers >= and =< as well |
|
# https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#comparison-requirements |
|
if ver.startswith(('>', '<', '=')): |
|
out.append(ver) |
|
|
|
elif ver.startswith('~'): |
|
# Rust has these tilde requirements, which means that it is >= to |
|
# the version, but less than the next version |
|
# https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#tilde-requirements |
|
# we convert those into a pair of constraints |
|
v = ver[1:].split('.') |
|
out.append(f'>= {".".join(v)}') |
|
if len(v) == 3: |
|
out.append(f'< {v[0]}.{int(v[1]) + 1}.0') |
|
elif len(v) == 2: |
|
out.append(f'< {v[0]}.{int(v[1]) + 1}') |
|
else: |
|
out.append(f'< {int(v[0]) + 1}') |
|
|
|
elif '*' in ver: |
|
# Rust has astrisk requirements,, which are like 1.* == ~1 |
|
# https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#wildcard-requirements |
|
v = ver.split('.')[:-1] |
|
if v: |
|
out.append(f'>= {".".join(v)}') |
|
if len(v) == 2: |
|
out.append(f'< {v[0]}.{int(v[1]) + 1}') |
|
elif len(v) == 1: |
|
out.append(f'< {int(v[0]) + 1}') |
|
|
|
else: |
|
# a Caret version is equivalent to the default strategy |
|
# https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#caret-requirements |
|
if ver.startswith('^'): |
|
ver = ver[1:] |
|
|
|
# If there is no qualifier, then it means this or the next non-zero version |
|
# That means that if this is `1.1.0``, then we need `>= 1.1.0` && `< 2.0.0` |
|
# Or if we have `0.1.0`, then we need `>= 0.1.0` && `< 0.2.0` |
|
# Or if we have `0.1`, then we need `>= 0.1.0` && `< 0.2.0` |
|
# Or if we have `0.0.0`, then we need `< 1.0.0` |
|
# Or if we have `0.0`, then we need `< 1.0.0` |
|
# Or if we have `0`, then we need `< 1.0.0` |
|
# Or if we have `0.0.3`, then we need `>= 0.0.3` && `< 0.0.4` |
|
# https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#specifying-dependencies-from-cratesio |
|
# |
|
# this works much like the ~ versions, but in reverse. Tilde starts |
|
# at the patch version and works up, to the major version, while |
|
# bare numbers start at the major version and work down to the patch |
|
# version |
|
vers = ver.split('.') |
|
min_: T.List[str] = [] |
|
max_: T.List[str] = [] |
|
bumped = False |
|
for v_ in vers: |
|
if v_ != '0' and not bumped: |
|
min_.append(v_) |
|
max_.append(str(int(v_) + 1)) |
|
bumped = True |
|
else: |
|
if not (bumped and v_ == '0'): |
|
min_.append(v_) |
|
if not bumped: |
|
max_.append('0') |
|
|
|
# If there is no minimum, don't emit one |
|
if set(min_) != {'0'}: |
|
out.append('>= {}'.format('.'.join(min_))) |
|
if set(max_) != {'0'}: |
|
out.append('< {}'.format('.'.join(max_))) |
|
else: |
|
out.append('< 1') |
|
|
|
return out
|
|
|