Skip to content

🐛 bug: Reload mounted view engines in ReloadViews#4031

Merged
ReneWerner87 merged 3 commits intomainfrom
update-app.reloadviews-for-sub-app-reloading
Jan 26, 2026
Merged

🐛 bug: Reload mounted view engines in ReloadViews#4031
ReneWerner87 merged 3 commits intomainfrom
update-app.reloadviews-for-sub-app-reloading

Conversation

@gaby
Copy link
Member

@gaby gaby commented Jan 25, 2026

Motivation

  • Ensure ReloadViews() reloads view engines for mounted sub-apps so on-disk template changes are picked up when invoked on the parent application.
  • Prevent panics by skipping nil and typed-nil view engine values when reloading.
  • Keep lint expectations by returning mount helpers directly from Use helpers without changing runtime behavior.

Description

  • Updated App.ReloadViews() to iterate mounted apps (app.mountFields.appList when present) and call Load() on each mounted app's config.Views, skipping nil and typed-nil engines and returning ErrNoViewEngineConfigured only if nothing was reloaded.
  • Preserved the typed-nil guard by checking reflect.ValueOf(...).Kind() == reflect.Pointer && IsNil() before calling Load() and wrap load errors with a descriptive message.
  • Changed App.Use and Group.Use to return the result of mount(...) directly to satisfy lint expectations without changing runtime behavior.
  • Moved the fileView test helper to the top of app_test.go and added Test_App_ReloadViews_MountedViews to verify that a mounted sub-app's view engine is reloaded when the parent ReloadViews() is invoked.

Fixes #3875

### Motivation
- Ensure `ReloadViews()` reloads view engines for mounted sub-apps so on-disk template changes are picked up when called on the parent application.
- Prevent panics by skipping nil and typed-nil view engines during reload.
- Fix lint feedback by returning mount helpers directly from `Use` helpers for `App` and `Group`.

### Description
- Updated `App.ReloadViews()` to iterate `app.mountFields.appList` when available, call `Load()` on each mounted app's `config.Views`, skip `nil`/typed-nil engines, and return `ErrNoViewEngineConfigured` only if nothing was reloaded.
- Preserved the typed-nil guard by checking `reflect.ValueOf(...).Kind() == reflect.Pointer && IsNil()` before calling `Load()`.
- Changed `Use` in `app.go` and `group.go` to return the result of `mount(...)` directly to satisfy lint expectations without changing runtime behavior.
- Added `fileView` test helper and a unit test `Test_App_ReloadViews_MountedViews` in `app_test.go` that mounts a sub-app with its own `Views`, updates an on-disk template, calls `ReloadViews()` on the parent, and asserts the sub-app engine reloaded.

### Testing
- Ran `make audit` (failed due to `govulncheck` findings in the Go 1.25.1 standard library; this is an environment/tooling scanner result, not a functional test failure).
- Ran `make generate`, `make betteralign`, `make modernize`, and `make format`, all completed successfully.
- Ran `make lint`, which completed with no reported issues after the changes.
- Ran `make test`, which executed the full test suite including the new `Test_App_ReloadViews_MountedViews`; the test suite completed successfully (all tests passed, some tests skipped as expected).
- The new unit test `Test_App_ReloadViews_MountedViews` passes and verifies that a mounted sub-app's view engine reloads when the parent `ReloadViews()` is invoked.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 25, 2026

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

ReloadViews() now reloads view engines for all mounted apps (including sub-apps) by iterating mountFields.appList; mounting/Use() returns mount(...) result when attaching a sub-app. Tests add a file-backed view helper and verify reload propagation, error handling, and multi-app reloads.

Changes

Cohort / File(s) Summary
ReloadViews & tests
app.go, app_test.go
ReloadViews() iterates mounted targets and calls each target's Views.Load(); returns wrapped load errors or ErrNoViewEngineConfigured if none reloaded. Tests add fileView and multiple cases validating reload across mounted sub-apps and error propagation.
Mount synchronization & return behavior
mount.go, group.go, app.go
Added mutex protection around updates to mounted app lists to guard concurrent mounts. Use() in group/app now returns the result of mount(prefix, subApp) directly when a sub-app is provided (changes chaining return flow).

Sequence Diagram(s)

sequenceDiagram
    participant Caller
    participant App
    participant MountedApp
    participant ViewEngine

    Caller->>App: ReloadViews()
    activate App
    App->>App: collect mountFields.appList
    loop for each mounted target
        App->>MountedApp: validate target (non-nil, has Views)
        alt valid target
            MountedApp->>ViewEngine: Views.Load()
            ViewEngine-->>MountedApp: success / error
            MountedApp-->>App: mark reloaded or propagate error
        else skip
        end
    end
    App-->>Caller: return nil | ErrNoViewEngineConfigured | wrapped error
    deactivate App
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • sixcolors
  • ReneWerner87
  • efectn

Poem

🐰 I hopped through mounts both near and far,
Peeked in each view and polished each star,
Templates refreshed with a joyful spin,
Mounts now return from the call within,
A little rabbit cheers — code up to par!

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the bug fix: reloading mounted view engines in ReloadViews function, which is the primary change.
Description check ✅ Passed The description covers motivation, detailed implementation, and references the linked issue. However, some template sections are unchecked (Benchmarks, Documentation, Changelog, Migration Guide).
Linked Issues check ✅ Passed The PR fulfills the main requirement from issue #3875 by exposing app.ReloadViews() that reloads view engines, including mounted sub-apps, allowing templates to be reloaded without app restart.
Out of Scope Changes check ✅ Passed Changes in mount.go and group.go (adding mutex protection and return value optimization) are complementary to the main objective and necessary for safe concurrent mounting.

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

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @gaby, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses issues related to view engine management, particularly when dealing with mounted sub-applications. The primary goal is to ensure that template changes are consistently reflected across all parts of a Fiber application, including those mounted as sub-apps, by enhancing the ReloadViews() functionality. It also improves the stability of the view reloading process by handling nil view engine configurations gracefully and refines method return types for better linting compliance.

