DjangoAdminHackers / django-linkcheck

An app that will analyze and report on links in any model that you register with it. Links can be bare (urls or image and file fields) or embedded in HTML (linkcheck handles the parsing). It's fairly easy to override methods of the Linkcheck object should you need to do anything more complicated (like generate URLs from slug fields etc).
BSD 3-Clause "New" or "Revised" License
75 stars 26 forks source link

Cannot install django-linkcheck on CI #200

Closed david-venhoff closed 9 months ago

david-venhoff commented 10 months ago

When trying to install django-linkcheck on CI, the following error shows up:

  × Building wheel for django-linkcheck (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [22 lines of output]
      Compile translation files
      Traceback (most recent call last):
        File "/opt/hostedtoolcache/Python/3.11.7/x64/lib/python3.11/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 353, in <module>
          main()
        File "/opt/hostedtoolcache/Python/3.11.7/x64/lib/python3.11/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 335, in main
          json_out['return_val'] = hook(**hook_input['kwargs'])
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/opt/hostedtoolcache/Python/3.11.7/x64/lib/python3.11/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 251, in build_wheel
          return _build_backend().build_wheel(wheel_directory, config_settings,
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/tmp/pip-install-rhq58wze/django-linkcheck_f1a0ea04f8c448d6b9cd55a44b9e3709/linkcheck/build_meta.py", line 18, in build_wheel
          compile_translation_files()
        File "/tmp/pip-install-rhq58wze/django-linkcheck_f1a0ea04f8c448d6b9cd55a44b9e3709/linkcheck/build_meta.py", line 9, in compile_translation_files
          subprocess.run(["django-admin", "compilemessages"], cwd="linkcheck")
        File "/opt/hostedtoolcache/Python/3.11.7/x64/lib/python3.11/subprocess.py", line 548, in run
          with Popen(*popenargs, **kwargs) as process:
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/opt/hostedtoolcache/Python/3.11.7/x64/lib/python3.11/subprocess.py", line 1026, in __init__
          self._execute_child(args, executable, preexec_fn, close_fds,
        File "/opt/hostedtoolcache/Python/3.11.7/x64/lib/python3.11/subprocess.py", line 1950, in _execute_child
          raise child_exception_type(errno_num, err_msg, err_filename)
      FileNotFoundError: [Errno 2] No such file or directory: 'django-admin'

So it seems like django-admin does not get installed correctly or in time. Installation usually works locally, because people often have django already installed previously (Which sets up the django-admin command). This issue only happens in version 2.3 of django-linkcheck and is probably related to this commit: https://github.com/DjangoAdminHackers/django-linkcheck/commit/6a60a2489fb5c66dec1c93879ebd644f5e7e8bec

timobrembeck commented 10 months ago

Hmm, this is definitely weird, I cannot reproduce this issue despite the fact that I don't have django installed globally. And also when I remove django in my venv before installing django-linkcheck, the setup command installs it again before compiling the translation file.

My Python version is 3.11.6 and setuptools version is 69.0.3.

timobrembeck commented 9 months ago

The problem seems to exist on environments where django is not yet installed locally and the package wheel has to be built before the package can be installed. This is due to the normal workflow of pip when executing pip install django-linkcheck:

  1. Download the package source
  2. Download the source/wheels of the dependencies
  3. Build all wheel files which are missing on PyPI (including django-linkcheck's wheel)
  4. Install all dependencies
  5. Install django-linkcheck

Since step 4 comes after 3, django-admin is not yet available when the wheel file is supposed to be built. So one option would be to install django manually before calling the subprocess, but I think the more robust and elegant solution would be to build the wheel on the maintainer's machine and upload it to PyPI as well. Apart from the error, it also has the advantage to speed up installations in general, because the intermediary step of generating the wheel is no longer necessary on the end user's machine.

@claudep Would you be open to this idea and upload the wheel for version 2.3.0 as well?

claudep commented 9 months ago

I just uploaded the wheel version. Is it OK now?

timobrembeck commented 9 months ago

@claudep awesome, thanks for the quick reply! :pray: Yes, this fixed our issues!