Skip to content

Conversation

@x753
Copy link
Contributor

@x753 x753 commented Jul 1, 2025

Register moderation urls for all plugins

Summary by CodeRabbit

  • New Features

    • Plugins can now contribute moderation routes so plugin-provided moderation pages are available in the app.
    • Moderation section automatically includes any plugin-defined URLs.
  • Tests

    • Added unit tests to ensure default plugin hooks return empty lists when not overridden, including the new moderation URLs hook.
  • Chores

    • Updated a submodule reference to a newer commit (no functional changes).

@codecov
Copy link

codecov bot commented Jul 1, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.28%. Comparing base (8e892ab) to head (3f5e900).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1166      +/-   ##
==========================================
+ Coverage   92.23%   92.28%   +0.04%     
==========================================
  Files         331      331              
  Lines       10087    10092       +5     
  Branches      927      928       +1     
==========================================
+ Hits         9304     9313       +9     
+ Misses        657      653       -4     
  Partials      126      126              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@x753 x753 force-pushed the moderation-urls branch from a81b05c to 45acb52 Compare July 2, 2025 00:01
@x753 x753 requested a review from Roffenlund July 2, 2025 04:20
@coderabbitai
Copy link

coderabbitai bot commented Aug 14, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds a moderation URL extension point: BasePlugin gains get_moderation_urls(), PluginRegistry aggregates plugins' moderation URLs, and moderation URLConf appends those patterns. Adds a unit test for BasePlugin default getters and updates a python-packages submodule reference.

Changes

Cohort / File(s) Summary of Changes
Moderation URL integration
django/thunderstore/moderation/urls.py
Appends plugin-provided moderation URL patterns by calling plugin_registry.get_moderation_urls() and extending moderation_urls.
Plugin base extension point
django/thunderstore/plugins/base.py
Adds BasePlugin.get_moderation_urls() classmethod returning an empty list by default.
Plugin registry aggregation
django/thunderstore/plugins/registry.py
Adds PluginRegistry.get_moderation_urls() to collect and concatenate moderation URL patterns from all registered plugins.
Tests for default getters
django/thunderstore/plugins/tests/test_plugins.py
New test asserting BasePlugin default getters (including get_moderation_urls) return empty lists.
Submodule update
python-packages
Updates submodule commit reference; no local code changes.

Sequence Diagram(s)

sequenceDiagram
    participant URLConf as Moderation URLConf
    participant Registry as PluginRegistry
    participant Plugin as Plugin[i]
    participant Router as Django URL router

    URLConf->>Registry: get_moderation_urls()
    loop for each plugin
        Registry->>Plugin: plugin.get_moderation_urls()
        Plugin-->>Registry: [URLPattern...]
    end
    Registry-->>URLConf: combined [URLPattern...]
    URLConf->>Router: moderation_urls += combined patterns
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

I twitch my ears at routes anew,
Moderation paths hop into view.
Plugins bring little URL treats,
Registry gathers tidy fleets.
Tests keep burrows safe and bright — happy hops through code tonight! 🐇✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch moderation-urls

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@x753 x753 force-pushed the moderation-urls branch from 9def33f to 3f5e900 Compare August 14, 2025 17:56
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
python-packages (1)

1-1: Verify python-packages submodule bump, tag provenance, and CI initialization

I wasn’t able to fetch the submodule automatically (access returned 404), so please manually confirm:

  • The new SHA b3f80dc6 corresponds to a known tag or release in the python-packages repo (pinning to a tag is preferred for reproducibility).
  • There are no breaking or behavioral changes between 5197ec47… and b3f80dc6… that would affect the new moderation URL integration.
  • Your CI pipelines include a git submodule update --init --recursive step before build/test so the submodule is properly initialized.

If helpful, consider pinning the submodule URL to HTTPS or switching to a tagged ref, and adding an explicit CI step to initialize submodules.

django/thunderstore/plugins/base.py (1)

25-28: Add a short docstring and consider future-proofing the type

A brief docstring will help plugin authors discover intent. Also, if plugins might ever return URLResolver (e.g., via include()), the current List[URLPattern] annotation could be too narrow for static type checkers (runtime is fine). Not a blocker, just a note.

Apply this minimal docstring:

 @classmethod
 def get_moderation_urls(cls) -> List[URLPattern]:
-        return []
+        """Plugin hook for moderation-related URL patterns.
+
+        Override in plugins to extend the moderation URLConf.
+        """
+        return []

If you expect plugins to return URLResolver too, we could widen the type in a follow-up:

  • Base: List[Union[URLPattern, URLResolver]]
  • Registry methods accordingly

Would you like me to prep that follow-up change?

django/thunderstore/plugins/tests/test_plugins.py (1)

4-9: Consider adding coverage for the registry aggregator

A focused test that stubs a simple plugin returning a sentinel URL and asserting that PluginRegistry.get_moderation_urls() aggregates it would guard against regressions in the plumbing.

I can add a test plugin class within tests to validate aggregation behavior without touching real plugins. Want me to draft that test?

django/thunderstore/plugins/registry.py (1)

39-41: Ordering is non-deterministic due to Set iteration — verify it won’t matter for URL resolution

Since plugins is a Set, route order depends on hash order. If different plugins register overlapping paths, resolution priority may vary between runs. This follows existing patterns, but moderation routes might be more sensitive to order.

If you want deterministic ordering without changing PluginRegistry.plugins, consider sorting just for URL aggregation. Example change (optional; apply across all URL aggregations for consistency in a follow-up):

-    def get_moderation_urls(self) -> List[URLPattern]:
-        return list(itertools.chain(*(x.get_moderation_urls() for x in self.plugins)))
+    def get_moderation_urls(self) -> List[URLPattern]:
+        # Preserve deterministic ordering by class name to avoid URL resolution surprises
+        plugins = sorted(self.plugins, key=lambda p: p.__name__)
+        return list(itertools.chain.from_iterable(x.get_moderation_urls() for x in plugins))

Would you like me to propose a separate PR aligning ordering across all similar getters?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these settings in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 2530f73 and 9def33f.

📒 Files selected for processing (5)
  • django/thunderstore/moderation/urls.py (2 hunks)
  • django/thunderstore/plugins/base.py (1 hunks)
  • django/thunderstore/plugins/registry.py (1 hunks)
  • django/thunderstore/plugins/tests/test_plugins.py (1 hunks)
  • python-packages (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
django/thunderstore/plugins/tests/test_plugins.py (1)
django/thunderstore/plugins/base.py (1)
  • BasePlugin (14-45)
django/thunderstore/plugins/registry.py (1)
django/thunderstore/plugins/base.py (1)
  • get_moderation_urls (26-27)
django/thunderstore/moderation/urls.py (2)
django/thunderstore/plugins/base.py (1)
  • get_moderation_urls (26-27)
django/thunderstore/plugins/registry.py (1)
  • get_moderation_urls (39-40)
django/thunderstore/plugins/base.py (1)
django/thunderstore/plugins/registry.py (1)
  • get_moderation_urls (39-40)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: Build docker image
🔇 Additional comments (5)
django/thunderstore/plugins/base.py (1)

25-28: Moderation URL hook added — looks good and aligns with existing plugin API

The new classmethod mirrors the existing getters’ shape and defaults, keeping backward compatibility and providing a clean extension point.

django/thunderstore/plugins/tests/test_plugins.py (1)

4-9: Solid sanity check for BasePlugin defaults

Covers the new getter and keeps behavior consistent across the existing ones. Good minimal test.

django/thunderstore/moderation/urls.py (2)

3-12: Appending plugin-provided moderation URLs is correct

Importing plugin_registry and extending the list keeps the existing URL intact while enabling plugin contributions.


3-12: Watch for circular‐import risks when discovering plugins
Loading plugin_registry at import time in django/thunderstore/moderation/urls.py (via autodiscoverload_ts_plugins()) will eagerly import all ts_*.ts_plugins modules. Meanwhile, django/thunderstore/core/urls.py brings in moderation_urls (line 19), so if any plugin’s ts_plugins submodule ever imports back into thunderstore.moderation.urls (or even thunderstore.core.urls), you’ll end up with an import cycle.

Please verify that none of your installed ts_* plugin packages perform such imports at module scope. If this pattern bites you later, consider deferring plugin loading (e.g. in an AppConfig.ready hook) or wrapping get_moderation_urls() behind a function instead of doing it at import time.

django/thunderstore/plugins/registry.py (1)

39-41: Aggregator mirrors existing patterns — OK

Consistent with get_settings_urls/get_legacy_package_urls. Produces a flat list suitable to extend moderation URLs.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
django/thunderstore/plugins/base.py (1)

25-28: Add a short docstring for plugin authors

A tiny docstring clarifies purpose and expectations for implementers.

Apply this diff:

 @classmethod
 def get_moderation_urls(cls) -> List[URLPattern]:
-    return []
+    """Hook for plugin-provided moderation URL patterns.
+
+    Override in plugins to return a list of URLPattern instances
+    related to moderation functionality.
+    """
+    return []
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these settings in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 9def33f and 3f5e900.

📒 Files selected for processing (5)
  • django/thunderstore/moderation/urls.py (2 hunks)
  • django/thunderstore/plugins/base.py (1 hunks)
  • django/thunderstore/plugins/registry.py (1 hunks)
  • django/thunderstore/plugins/tests/test_plugins.py (1 hunks)
  • python-packages (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • python-packages
🚧 Files skipped from review as they are similar to previous changes (2)
  • django/thunderstore/plugins/tests/test_plugins.py
  • django/thunderstore/plugins/registry.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: Build docker image
  • GitHub Check: Build docker image
🔇 Additional comments (2)
django/thunderstore/plugins/base.py (1)

25-28: Introduce get_moderation_urls extension point — LGTM

Consistent with existing plugin hooks, safe default, and clear type signature.

django/thunderstore/moderation/urls.py (1)

12-12: Appending plugin-provided moderation URLs — LGTM

Ordering preserves the core route precedence while enabling plugin extensions.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants