diff options
-rw-r--r-- | scripts/lib/devtool/standard.py | 3 | ||||
-rw-r--r-- | scripts/lib/recipetool/create.py | 1 | ||||
-rw-r--r-- | scripts/lib/recipetool/create_buildsys_python.py | 72 |
3 files changed, 76 insertions, 0 deletions
diff --git a/scripts/lib/devtool/standard.py b/scripts/lib/devtool/standard.py index ad6e346279..16ea328c6a 100644 --- a/scripts/lib/devtool/standard.py +++ b/scripts/lib/devtool/standard.py | |||
@@ -147,6 +147,8 @@ def add(args, config, basepath, workspace): | |||
147 | extracmdopts += ' -a' | 147 | extracmdopts += ' -a' |
148 | if args.npm_dev: | 148 | if args.npm_dev: |
149 | extracmdopts += ' --npm-dev' | 149 | extracmdopts += ' --npm-dev' |
150 | if args.no_pypi: | ||
151 | extracmdopts += ' --no-pypi' | ||
150 | if args.mirrors: | 152 | if args.mirrors: |
151 | extracmdopts += ' --mirrors' | 153 | extracmdopts += ' --mirrors' |
152 | if args.srcrev: | 154 | if args.srcrev: |
@@ -2328,6 +2330,7 @@ def register_commands(subparsers, context): | |||
2328 | group.add_argument('--no-same-dir', help='Force build in a separate build directory', action="store_true") | 2330 | group.add_argument('--no-same-dir', help='Force build in a separate build directory', action="store_true") |
2329 | parser_add.add_argument('--fetch', '-f', help='Fetch the specified URI and extract it to create the source tree (deprecated - pass as positional argument instead)', metavar='URI') | 2331 | parser_add.add_argument('--fetch', '-f', help='Fetch the specified URI and extract it to create the source tree (deprecated - pass as positional argument instead)', metavar='URI') |
2330 | parser_add.add_argument('--npm-dev', help='For npm, also fetch devDependencies', action="store_true") | 2332 | parser_add.add_argument('--npm-dev', help='For npm, also fetch devDependencies', action="store_true") |
2333 | parser_add.add_argument('--no-pypi', help='Do not inherit pypi class', action="store_true") | ||
2331 | parser_add.add_argument('--version', '-V', help='Version to use within recipe (PV)') | 2334 | parser_add.add_argument('--version', '-V', help='Version to use within recipe (PV)') |
2332 | parser_add.add_argument('--no-git', '-g', help='If fetching source, do not set up source tree as a git repository', action="store_true") | 2335 | parser_add.add_argument('--no-git', '-g', help='If fetching source, do not set up source tree as a git repository', action="store_true") |
2333 | group = parser_add.add_mutually_exclusive_group() | 2336 | group = parser_add.add_mutually_exclusive_group() |
diff --git a/scripts/lib/recipetool/create.py b/scripts/lib/recipetool/create.py index 5c5ac7ae40..963aa91421 100644 --- a/scripts/lib/recipetool/create.py +++ b/scripts/lib/recipetool/create.py | |||
@@ -1413,6 +1413,7 @@ def register_commands(subparsers): | |||
1413 | parser_create.add_argument('-B', '--srcbranch', help='Branch in source repository if fetching from an SCM such as git (default master)') | 1413 | parser_create.add_argument('-B', '--srcbranch', help='Branch in source repository if fetching from an SCM such as git (default master)') |
1414 | parser_create.add_argument('--keep-temp', action="store_true", help='Keep temporary directory (for debugging)') | 1414 | parser_create.add_argument('--keep-temp', action="store_true", help='Keep temporary directory (for debugging)') |
1415 | parser_create.add_argument('--npm-dev', action="store_true", help='For npm, also fetch devDependencies') | 1415 | parser_create.add_argument('--npm-dev', action="store_true", help='For npm, also fetch devDependencies') |
1416 | parser_create.add_argument('--no-pypi', action="store_true", help='Do not inherit pypi class') | ||
1416 | parser_create.add_argument('--devtool', action="store_true", help=argparse.SUPPRESS) | 1417 | parser_create.add_argument('--devtool', action="store_true", help=argparse.SUPPRESS) |
1417 | parser_create.add_argument('--mirrors', action="store_true", help='Enable PREMIRRORS and MIRRORS for source tree fetching (disabled by default).') | 1418 | parser_create.add_argument('--mirrors', action="store_true", help='Enable PREMIRRORS and MIRRORS for source tree fetching (disabled by default).') |
1418 | parser_create.set_defaults(func=create_recipe) | 1419 | parser_create.set_defaults(func=create_recipe) |
diff --git a/scripts/lib/recipetool/create_buildsys_python.py b/scripts/lib/recipetool/create_buildsys_python.py index b620e3271b..5e07222ece 100644 --- a/scripts/lib/recipetool/create_buildsys_python.py +++ b/scripts/lib/recipetool/create_buildsys_python.py | |||
@@ -18,7 +18,11 @@ import os | |||
18 | import re | 18 | import re |
19 | import sys | 19 | import sys |
20 | import subprocess | 20 | import subprocess |
21 | import json | ||
22 | import urllib.request | ||
21 | from recipetool.create import RecipeHandler | 23 | from recipetool.create import RecipeHandler |
24 | from urllib.parse import urldefrag | ||
25 | from recipetool.create import determine_from_url | ||
22 | 26 | ||
23 | logger = logging.getLogger('recipetool') | 27 | logger = logging.getLogger('recipetool') |
24 | 28 | ||
@@ -111,6 +115,74 @@ class PythonRecipeHandler(RecipeHandler): | |||
111 | def __init__(self): | 115 | def __init__(self): |
112 | pass | 116 | pass |
113 | 117 | ||
118 | def process_url(self, args, classes, handled, extravalues): | ||
119 | """ | ||
120 | Convert any pypi url https://pypi.org/project/<package>/<version> into https://files.pythonhosted.org/packages/source/... | ||
121 | which corresponds to the archive location, and add pypi class | ||
122 | """ | ||
123 | |||
124 | if 'url' in handled: | ||
125 | return None | ||
126 | |||
127 | fetch_uri = None | ||
128 | source = args.source | ||
129 | required_version = args.version if args.version else None | ||
130 | match = re.match(r'https?://pypi.org/project/([^/]+)(?:/([^/]+))?/?$', urldefrag(source)[0]) | ||
131 | if match: | ||
132 | package = match.group(1) | ||
133 | version = match.group(2) if match.group(2) else required_version | ||
134 | |||
135 | json_url = f"https://pypi.org/pypi/%s/json" % package | ||
136 | response = urllib.request.urlopen(json_url) | ||
137 | if response.status == 200: | ||
138 | data = json.loads(response.read()) | ||
139 | if not version: | ||
140 | # grab latest version | ||
141 | version = data["info"]["version"] | ||
142 | pypi_package = data["info"]["name"] | ||
143 | for release in reversed(data["releases"][version]): | ||
144 | if release["packagetype"] == "sdist": | ||
145 | fetch_uri = release["url"] | ||
146 | break | ||
147 | else: | ||
148 | logger.warning("Cannot handle pypi url %s: cannot fetch package information using %s", source, json_url) | ||
149 | return None | ||
150 | else: | ||
151 | match = re.match(r'^https?://files.pythonhosted.org/packages.*/(.*)-.*$', source) | ||
152 | if match: | ||
153 | fetch_uri = source | ||
154 | pypi_package = match.group(1) | ||
155 | _, version = determine_from_url(fetch_uri) | ||
156 | |||
157 | if match and not args.no_pypi: | ||
158 | if required_version and version != required_version: | ||
159 | raise Exception("Version specified using --version/-V (%s) and version specified in the url (%s) do not match" % (required_version, version)) | ||
160 | # This is optionnal if BPN looks like "python-<pypi_package>" or "python3-<pypi_package>" (see pypi.bbclass) | ||
161 | # but at this point we cannot know because because user can specify the output name of the recipe on the command line | ||
162 | extravalues["PYPI_PACKAGE"] = pypi_package | ||
163 | # If the tarball extension is not 'tar.gz' (default value in pypi.bblcass) whe should set PYPI_PACKAGE_EXT in the recipe | ||
164 | pypi_package_ext = re.match(r'.*%s-%s\.(.*)$' % (pypi_package, version), fetch_uri) | ||
165 | if pypi_package_ext: | ||
166 | pypi_package_ext = pypi_package_ext.group(1) | ||
167 | if pypi_package_ext != "tar.gz": | ||
168 | extravalues["PYPI_PACKAGE_EXT"] = pypi_package_ext | ||
169 | |||
170 | # Pypi class will handle S and SRC_URIxxx variables, so remove them | ||
171 | # TODO: allow oe.recipeutils.patch_recipe_lines() to accept regexp so we can simplify the following to: | ||
172 | # extravalues['SRC_URI(?:\[.*?\])?'] = None | ||
173 | extravalues['S'] = None | ||
174 | extravalues['SRC_URI'] = None | ||
175 | extravalues['SRC_URI[md5sum]'] = None | ||
176 | extravalues['SRC_URI[sha1sum]'] = None | ||
177 | extravalues['SRC_URI[sha256sum]'] = None | ||
178 | extravalues['SRC_URI[sha384sum]'] = None | ||
179 | extravalues['SRC_URI[sha512sum]'] = None | ||
180 | |||
181 | classes.append('pypi') | ||
182 | |||
183 | handled.append('url') | ||
184 | return fetch_uri | ||
185 | |||
114 | def handle_classifier_license(self, classifiers, existing_licenses=""): | 186 | def handle_classifier_license(self, classifiers, existing_licenses=""): |
115 | 187 | ||
116 | licenses = [] | 188 | licenses = [] |