Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support for musl environment #619

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 59 additions & 6 deletions rye-devtools/src/rye_devtools/find_downloads.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from dataclasses import dataclass
from enum import StrEnum
from urllib.parse import unquote
import unittest

import httpx
from httpx import HTTPStatusError
Expand Down Expand Up @@ -88,10 +89,14 @@ class CPythonFinder(Finder):
"linux": "linux",
}

# Environments were introduced later. In order to stay as much backwards compatible
# and reduce risk of breaking downloads, we only map the environments we must support to
# support new download urls. This is musl and gnu for now. For instance msvc is also
# an environment, but it is the only one on windows and doesn't change the download, hence
# we don't map it.
ENV_MAPPING = {
"gnu": "gnu",
# We must ignore musl for now
# "musl": "musl",
"musl": "musl",
}

FILENAME_RE = re.compile(
Expand All @@ -115,7 +120,9 @@ async def find(self) -> list[PythonDownload]:

async def fetch_indygreg_downloads(self, pages: int = 100) -> list[PythonDownload]:
"""Fetch all the indygreg downloads from the release API."""
results: dict[Version, dict[tuple[str, str], list[PythonDownload]]] = {}
results: dict[
Version, dict[tuple[str, str, str | None], list[PythonDownload]]
] = {}

for page in range(1, pages):
log(f"Fetching indygreg release page {page}")
Expand All @@ -133,7 +140,12 @@ async def fetch_indygreg_downloads(self, pages: int = 100) -> list[PythonDownloa
# For now, we only group by arch and platform, because Rust's PythonVersion doesn't have a notion
# of environment. Flavor will never be used to sort download choices and must not be included in grouping.
.setdefault(
(download.triple.arch, download.triple.platform), []
(
download.triple.arch,
download.triple.platform,
download.triple.environment,
),
[],
)
.append(download)
)
Expand Down Expand Up @@ -360,6 +372,18 @@ def sort_key(download: PythonDownload) -> tuple[int, Version, PlatformTriple]:
download.triple,
)

def to_rust_option(opt: str | None) -> str:
"""Takes an optional string and returns either a Some(...) or None"""
if opt is not None:
return f'Some("{opt}")'
return "None"

def to_rust_cow_option(opt: str | None) -> str:
"""Takes an optional string and returns either a Some(Cow::Borrowed(...)) or None"""
if opt is not None:
return f'Some(Cow::Borrowed("{opt}"))'
return "None"

downloads.sort(key=sort_key)

print("// Generated by rye-devtools. DO NOT EDIT.")
Expand All @@ -372,9 +396,10 @@ def sort_key(download: PythonDownload) -> tuple[int, Version, PlatformTriple]:
for download in downloads:
triple = download.triple
version = download.version
sha256 = f'Some("{download.sha256}")' if download.sha256 else "None"
sha256 = to_rust_option(download.sha256)
env = to_rust_cow_option(triple.environment)
print(
f' (PythonVersion {{ name: Cow::Borrowed("{download.implementation}"), arch: Cow::Borrowed("{triple.arch}"), os: Cow::Borrowed("{triple.platform}"), major: {version.major}, minor: {version.minor}, patch: {version.patch}, suffix: None }}, "{download.url}", {sha256}),'
f' (PythonVersion {{ name: Cow::Borrowed("{download.implementation}"), arch: Cow::Borrowed("{triple.arch}"), os: Cow::Borrowed("{triple.platform}"), environment: {env}, major: {version.major}, minor: {version.minor}, patch: {version.patch}, suffix: None }}, "{download.url}", {sha256}),'
)

print("];")
Expand Down Expand Up @@ -419,3 +444,31 @@ def main():

if __name__ == "__main__":
main()


class Tests(unittest.TestCase):
def test_parse_triplets(self):
expected = {
"aarch64-apple-darwin-lto": PlatformTriple("aarch64", "macos", None, "lto"),
"aarch64-unknown-linux-gnu-pgo+lto": PlatformTriple(
"aarch64", "linux", "gnu", "pgo+lto"
),
"x86_64-unknown-linux-musl-debug": PlatformTriple(
"x86_64", "linux", "musl", "debug"
),
"aarch64-unknown-linux-gnu-debug-full": PlatformTriple(
"aarch64", "linux", "gnu", "debug"
),
"x86_64-unknown-linux-gnu-debug": PlatformTriple(
"x86_64", "linux", "gnu", "debug"
),
"linux64": PlatformTriple("x86_64", "linux", "gnu", None),
"ppc64le-unknown-linux-gnu-noopt-full": None,
"x86_64_v3-unknown-linux-gnu-lto": None,
"x86_64-pc-windows-msvc-shared-pgo": PlatformTriple(
"x86_64", "windows", None, "shared-pgo"
),
}

