Skip to content

Commit

Permalink
feat: lock file format 2.0 (store package files on the package in loc…
Browse files Browse the repository at this point in the history
…kfile) (#6393)
  • Loading branch information
dimbleby committed Sep 24, 2022
1 parent be3d184 commit c061ac5
Show file tree
Hide file tree
Showing 41 changed files with 554 additions and 620 deletions.
31 changes: 18 additions & 13 deletions src/poetry/packages/locker.py
Expand Up @@ -47,7 +47,8 @@


class Locker:
_VERSION = "1.1"
_VERSION = "2.0"
_READ_VERSION_RANGE = ">=1,<3"

_legacy_keys = ["dependencies", "source", "extras", "dev-dependencies"]
_relevant_keys = [*_legacy_keys, "group"]
Expand Down Expand Up @@ -116,8 +117,9 @@ def locked_repository(self) -> LockfileRepository:
if source_type in ["directory", "file"]:
url = self._lock.path.parent.joinpath(url).resolve().as_posix()

name = info["name"]
package = Package(
info["name"],
name,
info["version"],
info["version"],
source_type=source_type,
Expand All @@ -130,9 +132,19 @@ def locked_repository(self) -> LockfileRepository:
package.category = info.get("category", "main")
package.optional = info["optional"]
metadata = cast("dict[str, Any]", lock_data["metadata"])
name = info["name"]
if "hashes" in metadata:
# Old lock so we create dummy files from the hashes

# Storing of package files and hashes has been through a few generations in
# the lockfile, we can read them all:
#
# - latest and preferred is that this is read per package, from
# package.files
# - oldest is that hashes were stored in metadata.hashes without filenames
# - in between those two, hashes were stored alongside filenames in
# metadata.files
package_files = info.get("files")
if package_files is not None:
package.files = package_files
elif "hashes" in metadata:
hashes = cast("dict[str, Any]", metadata["hashes"])
package.files = [{"name": h, "hash": h} for h in hashes[name]]
elif source_type in {"git", "directory", "url"}:
Expand Down Expand Up @@ -233,8 +245,6 @@ def set_lock_data(self, root: Package, packages: list[Package]) -> bool:
assert isinstance(package_files, Array)
files[package["name"]] = package_files.multiline(True)

del package["files"]

lock = document()
lock.add(comment(GENERATED_COMMENT))
lock["package"] = package_specs
Expand All @@ -249,7 +259,6 @@ def set_lock_data(self, root: Package, packages: list[Package]) -> bool:
"lock-version": self._VERSION,
"python-versions": root.python_versions,
"content-hash": self._content_hash,
"files": files,
}

if not self.is_locked() or lock != self.lock_data:
Expand Down Expand Up @@ -297,11 +306,7 @@ def _get_lock_data(self) -> TOMLDocument:
metadata = cast("Table", lock_data["metadata"])
lock_version = Version.parse(metadata.get("lock-version", "1.0"))
current_version = Version.parse(self._VERSION)
# We expect the locker to be able to read lock files
# from the same semantic versioning range
accepted_versions = parse_constraint(
f"^{Version.from_parts(current_version.major, 0)}"
)
accepted_versions = parse_constraint(self._READ_VERSION_RANGE)
lock_version_allowed = accepted_versions.allows(lock_version)
if lock_version_allowed and current_version < lock_version:
logger.warning(
Expand Down
2 changes: 1 addition & 1 deletion tests/console/commands/self/test_remove_plugins.py
Expand Up @@ -55,7 +55,7 @@ def install_plugin(installed: Repository) -> None:
"python-versions": "^3.6",
"platform": "*",
"content-hash": "123456789",
"hashes": {"poetry-plugin": []},
"files": {"poetry-plugin": []},
},
}
system_pyproject_file.parent.joinpath("poetry.lock").write_text(
Expand Down
2 changes: 1 addition & 1 deletion tests/console/commands/test_lock.py
Expand Up @@ -146,7 +146,7 @@ def test_lock_no_update(

assert len(packages) == len(locked_repository.packages)

assert locker.lock_data["metadata"].get("lock-version") == "1.1"
assert locker.lock_data["metadata"].get("lock-version") == "2.0"

for package in packages:
assert locked_repository.find_packages(package.to_dependency())
54 changes: 27 additions & 27 deletions tests/console/commands/test_show.py
Expand Up @@ -87,7 +87,7 @@ def test_show_basic_with_installed_packages(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"cachy": [], "pendulum": [], "pytest": []},
"files": {"cachy": [], "pendulum": [], "pytest": []},
},
}
)
Expand Down Expand Up @@ -168,7 +168,7 @@ def _configure_project_with_groups(poetry: Poetry, installed: Repository) -> Non
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"cachy": [], "pendulum": [], "pytest": []},
"files": {"cachy": [], "pendulum": [], "pytest": []},
},
}
)
Expand Down Expand Up @@ -293,7 +293,7 @@ def test_show_basic_with_installed_packages_single(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"cachy": []},
"files": {"cachy": []},
},
}
)
Expand Down Expand Up @@ -335,7 +335,7 @@ def test_show_basic_with_installed_packages_single_canonicalized(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"foo-bar": []},
"files": {"foo-bar": []},
},
}
)
Expand Down Expand Up @@ -390,7 +390,7 @@ def test_show_basic_with_not_installed_packages_non_decorated(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"cachy": [], "pendulum": []},
"files": {"cachy": [], "pendulum": []},
},
}
)
Expand Down Expand Up @@ -446,7 +446,7 @@ def test_show_basic_with_not_installed_packages_decorated(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"cachy": [], "pendulum": []},
"files": {"cachy": [], "pendulum": []},
},
}
)
Expand Down Expand Up @@ -516,7 +516,7 @@ def test_show_latest_non_decorated(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"cachy": [], "pendulum": []},
"files": {"cachy": [], "pendulum": []},
},
}
)
Expand Down Expand Up @@ -586,7 +586,7 @@ def test_show_latest_decorated(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"cachy": [], "pendulum": []},
"files": {"cachy": [], "pendulum": []},
},
}
)
Expand Down Expand Up @@ -655,7 +655,7 @@ def test_show_outdated(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"cachy": [], "pendulum": []},
"files": {"cachy": [], "pendulum": []},
},
}
)
Expand Down Expand Up @@ -699,7 +699,7 @@ def test_show_outdated_with_only_up_to_date_packages(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"cachy": []},
"files": {"cachy": []},
},
}
)
Expand Down Expand Up @@ -768,7 +768,7 @@ def test_show_outdated_has_prerelease_but_not_allowed(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"cachy": [], "pendulum": []},
"files": {"cachy": [], "pendulum": []},
},
}
)
Expand Down Expand Up @@ -843,7 +843,7 @@ def test_show_outdated_has_prerelease_and_allowed(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"cachy": [], "pendulum": []},
"files": {"cachy": [], "pendulum": []},
},
}
)
Expand Down Expand Up @@ -912,7 +912,7 @@ def test_show_outdated_formatting(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"cachy": [], "pendulum": []},
"files": {"cachy": [], "pendulum": []},
},
}
)
Expand Down Expand Up @@ -1029,7 +1029,7 @@ def test_show_outdated_local_dependencies(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {
"files": {
"cachy": [],
"pendulum": [],
"demo": [],
Expand Down Expand Up @@ -1136,7 +1136,7 @@ def test_show_outdated_git_dev_dependency(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"cachy": [], "pendulum": [], "demo": [], "pytest": []},
"files": {"cachy": [], "pendulum": [], "demo": [], "pytest": []},
},
}
)
Expand Down Expand Up @@ -1235,7 +1235,7 @@ def test_show_outdated_no_dev_git_dev_dependency(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"cachy": [], "pendulum": [], "demo": [], "pytest": []},
"files": {"cachy": [], "pendulum": [], "demo": [], "pytest": []},
},
}
)
Expand Down Expand Up @@ -1296,7 +1296,7 @@ def test_show_hides_incompatible_package(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"cachy": [], "pendulum": []},
"files": {"cachy": [], "pendulum": []},
},
}
)
Expand Down Expand Up @@ -1353,7 +1353,7 @@ def test_show_all_shows_incompatible_package(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"cachy": [], "pendulum": []},
"files": {"cachy": [], "pendulum": []},
},
}
)
Expand Down Expand Up @@ -1429,7 +1429,7 @@ def test_show_non_dev_with_basic_installed_packages(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"cachy": [], "pendulum": [], "pytest": []},
"files": {"cachy": [], "pendulum": [], "pytest": []},
},
}
)
Expand Down Expand Up @@ -1505,7 +1505,7 @@ def test_show_with_group_only(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"cachy": [], "pendulum": [], "pytest": []},
"files": {"cachy": [], "pendulum": [], "pytest": []},
},
}
)
Expand Down Expand Up @@ -1580,7 +1580,7 @@ def test_show_with_optional_group(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"cachy": [], "pendulum": [], "pytest": []},
"files": {"cachy": [], "pendulum": [], "pytest": []},
},
}
)
Expand Down Expand Up @@ -1642,7 +1642,7 @@ def test_show_tree(tester: CommandTester, poetry: Poetry, installed: Repository)
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"cachy": [], "msgpack-python": []},
"files": {"cachy": [], "msgpack-python": []},
},
}
)
Expand Down Expand Up @@ -1709,7 +1709,7 @@ def test_show_tree_no_dev(tester: CommandTester, poetry: Poetry, installed: Repo
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"cachy": [], "msgpack-python": [], "pytest": []},
"files": {"cachy": [], "msgpack-python": [], "pytest": []},
},
}
)
Expand Down Expand Up @@ -1768,7 +1768,7 @@ def test_show_tree_why_package(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"a": [], "b": [], "c": []},
"files": {"a": [], "b": [], "c": []},
},
}
)
Expand Down Expand Up @@ -1825,7 +1825,7 @@ def test_show_tree_why(tester: CommandTester, poetry: Poetry, installed: Reposit
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"a": [], "b": [], "c": []},
"files": {"a": [], "b": [], "c": []},
},
}
)
Expand Down Expand Up @@ -1894,7 +1894,7 @@ def test_show_required_by_deps(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"cachy": [], "pendulum": [], "msgpack-python": []},
"files": {"cachy": [], "pendulum": [], "msgpack-python": []},
},
}
)
Expand Down Expand Up @@ -1983,7 +1983,7 @@ def test_show_dependency_installed_from_git_in_dev(
"python-versions": "*",
"platform": "*",
"content-hash": "123456789",
"hashes": {"demo": [], "pendulum": []},
"files": {"demo": [], "pendulum": []},
},
}
)
Expand Down

0 comments on commit c061ac5

Please sign in to comment.