relenv 0.20.6__tar.gz → 0.20.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {relenv-0.20.6/relenv.egg-info → relenv-0.20.8}/PKG-INFO +1 -1
- {relenv-0.20.6 → relenv-0.20.8}/relenv/build/__init__.py +2 -1
- {relenv-0.20.6 → relenv-0.20.8}/relenv/build/common.py +1 -0
- {relenv-0.20.6 → relenv-0.20.8}/relenv/build/darwin.py +4 -5
- {relenv-0.20.6 → relenv-0.20.8}/relenv/build/linux.py +48 -22
- {relenv-0.20.6 → relenv-0.20.8}/relenv/build/windows.py +1 -0
- {relenv-0.20.6 → relenv-0.20.8}/relenv/common.py +106 -2
- {relenv-0.20.6 → relenv-0.20.8}/relenv/pyversions.py +40 -104
- {relenv-0.20.6 → relenv-0.20.8/relenv.egg-info}/PKG-INFO +1 -1
- {relenv-0.20.6 → relenv-0.20.8}/tests/test_common.py +4 -0
- {relenv-0.20.6 → relenv-0.20.8}/tests/test_verify_build.py +94 -5
- {relenv-0.20.6 → relenv-0.20.8}/LICENSE.md +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/MANIFEST.in +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/NOTICE +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/README.md +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/pyproject.toml +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/relenv/__init__.py +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/relenv/__main__.py +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/relenv/_scripts/install_vc_build.ps1 +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/relenv/buildenv.py +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/relenv/check.py +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/relenv/create.py +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/relenv/fetch.py +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/relenv/manifest.py +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/relenv/relocate.py +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/relenv/runtime.py +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/relenv/toolchain.py +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/relenv.egg-info/SOURCES.txt +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/relenv.egg-info/dependency_links.txt +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/relenv.egg-info/entry_points.txt +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/relenv.egg-info/requires.txt +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/relenv.egg-info/top_level.txt +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/setup.cfg +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/setup.py +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/tests/__init__.py +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/tests/conftest.py +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/tests/test_build.py +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/tests/test_create.py +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/tests/test_downloads.py +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/tests/test_fips_photon.py +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/tests/test_relocate.py +0 -0
- {relenv-0.20.6 → relenv-0.20.8}/tests/test_runtime.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: relenv
|
|
3
|
-
Version: 0.20.
|
|
3
|
+
Version: 0.20.8
|
|
4
4
|
Project-URL: Source Code, https://github.com/saltstack/relative-environment-for-python
|
|
5
5
|
Project-URL: Documentation, https://relenv.readthedocs.io/en/latest/
|
|
6
6
|
Project-URL: Changelog, https://relenv.readthedocs.io/en/latest/changelog.html
|
|
@@ -152,7 +152,7 @@ def main(args):
|
|
|
152
152
|
build_version = requested
|
|
153
153
|
else:
|
|
154
154
|
pyversions = python_versions(args.python)
|
|
155
|
-
build_version = pyversions[0]
|
|
155
|
+
build_version = pyversions.keys()[0]
|
|
156
156
|
|
|
157
157
|
# print(pyversions)
|
|
158
158
|
# print(pyversions[0].major)
|
|
@@ -168,6 +168,7 @@ def main(args):
|
|
|
168
168
|
build.version = str(build_version)
|
|
169
169
|
build.dirs.version = str(build_version)
|
|
170
170
|
build.recipies["python"]["download"].version = str(build_version)
|
|
171
|
+
build.recipies["python"]["download"].checksum = pyversions[build_version]
|
|
171
172
|
|
|
172
173
|
if args.check_versions:
|
|
173
174
|
if not CHECK_VERSIONS_SUPPORT:
|
|
@@ -28,7 +28,6 @@ def populate_env(env, dirs):
|
|
|
28
28
|
env["LDFLAGS"] = " ".join(ldflags).format(prefix=dirs.prefix)
|
|
29
29
|
env["MACOSX_DEPLOYMENT_TARGET"] = MACOS_DEVELOPMENT_TARGET
|
|
30
30
|
cflags = [
|
|
31
|
-
"-L{prefix}/lib",
|
|
32
31
|
"-I{prefix}/include",
|
|
33
32
|
"-I{prefix}/include/readline",
|
|
34
33
|
]
|
|
@@ -79,8 +78,8 @@ build.add(
|
|
|
79
78
|
build_func=build_openssl,
|
|
80
79
|
download={
|
|
81
80
|
"url": "https://github.com/openssl/openssl/releases/download/openssl-{version}/openssl-{version}.tar.gz",
|
|
82
|
-
"version": "3.
|
|
83
|
-
"checksum": "
|
|
81
|
+
"version": "3.5.4",
|
|
82
|
+
"checksum": "b75daac8e10f189abe28a076ba5905d363e4801f",
|
|
84
83
|
},
|
|
85
84
|
)
|
|
86
85
|
|
|
@@ -88,8 +87,8 @@ build.add(
|
|
|
88
87
|
"XZ",
|
|
89
88
|
download={
|
|
90
89
|
"url": "http://tukaani.org/xz/xz-{version}.tar.gz",
|
|
91
|
-
"version": "5.
|
|
92
|
-
"checksum": "
|
|
90
|
+
"version": "5.8.1",
|
|
91
|
+
"checksum": "ed4d5589c4cfe84e1697bd02a9954b76af336931",
|
|
93
92
|
},
|
|
94
93
|
)
|
|
95
94
|
|
|
@@ -6,7 +6,7 @@ The linux build process.
|
|
|
6
6
|
import pathlib
|
|
7
7
|
import tempfile
|
|
8
8
|
from .common import *
|
|
9
|
-
from ..common import arches, LINUX
|
|
9
|
+
from ..common import arches, LINUX, Version
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
ARCHES = arches[LINUX]
|
|
@@ -393,6 +393,43 @@ def build_python(env, dirs, logfp):
|
|
|
393
393
|
env["OPENSSL_LDFLAGS"] = f"-L{dirs.prefix}/lib"
|
|
394
394
|
env["CFLAGS"] = f"-Wno-coverage-mismatch {env['CFLAGS']}"
|
|
395
395
|
|
|
396
|
+
runcmd(
|
|
397
|
+
[
|
|
398
|
+
"sed",
|
|
399
|
+
"-i",
|
|
400
|
+
"s/#readline readline.c -lreadline -ltermcap/readline readline.c -lreadline -ltinfow/g",
|
|
401
|
+
"Modules/Setup",
|
|
402
|
+
]
|
|
403
|
+
)
|
|
404
|
+
if Version.parse_string(env["RELENV_PY_MAJOR_VERSION"]) <= Version.parse_string(
|
|
405
|
+
"3.10"
|
|
406
|
+
):
|
|
407
|
+
runcmd(
|
|
408
|
+
[
|
|
409
|
+
"sed",
|
|
410
|
+
"-i",
|
|
411
|
+
(
|
|
412
|
+
"s/#_curses -lncurses -lncursesw -ltermcap _cursesmodule.c"
|
|
413
|
+
"/_curses -lncursesw -ltinfow _cursesmodule.c/g"
|
|
414
|
+
),
|
|
415
|
+
"Modules/Setup",
|
|
416
|
+
]
|
|
417
|
+
)
|
|
418
|
+
runcmd(
|
|
419
|
+
[
|
|
420
|
+
"sed",
|
|
421
|
+
"-i",
|
|
422
|
+
(
|
|
423
|
+
"s/#_curses_panel _curses_panel.c -lpanel -lncurses"
|
|
424
|
+
"/_curses_panel _curses_panel.c -lpanelw -lncursesw/g"
|
|
425
|
+
),
|
|
426
|
+
"Modules/Setup",
|
|
427
|
+
]
|
|
428
|
+
)
|
|
429
|
+
else:
|
|
430
|
+
env["CURSES_LIBS"] = "-lncursesw -ltinfow"
|
|
431
|
+
env["PANEL_LIBS"] = "-lpanelw"
|
|
432
|
+
|
|
396
433
|
cmd = [
|
|
397
434
|
"./configure",
|
|
398
435
|
"-v",
|
|
@@ -421,14 +458,7 @@ def build_python(env, dirs, logfp):
|
|
|
421
458
|
]
|
|
422
459
|
|
|
423
460
|
runcmd(cmd, env=env, stderr=logfp, stdout=logfp)
|
|
424
|
-
|
|
425
|
-
[
|
|
426
|
-
"sed",
|
|
427
|
-
"-i",
|
|
428
|
-
"s/#readline readline.c -lreadline -ltermcap/readline readline.c -lreadline -ltinfow/g",
|
|
429
|
-
"Modules/Setup",
|
|
430
|
-
]
|
|
431
|
-
)
|
|
461
|
+
|
|
432
462
|
with io.open("Modules/Setup", "a+") as fp:
|
|
433
463
|
fp.seek(0, io.SEEK_END)
|
|
434
464
|
fp.write("*disabled*\n" "_tkinter\n" "nsl\n" "nis\n")
|
|
@@ -452,14 +482,13 @@ build.add(
|
|
|
452
482
|
build_func=build_openssl,
|
|
453
483
|
download={
|
|
454
484
|
"url": "https://github.com/openssl/openssl/releases/download/openssl-{version}/openssl-{version}.tar.gz",
|
|
455
|
-
"version": "3.
|
|
456
|
-
"checksum": "
|
|
485
|
+
"version": "3.5.4",
|
|
486
|
+
"checksum": "b75daac8e10f189abe28a076ba5905d363e4801f",
|
|
457
487
|
"checkfunc": tarball_version,
|
|
458
488
|
"checkurl": "https://www.openssl.org/source/",
|
|
459
489
|
},
|
|
460
490
|
)
|
|
461
491
|
|
|
462
|
-
|
|
463
492
|
build.add(
|
|
464
493
|
"openssl-fips-module",
|
|
465
494
|
build_func=build_openssl_fips,
|
|
@@ -489,8 +518,8 @@ build.add(
|
|
|
489
518
|
"XZ",
|
|
490
519
|
download={
|
|
491
520
|
"url": "http://tukaani.org/xz/xz-{version}.tar.gz",
|
|
492
|
-
"version": "5.
|
|
493
|
-
"checksum": "
|
|
521
|
+
"version": "5.8.1",
|
|
522
|
+
"checksum": "ed4d5589c4cfe84e1697bd02a9954b76af336931",
|
|
494
523
|
"checkfunc": tarball_version,
|
|
495
524
|
},
|
|
496
525
|
)
|
|
@@ -522,7 +551,7 @@ build.add(
|
|
|
522
551
|
name="gdbm",
|
|
523
552
|
build_func=build_gdbm,
|
|
524
553
|
download={
|
|
525
|
-
"url": "https://
|
|
554
|
+
"url": "https://mirrors.ocf.berkeley.edu/gnu/gdbm/gdbm-{version}.tar.gz",
|
|
526
555
|
"version": "1.26",
|
|
527
556
|
"checksum": "6cee3657de948e691e8df26509157be950cef4d4",
|
|
528
557
|
"checkfunc": tarball_version,
|
|
@@ -533,12 +562,9 @@ build.add(
|
|
|
533
562
|
name="ncurses",
|
|
534
563
|
build_func=build_ncurses,
|
|
535
564
|
download={
|
|
536
|
-
"url": "https://
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
# "checksum": "cde3024ac3f9ef21eaed6f001476ea8fffcaa381",
|
|
540
|
-
"version": "6.4",
|
|
541
|
-
"checksum": "bb5eb3f34b3ecd5bac8d0b58164b847f135b3d62",
|
|
565
|
+
"url": "https://mirrors.ocf.berkeley.edu/gnu/ncurses/ncurses-{version}.tar.gz",
|
|
566
|
+
"version": "6.5",
|
|
567
|
+
"checksum": "cde3024ac3f9ef21eaed6f001476ea8fffcaa381",
|
|
542
568
|
"checkfunc": tarball_version,
|
|
543
569
|
},
|
|
544
570
|
)
|
|
@@ -594,7 +620,7 @@ build.add(
|
|
|
594
620
|
build_func=build_readline,
|
|
595
621
|
wait_on=["ncurses"],
|
|
596
622
|
download={
|
|
597
|
-
"url": "https://
|
|
623
|
+
"url": "https://mirrors.ocf.berkeley.edu/gnu/readline/readline-{version}.tar.gz",
|
|
598
624
|
"version": "8.3",
|
|
599
625
|
"checksum": "2c05ae9350b695f69d70b47f17f092611de2081f",
|
|
600
626
|
"checkfunc": tarball_version,
|
|
@@ -18,7 +18,7 @@ import threading
|
|
|
18
18
|
import time
|
|
19
19
|
|
|
20
20
|
# relenv package version
|
|
21
|
-
__version__ = "0.20.
|
|
21
|
+
__version__ = "0.20.8"
|
|
22
22
|
|
|
23
23
|
MODULE_DIR = pathlib.Path(__file__).resolve().parent
|
|
24
24
|
|
|
@@ -105,7 +105,7 @@ def format_shebang(python, tpl=SHEBANG_TPL):
|
|
|
105
105
|
"""
|
|
106
106
|
Return a formatted shebang.
|
|
107
107
|
"""
|
|
108
|
-
return tpl.format(python).strip()
|
|
108
|
+
return tpl.format(python).strip() + "\n"
|
|
109
109
|
|
|
110
110
|
|
|
111
111
|
def build_arch():
|
|
@@ -727,3 +727,107 @@ def sanitize_sys_path(sys_path_entries):
|
|
|
727
727
|
if p not in __sys_path:
|
|
728
728
|
__sys_path.append(p)
|
|
729
729
|
return __sys_path
|
|
730
|
+
|
|
731
|
+
|
|
732
|
+
class Version:
|
|
733
|
+
"""
|
|
734
|
+
Version comparisons.
|
|
735
|
+
"""
|
|
736
|
+
|
|
737
|
+
def __init__(self, data):
|
|
738
|
+
self.major, self.minor, self.micro = self.parse_string(data)
|
|
739
|
+
self._data = data
|
|
740
|
+
|
|
741
|
+
def __str__(self):
|
|
742
|
+
"""
|
|
743
|
+
Version as string.
|
|
744
|
+
"""
|
|
745
|
+
_ = f"{self.major}"
|
|
746
|
+
if self.minor is not None:
|
|
747
|
+
_ += f".{self.minor}"
|
|
748
|
+
if self.micro is not None:
|
|
749
|
+
_ += f".{self.micro}"
|
|
750
|
+
# XXX What if minor was None but micro was an int.
|
|
751
|
+
return _
|
|
752
|
+
|
|
753
|
+
def __hash__(self):
|
|
754
|
+
"""
|
|
755
|
+
Hash of the version.
|
|
756
|
+
|
|
757
|
+
Hash the major, minor, and micro attributes.
|
|
758
|
+
"""
|
|
759
|
+
return hash((self.major, self.minor, self.micro))
|
|
760
|
+
|
|
761
|
+
@staticmethod
|
|
762
|
+
def parse_string(data):
|
|
763
|
+
"""
|
|
764
|
+
Parse a version string into major, minor, and micro integers.
|
|
765
|
+
"""
|
|
766
|
+
parts = data.split(".")
|
|
767
|
+
if len(parts) == 1:
|
|
768
|
+
return int(parts[0]), None, None
|
|
769
|
+
elif len(parts) == 2:
|
|
770
|
+
return int(parts[0]), int(parts[1]), None
|
|
771
|
+
elif len(parts) == 3:
|
|
772
|
+
return int(parts[0]), int(parts[1]), int(parts[2])
|
|
773
|
+
else:
|
|
774
|
+
raise RuntimeError("Too many parts to parse")
|
|
775
|
+
|
|
776
|
+
def __eq__(self, other):
|
|
777
|
+
"""
|
|
778
|
+
Equality comparisons.
|
|
779
|
+
"""
|
|
780
|
+
mymajor = 0 if self.major is None else self.major
|
|
781
|
+
myminor = 0 if self.minor is None else self.minor
|
|
782
|
+
mymicro = 0 if self.micro is None else self.micro
|
|
783
|
+
major = 0 if other.major is None else other.major
|
|
784
|
+
minor = 0 if other.minor is None else other.minor
|
|
785
|
+
micro = 0 if other.micro is None else other.micro
|
|
786
|
+
return mymajor == major and myminor == minor and mymicro == micro
|
|
787
|
+
|
|
788
|
+
def __lt__(self, other):
|
|
789
|
+
"""
|
|
790
|
+
Less than comparrison.
|
|
791
|
+
"""
|
|
792
|
+
mymajor = 0 if self.major is None else self.major
|
|
793
|
+
myminor = 0 if self.minor is None else self.minor
|
|
794
|
+
mymicro = 0 if self.micro is None else self.micro
|
|
795
|
+
major = 0 if other.major is None else other.major
|
|
796
|
+
minor = 0 if other.minor is None else other.minor
|
|
797
|
+
micro = 0 if other.micro is None else other.micro
|
|
798
|
+
if mymajor < major:
|
|
799
|
+
return True
|
|
800
|
+
elif mymajor == major:
|
|
801
|
+
if myminor < minor:
|
|
802
|
+
return True
|
|
803
|
+
if myminor == minor and mymicro < micro:
|
|
804
|
+
return True
|
|
805
|
+
return False
|
|
806
|
+
|
|
807
|
+
def __le__(self, other):
|
|
808
|
+
"""
|
|
809
|
+
Less than or equal to comparrison.
|
|
810
|
+
"""
|
|
811
|
+
mymajor = 0 if self.major is None else self.major
|
|
812
|
+
myminor = 0 if self.minor is None else self.minor
|
|
813
|
+
mymicro = 0 if self.micro is None else self.micro
|
|
814
|
+
major = 0 if other.major is None else other.major
|
|
815
|
+
minor = 0 if other.minor is None else other.minor
|
|
816
|
+
micro = 0 if other.micro is None else other.micro
|
|
817
|
+
if mymajor <= major:
|
|
818
|
+
if myminor <= minor:
|
|
819
|
+
if mymicro <= micro:
|
|
820
|
+
return True
|
|
821
|
+
return False
|
|
822
|
+
|
|
823
|
+
def __gt__(self, other):
|
|
824
|
+
"""
|
|
825
|
+
Greater than comparrison.
|
|
826
|
+
"""
|
|
827
|
+
return not self.__le__(other)
|
|
828
|
+
|
|
829
|
+
def __ge__(self, other):
|
|
830
|
+
"""
|
|
831
|
+
Greater than or equal to comparrison.
|
|
832
|
+
"""
|
|
833
|
+
return not self.__lt__(other)
|
|
@@ -21,7 +21,7 @@ import subprocess
|
|
|
21
21
|
import sys
|
|
22
22
|
import time
|
|
23
23
|
|
|
24
|
-
from relenv.common import check_url, download_url, fetch_url_content
|
|
24
|
+
from relenv.common import Version, check_url, download_url, fetch_url_content
|
|
25
25
|
|
|
26
26
|
log = logging.getLogger(__name__)
|
|
27
27
|
|
|
@@ -43,102 +43,6 @@ def _ref_path(x):
|
|
|
43
43
|
return x.split('href="')[1].split('"')[0]
|
|
44
44
|
|
|
45
45
|
|
|
46
|
-
class Version:
|
|
47
|
-
"""
|
|
48
|
-
Version comparrisons.
|
|
49
|
-
"""
|
|
50
|
-
|
|
51
|
-
def __init__(self, data):
|
|
52
|
-
self.major, self.minor, self.micro = self.parse_string(data)
|
|
53
|
-
self._data = data
|
|
54
|
-
|
|
55
|
-
def __str__(self):
|
|
56
|
-
"""
|
|
57
|
-
Version as string.
|
|
58
|
-
"""
|
|
59
|
-
_ = f"{self.major}"
|
|
60
|
-
if self.minor is not None:
|
|
61
|
-
_ += f".{self.minor}"
|
|
62
|
-
if self.micro is not None:
|
|
63
|
-
_ += f".{self.micro}"
|
|
64
|
-
# XXX What if minor was None but micro was an int.
|
|
65
|
-
return _
|
|
66
|
-
|
|
67
|
-
@staticmethod
|
|
68
|
-
def parse_string(data):
|
|
69
|
-
"""
|
|
70
|
-
Parse a version string into major, minor, and micro integers.
|
|
71
|
-
"""
|
|
72
|
-
parts = data.split(".")
|
|
73
|
-
if len(parts) == 1:
|
|
74
|
-
return int(parts[0]), None, None
|
|
75
|
-
elif len(parts) == 2:
|
|
76
|
-
return int(parts[0]), int(parts[1]), None
|
|
77
|
-
elif len(parts) == 3:
|
|
78
|
-
return int(parts[0]), int(parts[1]), int(parts[2])
|
|
79
|
-
else:
|
|
80
|
-
raise RuntimeError("Too many parts to parse")
|
|
81
|
-
|
|
82
|
-
def __eq__(self, other):
|
|
83
|
-
"""
|
|
84
|
-
Equality comparrison.
|
|
85
|
-
"""
|
|
86
|
-
mymajor = 0 if self.major is None else self.major
|
|
87
|
-
myminor = 0 if self.minor is None else self.minor
|
|
88
|
-
mymicro = 0 if self.micro is None else self.micro
|
|
89
|
-
major = 0 if other.major is None else other.major
|
|
90
|
-
minor = 0 if other.minor is None else other.minor
|
|
91
|
-
micro = 0 if other.micro is None else other.micro
|
|
92
|
-
return mymajor == major and myminor == minor and mymicro == micro
|
|
93
|
-
|
|
94
|
-
def __lt__(self, other):
|
|
95
|
-
"""
|
|
96
|
-
Less than comparrison.
|
|
97
|
-
"""
|
|
98
|
-
mymajor = 0 if self.major is None else self.major
|
|
99
|
-
myminor = 0 if self.minor is None else self.minor
|
|
100
|
-
mymicro = 0 if self.micro is None else self.micro
|
|
101
|
-
major = 0 if other.major is None else other.major
|
|
102
|
-
minor = 0 if other.minor is None else other.minor
|
|
103
|
-
micro = 0 if other.micro is None else other.micro
|
|
104
|
-
if mymajor < major:
|
|
105
|
-
return True
|
|
106
|
-
elif mymajor == major:
|
|
107
|
-
if myminor < minor:
|
|
108
|
-
return True
|
|
109
|
-
if myminor == minor and mymicro < micro:
|
|
110
|
-
return True
|
|
111
|
-
return False
|
|
112
|
-
|
|
113
|
-
def __le__(self, other):
|
|
114
|
-
"""
|
|
115
|
-
Less than or equal to comparrison.
|
|
116
|
-
"""
|
|
117
|
-
mymajor = 0 if self.major is None else self.major
|
|
118
|
-
myminor = 0 if self.minor is None else self.minor
|
|
119
|
-
mymicro = 0 if self.micro is None else self.micro
|
|
120
|
-
major = 0 if other.major is None else other.major
|
|
121
|
-
minor = 0 if other.minor is None else other.minor
|
|
122
|
-
micro = 0 if other.micro is None else other.micro
|
|
123
|
-
if mymajor <= major:
|
|
124
|
-
if myminor <= minor:
|
|
125
|
-
if mymicro <= micro:
|
|
126
|
-
return True
|
|
127
|
-
return False
|
|
128
|
-
|
|
129
|
-
def __gt__(self, other):
|
|
130
|
-
"""
|
|
131
|
-
Greater than comparrison.
|
|
132
|
-
"""
|
|
133
|
-
return not self.__le__(other)
|
|
134
|
-
|
|
135
|
-
def __ge__(self, other):
|
|
136
|
-
"""
|
|
137
|
-
Greater than or equal to comparrison.
|
|
138
|
-
"""
|
|
139
|
-
return not self.__lt__(other)
|
|
140
|
-
|
|
141
|
-
|
|
142
46
|
def _release_urls(version, gzip=False):
|
|
143
47
|
if gzip:
|
|
144
48
|
tarball = f"https://www.python.org/ftp/python/{version}/Python-{version}.tgz"
|
|
@@ -206,7 +110,7 @@ def digest(file):
|
|
|
206
110
|
"""
|
|
207
111
|
SHA-256 digest of file.
|
|
208
112
|
"""
|
|
209
|
-
hsh = hashlib.
|
|
113
|
+
hsh = hashlib.sha1()
|
|
210
114
|
with open(file, "rb") as fp:
|
|
211
115
|
hsh.update(fp.read())
|
|
212
116
|
return hsh.hexdigest()
|
|
@@ -301,9 +205,9 @@ def _main():
|
|
|
301
205
|
out[str(version)] = {url: digest(path)}
|
|
302
206
|
|
|
303
207
|
if PRINT:
|
|
304
|
-
vfile.write_text(json.dumps(pyversions))
|
|
208
|
+
vfile.write_text(json.dumps(pyversions, indent=1))
|
|
305
209
|
elif not CHECK and out:
|
|
306
|
-
vfile.write_text(json.dumps(out))
|
|
210
|
+
vfile.write_text(json.dumps(out, indent=1))
|
|
307
211
|
|
|
308
212
|
|
|
309
213
|
def create_pyversions(path):
|
|
@@ -313,9 +217,41 @@ def create_pyversions(path):
|
|
|
313
217
|
url = "https://www.python.org/downloads/"
|
|
314
218
|
content = fetch_url_content(url)
|
|
315
219
|
matched = re.findall(r'<a href="/downloads/.*">Python.*</a>', content)
|
|
220
|
+
cwd = os.getcwd()
|
|
316
221
|
parsed_versions = sorted([_ref_version(_) for _ in matched], reverse=True)
|
|
317
222
|
versions = [_ for _ in parsed_versions if _.major >= 3]
|
|
318
|
-
|
|
223
|
+
|
|
224
|
+
if path.exists():
|
|
225
|
+
data = json.loads(path.read_text())
|
|
226
|
+
else:
|
|
227
|
+
data = {}
|
|
228
|
+
|
|
229
|
+
for version in versions:
|
|
230
|
+
|
|
231
|
+
if str(version) in data:
|
|
232
|
+
continue
|
|
233
|
+
|
|
234
|
+
if version <= Version("3.2") and version.micro == 0:
|
|
235
|
+
url_version = Version(f"{version.major}.{version.minor}")
|
|
236
|
+
else:
|
|
237
|
+
url_version = version
|
|
238
|
+
if version >= Version("3.1.4"):
|
|
239
|
+
url = ARCHIVE.format(version=url_version, ext="tar.xz")
|
|
240
|
+
else:
|
|
241
|
+
url = ARCHIVE.format(version=url_version, ext="tgz")
|
|
242
|
+
download_path = download_url(url, cwd)
|
|
243
|
+
sig_path = download_url(f"{url}.asc", cwd)
|
|
244
|
+
verified = verify_signature(download_path, sig_path)
|
|
245
|
+
if verified:
|
|
246
|
+
print(f"Version {version} has digest {digest(download_path)}")
|
|
247
|
+
data[str(version)] = digest(download_path)
|
|
248
|
+
else:
|
|
249
|
+
raise Exception("Signature failed to verify: {url}")
|
|
250
|
+
|
|
251
|
+
path.write_text(json.dumps(data, indent=1))
|
|
252
|
+
|
|
253
|
+
# path.write_text(json.dumps({"versions": [str(_) for _ in versions]}))
|
|
254
|
+
path.write_text(json.dumps(data, indent=1))
|
|
319
255
|
|
|
320
256
|
|
|
321
257
|
def python_versions(minor=None, create=False, update=False):
|
|
@@ -337,11 +273,11 @@ def python_versions(minor=None, create=False, update=False):
|
|
|
337
273
|
else:
|
|
338
274
|
raise RuntimeError("No versions file found")
|
|
339
275
|
pyversions = json.loads(readfrom.read_text())
|
|
340
|
-
versions = [Version(_) for _ in pyversions
|
|
276
|
+
versions = [Version(_) for _ in pyversions]
|
|
341
277
|
if minor:
|
|
342
278
|
mv = Version(minor)
|
|
343
279
|
versions = [_ for _ in versions if _.major == mv.major and _.minor == mv.minor]
|
|
344
|
-
return versions
|
|
280
|
+
return {_: pyversions[str(_)] for _ in versions}
|
|
345
281
|
|
|
346
282
|
|
|
347
283
|
def setup_parser(subparsers):
|
|
@@ -402,7 +338,7 @@ def main(args):
|
|
|
402
338
|
if not pyversions:
|
|
403
339
|
print(f"Unknown minor version {requested}")
|
|
404
340
|
sys.exit(1)
|
|
405
|
-
build_version = pyversions[0]
|
|
341
|
+
build_version = list(pyversions.keys())[0]
|
|
406
342
|
print(build_version)
|
|
407
343
|
sys.exit()
|
|
408
344
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: relenv
|
|
3
|
-
Version: 0.20.
|
|
3
|
+
Version: 0.20.8
|
|
4
4
|
Project-URL: Source Code, https://github.com/saltstack/relative-environment-for-python
|
|
5
5
|
Project-URL: Documentation, https://relenv.readthedocs.io/en/latest/
|
|
6
6
|
Project-URL: Changelog, https://relenv.readthedocs.io/en/latest/changelog.html
|
|
@@ -179,6 +179,10 @@ def test_shebang_tpl_macos():
|
|
|
179
179
|
assert proc.returncode == 0
|
|
180
180
|
|
|
181
181
|
|
|
182
|
+
def test_format_shebang_newline():
|
|
183
|
+
assert format_shebang("python3", SHEBANG_TPL_LINUX).endswith("\n")
|
|
184
|
+
|
|
185
|
+
|
|
182
186
|
def test_relative_interpreter_default_location():
|
|
183
187
|
assert relative_interpreter(
|
|
184
188
|
"/tmp/relenv", "/tmp/relenv/bin", "/tmp/relenv/bin/python3"
|
|
@@ -665,20 +665,75 @@ def test_pip_install_m2crypto_system_ssl(pipexec, pyexec):
|
|
|
665
665
|
assert p.returncode == 0, p.stderr
|
|
666
666
|
|
|
667
667
|
|
|
668
|
+
SSLVERSION = """
|
|
669
|
+
import ctypes
|
|
670
|
+
import ctypes.util
|
|
671
|
+
import platform
|
|
672
|
+
|
|
673
|
+
def get_openssl_version():
|
|
674
|
+
'''
|
|
675
|
+
Programmatically discovers the OpenSSL version using ctypes.
|
|
676
|
+
'''
|
|
677
|
+
# Determine the library name based on the operating system
|
|
678
|
+
if platform.system() == "Windows":
|
|
679
|
+
lib_name = ctypes.util.find_library("libcrypto-3") or ctypes.util.find_library("libcrypto-1_1")
|
|
680
|
+
else:
|
|
681
|
+
lib_name = ctypes.util.find_library("crypto")
|
|
682
|
+
|
|
683
|
+
if not lib_name:
|
|
684
|
+
print("Could not find OpenSSL libcrypto library.")
|
|
685
|
+
return None, None
|
|
686
|
+
|
|
687
|
+
libcrypto = ctypes.CDLL(lib_name)
|
|
688
|
+
|
|
689
|
+
# Define the C function prototypes
|
|
690
|
+
libcrypto.OpenSSL_version_num.restype = ctypes.c_ulong
|
|
691
|
+
libcrypto.OpenSSL_version.argtypes = [ctypes.c_int]
|
|
692
|
+
libcrypto.OpenSSL_version.restype = ctypes.c_char_p
|
|
693
|
+
|
|
694
|
+
# Call the C functions
|
|
695
|
+
version_num_hex = libcrypto.OpenSSL_version_num()
|
|
696
|
+
version_str = libcrypto.OpenSSL_version(0).decode("utf-8")
|
|
697
|
+
|
|
698
|
+
# Parse the numeric version
|
|
699
|
+
# The version number format is MNNFFPPS
|
|
700
|
+
major = (version_num_hex >> 28) & 0xFF
|
|
701
|
+
minor = (version_num_hex >> 20) & 0xFF
|
|
702
|
+
patch = (version_num_hex >> 4) & 0xFF
|
|
703
|
+
|
|
704
|
+
return (major, minor, patch)
|
|
705
|
+
|
|
706
|
+
if __name__ == "__main__":
|
|
707
|
+
print(
|
|
708
|
+
",".join([str(x) for x in get_openssl_version()]
|
|
709
|
+
)
|
|
710
|
+
)
|
|
711
|
+
"""
|
|
712
|
+
|
|
713
|
+
|
|
714
|
+
@pytest.fixture
|
|
715
|
+
def ssl_version(pyexec, tmp_path):
|
|
716
|
+
file = tmp_path / "script.py"
|
|
717
|
+
file.write_text(SSLVERSION)
|
|
718
|
+
ret = subprocess.run([pyexec, str(file)], capture_output=True)
|
|
719
|
+
print(ret)
|
|
720
|
+
return tuple([int(x) for x in ret.stdout.decode().strip().split(",")])
|
|
721
|
+
|
|
722
|
+
|
|
668
723
|
@pytest.mark.skip_unless_on_linux
|
|
669
724
|
@pytest.mark.parametrize(
|
|
670
725
|
"m2crypto_version",
|
|
671
|
-
[
|
|
672
|
-
"0.38.0",
|
|
673
|
-
"0.44.0",
|
|
674
|
-
],
|
|
726
|
+
["0.38.0", "0.44.0", "0.46.0"],
|
|
675
727
|
)
|
|
676
728
|
def test_pip_install_m2crypto_relenv_ssl(
|
|
677
|
-
m2crypto_version, pipexec, pyexec, build, build_version, minor_version
|
|
729
|
+
m2crypto_version, pipexec, pyexec, build, build_version, minor_version, ssl_version
|
|
678
730
|
):
|
|
679
731
|
if m2crypto_version == "0.38.0" and minor_version in ["3.12", "3.13"]:
|
|
680
732
|
pytest.xfail("Fails due to no distutils")
|
|
681
733
|
|
|
734
|
+
if ssl_version >= (3, 5) and m2crypto_version in ["0.38.0", "0.44.0"]:
|
|
735
|
+
pytest.xfail("Openssl Needs newer m2crypto")
|
|
736
|
+
|
|
682
737
|
_install_ppbt(pyexec)
|
|
683
738
|
|
|
684
739
|
p = subprocess.run(
|
|
@@ -1169,6 +1224,40 @@ def test_install_with_target_shebang(pipexec, build, minor_version):
|
|
|
1169
1224
|
)
|
|
1170
1225
|
|
|
1171
1226
|
|
|
1227
|
+
@pytest.mark.skip_unless_on_linux
|
|
1228
|
+
def test_install_shebang_pip_24_2(pipexec, build, minor_version):
|
|
1229
|
+
subprocess.run(
|
|
1230
|
+
[str(pipexec), "install", "--upgrade", "pip==24.2"],
|
|
1231
|
+
check=True,
|
|
1232
|
+
)
|
|
1233
|
+
subprocess.run(
|
|
1234
|
+
[str(pipexec), "install", "cowsay"],
|
|
1235
|
+
check=True,
|
|
1236
|
+
)
|
|
1237
|
+
ret = subprocess.run(
|
|
1238
|
+
[str(build / "bin" / "cowsay"), "-t", "moo"],
|
|
1239
|
+
check=False,
|
|
1240
|
+
)
|
|
1241
|
+
assert ret.returncode == 0
|
|
1242
|
+
|
|
1243
|
+
|
|
1244
|
+
@pytest.mark.skip_unless_on_linux
|
|
1245
|
+
def test_install_shebang_pip_25_2(pipexec, build, minor_version):
|
|
1246
|
+
subprocess.run(
|
|
1247
|
+
[str(pipexec), "install", "--upgrade", "pip==25.2"],
|
|
1248
|
+
check=True,
|
|
1249
|
+
)
|
|
1250
|
+
subprocess.run(
|
|
1251
|
+
[str(pipexec), "install", "cowsay"],
|
|
1252
|
+
check=True,
|
|
1253
|
+
)
|
|
1254
|
+
ret = subprocess.run(
|
|
1255
|
+
[str(build / "bin" / "cowsay"), "-t", "moo"],
|
|
1256
|
+
check=False,
|
|
1257
|
+
)
|
|
1258
|
+
assert ret.returncode == 0
|
|
1259
|
+
|
|
1260
|
+
|
|
1172
1261
|
@pytest.mark.skip_unless_on_linux
|
|
1173
1262
|
def test_install_with_target_uninstall(pipexec, build):
|
|
1174
1263
|
env = os.environ.copy()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|