Skip to content

Commit 5772203

Browse files
committed
List runtime dependencies in pyproject toml
We could include requirements.txt as well but that requires more complex parsing as we would need to resolve `-r some_other_file.txt` and similar [1]. [1] https://pip.pypa.io/en/stable/reference/requirements-file-format/
1 parent b8b6976 commit 5772203

4 files changed

Lines changed: 54 additions & 5 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ https://github.com/scientific-python/changelist/blob/main/CHANGELOG.md.
1111
- Categorize pull requests into sections based on GitHub labels.
1212
- Point it at any repository on GitHub. No need to clone or checkout a
1313
repository locally, a Python package is all that's needed.
14+
- List latest runtime dependencies of your release.
1415

1516
We recommend to treat the generated document as a first draft to build
1617
on and not as an already perfect documentation of the release.

src/changelist/_cli.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
from github import Github
1212
from tqdm import tqdm
1313

14+
from . import _query
1415
from ._config import add_config_defaults, local_config, remote_config
1516
from ._format import MdFormatter, RstFormatter
16-
from ._query import commits_between, contributors, pull_requests_from_commits
1717

1818
logger = logging.getLogger(__name__)
1919

@@ -141,23 +141,27 @@ def main(
141141
config = add_config_defaults(config)
142142

143143
print("Fetching commits...", file=sys.stderr)
144-
commits = commits_between(gh, org_repo, start_rev, stop_rev)
145-
pull_requests = pull_requests_from_commits(
144+
commits = _query.commits_between(gh, org_repo, start_rev, stop_rev)
145+
pull_requests = _query.pull_requests_from_commits(
146146
lazy_tqdm(commits, desc="Fetching pull requests")
147147
)
148-
authors, reviewers = contributors(
148+
authors, reviewers = _query.contributors(
149149
gh=gh,
150150
org_repo=org_repo,
151151
commits=lazy_tqdm(commits, desc="Fetching authors"),
152152
pull_requests=lazy_tqdm(pull_requests, desc="Fetching reviewers"),
153153
)
154+
runtime_dependencies = _query.pyproject_dependencies(
155+
gh=gh, org_repo=org_repo, rev=stop_rev
156+
)
154157

155158
Formatter = {"md": MdFormatter, "rst": RstFormatter}[format]
156159
formatter = Formatter(
157160
repo_name=org_repo.split("/")[-1],
158161
pull_requests=pull_requests,
159162
authors=authors,
160163
reviewers=reviewers,
164+
runtime_dependencies=runtime_dependencies,
161165
version=version,
162166
title_template=config["title_template"],
163167
intro_template=config["intro_template"],

src/changelist/_format.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class MdFormatter:
1919
pull_requests: set[PullRequest]
2020
authors: set[Union[NamedUser]]
2121
reviewers: set[NamedUser]
22+
runtime_dependencies: set[str]
2223

2324
version: str
2425
title_template: str
@@ -52,6 +53,8 @@ def iter_lines(self) -> Iterable[str]:
5253
yield from self._format_intro()
5354
for title, pull_requests in self._prs_by_section.items():
5455
yield from self._format_pr_section(title, pull_requests)
56+
if self.runtime_dependencies:
57+
yield from self._format_dependencies_section(self.runtime_dependencies)
5558
yield from self._format_contributor_section(self.authors, self.reviewers)
5659
yield from self._format_outro()
5760

@@ -158,6 +161,17 @@ def _format_contributor_section(
158161
yield from sorted(reviewers_lines, key=lambda s: s.lower())
159162
yield "\n"
160163

164+
def _format_dependencies_section(self, runtime_dependencies: set[str]):
165+
yield from self._format_section_title("Dependencies", level=2)
166+
yield "\n"
167+
yield "Minimal runtime dependencies:\n"
168+
yield "\n"
169+
for dependency in sorted(runtime_dependencies):
170+
line = f"`{dependency}`"
171+
line = self._sanitize_text(line)
172+
yield f"- {line}\n"
173+
yield "\n"
174+
161175
def _format_intro(self):
162176
intro = self.intro_template.format(
163177
repo_name=self.repo_name, version=self.version

src/changelist/_query.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,17 @@
55
from dataclasses import dataclass
66

77
import requests
8-
from github import Github
8+
from github import Github, UnknownObjectException
99
from github.Commit import Commit
1010
from github.NamedUser import NamedUser
1111
from github.PullRequest import PullRequest
1212

13+
try:
14+
import tomllib
15+
except ModuleNotFoundError:
16+
import tomli as tomllib
17+
18+
1319
logger = logging.getLogger(__name__)
1420

1521

@@ -174,3 +180,27 @@ def contributors(
174180
reviewers.add(review.user)
175181

176182
return authors, reviewers
183+
184+
185+
def pyproject_dependencies(
186+
gh: Github,
187+
org_repo: str,
188+
rev: str,
189+
):
190+
"""Fetch runtime dependencies from pyproject.toml at the given revision."""
191+
repo = gh.get_repo(org_repo)
192+
try:
193+
file = repo.get_contents("pyproject.toml", ref=rev)
194+
logger.debug("found pyproject.toml in %s@%s", org_repo, rev)
195+
content = file.decoded_content.decode()
196+
except UnknownObjectException:
197+
content = ""
198+
pyproject = tomllib.loads(content)
199+
200+
runtime_dependencies = []
201+
python_dep = pyproject.get("project", {}).get("requires-python")
202+
if python_dep:
203+
runtime_dependencies += [f"python{python_dep}"]
204+
runtime_dependencies += pyproject.get("project", {}).get("dependencies", [])
205+
206+
return runtime_dependencies

0 commit comments

Comments
 (0)