ddelange / pipgrip

Lightweight pip dependency resolver with deptree preview functionality based on the PubGrub algorithm
Other
183 stars 14 forks source link

Show partial tree on errors #65

Closed abitrolly closed 2 years ago

abitrolly commented 2 years ago

Need pipgrip to render partial tree when installation fails with errors.

Use case / motivation

I need to see who pulls in broken dependency when CI jobs fail.

Related Issues

The discussion started here https://github.com/ddelange/pipgrip/issues/52#issuecomment-794050929

And the solution I used was to pipe requirements.txt line by line until pipgrip fails.

cat requirements.txt | xargs -n 1 pipgrip --tree -v

However, for this failure the dependencies are specified as .[test_all] in tox.ini and configured dynamically in setup.py.

The cat also won't work well for deeper levels in hierarchy.

abitrolly commented 2 years ago

The failure happens in VersionSolver.solve() even before the dependency tree is built.

https://github.com/ddelange/pipgrip/blob/43405b2849db552da49df3cb50564370eb66590a/src/pipgrip/cli.py#L426

ddelange commented 2 years ago

Hi @abitrolly,

At point of buid error, there is still an ensemble of potentially viable trees. Only when the final set of version pins has been resolved, the 'right' tree can be visualised. It could for instance be that the build error happens for an older version of a package, which would be later discarded during backtracking as it turned out a more recent version (or no version at all) of that package will satisfy by choosing a different version of another package: a different tree in the ensemble.

That said, for the use case you describe, it is possible to log which decision led to building the failing wheel:

https://github.com/ddelange/pipgrip/blob/cca9892be264ecc6504455f3c6bf450449e30c70/src/pipgrip/cli.py#L422 When this line errors, in a re-raising try-except, the last decision in the PartialSolution before the error occurred can be logged:

last_decision = next(reversed(solver.solution.decisions.items()))

Would that help?

ddelange commented 2 years ago

I'm pretty sure this decision coincides with the last INFO: selecting ... statement in the output: if I understand correctly, that's the one you need.

abitrolly commented 2 years ago

I need to try that. Having a partial tree with a mark of failing package in the final error message would definitely help.

A bit of context.

