-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: update poetry-core via poetry self update #5306
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -16,7 +16,6 @@ | |||||
|
||||||
if TYPE_CHECKING: | ||||||
from poetry.core.packages.package import Package | ||||||
from poetry.core.semver.version import Version | ||||||
|
||||||
from poetry.repositories.pool import Pool | ||||||
|
||||||
|
@@ -35,6 +34,7 @@ class SelfUpdateCommand(Command): | |||||
"Output the operations but do not execute anything " | ||||||
"(implicitly enables --verbose).", | ||||||
), | ||||||
option("core", None, "The poetry-core version to update to.", flag=False), | ||||||
] | ||||||
|
||||||
_data_dir = None | ||||||
|
@@ -88,22 +88,114 @@ def pool(self) -> Pool: | |||||
return pool | ||||||
|
||||||
def handle(self) -> int: | ||||||
from poetry.core.packages.dependency import Dependency | ||||||
from poetry.utils._compat import metadata | ||||||
|
||||||
poetry_release = self._find_poetry_release() | ||||||
core_release = self._find_compatible_core_release(poetry_release) | ||||||
|
||||||
update_releases = [ | ||||||
release | ||||||
for release in {poetry_release, core_release} | ||||||
if release.version.text != metadata.version(release.name) | ||||||
] | ||||||
|
||||||
if not update_releases: | ||||||
self.line("You are using the latest version") | ||||||
return 0 | ||||||
|
||||||
msg = [ | ||||||
f"<c1>{release.pretty_name}</c1> to <c2>{release.version}</c2>" | ||||||
for release in update_releases | ||||||
] | ||||||
self.line(f"Updating {' and '.join(msg)}.") | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
self.line("") | ||||||
|
||||||
self.update(update_releases) | ||||||
|
||||||
if poetry_release in update_releases: | ||||||
self._make_bin() | ||||||
|
||||||
self.line("") | ||||||
self.line(f"Successfully updated {' and '.join(msg)}. Great!") | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
return 0 | ||||||
|
||||||
def update(self, releases: list[Package]) -> None: | ||||||
from poetry.utils.env import EnvManager | ||||||
|
||||||
env = EnvManager.get_system_env(naive=True) | ||||||
|
||||||
# We can't use is_relative_to() since it's only available in Python 3.9+ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment could be a little more descriptive -- we're throwing away the result of the |
||||||
try: | ||||||
env.path.relative_to(self.data_dir) | ||||||
except ValueError: | ||||||
# Poetry was not installed using the recommended installer | ||||||
from poetry.console.exceptions import PoetrySimpleConsoleException | ||||||
|
||||||
raise PoetrySimpleConsoleException( | ||||||
"Poetry was not installed with the recommended installer, " | ||||||
"so it cannot be updated automatically." | ||||||
) | ||||||
|
||||||
self._update(releases) | ||||||
|
||||||
def _find_poetry_release(self) -> Package: | ||||||
from poetry.core.semver.version import Version | ||||||
|
||||||
from poetry.__version__ import __version__ | ||||||
from poetry.utils._compat import metadata | ||||||
|
||||||
is_prerelease = False | ||||||
version = self.argument("version") | ||||||
if not version: | ||||||
version = ">=" + __version__ | ||||||
is_prerelease = Version.parse(metadata.version("poetry")).is_prerelease() | ||||||
version = ">=" + metadata.version("poetry") | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use str.format() here -- it's a bit more readable. |
||||||
|
||||||
release = self._find_release( | ||||||
"poetry", version, is_prerelease or self.option("preview") | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use these as kwargs for readability. |
||||||
) | ||||||
return release | ||||||
|
||||||
def _find_compatible_core_release(self, poetry_release: Package) -> Package: | ||||||
from poetry.core.semver.version import Version | ||||||
|
||||||
from poetry.console.exceptions import PoetrySimpleConsoleException | ||||||
|
||||||
core = self.option("core") | ||||||
|
||||||
for dependency in poetry_release.all_requires: | ||||||
if dependency.name == "poetry-core": | ||||||
if core and not dependency.constraint.allows(Version.parse(core)): | ||||||
raise PoetrySimpleConsoleException( | ||||||
f"poetry-core {core} is not supported by poetry" | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
f" {poetry_release.version}." | ||||||
) | ||||||
|
||||||
core = core or str(dependency.constraint) | ||||||
break | ||||||
else: | ||||||
raise PoetrySimpleConsoleException( | ||||||
"No compatible version of poetry-core for poetry" | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
f" {poetry_release.version}." | ||||||
) | ||||||
|
||||||
core_release = self._find_release("poetry-core", core, True) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use kwargs here, please. |
||||||
|
||||||
return core_release | ||||||
|
||||||
def _find_release(self, name: str, version: str, preview: bool) -> Package: | ||||||
from poetry.core.packages.dependency import Dependency | ||||||
|
||||||
from poetry.console.exceptions import PoetrySimpleConsoleException | ||||||
|
||||||
repo = self.pool.repositories[0] | ||||||
|
||||||
packages = repo.find_packages( | ||||||
Dependency("poetry", version, allows_prereleases=self.option("preview")) | ||||||
Dependency(name, version, allows_prereleases=preview) | ||||||
) | ||||||
if not packages: | ||||||
self.line("No release found for the specified version") | ||||||
return 1 | ||||||
raise PoetrySimpleConsoleException( | ||||||
"No release found for the specified version." | ||||||
) | ||||||
|
||||||
def cmp(x: Package, y: Package) -> int: | ||||||
if x.version == y.version: | ||||||
|
@@ -115,7 +207,7 @@ def cmp(x: Package, y: Package) -> int: | |||||
release = None | ||||||
for package in packages: | ||||||
if package.is_prerelease(): | ||||||
if self.option("preview"): | ||||||
if preview: | ||||||
release = package | ||||||
|
||||||
break | ||||||
|
@@ -126,49 +218,9 @@ def cmp(x: Package, y: Package) -> int: | |||||
|
||||||
break | ||||||
|
||||||
if release is None: | ||||||
self.line("No new release found") | ||||||
return 1 | ||||||
|
||||||
if release.version == Version.parse(__version__): | ||||||
self.line("You are using the latest version") | ||||||
return 0 | ||||||
|
||||||
self.line(f"Updating <c1>Poetry</c1> to <c2>{release.version}</c2>") | ||||||
self.line("") | ||||||
|
||||||
self.update(release) | ||||||
|
||||||
self.line("") | ||||||
self.line( | ||||||
f"<c1>Poetry</c1> (<c2>{release.version}</c2>) is installed now. Great!" | ||||||
) | ||||||
|
||||||
return 0 | ||||||
|
||||||
def update(self, release: Package) -> None: | ||||||
from poetry.utils.env import EnvManager | ||||||
|
||||||
version = release.version | ||||||
|
||||||
env = EnvManager.get_system_env(naive=True) | ||||||
|
||||||
# We can't use is_relative_to() since it's only available in Python 3.9+ | ||||||
try: | ||||||
env.path.relative_to(self.data_dir) | ||||||
except ValueError: | ||||||
# Poetry was not installed using the recommended installer | ||||||
from poetry.console.exceptions import PoetrySimpleConsoleException | ||||||
|
||||||
raise PoetrySimpleConsoleException( | ||||||
"Poetry was not installed with the recommended installer, " | ||||||
"so it cannot be updated automatically." | ||||||
) | ||||||
return release | ||||||
|
||||||
self._update(version) | ||||||
self._make_bin() | ||||||
|
||||||
def _update(self, version: Version) -> None: | ||||||
def _update(self, releases: list[Package]) -> None: | ||||||
from poetry.core.packages.dependency import Dependency | ||||||
from poetry.core.packages.project_package import ProjectPackage | ||||||
|
||||||
|
@@ -183,7 +235,9 @@ def _update(self, version: Version) -> None: | |||||
|
||||||
root = ProjectPackage("poetry-updater", "0.0.0") | ||||||
root.python_versions = ".".join(str(c) for c in env.version_info[:3]) | ||||||
root.add_dependency(Dependency("poetry", version.text)) | ||||||
|
||||||
for release in releases: | ||||||
root.add_dependency(Dependency(release.name, release.version.text)) | ||||||
|
||||||
installer = Installer( | ||||||
self.io, | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.