Skip to content

Surface pyproject.toml [project.scripts] as runnable tasks#39

Merged
kjanat merged 3 commits into
masterfrom
feat/pyproject-scripts-tasks
Jun 4, 2026
Merged

Surface pyproject.toml [project.scripts] as runnable tasks#39
kjanat merged 3 commits into
masterfrom
feat/pyproject-scripts-tasks

Conversation

@kjanat
Copy link
Copy Markdown
Owner

@kjanat kjanat commented Jun 4, 2026

Problem

For Python projects, runner detected the package manager (uv / poetry / pipenv) but never listed the PEP 621 [project.scripts] console entry points declared in pyproject.toml. A project full of declared scripts showed no tasks:

❯ runner
runner 0.12.0

  Package Managers    uv

[project.scripts] was the one common task source with no extractor — every other source (package.json, Makefile, justfile, Taskfile, bacon.toml, mise.toml, Cargo aliases, Go packages) already had one.

Change

Adds a PyprojectScripts task source end-to-end:

  • Extraction (tool/python.rs): parses [project.scripts] from pyproject.toml via the toml crate, surfacing each script name with its entry-point target (e.g. greenpy.main:main) as the description. Empty when absent/scriptless; a malformed manifest surfaces as a TaskListUnreadable warning rather than silently dropping tasks.
  • Detection (detect.rs): runs the extractor whenever a Python-ecosystem PM is detected, in the same scoped-parallel pool as the other extractors.
  • Dispatch (cmd/run/dispatch.rs): runs via the detected Python PM's run subcommand — uv run <name>, poetry run <name>, or pipenv run <name> (run_cmd added to each tool module). Honors an explicit Python-ecosystem --pm / [pm].python override, falling back to the detected PM.
  • Surfaces: grouped under pyproject.toml in runner list, plus why, source selection, and JSON schema v1/v2 labels.
  • Docs: README supported-sources list + CHANGELOG entry.

Scoped to [project.scripts] (PEP 621) as reported — not the legacy poetry-specific [tool.poetry.scripts] table.

Verification

Against the reported pyproject.toml:

❯ runner list
  pyproject.toml  bodysuit       greenpy.bodysuit:main
  pyproject.toml  greenpy        greenpy.main:main
  pyproject.toml  navel-stamper  greenpy.navel_stamper:main

❯ runner run greenpy
→ pyproject.toml greenpy        # invokes `uv run greenpy`

Qualified syntax (pyproject.toml:greenpy), runner why, and both JSON schema versions all work. New unit + detection tests added covering extraction (sorted names, missing/empty/malformed manifests), uv/poetry/pipenv run_cmd, and dispatch.

Full suite passes (560 unit + 21 integration + doctests); clippy and fmt --check clean.

Python projects detected a package manager (uv/poetry/pipenv) but never
listed their PEP 621 [project.scripts] console entry points, so `runner`
showed "no tasks" for a project full of declared scripts.

Add a PyprojectScripts task source: parse [project.scripts] from
pyproject.toml, surface each entry with its entry-point target as the
description, and dispatch via the detected Python PM's run subcommand
(uv run / poetry run / pipenv run). Honors an explicit Python-ecosystem
--pm / [pm].python override, falling back to the detected PM.
@cloudflare-workers-and-pages
Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
runner bddba7f Commit Preview URL

Branch Preview URL
Jun 04 2026, 09:33 AM

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 4, 2026

Review Change Stack

Warning

Review limit reached

@kjanat, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 47 minutes and 24 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d3a46142-a929-45cb-bdb3-554704cef83a

📥 Commits

Reviewing files that changed from the base of the PR and between bddba7f and e8ed91f.

📒 Files selected for processing (14)
  • CHANGELOG.md
  • README.md
  • src/cmd/list.rs
  • src/cmd/run.rs
  • src/cmd/run/dispatch.rs
  • src/cmd/run/select.rs
  • src/cmd/why.rs
  • src/detect.rs
  • src/schema/v1.rs
  • src/tool/pipenv.rs
  • src/tool/poetry.rs
  • src/tool/python.rs
  • src/tool/uv.rs
  • src/types.rs
📝 Walkthrough

Walkthrough

This PR implements end-to-end support for Python PEP 621 console scripts in pyproject.toml's [project.scripts] section. Tasks are discovered during project detection when a Python package manager is found, extracted via TOML parsing with deterministic ordering, and made discoverable through runner list. Dispatch routes scripts through the detected package manager's run subcommand (uv run, poetry run, or pipenv run), with resolution logic supporting explicit overrides and per-ecosystem configuration. Task selection and resolution logic integrate across runner why and runner list output paths.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

enhancement, documentation

⚓ Ahoy, we've charted new waters fer Python scripts now! 🗺️
From pyproject to the command line, the code sails smooth,
Each package manager gets their rightful run command,
Avast, the task detection logic be satisfying, arr! 🏴‍☠️

🚥 Pre-merge checks | ✅ 7 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Semver Version Bump Validation ⚠️ Warning PR modifies 365+ lines of source code, adding new TaskSource variant and multiple pub(crate) functions, but Cargo.toml version remains 0.12.0—no MINOR bump to 0.13.0 as required by SemVer. Bump Cargo.toml version from 0.12.0 to 0.13.0 to reflect backward-compatible feature additions per SemVer MINOR increment.
✅ Passed checks (7 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Surface pyproject.toml [project.scripts] as runnable tasks' is descriptive, follows conventional commit guidelines by starting with an action verb ('Surface'), and clearly summarises the main feature addition.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Changelog Update ✅ Passed CHANGELOG.md updated in [Unreleased] section describing pyproject.toml [project.scripts] extraction; 11 src/ files modified; no version bump (stays 0.12.0).
Agents.Md Documentation Updated ✅ Passed No AGENTS.md file exists in the repository, so the requirement to update it does not apply.
Description check ✅ Passed The PR description thoroughly documents the problem, implementation approach, and verification across extraction, detection, dispatch, UI surfaces, and documentation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/pyproject-scripts-tasks

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot added documentation Improvements or additions to documentation enhancement New feature or request labels Jun 4, 2026
@kjanat kjanat self-assigned this Jun 4, 2026
coderabbitai[bot]

This comment was marked as resolved.

@kjanat kjanat added the wip wip label Jun 4, 2026
kjanat added a commit that referenced this pull request Jun 4, 2026
Align the PyprojectScripts source-path resolution in `runner list`
(OSC8 links) and `runner why` (source_dir) with the upward-walking
variant already used in run/select.rs, so all three path-resolution
sites agree. find_first_upwards checks the root first, so behavior is
unchanged for the currently reachable case (Python detection only reads
pyproject.toml at the project root), but it future-proofs against
ancestor pyproject.toml discovery.

Addresses CodeRabbit review on PR #39.

https://claude.ai/code/session_01C33r8rotqFuMbbNVvYYkPK
Match select.rs: PyprojectScripts source_dir walks ancestors via
find_first_upwards instead of probing only the root, so list/why
report the same dir where run executes the task.
@kjanat kjanat force-pushed the feat/pyproject-scripts-tasks branch from 14288bd to 5769518 Compare June 4, 2026 09:54
@kjanat kjanat removed the wip wip label Jun 4, 2026
Find pyproject.toml and Python PM signals upward so nested dirs list
PEP 621 scripts. Show Python PM resolution in `why` and include
pyproject.toml in `--source` help.
@kjanat kjanat merged commit 916c7b8 into master Jun 4, 2026
15 checks passed
@kjanat kjanat deleted the feat/pyproject-scripts-tasks branch June 4, 2026 10:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant