juftin / hatch-pip-compile

hatch plugin to use pip-compile (or uv) to manage project dependencies and lockfiles
http://juftin.com/hatch-pip-compile/
MIT License
76 stars 3 forks source link

🐛 dependency_hash #48

Closed juftin closed 10 months ago

juftin commented 10 months ago

Resolves #47

Changes

dependency_hash

This PR implements dependency_hash function on the plugin which is required for hatch >= 1.8.0. Before this fix the new dependency_hash behavior allows for lockfiles to be out of date without getting updated because their dependency_hash still matches.

Currently, dependency_hash calls run_pip_compile which regenerates the lockfile when needed, it then hashes super().dependency_hash() + the hash of the lockfile contents.

def dependency_hash(self) -> str:
    """
    Get the dependency hash
    """
    self.run_pip_compile()
    hatch_hash = super().dependency_hash()
    if not self.dependencies:
        return hatch_hash
    else:
        lockfile_hash = self.piptools_lock.get_hash()
        return hashlib.sha256(f"{hatch_hash}-{lockfile_hash}".encode()).hexdigest()

Testing

Integration Tests

Testing Environements

The project now includes a testing matrix where hatch 1.7.x, 1.8.x, and 1.9.x are all tested in addition to Python 3.8 though 3.12.

Version Pinning

After the latest tests, this plugin is found to be compatible with hatch>=1.7.0

Lock Files

Due to above mentioned version pinning all lockfiles were regenerated - I used macOS to generate these lockfiles so some linux specific dependencies will be removed.

plugin_check_command

Wrapped with safe_activation to ensure it does the right thing wherever it's used

juftin commented 10 months ago

Hey @oprypin could I get you to take a look at this and let me know your thoughts?

EDIT: after much commit editing I've come to a conclusion that the following is the best solution.

def dependency_hash(self) -> str:
    """
    Get the dependency hash
    """
    self.run_pip_compile()
    hatch_hash = super().dependency_hash()
    if not self.dependencies:
        return hatch_hash
    else:
        lockfile_hash = self.piptools_lock.get_hash()
        return hashlib.sha256(f"{hatch_hash}-{lockfile_hash}".encode()).hexdigest()

The lockfile is always checked whether it's out of date - the final hash takes a SHA256 of the lockfile alongside super().dependency_hash()

juftin commented 10 months ago

:tada: This PR is included in version 1.8.3 :tada:

The release is available on GitHub release

Your semantic-release bot :package::rocket: