feat: [#881] add imports alias support in package setup#1437
Conversation
There was a problem hiding this comment.
Pull request overview
Adds support for Go import aliases when registering packages via the setup/modify helpers, enabling cleaner provider/route registrations for packages with long import paths.
Changes:
- Introduced helper functions to add/remove imports that optionally include an alias (e.g.,
"admin github.com/foo/bar"). - Refactored slice-based and route modifications to use the new import helper utilities.
- Added tests covering provider registration/unregistration using an import alias.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| packages/modify/with_slice_actions.go | Refactors import add/remove paths to use centralized alias-aware helpers. |
| packages/modify/utils.go | Adds addImportsToFile / removeImportsFromFile with alias parsing; updates route add/remove to use them. |
| packages/modify/utils_test.go | Adds test cases validating provider add/remove flows when using an import alias. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if alias, importPath, found := strings.Cut(pkg, " "); found { | ||
| return GoFile(appFilePath).FindOrCreate(importMatchers, createImport).Modify(AddImport(importPath, alias)).Apply() | ||
| } |
There was a problem hiding this comment.
addImportsToFile uses strings.Cut(pkg, " ") without trimming/validating. Inputs with leading/multiple whitespace can yield an empty alias or an importPath with leading spaces, producing an invalid import ident/path and failing formatting/compilation. Consider using strings.Fields/TrimSpace and explicitly validating that the alias is a valid Go identifier before calling AddImport.
| return GoFile(appFilePath).FindOrCreate(importMatchers, createImport).Modify(AddImport(importPath, alias)).Apply() | ||
| } | ||
|
|
||
| return GoFile(appFilePath).FindOrCreate(importMatchers, createImport).Modify(AddImport(pkg)).Apply() | ||
| } |
There was a problem hiding this comment.
When an alias is requested, AddImport(importPath, alias) will no-op if the file already imports the same importPath (because AddImport only de-dupes by path). That can leave the import unaliased while the generated code references the alias (e.g., &r.ServiceProvider{}), causing a compile error. Update AddImport (or add an alias-aware action here) to set/verify the existing ImportSpec.Name when the path matches, or return a clear error when the path is already imported under a different name.
|
|
||
| import ( | ||
| contractsfoundation "github.com/goravel/framework/contracts/foundation" | ||
| "github.com/goravel/framework/foundation" | ||
| "goravel/config" | ||
| ) | ||
|
|
||
| func Boot() contractsfoundation.Application { | ||
| return foundation.Setup().WithConfig(config.Boot).Start() | ||
| } | ||
| `, | ||
| pkg: "r github.com/goravel/redis", | ||
| provider: "&r.ServiceProvider{}", | ||
| expectedApp: `package bootstrap | ||
|
|
||
| import ( |
There was a problem hiding this comment.
The new alias support is tested for the fresh-add/remove cases, but there isn’t coverage for the important conflict case where the target file already imports the same package path without an alias (or with a different alias). Adding a test that asserts the chosen behavior (update alias vs return error) would help prevent regressions and clarify expected semantics.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1437 +/- ##
=======================================
Coverage 68.78% 68.78%
=======================================
Files 361 361
Lines 27829 27833 +4
=======================================
+ Hits 19141 19145 +4
Misses 7840 7840
Partials 848 848 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| func addImportsToFile(appFilePath, pkg string) error { | ||
| importMatchers := match.Imports() | ||
|
|
||
| if alias, importPath, found := strings.Cut(pkg, " "); found { | ||
| return GoFile(appFilePath).FindOrCreate(importMatchers, createImport).Modify(AddImport(importPath, alias)).Apply() | ||
| } | ||
|
|
||
| return GoFile(appFilePath).FindOrCreate(importMatchers, createImport).Modify(AddImport(pkg)).Apply() |
There was a problem hiding this comment.
Alias parsing uses strings.Cut(pkg, " ") without trimming/validation. Inputs like multiple spaces (e.g., "r github.com/x") will produce an import path with leading whitespace, which becomes an invalid quoted import path. Consider strings.Fields (expect exactly 1 or 2 fields) or TrimSpace on both parts and reject empty alias/path.
| // removeImportsFromFile removes the specified import from the file. | ||
| func removeImportsFromFile(appFilePath, pkg string) error { | ||
| importMatchers := match.Imports() | ||
|
|
||
| if alias, importPath, found := strings.Cut(pkg, " "); found { | ||
| return GoFile(appFilePath).Find(importMatchers).Modify(RemoveImport(importPath, alias)).Apply() | ||
| } |
There was a problem hiding this comment.
removeImportsFromFile calls RemoveImport(importPath, alias), but match.Import(path, name...) currently matches the import even when ImportSpec.Name is nil (see packages/match/match.go:218-233). Combined with IsUsingImport(..., alias) this can incorrectly delete a non-aliased import that is still used under its real package name, breaking compilation. Fix by making match.Import require im.Name != nil && im.Name.Name == name when a name is provided, and/or tighten RemoveImport to only delete exact alias matches.
| // removeImports removes the item package import if it's no longer used. | ||
| // It checks both app.go and the helper file (if it exists) to determine if the import is still in use. | ||
| func (r *withSliceHandler) removeImports(pkg string) error { | ||
| importMatchers := match.Imports() | ||
| return GoFile(r.appFilePath).Find(importMatchers).Modify(RemoveImport(pkg)).Apply() | ||
| return removeImportsFromFile(r.appFilePath, pkg) |
There was a problem hiding this comment.
The comment says removeImports checks both app.go and the helper file, but the implementation only removes from r.appFilePath (helper-file cleanup happens elsewhere via removeItemFromFile). Please update the comment to match behavior, or extend removeImports to actually check both locations if that’s the intended contract.
There was a problem hiding this comment.
Could you help implement this?
There was a problem hiding this comment.
Could you help implement this?
Okay,I'll try.
There was a problem hiding this comment.
Yes, we can just need to optimize the annotation to keep the same logic as before.
There was a problem hiding this comment.
Yes, we can just need to optimize the annotation to keep the same logic as before.
Got it — we'll just update the comment to reflect the existing behavior (keep logic unchanged).
| // addImportsToFile adds the specified import to the file, creating the import block if needed. | ||
| func addImportsToFile(appFilePath, pkg string) error { | ||
| importMatchers := match.Imports() | ||
|
|
||
| if alias, importPath, found := strings.Cut(pkg, " "); found { | ||
| return GoFile(appFilePath).FindOrCreate(importMatchers, createImport).Modify(AddImport(importPath, alias)).Apply() | ||
| } | ||
|
|
||
| return GoFile(appFilePath).FindOrCreate(importMatchers, createImport).Modify(AddImport(pkg)).Apply() | ||
| } |
There was a problem hiding this comment.
Alias support is introduced via addImportsToFile, but current tests only cover provider install/uninstall through providers.go. Consider adding coverage for alias imports when modifying bootstrap/app.go (e.g., AddRoute/RemoveRoute and middleware setup) and for edge cases like an existing import of the same path with a different/no alias.
| // removeImports removes the item package import if it's no longer used. | ||
| // It checks both app.go and the helper file (if it exists) to determine if the import is still in use. | ||
| func (r *withSliceHandler) removeImports(pkg string) error { | ||
| importMatchers := match.Imports() | ||
| return GoFile(r.appFilePath).Find(importMatchers).Modify(RemoveImport(pkg)).Apply() | ||
| return removeImportsFromFile(r.appFilePath, pkg) |
There was a problem hiding this comment.
Could you help implement this?
Co-authored-by: Wenbo Han <hwbrzzl@gmail.com>
Co-authored-by: Wenbo Han <hwbrzzl@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (1)
packages/modify/utils.go:128
- Alias import support was added to
AddRoute/RemoveRouteviaaddImportsToFile/removeImportsFromFile, butTestAddRoute/TestRemoveRoutedon’t include any alias cases (unlike provider tests). Please add tests coveringpkgin the"<alias> <importPath>"format for both adding and removing routes to prevent regressions.
if err := addImportsToFile(appFilePath, pkg); err != nil {
return err
}
return GoFile(appFilePath).Find(match.FoundationSetup()).Modify(foundationSetupRouting(route)).Apply()
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if alias, importPath, found := strings.Cut(pkg, " "); found { | ||
| return GoFile(filePath).FindOrCreate(importMatchers, createImport).Modify(AddImport(importPath, alias)).Apply() | ||
| } | ||
|
|
||
| return GoFile(filePath).FindOrCreate(importMatchers, createImport).Modify(AddImport(pkg)).Apply() |
There was a problem hiding this comment.
addImportsToFile takes filePath but calls GoFile(appFilePath) in both branches. appFilePath isn’t defined in this scope (won’t compile) and it also ignores the filePath argument. Use the filePath parameter when selecting the file to modify.
| // removeImports removes the item package import if it's no longer used. | ||
| // It checks both app.go and the helper file (if it exists) to determine if the import is still in use. | ||
| func (r *withSliceHandler) removeImports(pkg string) error { | ||
| importMatchers := match.Imports() | ||
| return GoFile(r.appFilePath).Find(importMatchers).Modify(RemoveImport(pkg)).Apply() | ||
| return removeImportsFromFile(r.appFilePath, pkg) |
There was a problem hiding this comment.
The removeImports doc comment says it checks both app.go and the helper file, but the implementation only removes from r.appFilePath. Please update the comment to reflect the actual behavior (the usage check seems to happen elsewhere).
| // the route will be like "routes.Web()" | ||
| func AddRoute(pkg, route string) error { | ||
| appFilePath := path.Bootstrap("app.go") | ||
|
|
||
| if err := addRouteImports(appFilePath, pkg); err != nil { | ||
| if err := addImportsToFile(appFilePath, pkg); err != nil { |
There was a problem hiding this comment.
The AddRoute docstring still describes pkg strictly as an import path (e.g. "goravel/routes"), but the implementation now routes through addImportsToFile, which also accepts the "<alias> <importPath>" form. Please update the comment (and any similar ones) so callers know aliases are supported.
📑 Description
Closes goravel/goravel#881
Add support for import aliases when registering packages through the setup helpers. This allows developers to use custom package names with long import paths, improving code readability and reducing verbosity.
When registering service providers or other packages with long import paths, developers often had to use either:
Example
After installation,
bootstrap/providers.gowill contain aliased import and provider usage, for example:@coderabbitai summary
✅ Checks