Highlights

  • Enhanced View Engine Reloading: The ReloadViews() function now correctly reloads view engines for mounted sub-applications, ensuring on-disk template changes are picked up across the entire application structure.
  • Improved Robustness: The ReloadViews() function has been made more robust by explicitly skipping nil and typed-nil view engine values, preventing potential panics during the reload process.
  • Linting Compliance: The App.Use and Group.Use methods have been updated to directly return the result of the mount(...) helper, satisfying linting expectations without altering runtime behavior.
  • Comprehensive Testing: A new test case, Test_App_ReloadViews_MountedViews, has been added to specifically verify the correct reloading of view engines within mounted sub-applications.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@ReneWerner87 ReneWerner87 added this to v3 Jan 25, 2026
@ReneWerner87 ReneWerner87 added this to the v3 milestone Jan 25, 2026
@gaby gaby changed the title 🐛 bug: reload mounted view engines in ReloadViews 🐛 bug: Reload mounted view engines in ReloadViews Jan 25, 2026
@gaby gaby marked this pull request as ready for review January 25, 2026 17:23
@gaby gaby requested a review from a team as a code owner January 25, 2026 17:23
@codecov
Copy link

codecov bot commented Jan 25, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.22%. Comparing base (52eaa82) to head (539bed9).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4031   +/-   ##
=======================================
  Coverage   91.21%   91.22%           
=======================================
  Files         119      119           
  Lines       11101    11111   +10     
=======================================
+ Hits        10126    10136   +10     
  Misses        618      618           
  Partials      357      357           
Flag Coverage Δ
unittests 91.22% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ 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.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request correctly extends ReloadViews to also reload view engines for mounted sub-applications, which is a great bug fix. The added tests are thorough and validate the new behavior effectively. The changes to the Use methods in App and Group are good stylistic improvements.

I've found one potential concurrency issue. The new ReloadViews function reads from app.mountFields.appList with a lock, but the mount functions that write to this map do not use a lock, which can lead to a data race. I've left a detailed comment on how to address this.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR enhances the ReloadViews() method to reload view engines for mounted sub-applications, addressing issue #3875 which requested the ability to reload templates from disk without restarting the application. The changes ensure that when ReloadViews() is called on a parent app, all mounted sub-apps with configured view engines are also reloaded.

Changes:

  • Extended ReloadViews() to iterate through mounted sub-apps and reload their view engines
  • Added nil and typed-nil safety checks to prevent panics when view engines are nil
  • Refactored Use() methods in both App and Group to return mount results directly for cleaner code
  • Added test infrastructure (fileView helper) and comprehensive test case for mounted view reloading

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
app.go Enhanced ReloadViews() to handle mounted apps and refactored Use() for direct returns
group.go Refactored Use() to return mount result directly, consistent with app.go changes
app_test.go Added fileView test helper and Test_App_ReloadViews_MountedViews test case

@gaby
Copy link
Member Author

gaby commented Jan 25, 2026

Fixing AI review

### Motivation
- Ensure `ReloadViews()` reloads view engines for mounted sub-apps so on-disk template changes are picked up when invoked on the parent application.
- Prevent panics by skipping `nil` and typed-nil view engine values when reloading.
- Keep lint expectations by returning mount helpers directly from `Use` helpers without changing runtime behavior.

### Description
- Updated `App.ReloadViews()` to iterate mounted apps (`app.mountFields.appList` when present) and call `Load()` on each mounted app's `config.Views`, skipping `nil` and typed-nil engines and returning `ErrNoViewEngineConfigured` only if nothing was reloaded.
- Preserved the typed-nil guard by checking `reflect.ValueOf(...).Kind() == reflect.Pointer && IsNil()` before calling `Load()` and wrap load errors with a descriptive message.
- Changed `App.Use` and `Group.Use` to return the result of `mount(...)` directly to satisfy lint expectations without changing runtime behavior.
- Moved the `fileView` test helper to the top of `app_test.go` and added `Test_App_ReloadViews_MountedViews` to verify that a mounted sub-app's view engine is reloaded when the parent `ReloadViews()` is invoked.

### Testing
- Ran `make audit` which failed due to `govulncheck` reporting vulnerabilities in the Go 1.25.1 standard library (tooling scanner result, not a functional test failure).
- Ran `make generate` which completed successfully.
- Ran `make betteralign` which completed successfully.
- Ran `make modernize` which completed successfully.
- Ran `make format` which completed successfully.
- Ran `make lint` which completed successfully with no reported issues after the changes.
- Ran `make test` which executed the full test suite and completed successfully, e.g. `DONE 2603 tests, 1 skipped` (all non-skipped tests passed).
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@ReneWerner87 ReneWerner87 merged commit 41a898f into main Jan 26, 2026
17 checks passed
@ReneWerner87 ReneWerner87 deleted the update-app.reloadviews-for-sub-app-reloading branch January 26, 2026 07:39
@github-project-automation github-project-automation bot moved this to Done in v3 Jan 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Reload views?

3 participants