jorisroovers / gitlint

Linting for your git commit messages
http://jorisroovers.github.io/gitlint
MIT License
790 stars 99 forks source link

Enable support for git archive installs #464

Closed jorisroovers closed 1 year ago

jorisroovers commented 1 year ago

See:

Suggested by @webknjaz

webknjaz commented 1 year ago

@jorisroovers this https://github.com/jorisroovers/gitlint/pull/470 implements everything needed.

jorisroovers commented 1 year ago

For reference, here's an example of this failing:

❯ pip install https://github.com/jorisroovers/gitlint/archive/refs/tags/v0.19.1.tar.gz                                                                                                           
Collecting https://github.com/jorisroovers/gitlint/archive/refs/tags/v0.19.1.tar.gz
  Downloading https://github.com/jorisroovers/gitlint/archive/refs/tags/v0.19.1.tar.gz
     - 743.0 kB 2.5 MB/s 0:00:01
  Installing build dependencies ... \
done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... error
  error: subprocess-exited-with-error

  × Preparing metadata (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [24 lines of output]
      Traceback (most recent call last):
        File "/tmp/.venvgitlint470/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 363, in <module>
          main()
        File "/tmp/.venvgitlint470/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 345, in main
          json_out['return_val'] = hook(**hook_input['kwargs'])
        File "/tmp/.venvgitlint470/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 164, in prepare_metadata_for_build_wheel
          return hook(metadata_directory, config_settings)
        File "/tmp/pip-build-env-uyvnkjti/overlay/lib/python3.10/site-packages/hatchling/build.py", line 105, in prepare_metadata_for_build_wheel
          directory = os.path.join(metadata_directory, f'{builder.artifact_project_id}.dist-info')
        File "/tmp/pip-build-env-uyvnkjti/overlay/lib/python3.10/site-packages/hatchling/builders/wheel.py", line 660, in artifact_project_id
          self.project_id
        File "/tmp/pip-build-env-uyvnkjti/overlay/lib/python3.10/site-packages/hatchling/builders/plugin/interface.py", line 370, in project_id
          self.__project_id = f'{self.normalize_file_name_component(self.metadata.core.name)}-{self.metadata.version}'
        File "/tmp/pip-build-env-uyvnkjti/overlay/lib/python3.10/site-packages/hatchling/metadata/core.py", line 170, in core
          self._version = self._get_version(metadata)
        File "/tmp/pip-build-env-uyvnkjti/overlay/lib/python3.10/site-packages/hatchling/metadata/core.py", line 226, in _get_version
          version = self.hatch.version.cached
        File "/tmp/pip-build-env-uyvnkjti/overlay/lib/python3.10/site-packages/hatchling/metadata/core.py", line 1412, in cached
          raise type(e)(message) from None
      LookupError: Error getting the version from source `vcs`: setuptools-scm was unable to detect version for /tmp/pip-req-build-iqelh4ub.

      Make sure you're either building from a fully intact git repository or PyPI tarballs. Most other sources (such as GitHub's tarballs, a git checkout without the .git folder) don't contain the necessary metadata and will not work.

      For example, if you're using pip, instead of https://github.com/user/proj/archive/master.zip use git+https://github.com/user/proj.git#egg=proj
      [end of output]

  note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed

× Encountered error while generating package metadata.
╰─> See above for output.

note: This is an issue with the package mentioned above, not pip.
hint: See above for details.

While #470 makes the install itself succeed (thanks for the PR!), pip still errors on missing the gitlint-core dependency with the same version:

❯ pip install https://github.com/jorisroovers/gitlint/archive/c2596c308f6038a0d5d7317533900b5fa6072eab.tar.gz                                         
Collecting https://github.com/jorisroovers/gitlint/archive/c2596c308f6038a0d5d7317533900b5fa6072eab.tar.gz
  Downloading https://github.com/jorisroovers/gitlint/archive/c2596c308f6038a0d5d7317533900b5fa6072eab.tar.gz
     | 743.7 kB 2.7 MB/s 0:00:00
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
ERROR: Could not find a version that satisfies the requirement gitlint-core[trusted-deps]==0.19.2.dev1+gc2596c30 (from gitlint) (from versions: 0.17.0, 0.18.0, 0.19.0.dev73, 0.19.0.dev75, 0.19.0.dev76, 0.19.0.dev77, 0.19.0.dev78, 0.19.0.dev79, 0.19.0.dev80, 0.19.0.dev81, 0.19.0.dev82, 0.19.0rc1, 0.19.0rc2.dev1, 0.19.0rc2, 0.19.0rc3.dev1, 0.19.0, 0.19.1.dev1, 0.19.1.dev2, 0.19.1, 0.20.0.dev2, 0.20.0.dev3)
ERROR: No matching distribution found for gitlint-core[trusted-deps]==0.19.2.dev1+gc2596c30

This is because gitlint is really just a wrapper around gitlint-core[trusted-deps] where we strictly pin gitlint's dependencies. The version of gitlint and gitlint-core are always the same, this is by design:

https://github.com/jorisroovers/gitlint/blob/acc9d9de6369b76d22cb4167029d2035e8730b98/hatch_build.py#L9-L13

So pip doesn't know where to find that particular for gitlint-core. I'm not sure how to resolve this (or whether it's even possible). Maybe there's a way to tell pip gitlint-core version is present in the same tarball file?

During development, we solve this by skipping the pinned dependency install and doing an install of the local gitlint-core directory: https://github.com/jorisroovers/gitlint/blob/acc9d9de6369b76d22cb4167029d2035e8730b98/pyproject.toml#L83-L85

webknjaz commented 1 year ago

Maybe there's a way to tell pip gitlint-core version is present in the same tarball file?

I know that there's a syntax for pointing pip at a Git repository subdirectory, not sure about the tarballs, though. OTOH, we should at least try to make the gitlint-core bit compatible with this...

webknjaz commented 1 year ago

@jorisroovers I've updated the PR and verified that all of the following work:

$ pip install 'https://github.com/jorisroovers/gitlint/archive/4316b0d9c953441a5c7f249145b8eb52066fa2dc.tar.gz#subdirectory=gitlint-core'
$ pip install 'gitlint-core @ https://github.com/jorisroovers/gitlint/archive/4316b0d9c953441a5c7f249145b8eb52066fa2dc.tar.gz#subdirectory=gitlint-core'
$ pip install 'gitlint-core [trusted-deps] @ https://github.com/jorisroovers/gitlint/archive/4316b0d9c953441a5c7f249145b8eb52066fa2dc.tar.gz#subdirectory=gitlint-core'
$ pip install 'gitlint-core @ https://github.com/jorisroovers/gitlint/archive/4316b0d9c953441a5c7f249145b8eb52066fa2dc.tar.gz#subdirectory=gitlint-core' https://github.com/jorisroovers/gitlint/archive/4316b0d9c953441a5c7f249145b8eb52066fa2dc.tar.gz
jorisroovers commented 1 year ago

Great, I tried this out locally and can confirm this works!

Merged the PR, thanks!

webknjaz commented 1 year ago

Might be reasonable to document the commands since this is a lesser known feature — pip only documents it in the context of VCS URLs, not HTTP. Plus it doesn't feature examples of having two dists in the same resource, certainly not a tarball..

jorisroovers commented 1 year ago

Might be reasonable to document the commands since this is a lesser known feature — pip only documents it in the context of VCS URLs, not HTTP. Plus it doesn't feature examples of having two dists in the same resource, certainly not a tarball..

Will do!