Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 10c5292

Browse files
authoredOct 22, 2024··
Merge pull request #3074 from autosportlabs/brent/private_github_repos
Add ability to use private github repos for recipes
2 parents 399e450 + 5bed48d commit 10c5292

File tree

5 files changed

+60
-2
lines changed

5 files changed

+60
-2
lines changed
 

‎.github/workflows/push.yml

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ env:
88
AAR_ARTIFACT_FILENAME: bdist_unit_tests_app-release-1.1.aar
99
PYTHONFORANDROID_PREREQUISITES_INSTALL_INTERACTIVE: 0
1010

11+
concurrency:
12+
group: build-${{ github.ref }}
13+
cancel-in-progress: true
14+
1115
jobs:
1216

1317
flake8:

‎doc/source/recipes.rst

+18
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,28 @@ omitted if the source is somehow loaded from elsewhere.
5454
You must include ``recipe = YourRecipe()``. This variable is accessed
5555
when the recipe is imported.
5656

57+
Specifying the URL
58+
------------------
59+
5760
.. note:: The url includes the ``{version}`` tag. You should only
5861
access the url with the ``versioned_url`` property, which
5962
replaces this with the version attribute.
6063

64+
.. note:: you may need to specify additional headers to allow python-for-android
65+
to download the archive. Specify your additional headers by setting the
66+
download_headers property.
67+
68+
For example, when downloading from a private github repository, you can specify the following:
69+
70+
(For the download_headers property in your recipe)
71+
```
72+
[('Authorization', 'token <your personal access token>'), ('Accept', 'application/vnd.github+json')]
73+
```
74+
75+
(For the DOWNLOAD_HEADERS_my-package-name environment variable - specify as a JSON formatted set of values)
76+
```
77+
[["Authorization","token <your personal access token>"],["Accept", "application/vnd.github+json"]]
78+
```
6179
The actual build process takes place via three core methods::
6280

6381
def prebuild_arch(self, arch):

‎pythonforandroid/recipe.py

+30-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from os.path import basename, dirname, exists, isdir, isfile, join, realpath, split
22
import glob
3-
43
import hashlib
4+
import json
55
from re import match
66

77
import sh
@@ -59,6 +59,21 @@ class Recipe(metaclass=RecipeMeta):
5959
if you want.
6060
'''
6161

62+
_download_headers = None
63+
'''Add additional headers used when downloading the package, typically
64+
for authorization purposes.
65+
66+
Specified as an array of tuples:
67+
[("header1", "foo"), ("header2", "bar")]
68+
69+
When specifying as an environment variable (DOWNLOAD_HEADER_my-package-name), use a JSON formatted fragement:
70+
[["header1","foo"],["header2", "bar"]]
71+
72+
For example, when downloading from a private
73+
github repository, you can specify the following:
74+
[('Authorization', 'token <your personal access token>'), ('Accept', 'application/vnd.github+json')]
75+
'''
76+
6277
_version = None
6378
'''A string giving the version of the software the recipe describes,
6479
e.g. ``2.0.3`` or ``master``.'''
@@ -170,6 +185,18 @@ def versioned_url(self):
170185
return None
171186
return self.url.format(version=self.version)
172187

188+
@property
189+
def download_headers(self):
190+
key = "DOWNLOAD_HEADERS_" + self.name
191+
env_headers = environ.get(key)
192+
if env_headers:
193+
try:
194+
return [tuple(h) for h in json.loads(env_headers)]
195+
except Exception as ex:
196+
raise ValueError(f'Invalid Download headers for {key} - must be JSON formatted as [["header1","foo"],["header2","bar"]]: {ex}')
197+
198+
return environ.get(key, self._download_headers)
199+
173200
def download_file(self, url, target, cwd=None):
174201
"""
175202
(internal) Download an ``url`` to a ``target``.
@@ -205,6 +232,8 @@ def report_hook(index, blksize, size):
205232
# jqueryui.com returns a 403 w/ the default user agent
206233
# Mozilla/5.0 does not handle redirection for liblzma
207234
url_opener.addheaders = [('User-agent', 'Wget/1.0')]
235+
if self.download_headers:
236+
url_opener.addheaders += self.download_headers
208237
urlretrieve(url, target, report_hook)
209238
except OSError as e:
210239
attempts += 1

‎pythonforandroid/toolchain.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1023,7 +1023,7 @@ def _build_package(self, args, package_type):
10231023
# .../build/bootstrap_builds/sdl2-python3/gradlew
10241024
# if docker on windows, gradle contains CRLF
10251025
output = shprint(
1026-
sh.Command('dos2unix'), gradlew._path.decode('utf8'),
1026+
sh.Command('dos2unix'), gradlew._path,
10271027
_tail=20, _critical=True, _env=env
10281028
)
10291029
if args.build_mode == "debug":

‎tests/test_recipe.py

+7
Original file line numberDiff line numberDiff line change
@@ -326,3 +326,10 @@ def test_postarch_build(self, mock_install_stl_lib):
326326
assert recipe.need_stl_shared, True
327327
recipe.postbuild_arch(arch)
328328
mock_install_stl_lib.assert_called_once_with(arch)
329+
330+
def test_recipe_download_headers(self):
331+
"""Download header can be created on the fly using environment variables."""
332+
recipe = DummyRecipe()
333+
with mock.patch.dict(os.environ, {f'DOWNLOAD_HEADERS_{recipe.name}': '[["header1","foo"],["header2", "bar"]]'}):
334+
download_headers = recipe.download_headers
335+
assert download_headers == [("header1", "foo"), ("header2", "bar")]

0 commit comments

Comments
 (0)
Please sign in to comment.