relenv 0.19.4__tar.gz → 0.20.0__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.
Files changed (48) hide show
  1. {relenv-0.19.4/relenv.egg-info → relenv-0.20.0}/PKG-INFO +1 -1
  2. {relenv-0.19.4 → relenv-0.20.0}/relenv/__main__.py +4 -4
  3. {relenv-0.19.4 → relenv-0.20.0}/relenv/build/__init__.py +30 -10
  4. {relenv-0.19.4 → relenv-0.20.0}/relenv/build/common.py +43 -21
  5. {relenv-0.19.4 → relenv-0.20.0}/relenv/build/darwin.py +1 -16
  6. {relenv-0.19.4 → relenv-0.20.0}/relenv/build/linux.py +1 -16
  7. {relenv-0.19.4 → relenv-0.20.0}/relenv/build/windows.py +1 -16
  8. {relenv-0.19.4 → relenv-0.20.0}/relenv/buildenv.py +21 -6
  9. {relenv-0.19.4 → relenv-0.20.0}/relenv/common.py +88 -8
  10. {relenv-0.19.4 → relenv-0.20.0}/relenv/create.py +2 -4
  11. {relenv-0.19.4 → relenv-0.20.0}/relenv/fetch.py +2 -4
  12. relenv-0.20.0/relenv/manifest.py +34 -0
  13. relenv-0.20.0/relenv/pyversions.py +411 -0
  14. {relenv-0.19.4 → relenv-0.20.0}/relenv/runtime.py +49 -8
  15. relenv-0.20.0/relenv/toolchain.py +32 -0
  16. {relenv-0.19.4 → relenv-0.20.0/relenv.egg-info}/PKG-INFO +1 -1
  17. {relenv-0.19.4 → relenv-0.20.0}/relenv.egg-info/SOURCES.txt +2 -5
  18. {relenv-0.19.4 → relenv-0.20.0}/setup.py +3 -0
  19. {relenv-0.19.4 → relenv-0.20.0}/tests/conftest.py +3 -1
  20. {relenv-0.19.4 → relenv-0.20.0}/tests/test_build.py +2 -2
  21. {relenv-0.19.4 → relenv-0.20.0}/tests/test_common.py +8 -2
  22. {relenv-0.19.4 → relenv-0.20.0}/tests/test_fips_photon.py +3 -0
  23. {relenv-0.19.4 → relenv-0.20.0}/tests/test_verify_build.py +137 -25
  24. relenv-0.19.4/relenv/_toolchain/aarch64/aarch64-linux-gnu-ct-ng.config +0 -798
  25. relenv-0.19.4/relenv/_toolchain/aarch64/x86_64-linux-gnu-ct-ng.config +0 -800
  26. relenv-0.19.4/relenv/_toolchain/x86_64/aarch64-linux-gnu-ct-ng.config +0 -799
  27. relenv-0.19.4/relenv/_toolchain/x86_64/x86_64-linux-gnu-ct-ng.config +0 -801
  28. relenv-0.19.4/relenv/toolchain.py +0 -207
  29. relenv-0.19.4/tests/test_toolchain.py +0 -107
  30. {relenv-0.19.4 → relenv-0.20.0}/LICENSE.md +0 -0
  31. {relenv-0.19.4 → relenv-0.20.0}/MANIFEST.in +0 -0
  32. {relenv-0.19.4 → relenv-0.20.0}/NOTICE +0 -0
  33. {relenv-0.19.4 → relenv-0.20.0}/README.md +0 -0
  34. {relenv-0.19.4 → relenv-0.20.0}/pyproject.toml +0 -0
  35. {relenv-0.19.4 → relenv-0.20.0}/relenv/__init__.py +0 -0
  36. {relenv-0.19.4 → relenv-0.20.0}/relenv/_scripts/install_vc_build.ps1 +0 -0
  37. {relenv-0.19.4 → relenv-0.20.0}/relenv/check.py +0 -0
  38. {relenv-0.19.4 → relenv-0.20.0}/relenv/relocate.py +0 -0
  39. {relenv-0.19.4 → relenv-0.20.0}/relenv.egg-info/dependency_links.txt +0 -0
  40. {relenv-0.19.4 → relenv-0.20.0}/relenv.egg-info/entry_points.txt +0 -0
  41. {relenv-0.19.4 → relenv-0.20.0}/relenv.egg-info/requires.txt +0 -0
  42. {relenv-0.19.4 → relenv-0.20.0}/relenv.egg-info/top_level.txt +0 -0
  43. {relenv-0.19.4 → relenv-0.20.0}/setup.cfg +0 -0
  44. {relenv-0.19.4 → relenv-0.20.0}/tests/__init__.py +0 -0
  45. {relenv-0.19.4 → relenv-0.20.0}/tests/test_create.py +0 -0
  46. {relenv-0.19.4 → relenv-0.20.0}/tests/test_downloads.py +0 -0
  47. {relenv-0.19.4 → relenv-0.20.0}/tests/test_relocate.py +0 -0
  48. {relenv-0.19.4 → relenv-0.20.0}/tests/test_runtime.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: relenv
