Skip to content

Commit 10e7a5b

Browse files
authored
Merge pull request #63 from solvingj/add_http_header_support
Add custom source suffix and HTTP Headers for custom urls with authentication support via env var interpolation
2 parents 629ab08 + d4db990 commit 10e7a5b

File tree

6 files changed

+62
-4
lines changed

6 files changed

+62
-4
lines changed

portable-python.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,18 @@ cpython-additional-packages:
2929
# Uncomment to override cpython or a dependency source URL
3030
# Note: string "$version" will be replaced with version string (e.g. 1.2.3)
3131
# cpython-url: https://my-cpython-mirror/cpython-$version.tar.gz
32+
# cpython-http-headers:
33+
# - Authorization: Bearer ${GITHUB_TOKEN}
3234
# zlib-url: https://my-zlib-mirror/zlib-$version.tar.gz
35+
# zlib-http-headers:
36+
# - Authorization: Bearer ${GITHUB_TOKEN}
37+
#
38+
# The .tar.gz in projects public releases has additional files not present the tarball of the git tag
39+
# uuid-url: https://my-github-enterprise/api/v3/repos/opensource/libuuid/releases/assets/48151
40+
# uuid-src-suffix: .tar.gz
41+
# uuid-http-headers:
42+
# - Authorization: Bearer ${GITHUB_TOKEN}
43+
# Accept: application/octet-stream
3344

3445
# Uncomment to override the ./configure arguments for a dependency
3546
# Note: this will replace the default arguments, not extend them

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ ignore = [
6363
order-by-type = false
6464

6565
[tool.ruff.lint.mccabe]
66-
max-complexity = 14
66+
max-complexity = 18
6767

6868
[tool.ruff.lint.pydocstyle]
6969
convention = "numpy"

src/portable_python/__init__.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -492,10 +492,23 @@ def is_usable_module(self, name):
492492
def cfg_version(self, default):
493493
return PPG.config.get_value("%s-version" % self.m_name) or default
494494

495+
def cfg_http_headers(self):
496+
if config_http_headers := PPG.config.get_value("%s-http-headers" % self.m_name):
497+
expanded_http_headers = {}
498+
for header_dict in config_http_headers:
499+
for key, value in header_dict.items():
500+
expanded_http_headers[os.path.expandvars(key)] = os.path.expandvars(value)
501+
502+
return expanded_http_headers
503+
495504
def cfg_url(self, version):
496505
if config_url := PPG.config.get_value("%s-url" % self.m_name):
497506
url_template = Template(config_url)
498-
return url_template.substitute(version=version)
507+
url_subbed = url_template.substitute(version=version)
508+
return os.path.expandvars(url_subbed)
509+
510+
def cfg_src_suffix(self):
511+
return PPG.config.get_value("%s-src-suffix" % self.m_name)
499512

500513
def cfg_configure(self, deps_lib_dir, deps_lib64_dir):
501514
if configure := PPG.config.get_value("%s-configure" % self.m_name):
@@ -510,6 +523,16 @@ def url(self):
510523
"""Url of source tarball, if any"""
511524
return ""
512525

526+
@property
527+
def headers(self):
528+
"""Headers for connecting to source url, if any"""
529+
return self.cfg_http_headers()
530+
531+
@property
532+
def src_suffix(self):
533+
"""Suffix of src archive for when URL doesn't end in the file extension"""
534+
return self.cfg_src_suffix()
535+
513536
@property
514537
def version(self):
515538
"""Version to use"""
@@ -632,8 +655,16 @@ def compile(self):
632655
self._finalize()
633656
return
634657

658+
# Some URL's may not end in file extension, such as with redirects.
659+
# Github releases asset endpoint is this way .../releases/assets/48151
660+
635661
# Split on '#' for urls that include a checksum, such as #sha256=... fragment
636662
basename = runez.basename(self.url, extension_marker="#")
663+
if not basename.endswith((".zip", ".tar.gz")):
664+
suffix = self.src_suffix or ".tar.gz"
665+
suffix = ".%s" % (suffix.strip(".")) # Ensure it starts with a dot (in case config forgot leading dot)
666+
basename = f"{self.m_name}-{self.version}{suffix}"
667+
637668
path = self.setup.folders.sources / basename
638669
if not path.exists():
639670
proxies = {}
@@ -643,7 +674,8 @@ def compile(self):
643674
https_proxy = os.environ.get("HTTPS_PROXY") or os.environ.get("https_proxy")
644675
if https_proxy:
645676
proxies["https"] = https_proxy
646-
RestClient().download(self.url, path, proxies=proxies)
677+
678+
RestClient().download(self.url, path, proxies=proxies, headers=self.headers)
647679

648680
runez.decompress(path, self.m_src_build, simplify=True)
649681

src/portable_python/external/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class GettextTiny(ModuleBuilder):
66

77
@property
88
def url(self):
9-
return f"https://github.com/sabotage-linux/gettext-tiny/archive/refs/tags/v{self.version}.tar.gz"
9+
return self.cfg_url(self.version) or f"https://github.com/sabotage-linux/gettext-tiny/archive/refs/tags/v{self.version}.tar.gz"
1010

1111
@property
1212
def version(self):

tests/sample-config1.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,11 @@ cpython-pep668-externally-managed:
4040
4141
cpython-configure:
4242
- --enable-shared
43+
44+
# Exercise custom url
45+
bzip2-url: https://my-enterprise/.../assets/bzip2/123#sha256=123...def
46+
bzip2-version: 1.2.3
47+
bzip2-src-suffix: tar.gz # Forgot leading dot on purpose
48+
bzip2-http-headers:
49+
- Authorization: Bearer foo
50+
Accept: application/octet-stream

tests/test_setup.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,15 @@ def test_config(cli):
99
with pytest.raises(runez.system.AbortException):
1010
PPG.config.parsed_yaml("a: b\ninvalid line", "testing")
1111

12+
# Exercise custom url in config
13+
cli.run("-ntmacos-arm64", "-c", cli.tests_path("sample-config1.yml"), "build", "3.9.7", "-mbzip2")
14+
assert cli.succeeded
15+
assert "Would download https://my-enterprise/.../assets/bzip2/123#sha256=123...def\n" in cli.logged
16+
assert "Would untar build/sources/bzip2-1.2.3.tar.gz -> build/components/bzip2\n" in cli.logged
17+
1218
cli.run("-ntmacos-arm64", "-c", cli.tests_path("sample-config1.yml"), "build", "3.9.7", "-mnone")
1319
assert cli.succeeded
20+
1421
assert " -mpip install --no-cache-dir --upgrade my-additional-package" in cli.logged
1522
assert "env MACOSX_DEPLOYMENT_TARGET=12" in cli.logged # Comes from more specific macos-arm64.yml
1623
assert " -> dist/cpython-3.9.7-macos-arm64.tar.xz" in cli.logged # Comes from macos.yml (not defined in macos-arm64.yml)

0 commit comments

Comments
 (0)