Skip to content

feat: register service providers to providers.go[#790]#1248

Merged
hwbrzzl merged 9 commits intomasterfrom
kkumar-gcc/#790-2
Nov 24, 2025
Merged

feat: register service providers to providers.go[#790]#1248
hwbrzzl merged 9 commits intomasterfrom
kkumar-gcc/#790-2

Conversation

@krishankumar01
Copy link
Member

@krishankumar01 krishankumar01 commented Oct 26, 2025

📑 Description

Closes https://github.com/goravel/goravel/issues/

image

✅ Checks

  • Added test cases for my code

Greptile Overview

Greptile Summary

This PR migrates service provider registration from config/app.go to a dedicated bootstrap/providers.go file, implementing a cleaner separation of concerns for framework bootstrapping.

Key Changes:

  • Added AddProvider() and RemoveProvider() functions to programmatically manage service provider registration
  • Implemented RemoveItem() method in withSliceHandler for removing items from bootstrap slices with proper import cleanup
  • Added BootstrapPath() method to the Application interface and implementation
  • Refactored all 18 setup files (auth, cache, crypt, database, event, filesystem, grpc, hash, http, log, mail, process, queue, route, schedule, session, testing, translation, validation, view) to use the new AddProviderApply() and RemoveProviderApply() pattern
  • Updated make:provider command to automatically register new providers in bootstrap/providers.go
  • Deprecated ProvidersInConfig() matcher in favor of new Providers() matcher that targets the bootstrap file
  • Added comprehensive test coverage for the new provider management functionality

Impact:

  • Backward compatible - supports both inline arrays and the new helper function pattern
  • Improves code organization by moving provider registration out of config files
  • Consistent with existing patterns for commands, migrations, and seeders

Confidence Score: 4/5

  • This PR is safe to merge with minor testing recommended
  • Well-tested refactoring with comprehensive test coverage and backward compatibility. The implementation is clean and follows established patterns in the codebase. One point deducted because this is a significant architectural change affecting 35 files, so thorough integration testing in a real project is recommended before production use.
  • No files require special attention - the implementation is consistent across all changes

Important Files Changed

Filename Overview
packages/modify/with_slice_actions.go Added RemoveItem method to remove providers/commands/etc from bootstrap files, with proper import cleanup
packages/modify/utils.go Added AddProvider and RemoveProvider functions with comprehensive documentation
packages/modify/modify.go Added AddProviderApply and RemoveProviderApply wrapper functions with new Call modifier
foundation/application.go Implemented BootstrapPath method to get path to bootstrap directory
foundation/console/provider_make_command.go Updated to auto-register newly created providers to bootstrap/providers.go
packages/match/helper.go Refactored Providers() matcher for new pattern, deprecated old ProvidersInConfig()

Sequence Diagram

sequenceDiagram
    participant User
    participant MakeCommand as make:provider Command
    participant ModifyPkg as modify Package
    participant BootstrapApp as bootstrap/app.go
    participant ProvidersFile as bootstrap/providers.go
    
    User->>MakeCommand: Run make:provider MyProvider
    MakeCommand->>MakeCommand: Create provider file
    MakeCommand->>ModifyPkg: AddProvider(pkg, provider)
    
    alt providers.go doesn't exist AND WithProviders not in Setup
        ModifyPkg->>ProvidersFile: Create providers.go with stub template
        ModifyPkg->>ProvidersFile: Add provider to Providers() function
        ModifyPkg->>BootstrapApp: Add WithProviders(Providers()) to Setup chain
    else providers.go exists AND WithProviders in Setup
        ModifyPkg->>ProvidersFile: Add provider to existing Providers() function
        ModifyPkg->>ProvidersFile: Add import if needed
    else providers.go doesn't exist BUT WithProviders exists inline
        ModifyPkg->>BootstrapApp: Add provider to inline []foundation.ServiceProvider array
        ModifyPkg->>BootstrapApp: Add import if needed
    end
    
    ModifyPkg-->>MakeCommand: Success
    MakeCommand-->>User: Provider registered successfully
Loading

Copilot AI review requested due to automatic review settings October 26, 2025 16:19
@krishankumar01 krishankumar01 requested a review from a team as a code owner October 26, 2025 16:19
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 migrates service provider registration from config/app.go to bootstrap/providers.go across all framework setup files. The change adds a new BootstrapPath method to the Application interface and updates all service installation/uninstallation code to use the new location.

Key changes:

  • Added BootstrapPath method to Application interface and implementation
  • Updated all setup files to register providers in bootstrap/providers.go instead of config/app.go
  • Introduced new Providers() matcher function and deprecated the old ProvidersFallback() for backward compatibility

Reviewed Changes

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

Show a summary per file
File Description
contracts/foundation/application.go Added BootstrapPath method to Application interface
foundation/application.go Implemented BootstrapPath method to return bootstrap directory path
support/path/path.go Added Bootstrap helper function wrapping BootstrapPath
packages/match/helper.go Added new Providers() matcher and deprecated ProvidersFallback()
packages/match/helper_test.go Updated tests to use new provider registration pattern
mocks/foundation/Application.go Added mock implementation for BootstrapPath method
auth/setup/setup.go Updated to use providersBootstrapPath and fixed typo in modulePath variable
cache/setup/setup.go Updated to use providersBootstrapPath and extracted path variables
crypt/setup/setup.go Updated to use providersBootstrapPath and facade constants
database/setup/setup.go Updated to use providersBootstrapPath
event/setup/setup.go Updated to use providersBootstrapPath
filesystem/setup/setup.go Updated to use providersBootstrapPath and facade constants
http/setup/setup.go Updated to use providersBootstrapPath
log/setup/setup.go Updated to use providersBootstrapPath
mail/setup/setup.go Updated to use providersBootstrapPath
process/setup/setup.go Updated to use providersBootstrapPath
queue/setup/setup.go Updated to use providersBootstrapPath
route/setup/setup.go Updated to use providersBootstrapPath
schedule/setup/setup.go Updated to use providersBootstrapPath
session/setup/setup.go Updated to use providersBootstrapPath
testing/setup/setup.go Updated to use providersBootstrapPath
translation/setup/setup.go Updated to use providersBootstrapPath and facade constants
validation/setup/setup.go Updated to use providersBootstrapPath and facade constants

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

modify.GoFile(path.Config("app.go")).
Find(match.Providers()).Modify(modify.Unregister("&filesystem.ServiceProvider{}")).
modify.WhenNoFacades([]string{facades.Storage},
modify.GoFile(providersBootstrapPath).
Copy link
Member Author

Choose a reason for hiding this comment

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

@hwbrzzl The install and uninstall logic seems redundant. Should we move these to packages as InstallServiceProvider and UninstallServiceProvider? In the case of uninstall, I now have to fall back to the previous logic as well.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, InstallServiceProvider and UninstallServiceProvider are fine, and we only need to implement registering ServiceProvider in the providers.go file. It's compatible with the old style.

Copy link
Member Author

Choose a reason for hiding this comment

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

That’s already implemented, it’s just that during uninstallation, we first need to remove the entry from bootstrap/providers.go, and then from config/app.go as a fallback for older applications.

@codecov
Copy link

codecov bot commented Oct 26, 2025

Codecov Report

❌ Patch coverage is 35.51402% with 138 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.42%. Comparing base (6252baa) to head (f9c7d91).
⚠️ Report is 84 commits behind head on master.

Files with missing lines Patch % Lines
packages/modify/modify.go 0.00% 13 Missing ⚠️
hash/setup/setup.go 0.00% 12 Missing ⚠️
packages/modify/with_slice_actions.go 72.09% 6 Missing and 6 partials ⚠️
cache/setup/setup.go 0.00% 11 Missing ⚠️
filesystem/setup/setup.go 0.00% 11 Missing ⚠️
translation/setup/setup.go 0.00% 9 Missing ⚠️
view/setup/setup.go 0.00% 9 Missing ⚠️
crypt/setup/setup.go 0.00% 8 Missing ⚠️
validation/setup/setup.go 0.00% 8 Missing ⚠️
foundation/console/provider_make_command.go 14.28% 4 Missing and 2 partials ⚠️
... and 14 more
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1248      +/-   ##
==========================================
+ Coverage   68.19%   68.42%   +0.22%     
==========================================
  Files         264      264              
  Lines       15425    15483      +58     
==========================================
+ Hits        10519    10594      +75     
+ Misses       4449     4425      -24     
- Partials      457      464       +7     

☔ 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

@hwbrzzl hwbrzzl left a comment

Choose a reason for hiding this comment

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

Pretty good

Install(
modify.GoFile(appConfigPath).
Find(match.Imports()).Modify(modify.AddImport(modulepath)).
modify.GoFile(providersBootstrapPath).
Copy link
Contributor

Choose a reason for hiding this comment

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

Will you implement InstallServiceProvider and UninstallServiceProvider functions in this PR, please? The basic logic of them should be: Check if the bootstrap/provider.go exists, if so, add the service provider into provider.go, if not, add the service provider into config/app.go. The same as UninstallServiceProvider

Copy link
Member Author

@krishankumar01 krishankumar01 Oct 27, 2025

Choose a reason for hiding this comment

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

Hmm, I believe the logic should ideally be this: if providers.go doesn’t exist, then create it and add the provider(this should also add .WithProviders(Providers()) automatically). Otherwise, we won’t be able to deprecate the old one. In the case of uninstall, we should first try to uninstall from providers.go and then from the config as a fallback. This way, we establish the habit that new providers should go into providers.go, and the user can either migrate app.providers to providers.go or maintain both.

Copy link
Contributor

Choose a reason for hiding this comment

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

The old project may not use foundation.Configure, so creating providers.go is unnecessary.

Copy link
Contributor

Choose a reason for hiding this comment

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

providers.go should exist in the new project by default, app_service_provider should be registered there.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm, make sense, but in case of uninstall regardless of providers.go should I try to delete from both the file?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, I think so.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.50.

Benchmark suite Current: da8a5c4 Previous: 100c50f Ratio
Benchmark_DecryptString 6551 ns/op 2032 B/op 16 allocs/op 2109 ns/op 2032 B/op 16 allocs/op 3.11
Benchmark_DecryptString - ns/op 6551 ns/op 2109 ns/op 3.11

This comment was automatically generated by workflow using github-action-benchmark.

@hwbrzzl
Copy link
Contributor

hwbrzzl commented Nov 22, 2025

Hey @kkumar-gcc This PR is blocking me, let me optimize it directly. Thanks for the completed logic.

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 34 out of 34 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@hwbrzzl
Copy link
Contributor

hwbrzzl commented Nov 22, 2025

Hey @kkumar-gcc This PR has been completed. Could you review it if you have time? I'll merge it if you don't have any concerns. Thanks!

Copy link
Member Author

@krishankumar01 krishankumar01 left a comment

Choose a reason for hiding this comment

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

LGTM, just a couple of doubts


func (r *Application) BootstrapPath(path ...string) string {
path = append([]string{support.RelativePath, "bootstrap"}, path...)
return internals.Abs(path...)
Copy link
Member Author

Choose a reason for hiding this comment

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

Should we use r.Path here?

Copy link
Contributor

Choose a reason for hiding this comment

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

r.Path is app/**, so it cannot be used here.

return WrapNewline(expr)
}

// RemoveProvider removes a service provider from the foundation.Setup() chain in the Boot function.
Copy link
Member Author

Choose a reason for hiding this comment

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

Are we moving towards GoDoc-style comments? Though most of these feels redundant.

Copy link
Contributor

Choose a reason for hiding this comment

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

The logic is a bit complicated, so the comment is necessary I think, and it's also used by AI, it should not be a big deal.

}

// Remove from inline array in app.go
if err := GoFile(r.appFilePath).Find(match.FoundationSetup()).Modify(r.removeInline(item)).Apply(); err != nil {
Copy link
Member Author

Choose a reason for hiding this comment

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

Will this also remove provider from config/app.go?

Copy link
Contributor

Choose a reason for hiding this comment

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

The current goravel/goravel structure doesn't support package:install/uninsatll facade, so I think it's unnecessary to remove provider from config/app.go.

@hwbrzzl hwbrzzl merged commit 23144c7 into master Nov 24, 2025
14 of 15 checks passed
@hwbrzzl hwbrzzl deleted the kkumar-gcc/#790-2 branch November 24, 2025 13:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants