Skip to content

feat: add topgrade configuration management plugin#369

Open
AdityaM-IITH wants to merge 9 commits into
DotDev262:mainfrom
AdityaM-IITH:feat/topgrade-plugin-python
Open

feat: add topgrade configuration management plugin#369
AdityaM-IITH wants to merge 9 commits into
DotDev262:mainfrom
AdityaM-IITH:feat/topgrade-plugin-python

Conversation

@AdityaM-IITH

Copy link
Copy Markdown
Contributor

Related Issue

Closes #186

Proposed Changes

  • Added a new Python plugin to manage the topgrade system-wide upgrade configuration (topgrade.toml).
  • Implemented the config_provider capability using tomlkit to safely merge incoming settings while perfectly preserving existing user comments and TOML formatting.
  • Set up inline script metadata (PEP 723) so uv automatically handles dependencies without manual pip installs.
  • Created plugins/topgrade/plugin.yaml manifest.
  • Created plugins/topgrade/src/plugin.py containing the core config parsing and merging logic.
  • Created plugins/topgrade/test/test_topgrade.py for automated tests of the new plugin.

Type of Change

  • 🐛 Bug fix
  • ✨ New feature
  • 📖 Documentation
  • 🧪 Testing
  • 🛠️ Refactoring
  • 🚀 DevOps/CI

Screenshots / Logs (if applicable)

============================= test session starts =============================
platform win32 -- Python 3.12.13, pytest-9.0.3, pluggy-1.6.0
rootdir: C:\Users\hp\.gemini\antigravity\scratch\WinHome
configfile: pyproject.toml
collected 3 items

plugins\topgrade\test\test_topgrade.py ...                               [100%]

============================== 3 passed in 0.42s ==============================

Testing & Verification

  • I have run dotnet test and all 60+ cross-platform tests passed.
  • I have verified the changes on a Windows environment (if applicable).
  • I have added new unit tests to cover my changes.

GSSOC 2026 Checklist

  • I have read the Contribution Guidelines.
  • My code is formatted correctly (I have run dotnet format, uv tool run ruff format plugins/, and bun x prettier --write plugins/).
  • I have linked the PR to an approved issue.
  • I understand that a maintainer must apply the gssoc:approved label for this PR to count for points.

@github-actions github-actions Bot added level:beginner Beginner level task type:feature New feature GSSOC GirlScript Summer of Code 2026 labels Jun 4, 2026
@AdityaM-IITH

Copy link
Copy Markdown
Contributor Author

Hi maintainers, just a heads-up the ruff check CI failure on plugins/everything/src/plugin.py (I001 unsorted imports) is a pre-existing issue on main and is not introduced by this PR.

You can verify by running:

git checkout main
uv tool run ruff check plugins/everything/src/plugin.py

@DotDev262 DotDev262 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR. Several issues to fix:

1. CRITICAL: Empty stdin causes silent exit (host hangs)

if not raw_input: return returns nothing to stdout. Must return a JSON error response:

{"requestId": "unknown", "error": "No input received"}

2. CRITICAL: JSON parse error has no stdout response

Writing to stderr only and returning silently still leaves the host hanging. Must print a JSON error to stdout.

3. check_installed must return bare bool

Returns {"data": {"installed": bool}}. Must return bare bool, and main() wraps it:

result = handle_check_installed()
response = {"requestId": req_id, "installed": result}

4. dryRun must come from args, not context

dry_run = context.get("dryRun", False) should be args.get("dryRun", False).

5. requestId must use .get("requestId") or "unknown"

request.get("requestId") returns None when key exists but is null.

6. Non-standard response fields

"success" and "changed" are not standard. Use only requestId, error, and action-specific fields.

7. response.update() merge pattern

The response.update(res) pattern breaks when functions return non-dict values. Design each handler to return data, and let main() construct the response.

Please reference existing merged plugins (e.g., plugins/pnpm/) for correct patterns.

@DotDev262

Copy link
Copy Markdown
Owner

@AdityaM-IITH — Thanks for addressing the review feedback! The PR needs a rebase before I can do a final review. Please rebase onto latest main.

@AdityaM-IITH AdityaM-IITH force-pushed the feat/topgrade-plugin-python branch from 6547f4f to 636c48f Compare June 5, 2026 12:02
@DotDev262

Copy link
Copy Markdown
Owner

@AdityaM-IITH — please rebase on latest main (6 commits behind) so I can re-review. Let me know if you need help.

@AdityaM-IITH AdityaM-IITH force-pushed the feat/topgrade-plugin-python branch from 636c48f to aae085f Compare June 9, 2026 09:25
@DotDev262

Copy link
Copy Markdown
Owner

@AdityaM-IITH Please rebase onto latest main before review. Let me know when done.

@DotDev262

Copy link
Copy Markdown
Owner

@AdityaM-IITH Please rebase onto latest main. Let me know when done.

@AdityaM-IITH AdityaM-IITH force-pushed the feat/topgrade-plugin-python branch from aae085f to 7ea1250 Compare June 13, 2026 15:30
@AdityaM-IITH

Copy link
Copy Markdown
Contributor Author

@DotDev262 Rebased onto latest main. I also fixed the pre-existing linting errors that were failing CI, so everything should pass cleanly now.

@DotDev262 DotDev262 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @AdityaM-IITH,

Thank you for rebasing this PR and updating the format!

However, the plugin does not yet comply with the repository's updated JSON-RPC protocol contract and guidelines. Please address the following issues:

  1. check_installed Return Type:

    • Per the repository guidelines, check_installed must return a bare bool. It is the responsibility of main() to wrap it into the standard JSON response format: {"requestId": request_id, "installed": result}.
    • Currently, check_installed returns a dictionary including success and data fields.
  2. Banned Response Fields (success and data):

    • The "success" field and "data" wrapper are banned from all JSON-RPC responses.
    • Currently, they are used across all responses in check_installed, apply_config, and the error handlers. Please remove them and return flat response objects containing only the required fields (e.g. requestId, changed, installed, error).
  3. Non-Atomic File Writes:

    • In apply_config (lines 113–114), the file is written to directly using open(config_path, "w").
    • The repository requires atomic writes using tempfile.mkstemp() and os.replace() to prevent configuration corruption.
  4. Test Refactoring:

    • Once the response schema is updated to remove success and data and wrap check_installed properly, the unit tests in plugins/topgrade/test/test_topgrade.py must be updated to match the new schema (i.e. assert on installed directly and remove success/data assertions).
  5. Rebase Required:

    • The branch is 1 commit behind main due to a recent merge. Please rebase your branch on the latest main.

Thank you!

@DotDev262

Copy link
Copy Markdown
Owner

Hi @AdityaM-IITH! Just a friendly reminder — this PR is 10 commits behind main and has outstanding protocol issues (check_installed bare bool, success/data fields). Could you please rebase and address the remaining feedback? Thanks!

@DotDev262 DotDev262 added the gssoc:approved Approved for GSSOC points (Required) label Jun 21, 2026

@DotDev262 DotDev262 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your branch is behind main. Please rebase onto latest main and force-push so we can proceed with the review. Thanks!

@AdityaM-IITH AdityaM-IITH force-pushed the feat/topgrade-plugin-python branch from 7e0aa2e to c8f9726 Compare June 23, 2026 16:16
@AdityaM-IITH

Copy link
Copy Markdown
Contributor Author

@DotDev262 Rebase is complete. I've also fully addressed the protocol issues:

check_installed now returns a bare bool, which main() handles.
Removed success and data wrappers everywhere to ensure flat responses.
Implemented atomic file writes via tempfile and os.replace for config generation.
Fixed the empty stdin / bad JSON parsing edge cases so the plugin correctly returns an error instead of hanging.
Updated tests to match the new schema.
Let me know if anything else is needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gssoc:approved Approved for GSSOC points (Required) GSSOC GirlScript Summer of Code 2026 level:beginner Beginner level task type:feature New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Plugin] topgrade: manage upgrade-all configuration

2 participants