Skip to content

Commit

Permalink
fix: fix a bug of show command not showing metadata of current project (
Browse files Browse the repository at this point in the history
  • Loading branch information
frostming authored Feb 26, 2023
1 parent beac66d commit e9f64c9
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 39 deletions.
1 change: 1 addition & 0 deletions news/1740.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a bug of show command not showing metadata of the current project.
8 changes: 4 additions & 4 deletions src/pdm/cli/commands/show.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,18 @@ def handle(self, project: Project, options: argparse.Namespace) -> None:
return
latest_stable = next(filter(filter_stable, matches), None)
metadata = latest.prepare(project.environment).metadata
project_info = ProjectInfo.from_distribution(metadata)
else:
if not project.name:
raise PdmUsageError("This project is not a package")
package = normalize_name(project.name)
metadata = project.make_self_candidate().prepare(project.environment).metadata
project_info = ProjectInfo.from_metadata(project.pyproject.metadata)
latest_stable = None
assert metadata
project_info = ProjectInfo(metadata)

if any(getattr(options, key, None) for key in self.metadata_keys):
for key in self.metadata_keys:
if getattr(options, key, None):
project.core.ui.echo(project_info[key])
project.core.ui.echo(getattr(project_info, key))
return

installed = project.environment.get_working_set().get(package)
Expand Down
101 changes: 66 additions & 35 deletions src/pdm/models/project_info.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,35 @@
from __future__ import annotations

import itertools
from dataclasses import dataclass, field
from email.message import Message
from typing import TYPE_CHECKING, Any, Iterator, cast

if TYPE_CHECKING:
from pdm.compat import Distribution


DYNAMIC = "DYNAMIC"


@dataclass
class ProjectInfo:
def __init__(self, metadata: Distribution) -> None:
self.latest_stable_version = ""
self.installed_version = ""
self._parsed = self._parse(metadata)
name: str
version: str
summary: str = ""
author: str = ""
email: str = ""
license: str = ""
requires_python: str = ""
platform: str = ""
keywords: str = ""
homepage: str = ""
project_urls: list[str] = field(default_factory=list)
latest_stable_version: str = ""
installed_version: str = ""

def _parse(self, data: Distribution) -> dict[str, Any]:
@classmethod
def from_distribution(cls, data: Distribution) -> ProjectInfo:
metadata = cast(Message, data.metadata)
keywords = metadata.get("Keywords", "").replace(",", ", ")
platform = metadata.get("Platform", "").replace(",", ", ")
Expand All @@ -26,40 +41,56 @@ def _parse(self, data: Distribution) -> dict[str, Any]:
else:
project_urls = {}

return {
"name": metadata["Name"],
"version": metadata["Version"],
"summary": metadata.get("Summary", ""),
"author": metadata.get("Author", ""),
"email": metadata.get("Author-email", ""),
"license": metadata.get("License", ""),
"requires-python": metadata.get("Requires-Python", ""),
"platform": platform,
"keywords": keywords,
"homepage": metadata.get("Home-page", ""),
"project-urls": [": ".join(parts) for parts in project_urls.items()],
}
return cls(
name=metadata["Name"],
version=metadata["Version"],
summary=metadata.get("Summary", ""),
author=metadata.get("Author", ""),
email=metadata.get("Author-email", ""),
license=metadata.get("License", ""),
requires_python=metadata.get("Requires-Python", ""),
platform=platform,
keywords=keywords,
homepage=metadata.get("Home-page", ""),
project_urls=[": ".join(parts) for parts in project_urls.items()],
)

@classmethod
def from_metadata(cls, metadata: dict[str, Any]) -> ProjectInfo:
def get_str(key: str) -> str:
if key in metadata.get("dynamic", []):
return DYNAMIC
return metadata.get(key, "")

def __getitem__(self, key: str) -> Any:
return self._parsed[key]
authors = metadata.get("authors", [])
author = authors[0]["name"] if authors else ""
email = authors[0]["email"] if authors else ""

return cls(
name=metadata["name"],
version=get_str("version"),
summary=get_str("description"),
author=author,
email=email,
license=metadata.get("license", {}).get("text", ""),
requires_python=get_str("requires-python"),
keywords=",".join(get_str("keywords")),
project_urls=[": ".join(parts) for parts in metadata.get("urls", {}).items()],
)

def generate_rows(self) -> Iterator[tuple[str, str]]:
yield "[primary]Name[/]:", self._parsed["name"]
yield "[primary]Latest version[/]:", self._parsed["version"]
yield "[primary]Name[/]:", self.name
yield "[primary]Latest version[/]:", self.version
if self.latest_stable_version:
yield ("[primary]Latest stable version[/]:", self.latest_stable_version)
if self.installed_version:
yield ("[primary]Installed version[/]:", self.installed_version)
yield "[primary]Summary[/]:", self._parsed.get("summary", "")
yield "[primary]Requires Python:", self._parsed["requires-python"]
yield "[primary]Author[/]:", self._parsed.get("author", "")
yield "[primary]Author email[/]:", self._parsed.get("email", "")
yield "[primary]License[/]:", self._parsed.get("license", "")
yield "[primary]Homepage[/]:", self._parsed.get("homepage", "")
yield from itertools.zip_longest(
("[primary]Project URLs[/]:",),
self._parsed.get("project-urls", []),
fillvalue="",
)
yield "[primary]Platform[/]:", self._parsed.get("platform", "")
yield "[primary]Keywords[/]:", self._parsed.get("keywords", "")
yield "[primary]Summary[/]:", self.summary
yield "[primary]Requires Python:", self.requires_python
yield "[primary]Author[/]:", self.author
yield "[primary]Author email[/]:", self.email
yield "[primary]License[/]:", self.license
yield "[primary]Homepage[/]:", self.homepage
yield from itertools.zip_longest(("[primary]Project URLs[/]:",), self.project_urls, fillvalue="")
yield "[primary]Platform[/]:", self.platform
yield "[primary]Keywords[/]:", self.keywords

0 comments on commit e9f64c9

Please sign in to comment.