pyenv verification source
Some checks are pending
macos_build / macos_build (3.10) (push) Waiting to run
macos_build / macos_build (3.11) (push) Waiting to run
macos_build / macos_build (3.12) (push) Waiting to run
macos_build / macos_build (3.13) (push) Waiting to run
macos_build / macos_build (3.14) (push) Waiting to run
pyenv_tests / pyenv_tests (macos-14) (push) Waiting to run
pyenv_tests / pyenv_tests (macos-15) (push) Waiting to run
pyenv_tests / pyenv_tests (macos-15-intel) (push) Waiting to run
pyenv_tests / pyenv_tests (macos-26) (push) Waiting to run
pyenv_tests / pyenv_tests (ubuntu-22.04) (push) Waiting to run
pyenv_tests / pyenv_tests (ubuntu-24.04) (push) Waiting to run
ubuntu_build / ubuntu_build (3.10) (push) Waiting to run
ubuntu_build / ubuntu_build (3.11) (push) Waiting to run
ubuntu_build / ubuntu_build (3.12) (push) Waiting to run
ubuntu_build / ubuntu_build (3.13) (push) Waiting to run
ubuntu_build / ubuntu_build (3.14) (push) Waiting to run
Some checks are pending
macos_build / macos_build (3.10) (push) Waiting to run
macos_build / macos_build (3.11) (push) Waiting to run
macos_build / macos_build (3.12) (push) Waiting to run
macos_build / macos_build (3.13) (push) Waiting to run
macos_build / macos_build (3.14) (push) Waiting to run
pyenv_tests / pyenv_tests (macos-14) (push) Waiting to run
pyenv_tests / pyenv_tests (macos-15) (push) Waiting to run
pyenv_tests / pyenv_tests (macos-15-intel) (push) Waiting to run
pyenv_tests / pyenv_tests (macos-26) (push) Waiting to run
pyenv_tests / pyenv_tests (ubuntu-22.04) (push) Waiting to run
pyenv_tests / pyenv_tests (ubuntu-24.04) (push) Waiting to run
ubuntu_build / ubuntu_build (3.10) (push) Waiting to run
ubuntu_build / ubuntu_build (3.11) (push) Waiting to run
ubuntu_build / ubuntu_build (3.12) (push) Waiting to run
ubuntu_build / ubuntu_build (3.13) (push) Waiting to run
ubuntu_build / ubuntu_build (3.14) (push) Waiting to run
This commit is contained in:
152
plugins/python-build/scripts/add_miniforge.py
Executable file
152
plugins/python-build/scripts/add_miniforge.py
Executable file
@@ -0,0 +1,152 @@
|
||||
#!/usr/bin/env python3
|
||||
'Adds the latest miniforge and mambaforge releases.'
|
||||
from pathlib import Path
|
||||
import logging
|
||||
import os
|
||||
import string
|
||||
|
||||
import requests
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logging.basicConfig(level=os.environ.get('LOGLEVEL', 'INFO'))
|
||||
|
||||
MINIFORGE_REPO = 'conda-forge/miniforge'
|
||||
DISTRIBUTIONS = ['miniforge']
|
||||
DISTRIBUTIONS_PRE25 = ['miniforge', 'mambaforge']
|
||||
|
||||
SKIPPED_RELEASES = [
|
||||
'4.13.0-0', #has no Mambaforge. We already generated scripts for Miniforge
|
||||
'22.11.1-0', #MacOS packages are broken (have broken dep tarballs, downloading them fails with 403)
|
||||
'22.11.1-1', #MacOS packages are broken (have broken dep tarballs, downloading them fails with 403)
|
||||
'22.11.1-2', #MacOS packages are broken (have broken dep tarballs, downloading them fails with 403)
|
||||
'25.3.0-0', #marked as prerelease, no Linux version
|
||||
'25.11.0-0', #regression reported in constructor, re-released as 25.11.0-1 with hotfix bumping to constructor>=3.14 (was >=3.12, 3.13 implicit)
|
||||
]
|
||||
|
||||
install_script_fmt = """
|
||||
case "$(anaconda_architecture 2>/dev/null || true)" in
|
||||
{install_lines}
|
||||
* )
|
||||
{{ echo
|
||||
colorize 1 "ERROR"
|
||||
echo ": The binary distribution of {flavor} is not available for $(anaconda_architecture 2>/dev/null || true)."
|
||||
echo
|
||||
}} >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
""".lstrip()
|
||||
|
||||
install_line_fmt = """
|
||||
"{os}-{arch}" )
|
||||
install_script "{filename}" "{url}#{sha}" "miniconda" verify_py{py_version}
|
||||
;;
|
||||
""".strip()
|
||||
|
||||
here = Path(__file__).resolve()
|
||||
out_dir: Path = here.parent.parent / "share" / "python-build"
|
||||
|
||||
def download_sha(url):
|
||||
logger.info(f'Downloading SHA file {url}')
|
||||
tup = tuple(reversed(requests.get(url).text.replace('./', '').rstrip().split()))
|
||||
logger.debug(f'Got {tup}')
|
||||
return tup
|
||||
|
||||
def create_spec(filename, sha, url):
|
||||
flavor_with_suffix, version, subversion, os, arch = filename.replace('.sh', '').split('-')
|
||||
suffix = flavor_with_suffix[-1]
|
||||
|
||||
if suffix in string.digits:
|
||||
flavor = flavor_with_suffix[:-1]
|
||||
else:
|
||||
flavor = flavor_with_suffix
|
||||
|
||||
spec = {
|
||||
'filename': filename,
|
||||
'sha': sha,
|
||||
'url': url,
|
||||
'py_version': py_version(version),
|
||||
'flavor': flavor,
|
||||
'os': os,
|
||||
'arch': arch,
|
||||
'installer_filename': f'{flavor_with_suffix.lower()}-{version}-{subversion}',
|
||||
}
|
||||
|
||||
logger.debug(f'Created spec {spec}')
|
||||
|
||||
return spec
|
||||
|
||||
def version_tuple(version):
|
||||
return tuple(int(part) for part in version.split('-')[0].split("."))
|
||||
|
||||
def py_version(version):
|
||||
"""Suffix for `verify_pyXXX` to call in the generated build script"""
|
||||
version_tuple_ = version_tuple(version)
|
||||
# current version: mentioned under https://github.com/conda-forge/miniforge?tab=readme-ov-file#requirements-and-installers
|
||||
# transition points:
|
||||
# https://github.com/conda-forge/miniforge/blame/main/Miniforge3/construct.yaml
|
||||
# look for "- python <version>" in non-pypy branch and which tag the commit is first in
|
||||
if version_tuple_ >= (26,1):
|
||||
# https://github.com/conda-forge/miniforge/commit/0016367731e52c67234d6d0e7e6a24c6bf7673e4
|
||||
return "313"
|
||||
if version_tuple_ >= (24,5):
|
||||
# yes, they jumped from 3.10 directly to 3.12
|
||||
# https://github.com/conda-forge/miniforge/commit/bddad0baf22b37cfe079e47fd1680fdfb2183590
|
||||
return "312"
|
||||
if version_tuple_ >= (4,14):
|
||||
return "310"
|
||||
raise ValueError("Bundled Python version unknown for release `%s'"%version)
|
||||
|
||||
def supported(filename):
|
||||
return ('pypy' not in filename) and ('Windows' not in filename) and (not filename.endswith('.pkg'))
|
||||
|
||||
def add_version(release, distributions):
|
||||
tag_name = release['tag_name']
|
||||
download_urls = { f['name']: f['browser_download_url'] for f in release['assets'] }
|
||||
# can assume that sha files are named similar to release files so can also check supported(on their names)
|
||||
shas = dict([download_sha(url) for (name, url) in download_urls.items()
|
||||
if name.endswith('.sha256') and supported(os.path.splitext(name)[0]) and tag_name in name])
|
||||
specs = [create_spec(filename, sha, download_urls[filename]) for (filename, sha) in shas.items() if supported(filename)]
|
||||
|
||||
|
||||
for distribution in distributions:
|
||||
distribution_specs = [spec for spec in specs if distribution in spec['flavor'].lower()]
|
||||
count = len(distribution_specs)
|
||||
|
||||
if count > 0:
|
||||
output_file = out_dir / distribution_specs[0]['installer_filename']
|
||||
|
||||
logger.info(f'Writing {count} specs for {distribution} to {output_file}')
|
||||
|
||||
script_str = install_script_fmt.format(
|
||||
install_lines="\n".join([install_line_fmt.format_map(s) for s in distribution_specs]),
|
||||
flavor=distribution_specs[0]['flavor'],
|
||||
)
|
||||
|
||||
with open(output_file, 'w') as f:
|
||||
f.write(script_str)
|
||||
else:
|
||||
logger.info(f'Did not find specs for {distribution}')
|
||||
|
||||
|
||||
def main():
|
||||
for release in requests.get(f'https://api.github.com/repos/{MINIFORGE_REPO}/releases').json():
|
||||
version = release['tag_name']
|
||||
|
||||
if version in SKIPPED_RELEASES:
|
||||
continue
|
||||
|
||||
logger.info(f'Looking for {version} in {out_dir}')
|
||||
|
||||
# mambaforge is retired https://github.com/conda-forge/miniforge/releases/tag/24.11.2-0
|
||||
if version_tuple(version) >= (24, 11, 2):
|
||||
distributions = DISTRIBUTIONS
|
||||
else:
|
||||
distributions = DISTRIBUTIONS_PRE25
|
||||
|
||||
if any(not list(out_dir.glob(f'{distribution}*-{version}')) for distribution in distributions):
|
||||
logger.info(f'Downloading {version}')
|
||||
add_version(release, distributions)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user