|
19 | 19 | from tinynetrc import Netrc |
20 | 20 |
|
21 | 21 | from _packagedcode.models import DependentPackage |
22 | | -from _packagedcode.pypi import PipRequirementsFileHandler |
| 22 | +from _packagedcode.pypi import PythonSetupPyHandler |
23 | 23 | from _packagedcode.pypi import can_process_dependent_package |
24 | 24 | from python_inspector import dependencies |
25 | 25 | from python_inspector import utils |
26 | 26 | from python_inspector import utils_pypi |
27 | 27 | from python_inspector.cli_utils import FileOptionType |
28 | 28 | from python_inspector.resolution import get_environment_marker_from_environment |
| 29 | +from python_inspector.resolution import get_python_version_from_env_tag |
29 | 30 | from python_inspector.resolution import get_resolved_dependencies |
30 | 31 |
|
31 | 32 | TRACE = False |
|
50 | 51 | "This option can be used multiple times.", |
51 | 52 | ) |
52 | 53 | @click.option( |
53 | | - "-n", |
54 | | - "--netrc", |
55 | | - "netrc_file", |
| 54 | + "-s", |
| 55 | + "--setup-py", |
| 56 | + "setup_py_file", |
56 | 57 | type=click.Path(exists=True, readable=True, path_type=str, dir_okay=False), |
57 | | - metavar="NETRC-FILE", |
| 58 | + metavar="SETUP-PY-FILE", |
58 | 59 | required=False, |
59 | | - help="Netrc file to use for authentication. ", |
| 60 | + help="Path to setuptools setup.py file listing dependencies and metadata. " |
| 61 | + "This option can be used multiple times.", |
60 | 62 | ) |
61 | 63 | @click.option( |
62 | 64 | "--spec", |
|
117 | 119 | help="Write output as pretty-printed JSON to FILE as a tree in the style of pipdeptree. " |
118 | 120 | "Use the special '-' file name to print results on screen/stdout.", |
119 | 121 | ) |
| 122 | +@click.option( |
| 123 | + "-n", |
| 124 | + "--netrc", |
| 125 | + "netrc_file", |
| 126 | + type=click.Path(exists=True, readable=True, path_type=str, dir_okay=False), |
| 127 | + metavar="NETRC-FILE", |
| 128 | + hidden=True, |
| 129 | + required=False, |
| 130 | + help="Netrc file to use for authentication. ", |
| 131 | +) |
120 | 132 | @click.option( |
121 | 133 | "--max-rounds", |
122 | 134 | "max_rounds", |
| 135 | + hidden=True, |
123 | 136 | type=int, |
124 | 137 | default=200000, |
125 | 138 | help="Increase the max rounds whenever the resolution is too deep", |
|
146 | 159 | def resolve_dependencies( |
147 | 160 | ctx, |
148 | 161 | requirement_files, |
149 | | - netrc_file, |
| 162 | + setup_py_file, |
150 | 163 | specifiers, |
151 | 164 | python_version, |
152 | 165 | operating_system, |
153 | 166 | index_urls, |
154 | 167 | json_output, |
155 | 168 | pdt_output, |
| 169 | + netrc_file, |
156 | 170 | max_rounds, |
157 | 171 | use_cached_index=False, |
158 | 172 | use_pypi_json_api=False, |
159 | 173 | verbose=TRACE, |
160 | 174 | ): |
161 | 175 | """ |
162 | | - Resolve the dependencies of the packages listed in REQUIREMENT-FILE(s) file |
163 | | - and SPECIFIER(s) and save the results as JSON to FILE. |
| 176 | + Resolve the dependencies for the package requirements listed in one or |
| 177 | + more REQUIREMENT-FILE file, one or more SPECIFIER and one setuptools |
| 178 | + SETUP-PY-FILE file and save the results as JSON to FILE. |
164 | 179 |
|
165 | 180 | Resolve the dependencies for the requested ``--python-version`` PYVER and |
166 | 181 | ``--operating_system`` OS combination defaulting Python version 3.8 and |
@@ -221,6 +236,28 @@ def resolve_dependencies( |
221 | 236 | dep = dependencies.get_dependency(specifier=specifier) |
222 | 237 | direct_dependencies.append(dep) |
223 | 238 |
|
| 239 | + if setup_py_file: |
| 240 | + package_data = list(PythonSetupPyHandler.parse(location=setup_py_file)) |
| 241 | + assert len(package_data) == 1 |
| 242 | + package_data = package_data[0] |
| 243 | + # validate if python require matches our current python version |
| 244 | + python_requires = package_data.extra_data.get("python_requires") |
| 245 | + if not utils_pypi.valid_python_version( |
| 246 | + python_version=get_python_version_from_env_tag(python_version), |
| 247 | + python_requires=python_requires, |
| 248 | + ): |
| 249 | + click.secho( |
| 250 | + f"Python version {python_version} is not compatible with setup.py {setup_py_file} " |
| 251 | + f"python_requires {python_requires}", |
| 252 | + err=True, |
| 253 | + ) |
| 254 | + ctx.exit(1) |
| 255 | + |
| 256 | + for dep in package_data.dependencies: |
| 257 | + # TODO : we need to handle to all the scopes |
| 258 | + if dep.scope == "install": |
| 259 | + direct_dependencies.append(dep) |
| 260 | + |
224 | 261 | if not direct_dependencies: |
225 | 262 | click.secho("Error: no requirements requested.") |
226 | 263 | ctx.exit(1) |
|
0 commit comments