Skip to content

Commit

Permalink
feat: add --no-hash option to update, preventing metadata.content-hash
Browse files Browse the repository at this point in the history
Currently when creating a lockfile, a metadata.content-hash field is
generated, containing the hash of the sorted contents of pyproject.toml.

However (see python-poetry#496) this causes merge conflicts, particularly
when using a tool such as dependabot that makes multiple parallel
branches with dependency changes.

Add a --no-hash option to poetry update. This causes metadata.content-hash
to be omitted. In turn poetry will later complain that the lock file
may not be fresh, (although it is correct), and the user can run poetry lock
to update it, after all the merges are complete.

dependabot currently runs `poetry update <DEPENDENCY> --lock`, I would
propose to incrporate this PR to poetry and then modify dependabot
to have teh --no-hash option.
  • Loading branch information
donbowman committed Aug 18, 2020
1 parent 0d48fb6 commit ff3f2af
Show file tree
Hide file tree
Showing 6 changed files with 12 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ update the constraint, for example `^2.3`. You can do this using the `add` comma
* `--dry-run` : Outputs the operations but will not execute anything (implicitly enables --verbose).
* `--no-dev` : Do not install dev dependencies.
* `--lock` : Do not perform install (only update the lockfile).
* `--no-hash` : Do not write a content-hash to the lockfile. Useful with merge conflics.

## add

Expand Down
2 changes: 2 additions & 0 deletions poetry/console/commands/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class UpdateCommand(InstallerCommand):
"(implicitly enables --verbose).",
),
option("lock", None, "Do not perform operations (only update the lockfile)."),
option("no-hash", None, "Do not write a content-hash to the lockfile."),
]

loggers = ["poetry.repositories.pypi_repository"]
Expand All @@ -39,6 +40,7 @@ def handle(self):

self._installer.dev_mode(not self.option("no-dev"))
self._installer.dry_run(self.option("dry-run"))
self.poetry.locker.set_write_hash(not self.option("no-hash"))
self._installer.execute_operations(not self.option("lock"))

# Force update
Expand Down
6 changes: 6 additions & 0 deletions poetry/packages/locker.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def __init__(self, lock, local_config): # type: (Path, dict) -> None
self._local_config = local_config
self._lock_data = None
self._content_hash = self._get_content_hash()
self._write_hash = True

@property
def lock(self): # type: () -> TomlFile
Expand Down Expand Up @@ -190,6 +191,8 @@ def set_lock_data(self, root, packages): # type: (...) -> bool
"content-hash": self._content_hash,
"files": files,
}
if not self._write_hash:
del lock["metadata"]["content-hash"]

if not self.is_locked() or lock != self.lock_data:
self._write_lock_data(lock)
Expand All @@ -207,6 +210,9 @@ def _write_lock_data(self, data):

self._lock_data = None

def set_write_hash(self, write_hash=True):
self._write_hash = write_hash

def _get_content_hash(self): # type: () -> str
"""
Returns the sha256 hash of the sorted content of the pyproject file.
Expand Down
1 change: 1 addition & 0 deletions tests/console/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ def __init__(self, lock, local_config):
self._locked = False
self._lock_data = None
self._write = False
self._write_hash = True

def write(self, write=True):
self._write = write
Expand Down
1 change: 1 addition & 0 deletions tests/installation/test_installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ def __init__(self):
self._written_data = None
self._locked = False
self._content_hash = self._get_content_hash()
self._write_hash = True

@property
def written_data(self):
Expand Down
1 change: 1 addition & 0 deletions tests/utils/test_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class Locker(BaseLocker):
def __init__(self):
self._locked = True
self._content_hash = self._get_content_hash()
self._write_hash = True

def locked(self, is_locked=True):
self._locked = is_locked
Expand Down

0 comments on commit ff3f2af

Please sign in to comment.