Click to expand ```bash $ pipgrip .[test_all] -vvv --tree DEBUG: environment: {'implementation_name': 'cpython', 'implementation_version': '3.9.7', 'os_name': 'posix', 'platform_machine': 'x86_64', 'platform_release': '5.14.10-300.fc35.x86_64', 'platform_system': 'Linux', 'platform_version': '#1 SMP Thu Oct 7 20:48:44 UTC 2021', 'python_full_version': '3.9.7', 'platform_python_implementation': 'CPython', 'python_version': '3.9', 'sys_platform': 'linux'} DEBUG: pip version: [21, 2, 4] DEBUG: pipgrip version: 0.6.10 DEBUG: ----------[PackageSource]--- INFO: discovering .[test_all] DEBUG: Downloading/building wheel for .[test_all] into cache_dir /root/.cache/pip/wheels/pipgrip DEBUG: ['/usr/local/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/root/.cache/pip/wheels/pipgrip', '--progress-bar=off', '.[test_all]'] DEBUG: {'.[test_all]': '/root/.cache/pip/wheels/pipgrip/SQLAlchemy_Utils-0.37.8-py3-none-any.whl'} DEBUG: Searching metadata in /root/.cache/pip/wheels/pipgrip/SQLAlchemy_Utils-0.37.8-py3-none-any.whl DEBUG: dropped conditional dep anyjson (>=0.3.3) ; extra == 'anyjson' DEBUG: dropped conditional dep arrow (>=0.3.4) ; extra == 'arrow' DEBUG: dropped conditional dep Babel (>=1.3) ; extra == 'babel' DEBUG: dropped conditional dep colour (>=0.0.4) ; extra == 'color' DEBUG: dropped conditional dep cryptography (>=0.6) ; extra == 'encrypted' DEBUG: dropped conditional dep intervals (>=0.7.1) ; extra == 'intervals' DEBUG: dropped conditional dep passlib (<2.0,>=1.6) ; extra == 'password' DEBUG: dropped conditional dep pendulum (>=2.0.5) ; extra == 'pendulum' DEBUG: dropped conditional dep phonenumbers (>=5.9.2) ; extra == 'phone' DEBUG: dropped conditional dep pytest (>=2.7.1) ; extra == 'test' DEBUG: dropped conditional dep Pygments (>=1.2) ; extra == 'test' DEBUG: dropped conditional dep Jinja2 (>=2.3) ; extra == 'test' DEBUG: dropped conditional dep docutils (>=0.10) ; extra == 'test' DEBUG: dropped conditional dep flexmock (>=0.9.7) ; extra == 'test' DEBUG: dropped conditional dep mock (==2.0.0) ; extra == 'test' DEBUG: dropped conditional dep psycopg2 (>=2.5.1) ; extra == 'test' DEBUG: dropped conditional dep psycopg2cffi (>=2.8.1) ; extra == 'test' DEBUG: dropped conditional dep pg8000 (>=1.12.4) ; extra == 'test' DEBUG: dropped conditional dep pytz (>=2014.2) ; extra == 'test' DEBUG: dropped conditional dep python-dateutil (>=2.6) ; extra == 'test' DEBUG: dropped conditional dep pymysql ; extra == 'test' DEBUG: dropped conditional dep flake8 (>=2.4.0) ; extra == 'test' DEBUG: dropped conditional dep isort (>=4.2.2) ; extra == 'test' DEBUG: dropped conditional dep pyodbc ; extra == 'test' DEBUG: dropped conditional dep backports.zoneinfo ; (python_version < "3.9") and extra == 'test' DEBUG: included conditional dep Babel (>=1.3) ; extra == 'test_all' DEBUG: included conditional dep Jinja2 (>=2.3) ; extra == 'test_all' DEBUG: included conditional dep Pygments (>=1.2) ; extra == 'test_all' DEBUG: included conditional dep anyjson (>=0.3.3) ; extra == 'test_all' DEBUG: included conditional dep arrow (>=0.3.4) ; extra == 'test_all' DEBUG: included conditional dep colour (>=0.0.4) ; extra == 'test_all' DEBUG: included conditional dep cryptography (>=0.6) ; extra == 'test_all' DEBUG: included conditional dep docutils (>=0.10) ; extra == 'test_all' DEBUG: included conditional dep flake8 (>=2.4.0) ; extra == 'test_all' DEBUG: included conditional dep flexmock (>=0.9.7) ; extra == 'test_all' DEBUG: included conditional dep furl (>=0.4.1) ; extra == 'test_all' DEBUG: included conditional dep intervals (>=0.7.1) ; extra == 'test_all' DEBUG: included conditional dep isort (>=4.2.2) ; extra == 'test_all' DEBUG: included conditional dep mock (==2.0.0) ; extra == 'test_all' DEBUG: included conditional dep passlib (<2.0,>=1.6) ; extra == 'test_all' DEBUG: included conditional dep pendulum (>=2.0.5) ; extra == 'test_all' DEBUG: included conditional dep pg8000 (>=1.12.4) ; extra == 'test_all' DEBUG: included conditional dep phonenumbers (>=5.9.2) ; extra == 'test_all' DEBUG: included conditional dep psycopg2 (>=2.5.1) ; extra == 'test_all' DEBUG: included conditional dep psycopg2cffi (>=2.8.1) ; extra == 'test_all' DEBUG: included conditional dep pymysql ; extra == 'test_all' DEBUG: included conditional dep pyodbc ; extra == 'test_all' DEBUG: included conditional dep pytest (>=2.7.1) ; extra == 'test_all' DEBUG: included conditional dep python-dateutil ; extra == 'test_all' DEBUG: included conditional dep python-dateutil (>=2.6) ; extra == 'test_all' DEBUG: included conditional dep pytz (>=2014.2) ; extra == 'test_all' DEBUG: dropped conditional dep backports.zoneinfo ; (python_version < "3.9") and extra == 'test_all' DEBUG: dropped conditional dep python-dateutil ; extra == 'timezone' DEBUG: dropped conditional dep furl (>=0.4.1) ; extra == 'url' DEBUG: ----------[VersionSolver]--- INFO: fact: _root_ is root INFO: derived: root INFO: fact: root depends on .[test_all] (*) INFO: selecting . (0.0.0) INFO: derived: .[test_all] (*) INFO: fact: .[test_all] (0.37.8) depends on anyjson (>=0.3.3) INFO: fact: .[test_all] (0.37.8) depends on arrow (>=0.3.4) INFO: fact: .[test_all] (0.37.8) depends on babel (>=1.3) INFO: fact: .[test_all] (0.37.8) depends on colour (>=0.0.4) INFO: fact: .[test_all] (0.37.8) depends on cryptography (>=0.6) INFO: fact: .[test_all] (0.37.8) depends on docutils (>=0.10) INFO: fact: .[test_all] (0.37.8) depends on flake8 (>=2.4.0) INFO: fact: .[test_all] (0.37.8) depends on flexmock (>=0.9.7) INFO: fact: .[test_all] (0.37.8) depends on furl (>=0.4.1) INFO: fact: .[test_all] (0.37.8) depends on intervals (>=0.7.1) INFO: fact: .[test_all] (0.37.8) depends on isort (>=4.2.2) INFO: fact: .[test_all] (0.37.8) depends on jinja2 (>=2.3) INFO: fact: .[test_all] (0.37.8) depends on mock (==2.0.0) INFO: fact: .[test_all] (0.37.8) depends on passlib (<2.0,>=1.6) INFO: fact: .[test_all] (0.37.8) depends on pendulum (>=2.0.5) INFO: fact: .[test_all] (0.37.8) depends on pg8000 (>=1.12.4) INFO: fact: .[test_all] (0.37.8) depends on phonenumbers (>=5.9.2) INFO: fact: .[test_all] (0.37.8) depends on psycopg2 (>=2.5.1) INFO: fact: .[test_all] (0.37.8) depends on psycopg2cffi (>=2.8.1) INFO: fact: .[test_all] (0.37.8) depends on pygments (>=1.2) INFO: fact: .[test_all] (0.37.8) depends on pymysql (*) INFO: fact: .[test_all] (0.37.8) depends on pyodbc (*) INFO: fact: .[test_all] (0.37.8) depends on pytest (>=2.7.1) INFO: fact: .[test_all] (0.37.8) depends on python-dateutil (*) INFO: fact: .[test_all] (0.37.8) depends on python-dateutil (>=2.6) INFO: fact: .[test_all] (0.37.8) depends on pytz (>=2014.2) INFO: fact: .[test_all] (0.37.8) depends on six (*) INFO: fact: .[test_all] (0.37.8) depends on sqlalchemy (>=1.0) INFO: selecting .[test_all] (0.37.8) INFO: derived: sqlalchemy (>=1.0) INFO: derived: six (*) INFO: derived: pytz (>=2014.2) INFO: derived: python-dateutil (>=2.6) INFO: derived: pytest (>=2.7.1) INFO: derived: pyodbc (*) INFO: derived: pymysql (*) INFO: derived: pygments (>=1.2) INFO: derived: psycopg2cffi (>=2.8.1) INFO: derived: psycopg2 (>=2.5.1) INFO: derived: phonenumbers (>=5.9.2) INFO: derived: pg8000 (>=1.12.4) INFO: derived: pendulum (>=2.0.5) INFO: derived: passlib (<2.0,>=1.6) INFO: derived: mock (==2.0.0) INFO: derived: jinja2 (>=2.3) INFO: derived: isort (>=4.2.2) INFO: derived: intervals (>=0.7.1) INFO: derived: furl (>=0.4.1) INFO: derived: flexmock (>=0.9.7) INFO: derived: flake8 (>=2.4.0) INFO: derived: docutils (>=0.10) INFO: derived: cryptography (>=0.6) INFO: derived: colour (>=0.0.4) INFO: derived: babel (>=1.3) INFO: derived: arrow (>=0.3.4) INFO: derived: anyjson (>=0.3.3) INFO: discovering sqlalchemy>=1.0 DEBUG: Downloading/building wheel for sqlalchemy>=1.0 into cache_dir /root/.cache/pip/wheels/pipgrip DEBUG: ['/usr/local/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/root/.cache/pip/wheels/pipgrip', '--progress-bar=off', 'sqlalchemy>=1.0'] DEBUG: {'sqlalchemy>=1.0': '/root/.cache/pip/wheels/pipgrip/SQLAlchemy-1.4.25-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl'} DEBUG: Searching metadata in /root/.cache/pip/wheels/pipgrip/SQLAlchemy-1.4.25-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl DEBUG: dropped conditional dep importlib-metadata ; python_version < "3.8" DEBUG: included conditional dep greenlet (!=0.4.17) ; python_version >= "3" and (platform_machine == "aarch64" or (platform_machine == "ppc64le" or (platform_machine == "x86_64" or (platform_machine == "amd64" or (platform_machine == "AMD64" or (platform_machine == "win32" or platform_machine == "WIN32")))))) DEBUG: dropped conditional dep greenlet (!=0.4.17) ; (python_version >= "3") and extra == 'aiomysql' DEBUG: dropped conditional dep aiomysql ; (python_version >= "3") and extra == 'aiomysql' DEBUG: dropped conditional dep typing-extensions (!=3.10.0.1) ; extra == 'aiosqlite' DEBUG: dropped conditional dep greenlet (!=0.4.17) ; (python_version >= "3") and extra == 'aiosqlite' DEBUG: dropped conditional dep aiosqlite ; (python_version >= "3") and extra == 'aiosqlite' DEBUG: dropped conditional dep greenlet (!=0.4.17) ; (python_version >= "3") and extra == 'asyncio' DEBUG: dropped conditional dep greenlet (!=0.4.17) ; (python_version >= "3") and extra == 'asyncmy' DEBUG: dropped conditional dep asyncmy (>=0.2.0) ; (python_version >= "3") and extra == 'asyncmy' DEBUG: dropped conditional dep mariadb (>=1.0.1) ; (python_version >= "3") and extra == 'mariadb_connector' DEBUG: dropped conditional dep pyodbc ; extra == 'mssql' DEBUG: dropped conditional dep pymssql ; extra == 'mssql_pymssql' DEBUG: dropped conditional dep pyodbc ; extra == 'mssql_pyodbc' DEBUG: dropped conditional dep sqlalchemy2-stubs ; extra == 'mypy' DEBUG: dropped conditional dep mypy (>=0.910) ; (python_version >= "3") and extra == 'mypy' DEBUG: dropped conditional dep mysqlclient (<2,>=1.4.0) ; (python_version < "3") and extra == 'mysql' DEBUG: dropped conditional dep mysqlclient (>=1.4.0) ; (python_version >= "3") and extra == 'mysql' DEBUG: dropped conditional dep mysql-connector-python ; extra == 'mysql_connector' DEBUG: dropped conditional dep cx-oracle (<8,>=7) ; (python_version < "3") and extra == 'oracle' DEBUG: dropped conditional dep cx-oracle (>=7) ; (python_version >= "3") and extra == 'oracle' DEBUG: dropped conditional dep psycopg2 (>=2.7) ; extra == 'postgresql' DEBUG: dropped conditional dep greenlet (!=0.4.17) ; (python_version >= "3") and extra == 'postgresql_asyncpg' DEBUG: dropped conditional dep asyncpg ; (python_version >= "3") and extra == 'postgresql_asyncpg' DEBUG: dropped conditional dep pg8000 (>=1.16.6) ; extra == 'postgresql_pg8000' DEBUG: dropped conditional dep psycopg2-binary ; extra == 'postgresql_psycopg2binary' DEBUG: dropped conditional dep psycopg2cffi ; extra == 'postgresql_psycopg2cffi' DEBUG: dropped conditional dep pymysql (<1) ; (python_version < "3") and extra == 'pymysql' DEBUG: dropped conditional dep pymysql ; (python_version >= "3") and extra == 'pymysql' DEBUG: dropped conditional dep sqlcipher3-binary ; (python_version >= "3") and extra == 'sqlcipher' DEBUG: Finding possible versions for sqlalchemy DEBUG: ['/usr/local/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--progress-bar=off', 'sqlalchemy==42.42.post424242'] DEBUG: {'sqlalchemy': ['0.1.0', '0.1.1', '0.1.2', '0.1.3', '0.1.4', '0.1.5', '0.1.6', '0.1.7', '0.2.0', '0.2.1', '0.2.2', '0.2.3', '0.2.4', '0.2.5', '0.2.6', '0.2.7', '0.2.8', '0.3.0', '0.3.1', '0.3.2', '0.3.3', '0.3.4', '0.3.5', '0.3.6', '0.3.7', '0.3.8', '0.3.9', '0.3.10', '0.3.11', '0.4.0', '0.4.1', '0.4.2', '0.4.3', '0.4.4', '0.4.5', '0.4.6', '0.4.7', '0.4.8', '0.5.0', '0.5.1', '0.5.2', '0.5.3', '0.5.4', '0.5.5', '0.5.6', '0.5.7', '0.5.8', '0.6.0', '0.6.1', '0.6.2', '0.6.3', '0.6.4', '0.6.5', '0.6.6', '0.6.7', '0.6.8', '0.6.9', '0.7.0', '0.7.1', '0.7.2', '0.7.3', '0.7.4', '0.7.5', '0.7.6', '0.7.7', '0.7.8', '0.7.9', '0.7.10', '0.8.0', '0.8.1', '0.8.2', '0.8.3', '0.8.4', '0.8.5', '0.8.6', '0.8.7', '0.9.0', '0.9.1', '0.9.2', '0.9.3', '0.9.4', '0.9.5', '0.9.6', '0.9.7', '0.9.8', '0.9.9', '0.9.10', '1.0.0', '1.0.1', '1.0.2', '1.0.3', '1.0.4', '1.0.5', '1.0.6', '1.0.7', '1.0.8', '1.0.9', '1.0.10', '1.0.11', '1.0.12', '1.0.13', '1.0.14', '1.0.15', '1.0.16', '1.0.17', '1.0.18', '1.0.19', '1.1.0', '1.1.1', '1.1.2', '1.1.3', '1.1.4', '1.1.5', '1.1.6', '1.1.7', '1.1.8', '1.1.9', '1.1.10', '1.1.11', '1.1.12', '1.1.13', '1.1.14', '1.1.15', '1.1.16', '1.1.17', '1.1.18', '1.2.0', '1.2.1', '1.2.2', '1.2.3', '1.2.4', '1.2.5', '1.2.6', '1.2.7', '1.2.8', '1.2.9', '1.2.10', '1.2.11', '1.2.12', '1.2.13', '1.2.14', '1.2.15', '1.2.16', '1.2.17', '1.2.18', '1.2.19', '1.3.0', '1.3.1', '1.3.2', '1.3.3', '1.3.4', '1.3.5', '1.3.6', '1.3.7', '1.3.8', '1.3.9', '1.3.10', '1.3.11', '1.3.12', '1.3.13', '1.3.14', '1.3.15', '1.3.16', '1.3.17', '1.3.18', '1.3.19', '1.3.20', '1.3.21', '1.3.22', '1.3.23', '1.3.24', '1.4.0', '1.4.1', '1.4.2', '1.4.3', '1.4.4', '1.4.5', '1.4.6', '1.4.7', '1.4.8', '1.4.9', '1.4.10', '1.4.11', '1.4.12', '1.4.13', '1.4.14', '1.4.15', '1.4.16', '1.4.17', '1.4.18', '1.4.19', '1.4.20', '1.4.21', '1.4.22', '1.4.23', '1.4.24', '1.4.25']} INFO: discovering six DEBUG: Downloading/building wheel for six into cache_dir /root/.cache/pip/wheels/pipgrip DEBUG: ['/usr/local/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/root/.cache/pip/wheels/pipgrip', '--progress-bar=off', 'six'] DEBUG: {'six': '/root/.cache/pip/wheels/pipgrip/six-1.16.0-py2.py3-none-any.whl'} DEBUG: Searching metadata in /root/.cache/pip/wheels/pipgrip/six-1.16.0-py2.py3-none-any.whl DEBUG: Finding possible versions for six DEBUG: ['/usr/local/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--progress-bar=off', 'six==42.42.post424242'] DEBUG: {'six': ['0.9.0', '0.9.1', '0.9.2', '1.0.0', '1.1.0', '1.2.0', '1.3.0', '1.4.0', '1.4.1', '1.5.0', '1.5.1', '1.5.2', '1.6.0', '1.6.1', '1.7.0', '1.7.1', '1.7.2', '1.7.3', '1.8.0', '1.9.0', '1.10.0', '1.11.0', '1.12.0', '1.13.0', '1.14.0', '1.15.0', '1.16.0']} INFO: discovering pytz>=2014.2 DEBUG: Downloading/building wheel for pytz>=2014.2 into cache_dir /root/.cache/pip/wheels/pipgrip DEBUG: ['/usr/local/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/root/.cache/pip/wheels/pipgrip', '--progress-bar=off', 'pytz>=2014.2'] DEBUG: {'pytz>=2014.2': '/root/.cache/pip/wheels/pipgrip/pytz-2021.3-py2.py3-none-any.whl'} DEBUG: Searching metadata in /root/.cache/pip/wheels/pipgrip/pytz-2021.3-py2.py3-none-any.whl DEBUG: Finding possible versions for pytz DEBUG: ['/usr/local/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--progress-bar=off', 'pytz==42.42.post424242'] DEBUG: {'pytz': ['2013.6', '2013.7', '2013.8', '2013.9', '2014.1', '2014.1.1', '2014.2', '2014.3', '2014.4', '2014.7', '2014.9', '2014.10', '2015.2', '2015.4', '2015.6', '2015.7', '2016.1', '2016.2', '2016.3', '2016.4', '2016.6', '2016.6.1', '2016.7', '2016.10', '2017.2', '2017.3', '2018.3', '2018.4', '2018.5', '2018.6', '2018.7', '2018.9', '2019.1', '2019.2', '2019.3', '2020.1', '2020.4', '2020.5', '2021.1', '2021.3']} INFO: discovering python-dateutil>=2.6 DEBUG: Downloading/building wheel for python-dateutil>=2.6 into cache_dir /root/.cache/pip/wheels/pipgrip DEBUG: ['/usr/local/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/root/.cache/pip/wheels/pipgrip', '--progress-bar=off', 'python-dateutil>=2.6'] DEBUG: {'python-dateutil>=2.6': '/root/.cache/pip/wheels/pipgrip/python_dateutil-2.8.2-py2.py3-none-any.whl'} DEBUG: Searching metadata in /root/.cache/pip/wheels/pipgrip/python_dateutil-2.8.2-py2.py3-none-any.whl DEBUG: Finding possible versions for python-dateutil DEBUG: ['/usr/local/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--progress-bar=off', 'python-dateutil==42.42.post424242'] DEBUG: {'python-dateutil': ['1.4', '1.4.1', '1.5', '2.1', '2.2', '2.3', '2.4.0', '2.4.1', '2.4.2', '2.5.0', '2.5.1', '2.5.2', '2.5.3', '2.6.0', '2.6.1', '2.7.0', '2.7.1', '2.7.2', '2.7.3', '2.7.4', '2.7.5', '2.8.0', '2.8.1', '2.8.2']} INFO: discovering pytest>=2.7.1 DEBUG: Downloading/building wheel for pytest>=2.7.1 into cache_dir /root/.cache/pip/wheels/pipgrip DEBUG: ['/usr/local/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/root/.cache/pip/wheels/pipgrip', '--progress-bar=off', 'pytest>=2.7.1'] DEBUG: {'pytest>=2.7.1': '/root/.cache/pip/wheels/pipgrip/pytest-6.2.5-py3-none-any.whl'} DEBUG: Searching metadata in /root/.cache/pip/wheels/pipgrip/pytest-6.2.5-py3-none-any.whl DEBUG: dropped conditional dep importlib-metadata (>=0.12) ; python_version < "3.8" DEBUG: dropped conditional dep atomicwrites (>=1.0) ; sys_platform == "win32" DEBUG: dropped conditional dep colorama ; sys_platform == "win32" DEBUG: dropped conditional dep argcomplete ; extra == 'testing' DEBUG: dropped conditional dep hypothesis (>=3.56) ; extra == 'testing' DEBUG: dropped conditional dep mock ; extra == 'testing' DEBUG: dropped conditional dep nose ; extra == 'testing' DEBUG: dropped conditional dep requests ; extra == 'testing' DEBUG: dropped conditional dep xmlschema ; extra == 'testing' DEBUG: Finding possible versions for pytest DEBUG: ['/usr/local/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--progress-bar=off', 'pytest==42.42.post424242'] DEBUG: {'pytest': ['2.0.0', '2.0.1', '2.0.2', '2.0.3', '2.1.0', '2.1.1', '2.1.2', '2.1.3', '2.2.0', '2.2.1', '2.2.2', '2.2.3', '2.2.4', '2.3.0', '2.3.1', '2.3.2', '2.3.3', '2.3.4', '2.3.5', '2.4.0', '2.4.1', '2.4.2', '2.5.0', '2.5.1', '2.5.2', '2.6.0', '2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.7.0', '2.7.1', '2.7.2', '2.7.3', '2.8.0', '2.8.1', '2.8.2', '2.8.3', '2.8.4', '2.8.5', '2.8.6', '2.8.7', '2.9.0', '2.9.1', '2.9.2', '3.0.0', '3.0.1', '3.0.2', '3.0.3', '3.0.4', '3.0.5', '3.0.6', '3.0.7', '3.1.0', '3.1.1', '3.1.2', '3.1.3', '3.2.0', '3.2.1', '3.2.2', '3.2.3', '3.2.4', '3.2.5', '3.3.0', '3.3.1', '3.3.2', '3.4.0', '3.4.1', '3.4.2', '3.5.0', '3.5.1', '3.6.0', '3.6.1', '3.6.2', '3.6.3', '3.6.4', '3.7.0', '3.7.1', '3.7.2', '3.7.3', '3.7.4', '3.8.0', '3.8.1', '3.8.2', '3.9.1', '3.9.2', '3.9.3', '3.10.0', '3.10.1', '4.0.0', '4.0.1', '4.0.2', '4.1.0', '4.1.1', '4.2.0', '4.2.1', '4.3.0', '4.3.1', '4.4.0', '4.4.1', '4.4.2', '4.5.0', '4.6.0', '4.6.1', '4.6.2', '4.6.3', '4.6.4', '4.6.5', '4.6.6', '4.6.7', '4.6.8', '4.6.9', '4.6.10', '4.6.11', '5.0.0', '5.0.1', '5.1.0', '5.1.1', '5.1.2', '5.1.3', '5.2.0', '5.2.1', '5.2.2', '5.2.3', '5.2.4', '5.3.0', '5.3.1', '5.3.2', '5.3.3', '5.3.4', '5.3.5', '5.4.0', '5.4.1', '5.4.2', '5.4.3', '6.0.0', '6.0.1', '6.0.2', '6.1.0', '6.1.1', '6.1.2', '6.2.0', '6.2.1', '6.2.2', '6.2.3', '6.2.4', '6.2.5']} INFO: discovering pyodbc DEBUG: Downloading/building wheel for pyodbc into cache_dir /root/.cache/pip/wheels/pipgrip DEBUG: ['/usr/local/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/root/.cache/pip/wheels/pipgrip', '--progress-bar=off', 'pyodbc'] ERROR: Collecting pyodbc Using cached pyodbc-4.0.32.tar.gz (280 kB) Building wheels for collected packages: pyodbc Building wheel for pyodbc (setup.py): started Building wheel for pyodbc (setup.py): finished with status 'error' ERROR: Command errored out with exit status 1: command: /usr/local/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-wheel-718u5rm2/pyodbc_b396fff2db2e4ecd9ab5d2bac0f9620d/setup.py'"'"'; __file__='"'"'/tmp/pip-wheel-718u5rm2/pyodbc_b396fff2db2e4ecd9ab5d2bac0f9620d/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-1ep3_wfg cwd: /tmp/pip-wheel-718u5rm2/pyodbc_b396fff2db2e4ecd9ab5d2bac0f9620d/ Complete output (14 lines): running bdist_wheel running build running build_ext building 'pyodbc' extension creating build creating build/temp.linux-x86_64-3.9 creating build/temp.linux-x86_64-3.9/src gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -DPYODBC_VERSION=4.0.32 -I/usr/local/include/python3.9 -c src/buffer.cpp -o build/temp.linux-x86_64-3.9/src/buffer.o -Wno-write-strings In file included from src/buffer.cpp:12: src/pyodbc.h:56:10: fatal error: sql.h: No such file or directory 56 | #include | ^~~~~~~ compilation terminated. error: command '/usr/bin/gcc' failed with exit code 1 ---------------------------------------- ERROR: Failed building wheel for pyodbc Running setup.py clean for pyodbc Failed to build pyodbc ERROR: Failed to build one or more wheels Error: Command '['/usr/local/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/root/.cache/pip/wheels/pipgrip', '--progress-bar=off', 'pyodbc']' returned non-zero exit status 1. ```
ddelange commented 2 years ago