3
- Version: 0.19.4
3
+ Version: 0.20.0
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
@@ -6,7 +6,7 @@ The entrypoint into relenv.
6
6
 
7
7
  from argparse import ArgumentParser
8
8
 
9
- from . import build, buildenv, check, create, fetch, toolchain
9
+ from . import build, buildenv, check, create, fetch, pyversions, toolchain
10
10
  from .common import __version__
11
11
 
12
12
 
@@ -34,6 +34,7 @@ def setup_cli():
34
34
  fetch,
35
35
  check,
36
36
  buildenv,
37
+ pyversions,
37
38
  ]
38
39
  for mod in modules_to_setup:
39
40
  mod.setup_parser(subparsers)
@@ -47,10 +48,9 @@ def main():
47
48
  """
48
49
  parser = setup_cli()
49
50
  args = parser.parse_args()
50
- # args.func(args)
51
- try:
51
+ if hasattr(args, "func"):
52
52
  args.func(args)
53
- except AttributeError:
53
+ else:
54
54
  parser.print_help()
55
55
  parser.exit(1, "\nNo subcommand given...\n\n")
56
56
 
@@ -11,6 +11,8 @@ import signal
11
11
  from . import linux, darwin, windows
12
12
  from .common import builds, CHECK_VERSIONS_SUPPORT
13
13
 
14
+ from ..pyversions import python_versions, Version
15
+
14
16
  from ..common import build_arch
15
17
 
16
18
 
@@ -26,13 +28,6 @@ def platform_module():
26
28
  return windows
27
29
 
28
30
 
29
- def platform_versions():
30
- """
31
- Return the right module based on `sys.platform`.
32
- """
33
- return list(builds.builds[sys.platform].keys())
34
-
35
-
36
31
  def setup_parser(subparsers):
37
32
  """
38
33
  Setup the subparser for the ``build`` command.
@@ -63,8 +58,7 @@ def setup_parser(subparsers):
63
58
  )
64
59
  build_subparser.add_argument(
65
60
  "--python",
66
- default=platform_versions()[0],
67
- choices=platform_versions(),
61
+ default="3.10.17",
68
62
  type=str,
69
63
  help="The python version [default: %(default)s]",
70
64
  )
@@ -146,8 +140,34 @@ def main(args):
146
140
  print(f"Unsupported platform: {sys.platform}")
147
141
  sys.exit(1)
148
142
 
143
+ requested = Version(args.python)
144
+
145
+ if requested.micro:
146
+ pyversions = python_versions()
147
+ if requested not in pyversions:
148
+ print(f"Unknown version {requested}")
149
+ strversions = "\n".join([str(_) for _ in pyversions])
150
+ print(f"Known versions are:\n{strversions}")
151
+ sys.exit(1)
152
+ build_version = requested
153
+ else:
154
+ pyversions = python_versions(args.python)
155
+ build_version = pyversions[0]
156
+
157
+ # print(pyversions)
158
+ # print(pyversions[0].major)
159
+ # print(pyversions[0].minor)
160
+ # print(pyversions[0].micro)
161
+ # print(pyversions[0].pre)
162
+ # print(pyversions[0].post)
163
+ # print(pyversions)
164
+ print(f"Build Python {build_version}")
165
+
149
166
  # XXX
150
- build = builds.builds[sys.platform][args.python]
167
+ build = builds.builds[sys.platform]
168
+ build.version = str(build_version)
169
+ build.dirs.version = str(build_version)
170
+ build.recipies["python"]["download"].version = str(build_version)
151
171
 
152
172
  if args.check_versions:
153
173
  if not CHECK_VERSIONS_SUPPORT:
@@ -78,7 +78,9 @@ RELENV_PTH = (
78
78
 
79
79
 
80
80
  SYSCONFIGDATA = """
81
- import pathlib, sys, platform, os
81
+ import pathlib, sys, platform, os, logging
82
+
83
+ log = logging.getLogger(__name__)
82
84
 
83
85
  def build_arch():
84
86
  machine = platform.machine()
@@ -112,7 +114,22 @@ else:
112
114
  DATA_DIR = DEFAULT_DATA_DIR
113
115
 
114
116
  buildroot = pydir.parent.parent
115
- toolchain = DATA_DIR / "toolchain" / get_triplet()
117
+
118
+ if sys.platform == "linux":
119
+ toolchain = ""
120
+ ppbt = None
121
+ try:
122
+ import ppbt
123
+ except ImportError:
124
+ pass
125
+ if ppbt:
126
+ env = ppbt.environ(auto_extract=True)
127
+ toolchain = pathlib.Path(env["TOOLCHAIN_PATH"])
128
+ else:
129
+ print("ppbt package not installed")
130
+ else:
131
+ toolchain = DATA_DIR / "toolchain" / get_triplet()
132
+
116
133
  build_time_vars = {}
117
134
  for key in _build_time_vars:
118
135
  val = _build_time_vars[key]
@@ -768,9 +785,9 @@ class Builds:
768
785
  else:
769
786
  build = Builder(*args, **kwargs)
770
787
  if platform not in self.builds:
771
- self.builds[platform] = {build.version: build}
788
+ self.builds[platform] = build
772
789
  else:
773
- self.builds[platform][build.version] = build
790
+ self.builds[platform] = build
774
791
  return build
775
792
 
776
793
 
@@ -809,10 +826,6 @@ class Builder:
809
826
  self.build_arch = build_arch()
810
827
  self.build_triplet = get_triplet(self.build_arch)
811
828
  self.arch = arch
812
- self.triplet = get_triplet(self.arch)
813
- self.version = version
814
- # XXX Refactor WorkDirs, Dirs and Builder so as not to duplicate logic
815
- self.prefix = self.dirs.build / f"{self.version}-{self.triplet}"
816
829
  self.sources = self.dirs.src
817
830
  self.downloads = self.dirs.download
818
831
 
@@ -823,6 +836,7 @@ class Builder:
823
836
 
824
837
  self.build_default = build_default
825
838
  self.populate_env = populate_env
839
+ self.version = version
826
840
  self.toolchains = get_toolchain(root=self.dirs.root)
827
841
  self.set_arch(self.arch)
828
842
 
@@ -855,13 +869,19 @@ class Builder:
855
869
  :type arch: str
856
870
  """
857
871
  self.arch = arch
858
- self.triplet = get_triplet(self.arch)
859
- self.prefix = self.dirs.build / f"{self.version}-{self.triplet}"
860
872
  if sys.platform in ["darwin", "win32"]:
861
873
  self.toolchain = None
862
874
  else:
863
875
  self.toolchain = get_toolchain(self.arch, self.dirs.root)
864
876
 
877
+ @property
878
+ def triplet(self):
879
+ return get_triplet(self.arch)
880
+
881
+ @property
882
+ def prefix(self):
883
+ return self.dirs.build / f"{self.version}-{self.triplet}"
884
+
865
885
  @property
866
886
  def _triplet(self):
867
887
  if sys.platform == "darwin":
@@ -974,6 +994,7 @@ class Builder:
974
994
  env["RELENV_NATIVE_PY"] = str(native_root / "bin" / "python3")
975
995
 
976
996
  self.populate_env(env, dirs)
997
+
977
998
  _ = dirs.to_dict()
978
999
  for k in _:
979
1000
  log.info("Directory %s %s", k, _[k])
@@ -1191,10 +1212,11 @@ class Builder:
1191
1212
  :rtype: list
1192
1213
  """
1193
1214
  fail = []
1194
- if self.toolchain and not self.toolchain.exists():
1195
- fail.append(
1196
- f"Toolchain for {self.arch} does not exist. Please use relenv toolchain to obtain a toolchain."
1197
- )
1215
+ if sys.platform == "linux":
1216
+ if not self.toolchain or not self.toolchain.exists():
1217
+ fail.append(
1218
+ f"Toolchain for {self.arch} does not exist. Please pip install ppbt."
1219
+ )
1198
1220
  return fail
1199
1221
 
1200
1222
  def __call__(
@@ -1470,6 +1492,9 @@ def finalize(env, dirs, logfp):
1470
1492
  env["RELENV_CROSS"] = dirs.prefix
1471
1493
  python = env["RELENV_NATIVE_PY"]
1472
1494
  logfp.write("\nRUN ENSURE PIP\n")
1495
+
1496
+ env.pop("RELENV_BUILDENV")
1497
+
1473
1498
  runcmd(
1474
1499
  [str(python), "-m", "ensurepip"],
1475
1500
  env=env,
@@ -1578,9 +1603,8 @@ def create_archive(tarfp, toarchive, globs, logfp=None):
1578
1603
  :param logfp: A pointer to the log file
1579
1604
  :type logfp: file
1580
1605
  """
1581
- if logfp is None:
1582
- log.info("Current directory %s", os.getcwd())
1583
- log.info("Creating archive %s", tarfp.name)
1606
+ log.debug("Current directory %s", os.getcwd())
1607
+ log.debug("Creating archive %s", tarfp.name)
1584
1608
  for root, _dirs, files in os.walk(toarchive):
1585
1609
  relroot = pathlib.Path(root).relative_to(toarchive)
1586
1610
  for f in files:
@@ -1591,9 +1615,7 @@ def create_archive(tarfp, toarchive, globs, logfp=None):
1591
1615
  matches = True
1592
1616
  break
1593
1617
  if matches:
1594
- if logfp is None:
1595
- log.info("Adding %s", relpath)
1618
+ log.debug("Adding %s", relpath)
1596
1619
  tarfp.add(relpath, relpath, recursive=False)
1597
1620
  else:
1598
- if logfp is None:
1599
- log.info("Skipping %s", relpath)
1621
+ log.debug("Skipping %s", relpath)
@@ -72,7 +72,7 @@ def build_python(env, dirs, logfp):
72
72
  runcmd(["make", "install"], env=env, stderr=logfp, stdout=logfp)
73
73
 
74
74
 
75
- build = builds.add("darwin", populate_env=populate_env, version="3.10.17")
75
+ build = builds.add("darwin", populate_env=populate_env)
76
76
 
77
77
  build.add(
78
78
  "openssl",
@@ -128,18 +128,3 @@ build.add(
128
128
  "python",
129
129
  ],
130
130
  )
131
-
132
- build = build.copy(
133
- version="3.11.11", checksum="acf539109b024d3c5f1fc63d6e7f08cd294ba56d"
134
- )
135
- builds.add("darwin", builder=build)
136
-
137
- build = build.copy(
138
- version="3.12.9", checksum="465d8a664e63dc5aa1f0d90cd1d0000a970ee2fb"
139
- )
140
- builds.add("darwin", builder=build)
141
-
142
- build = build.copy(
143
- version="3.13.5", checksum="dbf3aed444cbb2221eabfb52688aa371423aa0ba"
144
- )
145
- builds.add("darwin", builder=build)
@@ -445,7 +445,7 @@ def build_python(env, dirs, logfp):
445
445
  # runcmd([str(python), "-m", "ensurepip", "-U"], env=env, stderr=logfp, stdout=logfp)
446
446
 
447
447
 
448
- build = builds.add("linux", populate_env=populate_env, version="3.10.17")
448
+ build = builds.add("linux", populate_env=populate_env)
449
449
 
450
450
  build.add(
451
451
  "openssl",
@@ -651,18 +651,3 @@ build.add(
651
651
  "openssl-fips-module",
652
652
  ],
653
653
  )
654
-
655
- build = build.copy(
656
- version="3.11.11", checksum="acf539109b024d3c5f1fc63d6e7f08cd294ba56d"
657
- )
658
- builds.add("linux", builder=build)
659
-
660
- build = build.copy(
661
- version="3.12.9", checksum="465d8a664e63dc5aa1f0d90cd1d0000a970ee2fb"
662
- )
663
- builds.add("linux", builder=build)
664
-
665
- build = build.copy(
666
- version="3.13.5", checksum="dbf3aed444cbb2221eabfb52688aa371423aa0ba"
667
- )
668
- builds.add("linux", builder=build)
@@ -130,7 +130,7 @@ def build_python(env, dirs, logfp):
130
130
  )
131
131
 
132
132
 
133
- build = builds.add("win32", populate_env=populate_env, version="3.10.17")
133
+ build = builds.add("win32", populate_env=populate_env)
134
134
 
135
135
  build.add(
136
136
  "python",
@@ -210,18 +210,3 @@ build.add(
210
210
  build_func=finalize,
211
211
  wait_on=["python"],
212
212
  )
213
-
214
- build = build.copy(
215
- version="3.11.11", checksum="acf539109b024d3c5f1fc63d6e7f08cd294ba56d"
216
- )
217
- builds.add("win32", builder=build)
218
-
219
- build = build.copy(
220
- version="3.12.9", checksum="465d8a664e63dc5aa1f0d90cd1d0000a970ee2fb"
221
- )
222
- builds.add("win32", builder=build)
223
-
224
- build = build.copy(
225
- version="3.13.5", checksum="dbf3aed444cbb2221eabfb52688aa371423aa0ba"
226
- )
227
- builds.add("win32", builder=build)
@@ -3,10 +3,16 @@
3
3
  """
4
4
  Helper for building libraries to install into a relenv environment.
5
5
  """
6
+ import json
6
7
  import logging
7
8
  import sys
8
9
 
9
- from .common import MACOS_DEVELOPMENT_TARGET, RelenvException, get_triplet, work_dirs
10
+ from .common import (
11
+ MACOS_DEVELOPMENT_TARGET,
12
+ RelenvException,
13
+ get_toolchain,
14
+ get_triplet,
15
+ )
10
16
 
11
17
  log = logging.getLogger()
12
18
 
@@ -22,6 +28,12 @@ def setup_parser(subparsers):
22
28
  "buildenv", description="Relenv build environment"
23
29
  )
