Skip to content

feat: [#881] add imports alias support in package setup#1437

Merged
almas-x merged 5 commits into
masterfrom
almas/#881
Apr 10, 2026
Merged

feat: [#881] add imports alias support in package setup#1437
almas-x merged 5 commits into
masterfrom
almas/#881

Conversation

@almas-x

@almas-x almas-x commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

📑 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:

  • The full package name multiple times in code
  • Or manually manage imports with aliases

Example

func main() {
    setup := packages.Setup(os.Args)
    serviceProvider := "&admin.ServiceProvider{}"
    moduleImport := setup.Paths().Module().Import() // e.g., github.com/some/goravel-admin
    configPath := path.Config("goravel_admin.go")

    setup.Install(
        // ✨ Register the service provider with 'admin' alias
        modify.RegisterProvider("admin "+moduleImport, serviceProvider),
        
        // Add config
        modify.File(configPath).Overwrite(config(...)),
    ).Uninstall(
        modify.File(configPath).Remove(),
        modify.UnregisterProvider("admin "+moduleImport, serviceProvider),
    ).Execute()
}

After installation, bootstrap/providers.go will contain aliased import and provider usage, for example:

import (
    // ...
    admin "github.com/some/goravel-admin"
    // ...
)

func Providers() []foundation.ServiceProvider {
    return []foundation.ServiceProvider{
        // ...
        &admin.ServiceProvider{},
        // ...
    }
}

@coderabbitai summary

✅ Checks

  • Added test cases for my code

@almas-x
almas-x requested a review from a team as a code owner April 9, 2026 07:44
Copilot AI review requested due to automatic review settings April 9, 2026 07:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Comment thread packages/modify/utils.go
Comment on lines +442 to +444
if alias, importPath, found := strings.Cut(pkg, " "); found {
return GoFile(appFilePath).FindOrCreate(importMatchers, createImport).Modify(AddImport(importPath, alias)).Apply()
}

Copilot AI Apr 9, 2026

Copy link

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment thread packages/modify/utils.go Outdated
Comment on lines +443 to +447
return GoFile(appFilePath).FindOrCreate(importMatchers, createImport).Modify(AddImport(importPath, alias)).Apply()
}

return GoFile(appFilePath).FindOrCreate(importMatchers, createImport).Modify(AddImport(pkg)).Apply()
}

Copilot AI Apr 9, 2026

Copy link

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment on lines +1843 to +1858

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 (

Copilot AI Apr 9, 2026

Copy link

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings April 9, 2026 07:51
@codecov

codecov Bot commented Apr 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 71.42857% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.78%. Comparing base (cb974a8) to head (51920f2).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
packages/modify/utils.go 78.57% 1 Missing and 2 partials ⚠️
packages/modify/with_slice_actions.go 57.14% 0 Missing and 3 partials ⚠️
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.
📢 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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 4 comments.


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

Comment thread packages/modify/utils.go Outdated
Comment on lines +439 to +446
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()

Copilot AI Apr 9, 2026

Copy link

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment thread packages/modify/utils.go
Comment on lines +497 to +503
// 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()
}

Copilot AI Apr 9, 2026

Copy link

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment on lines 321 to +324
// 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)

Copilot AI Apr 9, 2026

Copy link

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could you help implement this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Could you help implement this?

Okay,I'll try.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes, we can just need to optimize the annotation to keep the same logic as before.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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

Comment thread packages/modify/utils.go
Comment on lines +438 to +447
// 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()
}

Copilot AI Apr 9, 2026

Copy link

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.

@hwbrzzl hwbrzzl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Great 👍

Comment on lines 321 to +324
// 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)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could you help implement this?

Comment thread packages/modify/utils.go Outdated
Comment thread packages/modify/utils.go Outdated
Co-authored-by: Wenbo Han <hwbrzzl@gmail.com>
Copilot AI review requested due to automatic review settings April 10, 2026 03:46
Co-authored-by: Wenbo Han <hwbrzzl@gmail.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 3 comments.

Comments suppressed due to low confidence (1)

packages/modify/utils.go:128

  • Alias import support was added to AddRoute/RemoveRoute via addImportsToFile/removeImportsFromFile, but TestAddRoute/TestRemoveRoute don’t include any alias cases (unlike provider tests). Please add tests covering pkg in 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.

Comment thread packages/modify/utils.go
Comment on lines +442 to +446
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()

Copilot AI Apr 10, 2026

Copy link

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment on lines 321 to +324
// 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)

Copilot AI Apr 10, 2026

Copy link

Choose a reason for hiding this comment

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

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

Copilot uses AI. Check for mistakes.
Comment thread packages/modify/utils.go
Comment on lines 120 to +124
// 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 {

Copilot AI Apr 10, 2026

Copy link

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.

@hwbrzzl hwbrzzl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks, LGTM

@almas-x
almas-x merged commit 74e578a into master Apr 10, 2026
17 checks passed
@almas-x
almas-x deleted the almas/#881 branch April 10, 2026 04:03
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