Hi @abitrolly, could you give #67 a spin? If that does the trick for you, I'd merge and release :)

abitrolly commented 2 years ago

Hi @ddelange. #67 already good enough to be merged. Although a perfectionist inside says the error state could be more descriptive. Like having the obvious marker to indicate which package failed and why.

├── pymysql (?)
├x─ pyodbc (ERROR: Failed building wheel)
├── pytest>=2.7.1 (?)

It also interesting to know which packages succeeded to be processes before the failure and which are not.

ddelange commented 2 years ago

^ see new visualisation @ https://github.com/ddelange/pipgrip/pull/67#issuecomment-942612902

It also interesting to know which packages succeeded to be processes before the failure and which are not.

all succeeded ones (and there can only be one failed one) for the current best guess tree will be visualised -- for any other tree in the ensemble, I guess there is no trivial way of getting statistics on the solving process apart from analysing the logs...

ddelange commented 2 years ago

Released 0.6.11, thanks for your input 💥

abitrolly commented 2 years ago

Thanks for fixing this so fast. ) Do you user some helper tools to wrap releases?

ddelange commented 2 years ago

Release builds are triggered from the repo's releases tab (creating and releasing a new tag from there) - github actions (and setuptools_scm) takes care of the rest :) the setup in this repo is slightly outdated, I simplified it in this repo: https://github.com/ddelange/mapply/blob/0.1.9/.github/workflows/CD.yml

abitrolly commented 2 years ago

Nice. Google uses https://github.com/googleapis/release-please tool, but it uses too boring prefixes for releases. :D

ddelange commented 2 years ago

Cool one, didn't know it! For now I avoided release PRs altogether (updating CHANGELOG.md and bumping __version__) by letting Github GUI autofill release title and description after I click 'release', and by using setuptools_scm to detect the new version from git in CD.yml during python setup.py. However, auto release PR + github release could be interesting for integrating https://github.com/frinyvonnick/gitmoji-changelog 🤔