for input, expected in expected.items():
self.assertEqual(CPythonFinder.parse_triple(input), expected, input)
9 changes: 7 additions & 2 deletions rye-devtools/src/rye_devtools/find_uv_downloads.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class UvDownloads:

PLATFORM_ENV = {
"unknown-linux-gnu": ("linux", "gnu"),
# "unknown-linux-musl": ("linux", "musl"),
"unknown-linux-musl": ("linux", "musl"),
"apple-darwin": ("macos", None),
"pc-windows-msvc": ("windows", None),
}
Expand Down Expand Up @@ -101,8 +101,13 @@ def render(downloads: list[UvDownload]):
version = download.version
sha = download.sha256
url = download.url
env = (
f'Some(Cow::Borrowed("{triple.environment}"))'
if triple.environment
else "None"
)
print(
f' UvDownload {{arch: Cow::Borrowed("{triple.arch}"), os: Cow::Borrowed("{triple.platform}"), major: {version.major}, minor: {version.minor}, patch: {version.patch}, suffix: None, url: Cow::Borrowed("{url}"), sha256: Cow::Borrowed("{sha}") }},'
f' UvDownload {{arch: Cow::Borrowed("{triple.arch}"), os: Cow::Borrowed("{triple.platform}"), environment: {env}, major: {version.major}, minor: {version.minor}, patch: {version.patch}, suffix: None, url: Cow::Borrowed("{url}"), sha256: Cow::Borrowed("{sha}") }},'
)

print("];")
Expand Down
6 changes: 5 additions & 1 deletion rye/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ clap = { version = "4.3.5", default-features = false, features = [
] }
clap_complete = "4.2.1"
console = "0.15.7"
curl = { version = "0.4.44", features = ["ssl", "static-curl", "static-ssl"] }
curl = { version = "0.4.44", features = ["ssl", "static-curl"] }
flate2 = "1.0.25"
git-testament = "0.2.4"
globset = "0.4.10"
Expand Down Expand Up @@ -69,3 +69,7 @@ static_vcruntime = "2.0.0"
fslock = "0.2.1"
insta = { version = "1.35.1", features = ["filters"] }
insta-cmd = "0.5.0"

[features]
default = ["curl/static-ssl"]
system-ssl = []
3 changes: 2 additions & 1 deletion rye/src/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub const SELF_PYTHON_TARGET_VERSION: PythonVersionRequest = PythonVersionReques
name: Some(Cow::Borrowed("cpython")),
arch: None,
os: None,
environment: None,
major: 3,
minor: Some(12),
patch: None,
Expand Down Expand Up @@ -144,7 +145,7 @@ pub fn ensure_self_venv_with_toolchain(
let py_bin = get_toolchain_python_bin(&version)?;

// linux specific detection of shared libraries.
#[cfg(target_os = "linux")]
#[cfg(all(target_os = "linux", not(targetenv = "musl")))]
{
validate_shared_libraries(&py_bin)?;
}
Expand Down
1 change: 1 addition & 0 deletions rye/src/cli/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ pub fn execute(mut cmd: Args) -> Result<(), Error> {
name: None,
arch: None,
os: None,
environment: None,
major: 3,
minor: None,
patch: None,
Expand Down
11 changes: 11 additions & 0 deletions rye/src/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ pub fn get_latest_cpython_version() -> Result<PythonVersion, Error> {
name: None,
arch: None,
os: None,
environment: None,
major: 3,
minor: None,
patch: None,
Expand Down Expand Up @@ -278,3 +279,13 @@ pub fn write_credentials(doc: &toml_edit::DocumentMut) -> Result<(), Error> {
pub fn get_credentials_filepath() -> Result<PathBuf, Error> {
Ok(get_app_dir().join("credentials"))
}

pub fn default_environment() -> Option<&'static str> {
if cfg!(all(target_os = "linux", target_env = "gnu")) {
Some("gnu")
} else if cfg!(all(target_os = "linux", target_env = "musl")) {
Some("musl")
} else {
None
}
}
Loading
Loading