10000 Add custom source suffix and HTTP Headers for custom urls with authentication support via env var interpolation by solvingj · Pull Request #63 · codrsquad/portable-python · GitHub
[go: up one dir, main page]

Skip to content

Add custom source suffix and HTTP Headers for custom urls with authentication support via env var interpolation #63

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

Merged
merged 11 commits into from
Feb 18, 2025
Merged
11 changes: 11 additions & 0 deletions portable-python.yml
10000
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,18 @@ cpython-additional-packages:
# Uncomment to override cpython or a dependency source URL
# Note: string "$version" will be replaced with version string (e.g. 1.2.3)
# cpython-url: https://my-cpython-mirror/cpython-$version.tar.gz
# cpython-http-headers:
# - Authorization: Bearer ${GITHUB_TOKEN}
# zlib-url: https://my-zlib-mirror/zlib-$version.tar.gz
# zlib-http-headers:
# - Authorization: Bearer ${GITHUB_TOKEN}
#
# The .tar.gz in projects public releases has additional files not present the tarball of the git tag
# uuid-url: https://my-github-enterprise/api/v3/repos/opensource/libuuid/releases/assets/48151
# uuid-src-suffix: .tar.gz
# uuid-http-headers:
# - Authorization: Bearer ${GITHUB_TOKEN}
# Accept: application/octet-stream

# Uncomment to override the ./configure arguments for a dependency
# Note: this will replace the default arguments, not extend them
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ ignore = [
order-by-type = false

[tool.ruff.lint.mccabe]
max-complexity = 14
max-complexity = 18

[tool.ruff.lint.pydocstyle]
convention = "numpy"
Expand Down
36 changes: 34 additions & 2 deletions src/portable_python/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -492,10 +492,23 @@ def is_usable_module(self, name):
def cfg_version(self, default):
return PPG.config.get_value("%s-version" % self.m_name) or default

def cfg_http_headers(self):
if config_http_headers := PPG.config.get_value("%s-http-headers" % self.m_name):
expanded_http_headers = {}
for header_dict in config_http_headers:
for key, value in header_dict.items():
expanded_http_headers[os.path.expandvars(key)] = os.path.expandvars(value)

return expanded_http_headers

def cfg_url(self, version):
if config_url := PPG.config.get_value("%s-url" % self.m_name):
url_template = Template(config_url)
return url_template.substitute(version=version)
url_subbed = url_template.substitute(version=version)
return os.path.expandvars(url_subbed)

def cfg_src_suffix(self):
return PPG.config.get_value("%s-src-suffix" % self.m_name)

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

@property
def headers(self):
"""Headers for connecting to source url, if any"""
return self.cfg_http_headers()

@property
def src_suffix(self):
"""Suffix of src archive for when URL doesn't end in the file extension"""
return self.cfg_src_suffix()

@property
def version(self):
"""Version to use"""
Expand Down Expand Up @@ -632,8 +655,16 @@ def compile(self):
self._finalize()
return

# Some URL's may not end in file extension, such as with redirects.
# Github releases asset endpoint is this way .../releases/assets/48151

# Split on '#' for urls that include a checksum, such as #sha256=... fragment
basename = runez.basename(self.url, extension_marker="#")
if not basename.endswith((".zip", ".tar.gz")):
suffix = self.src_suffix or ".tar.gz"
suffix = ".%s" % (suffix.strip(".")) # Ensure it starts with a dot (in case config forgot leading dot)
basename = f"{self.m_name}-{self.version}{suffix}"

path = self.setup.folders.sources / basename
if not path.exists():
proxies = {}
Expand All @@ -643,7 +674,8 @@ def compile(self):
https_proxy = os.environ.get("HTTPS_PROXY") or os.environ.get("https_proxy")
if https_proxy:
proxies["https"] = https_proxy
RestClient().download(self.url, path, proxies=proxies)

RestClient().download(self.url, path, proxies=proxies, headers=self.headers)

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

Expand Down
2 changes: 1 addition & 1 deletion src/portable_python/external/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class GettextTiny(ModuleBuilder):

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

@property
def version(self):
Expand Down
8 changes: 8 additions & 0 deletions tests/sample-config1.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,11 @@ cpython-pep668-externally-managed:

cpython-configure:
- --enable-shared

# Exercise custom url
bzip2-url: https://my-enterprise/.../assets/bzip2/123#sha256=123...def
bzip2-version: 1.2.3
bzip2-src-suffix: tar.gz # Forgot leading dot on purpose
bzip2-http-headers:
- Authorization: Bearer foo
Accept: application/octet-stream
7 changes: 7 additions & 0 deletions tests/test_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@ def test_config(cli):
with pytest.raises(runez.system.AbortException):
PPG.config.parsed_yaml("a: b\ninvalid line", "testing")

# Exercise custom url in config
cli.run("-ntmacos-arm64", "-c", cli.tests_path("sample-config1.yml"), "build", "3.9.7", "-mbzip2")
assert cli.succeeded
assert "Would download https://my-enterprise/.../assets/bzip2/123#sha256=123...def\n" in cli.logged
assert "Would untar build/sources/bzip2-1.2.3.tar.gz -> build/components/bzip2\n" in cli.logged

cli.run("-ntmacos-arm64", "-c", cli.tests_path("sample-config1.yml"), "build", "3.9.7", "-mnone")
assert cli.succeeded

assert " -mpip install --no-cache-dir --upgrade my-additional-package" in cli.logged
assert "env MACOSX_DEPLOYMENT_TARGET=12" in cli.logged # Comes from more specific macos-arm64.yml
assert " -> dist/cpython-3.9.7-macos-arm64.tar.xz" in cli.logged # Comes from macos.yml (not defined in macos-arm64.yml)
Expand Down
0