24
30
  subparser.set_defaults(func=main)
31
+ subparser.add_argument(
32
+ "--json",
33
+ default=False,
34
+ action="store_true",
35
+ help=("Output json to stdout instead of export statments"),
36
+ )
25
37
 
26
38
 
27
39
  def is_relenv():
@@ -43,9 +55,11 @@ def buildenv(relenv_path=None):
43
55
  if sys.platform != "linux":
44
56
  raise RelenvException("buildenv is only supported on Linux")
45
57
 
46
- dirs = work_dirs()
58
+ toolchain = get_toolchain()
59
+ if not toolchain:
60
+ raise RelenvException("buildenv is only supported on Linux")
61
+
47
62
  triplet = get_triplet()
48
- toolchain = dirs.toolchain / get_triplet()
49
63
  env = {
50
64
  "RELENV_BUILDENV": "1",
51
65
  "TOOLCHAIN_PATH": f"{toolchain}",
@@ -90,12 +104,13 @@ def main(args):
90
104
  if sys.platform != "linux":
91
105
  log.error("buildenv is only supported on Linux.")
92
106
 
93
- # dirs = work_dirs()
94
- # triplet = get_triplet()
95
- # toolchain = dirs.toolchain / get_triplet()
107
+ if args.json:
108
+ print(json.dumps(buildenv()))
109
+ sys.exit(0)
96
110
 
97
111
  script = ""
98
112
  for k, v in buildenv().items():
99
113
  script += f'export {k}="{v}"\n'
100
114
 
101
115
  print(script)
116
+ sys.exit(0)
@@ -18,7 +18,7 @@ import threading
18
18
  import time
19
19
 
20
20
  # relenv package version
21
- __version__ = "0.19.4"
21
+ __version__ = "0.20.0"
22
22
 
23
23
  MODULE_DIR = pathlib.Path(__file__).resolve().parent
24
24
 
@@ -28,6 +28,8 @@ DARWIN = "darwin"
28
28
 
29
29
  MACOS_DEVELOPMENT_TARGET = "10.15"
30
30
 
31
+ REQUEST_HEADERS = {"User-Agent": f"relenv {__version__}"}
32
+
31
33
  CHECK_HOSTS = (
32
34
  "packages.broadcom.com/artifactory/saltproject-generic",
33
35
  "repo.saltproject.io",
@@ -160,6 +162,7 @@ class WorkDirs:
160
162
 
161
163
  def __init__(self, root):
162
164
  self.root = root
165
+ self.data = DATA_DIR
163
166
  self.toolchain_config = work_dir("toolchain", self.root)
164
167
  self.toolchain = work_dir("toolchain", DATA_DIR)
165
168
  self.build = work_dir("build", DATA_DIR)
@@ -224,10 +227,18 @@ def get_toolchain(arch=None, root=None):
224
227
  :return: The directory holding the toolchain
225
228
  :rtype: ``pathlib.Path``
226
229
  """
227
- dirs = work_dirs(root)
228
- if arch:
229
- return dirs.toolchain / "{}-linux-gnu".format(arch)
230
- return dirs.toolchain
230
+ if sys.platform != "linux":
231
+ return DATA_DIR
232
+ ppbt = None
233
+
234
+ try:
235
+ import ppbt
236
+ except ImportError:
237
+ pass
238
+
239
+ if ppbt:
240
+ env = ppbt.environ(auto_extract=True)
241
+ return pathlib.Path(env["TOOLCHAIN_PATH"])
231
242
 
232
243
 
233
244
  def get_triplet(machine=None, plat=None):
@@ -342,17 +353,30 @@ def get_download_location(url, dest):
342
353
  return os.path.join(dest, os.path.basename(url))
343
354
 
344
355
 
345
- def check_url(url, timeout=30):
356
+ def check_url(url, timestamp=None, timeout=30):
346
357
  """
347
358
  Check that the url returns a 200.
348
359
  """
349
360
  # Late import so we do not import hashlib before runtime.bootstrap is called.
361
+ import time
350
362
  import urllib.request
351
363
 
364
+ headers = dict(REQUEST_HEADERS)
365
+ req = urllib.request.Request(url)
366
+
367
+ if timestamp:
368
+ headers["If-Modified-Since"] = time.strftime(
369
+ "%a, %d %b %Y %H:%M:%S GMT", time.gmtime(timestamp)
370
+ )
371
+
372
+ for k, v in headers.items():
373
+ req.add_header(k, v)
374
+
352
375
  fin = None
353
376
  try:
354
- fin = urllib.request.urlopen(url, timeout=timeout)
355
- except Exception:
377
+ fin = urllib.request.urlopen(req, timeout=timeout)
378
+ except Exception as exc:
379
+ print(exc)
356
380
  return False
357
381
  finally:
358
382
  if fin:
@@ -405,6 +429,62 @@ def fetch_url(url, fp, backoff=3, timeout=30):
405
429
  log.info("Download complete %s", url)
406
430
 
407
431
 
432
+ def fetch_url_content(url, backoff=3, timeout=30):
433
+ """
434
+ Fetch the contents of a url.
435
+
436
+ This method will store the contents in the given file like object.
437
+ """
438
+ # Late import so we do not import hashlib before runtime.bootstrap is called.
439
+ import gzip
440
+ import io
441
+ import urllib.error
442
+ import urllib.request
443
+
444
+ fp = io.BytesIO()
445
+
446
+ last = time.time()
447
+ if backoff < 1:
448
+ backoff = 1
449
+ n = 0
450
+ while n < backoff:
451
+ n += 1
452
+ try:
453
+ fin = urllib.request.urlopen(url, timeout=timeout)
454
+ except (
455
+ urllib.error.HTTPError,
456
+ urllib.error.URLError,
457
+ http.client.RemoteDisconnected,
458
+ ) as exc:
459
+ if n >= backoff:
460
+ raise RelenvException(f"Error fetching url {url} {exc}")
461
+ log.debug("Unable to connect %s", url)
462
+ time.sleep(n * 10)
463
+ log.info("url opened %s", url)
464
+ try:
465
+ total = 0
466
+ size = 1024 * 300
467
+ block = fin.read(size)
468
+ while block:
469
+ total += size
470
+ if time.time() - last > 10:
471
+ log.info("%s > %d", url, total)
472
+ last = time.time()
473
+ fp.write(block)
474
+ block = fin.read(10240)
475
+ finally:
476
+ fin.close()
477
+ # fp.close()
478
+ log.info("Download complete %s", url)
479
+ fp.seek(0)
480
+ info = fin.info()
481
+ if "content-encoding" in info:
482
+ if info["content-encoding"] == "gzip":
483
+ log.debug("Found gzipped content")
484
+ fp = gzip.GzipFile(fileobj=fp)
485
+ return fp.read().decode()
486
+
487
+
408
488
  def download_url(url, dest, verbose=True, backoff=3, timeout=60):
409
489
  """
410
490
  Download the url to the provided destination.
@@ -10,7 +10,6 @@ import pathlib
10
10
  import sys
11
11
  import tarfile
12
12
 
13
- from .build import platform_versions
14
13
  from .common import RelenvException, arches, archived_build, build_arch
15
14
 
16
15
 
@@ -61,8 +60,7 @@ def setup_parser(subparsers):
61
60
  )
62
61
  subparser.add_argument(
63
62
  "--python",
64
- default=platform_versions()[0],
65
- choices=platform_versions(),
63
+ default="3.10.17",
66
64
  type=str,
67
65
  help="The python version [default: %(default)s]",
68
66
  )
@@ -89,7 +87,7 @@ def create(name, dest=None, arch=None, version=None):
89
87
  writeto = pathlib.Path(name).resolve()
90
88
 
91
89
  if version is None:
92
- version = platform_versions()[0]
90
+ version = "3.10.17"
93
91
 
94
92
  if pathlib.Path(writeto).exists():
95
93
  raise CreateException("The requested path already exists.")
@@ -7,7 +7,7 @@ The ``relenv fetch`` command.
7
7
  import os
8
8
  import sys
9
9
 
10
- from .build import platform_module, platform_versions
10
+ from .build import platform_module
11
11
  from .common import (
12
12
  CHECK_HOSTS,
13
13
  DATA_DIR,
@@ -39,9 +39,7 @@ def setup_parser(subparsers):
39
39
  )
40
40
  subparser.add_argument(
41
41
  "--python",
42
- default=platform_versions()[0],
43
- # Allow fetching of older versions
44
- # choices=platform_versions(),
42
+ default="3.10.17",
45
43
  type=str,
46
44
  help="The python version [default: %(default)s]",
47
45
  )
@@ -0,0 +1,34 @@
1
+ # Copyright 2025 Broadcom.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ """
5
+ Relenv manifest.
6
+ """
7
+ import hashlib
8
+ import os
9
+ import sys
10
+
11
+
12
+ def manifest(root=None):
13
+ """
14
+ List all the file in a relenv and their hashes.
15
+ """
16
+ if root is None:
17
+ root = getattr(sys, "RELENV", os.getcwd())
18
+ for root, dirs, files in os.walk(root):
19
+ for file in files:
20
+ hsh = hashlib.sha256()
21
+ try:
22
+ with open(root + os.path.sep + file, "rb") as fp:
23
+ while True:
24
+ chunk = fp.read(9062)
25
+ if not chunk:
26
+ break
27
+ hsh.update(chunk)
28
+ except OSError:
29
+ pass
30
+ print(f"{root + os.path.sep + file} => {hsh.hexdigest()}")
31
+
32
+
33
+ if __name__ == "__main__":
34
+ manifest()