From 5fe4eec2367913d37b2a2e902028cfd7f3722cae Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 12 Jan 2026 01:56:41 +0000 Subject: [PATCH] Apply gci import order changes --- cmd/gf/internal/cmd/cmddep/cmddep_analyzer.go | 111 +++++++++--------- .../cmd/cmddep/cmddep_external_test.go | 2 +- cmd/gf/internal/cmd/cmddep/cmddep_output.go | 24 ++-- cmd/gf/internal/cmd/cmddep/cmddep_server.go | 14 +-- .../internal/cmd/cmddep/cmddep_z_unit_test.go | 22 ++-- 5 files changed, 86 insertions(+), 87 deletions(-) diff --git a/cmd/gf/internal/cmd/cmddep/cmddep_analyzer.go b/cmd/gf/internal/cmd/cmddep/cmddep_analyzer.go index beb0d7e10..f56c818ed 100644 --- a/cmd/gf/internal/cmd/cmddep/cmddep_analyzer.go +++ b/cmd/gf/internal/cmd/cmddep/cmddep_analyzer.go @@ -40,8 +40,8 @@ type PackageKind int const ( KindInternal PackageKind = iota // Internal to main module - KindExternal // External dependency - KindStdLib // Standard library + KindExternal // External dependency + KindStdLib // Standard library ) // PackageInfo represents unified information about a Go package. @@ -79,11 +79,11 @@ type FilterOptions struct { // It centralizes visited tracking, depth management, and filtering logic // to ensure consistent behavior across different output formats. type TraversalContext struct { - visited map[string]bool // Track visited packages to prevent cycles - depth int // Current traversal depth - maxDepth int // Maximum traversal depth - options *FilterOptions // Filtering criteria - store *PackageStore // Reference to package store + visited map[string]bool // Track visited packages to prevent cycles + depth int // Current traversal depth + maxDepth int // Maximum traversal depth + options *FilterOptions // Filtering criteria + store *PackageStore // Reference to package store } // PackageStore manages a collection of packages and provides unified data access. @@ -91,10 +91,10 @@ type TraversalContext struct { // It replaces the scattered data access patterns in the original analyzer. type PackageStore struct { packages map[string]*PackageInfo // Package data indexed by import path - modulePrefix string // Main module path (from go.mod) - sortedPkgs []string // Cached sorted package list - internalCount int // Cached count of internal packages - externalCount int // Cached count of external packages + modulePrefix string // Main module path (from go.mod) + sortedPkgs []string // Cached sorted package list + internalCount int // Cached count of internal packages + externalCount int // Cached count of external packages } // analyzer handles dependency analysis. @@ -105,9 +105,9 @@ type analyzer struct { edges map[string]bool store *PackageStore // New unified package store // Module-level dependency data (from go mod graph) - modules map[string]*ModuleInfo // All modules indexed by path - moduleGraph map[string][]string // Module dependency graph: module -> dependencies - directModules map[string]bool // Direct dependencies (from go.mod require) + modules map[string]*ModuleInfo // All modules indexed by path + moduleGraph map[string][]string // Module dependency graph: module -> dependencies + directModules map[string]bool // Direct dependencies (from go.mod require) } // ModuleInfo represents a Go module dependency. @@ -169,12 +169,13 @@ func (a *analyzer) detectModulePrefix() string { // loadPackages loads package information using go list with optimized approach. // OPTIMIZATION: Reduced from 3 separate go list calls to 2 efficient calls: // Previously: -// 1. go list -json %s (target packages only) -// 2. go list -json -deps %s (with dependencies) -// 3. go list -json -m all (all modules) +// 1. go list -json %s (target packages only) +// 2. go list -json -deps %s (with dependencies) +// 3. go list -json -m all (all modules) +// // Now (optimized): -// 1. go list -json -m all (all modules - fast, definitive) -// 2. go list -json -deps ./... (all packages with dependencies) +// 1. go list -json -m all (all modules - fast, definitive) +// 2. go list -json -deps ./... (all packages with dependencies) func (a *analyzer) loadPackages(ctx context.Context, pkgPath string) error { // First, load module information - this is fast and provides module metadata // Load all module dependencies using go list -m all @@ -659,13 +660,13 @@ func (a *analyzer) convertInputToFilterOptions(in Input) *FilterOptions { IncludeStdLib: !in.NoStd, Depth: in.Depth, } - + // Apply default: if neither internal nor external, include internal only if !in.Internal && !in.External { opts.IncludeInternal = true opts.IncludeExternal = false } - + return opts } @@ -736,14 +737,14 @@ func (opts *FilterOptions) Normalize(modulePrefix string) error { opts.IncludeInternal = true opts.IncludeExternal = false } - + // Always include stdlib by default unless explicitly excluded if opts.IncludeStdLib == false { // This is the default (NoStd=true), stdlib is excluded } else { opts.IncludeStdLib = true } - + return nil } @@ -764,7 +765,7 @@ func (opts *FilterOptions) ShouldInclude(pkg *PackageInfo) bool { return false } } - + return true } @@ -783,26 +784,26 @@ func (tc *TraversalContext) GetDependencies(pkg string) []string { if !ok { return []string{} } - + result := make([]string, 0) seen := make(map[string]bool) - + for _, dep := range pkgInfo.Imports { if seen[dep] { continue } - + depInfo, ok := tc.store.packages[dep] if !ok { continue } - + if tc.options.ShouldInclude(depInfo) { seen[dep] = true result = append(result, dep) } } - + return result } @@ -819,7 +820,7 @@ func (a *analyzer) shortName(pkg string, group bool) string { } return short } - + // For external packages, handle grouping differently if group { return a.getExternalGroup(pkg) @@ -833,7 +834,7 @@ func (a *analyzer) getExternalGroup(pkg string) string { if a.isStdLib(pkg) { return "stdlib" } - + // For external packages, group by domain/organization parts := gstr.Split(pkg, "/") if len(parts) > 0 { @@ -870,7 +871,7 @@ func (a *analyzer) getSortedPackages() []string { func (a *analyzer) collectEdges(in Input) map[string]bool { opts := a.convertInputToFilterOptions(in) opts.Normalize(a.modulePrefix) - + store := a.buildPackageStore() edges := make(map[string]bool) visited := make(map[string]bool) @@ -898,7 +899,7 @@ func (a *analyzer) collectEdgesRecursiveNew(pkgPath string, opts *FilterOptions, visited[pkgPath] = true fromName := a.shortName(pkgPath, in.Group) - + for _, dep := range pkgInfo.Imports { depInfo, ok := store.packages[dep] if !ok || !opts.ShouldInclude(depInfo) { @@ -918,10 +919,10 @@ func (a *analyzer) collectEdgesRecursiveNew(pkgPath string, opts *FilterOptions, // getDependencyStats returns statistics about dependencies using new system. func (a *analyzer) getDependencyStats(_ Input) map[string]any { stats := make(map[string]any) - + var internalCount, externalCount, stdlibCount int externalGroups := make(map[string]int) - + store := a.buildPackageStore() opts := &FilterOptions{ IncludeInternal: true, @@ -929,12 +930,12 @@ func (a *analyzer) getDependencyStats(_ Input) map[string]any { IncludeStdLib: true, Depth: 0, } - + for _, pkgInfo := range store.packages { if !opts.ShouldInclude(pkgInfo) { continue } - + if pkgInfo.IsStdLib { stdlibCount++ } else if pkgInfo.Kind == KindInternal { @@ -945,13 +946,13 @@ func (a *analyzer) getDependencyStats(_ Input) map[string]any { externalGroups[group]++ } } - + stats["total"] = len(store.packages) stats["internal"] = internalCount stats["external"] = externalCount stats["stdlib"] = stdlibCount stats["external_groups"] = externalGroups - + return stats } @@ -966,7 +967,7 @@ func (ps *PackageStore) TraverseDependencies( options: options, store: ps, } - + result := make([]string, 0) ps.traverseRecursive(root, ctx, &result) return result @@ -981,22 +982,22 @@ func (ps *PackageStore) traverseRecursive( if ctx.maxDepth > 0 && ctx.depth >= ctx.maxDepth { return } - + if ctx.Visit(pkg) { return // Already visited } - + pkgInfo, ok := ps.packages[pkg] if !ok { return } - + if !ctx.options.ShouldInclude(pkgInfo) { return // Filtered out } - + *result = append(*result, pkg) - + ctx.depth++ for _, dep := range pkgInfo.Imports { ps.traverseRecursive(dep, ctx, result) @@ -1010,7 +1011,7 @@ func (ps *PackageStore) TraverseReverse( options *FilterOptions, ) []string { result := make([]string, 0) - + // Build reverse dependency map on-the-fly for _, pkg := range ps.packages { for _, dep := range pkg.Imports { @@ -1019,7 +1020,7 @@ func (ps *PackageStore) TraverseReverse( } } } - + sort.Strings(result) return result } @@ -1027,7 +1028,7 @@ func (ps *PackageStore) TraverseReverse( // buildPackageStore converts current analyzer state to PackageStore for new traversal system. func (a *analyzer) buildPackageStore() *PackageStore { store := newPackageStore(a.modulePrefix) - + // Convert go packages to PackageInfo for path, goPkg := range a.packages { pkgInfo := &PackageInfo{ @@ -1039,7 +1040,7 @@ func (a *analyzer) buildPackageStore() *PackageStore { pkgInfo.Kind = store.identifyPackageKind(pkgInfo) store.packages[path] = pkgInfo } - + return store } @@ -1047,16 +1048,16 @@ func (a *analyzer) buildPackageStore() *PackageStore { func (a *analyzer) getFilteredPackages(in Input) []*PackageInfo { opts := a.convertInputToFilterOptions(in) opts.Normalize(a.modulePrefix) - + store := a.buildPackageStore() result := make([]*PackageInfo, 0) - + for _, pkgInfo := range store.packages { if opts.ShouldInclude(pkgInfo) { result = append(result, pkgInfo) } } - + return result } @@ -1066,16 +1067,16 @@ func (a *analyzer) getFilteredDependencies(pkgPath string, in Input) []string { if !ok { return []string{} } - + opts := a.convertInputToFilterOptions(in) opts.Normalize(a.modulePrefix) - + store := a.buildPackageStore() ctx := &TraversalContext{ visited: make(map[string]bool), options: opts, store: store, } - + return ctx.GetDependencies(pkgPath) } diff --git a/cmd/gf/internal/cmd/cmddep/cmddep_external_test.go b/cmd/gf/internal/cmd/cmddep/cmddep_external_test.go index b62718fa8..50392f31e 100644 --- a/cmd/gf/internal/cmd/cmddep/cmddep_external_test.go +++ b/cmd/gf/internal/cmd/cmddep/cmddep_external_test.go @@ -104,4 +104,4 @@ func TestDependencyStats(t *testing.T) { t.Assert(stats["external"], 1) t.Assert(stats["stdlib"], 1) }) -} \ No newline at end of file +} diff --git a/cmd/gf/internal/cmd/cmddep/cmddep_output.go b/cmd/gf/internal/cmd/cmddep/cmddep_output.go index 17222ec14..ba7af96cb 100644 --- a/cmd/gf/internal/cmd/cmddep/cmddep_output.go +++ b/cmd/gf/internal/cmd/cmddep/cmddep_output.go @@ -48,7 +48,7 @@ func (a *analyzer) generateTree(in Input) string { fmt.Fprintf(&sb, " Internal: %v\n", stats["internal"]) fmt.Fprintf(&sb, " External: %v\n", stats["external"]) fmt.Fprintf(&sb, " Standard library: %v\n", stats["stdlib"]) - + if groups, ok := stats["external_groups"].(map[string]int); ok && len(groups) > 0 { sb.WriteString(" External groups:\n") for group, count := range groups { @@ -77,10 +77,10 @@ func (a *analyzer) generateTree(in Input) string { if !ok || !opts.ShouldInclude(pkgInfo) { continue } - + shortName := a.shortName(pkgPath, in.Group) sb.WriteString(shortName + "\n") - + // Use new traversal system a.printTreeNodeNew(&sb, pkgPath, "", in, ctx, 0) } @@ -114,8 +114,6 @@ func (a *analyzer) findRootPackages() []string { return roots } - - // printTreeNodeNew prints tree node using new traversal system. func (a *analyzer) printTreeNodeNew(sb *strings.Builder, pkgPath string, prefix string, in Input, ctx *TraversalContext, depth int) { if ctx.maxDepth > 0 && depth >= ctx.maxDepth { @@ -163,16 +161,16 @@ func (a *analyzer) printTreeNodeNew(sb *strings.Builder, pkgPath string, prefix // generateList generates simple list output using new traversal system. func (a *analyzer) generateList(in Input) string { var sb strings.Builder - + // Prepare options opts := a.convertInputToFilterOptions(in) opts.Normalize(a.modulePrefix) - + // Add statistics header if showing external dependencies if in.External { stats := a.getDependencyStats(in) sb.WriteString("# Dependency Statistics\n") - fmt.Fprintf(&sb, "# Total: %v, Internal: %v, External: %v, Stdlib: %v\n", + fmt.Fprintf(&sb, "# Total: %v, Internal: %v, External: %v, Stdlib: %v\n", stats["total"], stats["internal"], stats["external"], stats["stdlib"]) sb.WriteString("\n") } @@ -278,7 +276,7 @@ func (a *analyzer) generateJSON(in Input) string { store := a.buildPackageStore() result := make(map[string]any) - + // Add dependency nodes nodes := make([]*depNode, 0) for _, pkgPath := range a.getSortedPackages() { @@ -293,10 +291,10 @@ func (a *analyzer) generateJSON(in Input) string { nodes = append(nodes, node) } result["dependencies"] = nodes - + // Add statistics result["statistics"] = a.getDependencyStats(in) - + // Add metadata result["metadata"] = map[string]any{ "module": a.modulePrefix, @@ -307,7 +305,7 @@ func (a *analyzer) generateJSON(in Input) string { "external": in.External, "nostd": in.NoStd, } - + data, err := json.MarshalIndent(result, "", " ") if err != nil { return fmt.Sprintf("Error: %v", err) @@ -361,7 +359,7 @@ func (a *analyzer) buildDepNode(pkg *goPackage, in Input, depth int) *depNode { func (a *analyzer) generateReverse(in Input) string { opts := a.convertInputToFilterOptions(in) opts.Normalize(a.modulePrefix) - + store := a.buildPackageStore() // Build reverse dependency map diff --git a/cmd/gf/internal/cmd/cmddep/cmddep_server.go b/cmd/gf/internal/cmd/cmddep/cmddep_server.go index 78301f3ea..fad1d8cb7 100644 --- a/cmd/gf/internal/cmd/cmddep/cmddep_server.go +++ b/cmd/gf/internal/cmd/cmddep/cmddep_server.go @@ -195,7 +195,7 @@ func (a *analyzer) handleGraphAPI(w http.ResponseWriter, r *http.Request, in Inp return } } - + data := a.buildModuleGraphData(in) w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(data) @@ -288,13 +288,13 @@ func (a *analyzer) handlePackagesAPI(w http.ResponseWriter, r *http.Request, in UsedByCount: usedByMap[shortName], }) } - + // Add statistics to response result := map[string]any{ "packages": packages, "statistics": a.getDependencyStats(in), } - + w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(result) } @@ -398,7 +398,7 @@ func (a *analyzer) handleTreeAPI(w http.ResponseWriter, r *http.Request, in Inpu return } } - + output := a.generateModuleTree(in) w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.Write([]byte(output)) @@ -442,7 +442,7 @@ func (a *analyzer) handleListAPI(w http.ResponseWriter, r *http.Request, in Inpu return } } - + output := a.generateModuleList(in) w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.Write([]byte(output)) @@ -880,7 +880,7 @@ func (s *serverState) handleAnalyzeAPI(w http.ResponseWriter, r *http.Request) { // IMPORTANT: Load module dependencies from the actual module directory // We need to run commands in moduleDir context to get the correct direct/indirect info // Running in tempDir would show everything as indirect since we're not using them there - + // IMPORTANT: Load direct dependencies info FIRST // This must be done before parsing go mod graph so that IsDirect flag is correct listModCmd := exec.Command("go", "list", "-m", "-json", "all") @@ -1051,7 +1051,7 @@ func (a *analyzer) handleModulesAPI(w http.ResponseWriter, in Input) { return } } - + modules := a.getFilteredModules(in) // Build module list diff --git a/cmd/gf/internal/cmd/cmddep/cmddep_z_unit_test.go b/cmd/gf/internal/cmd/cmddep/cmddep_z_unit_test.go index 50afeb108..06e9404a3 100644 --- a/cmd/gf/internal/cmd/cmddep/cmddep_z_unit_test.go +++ b/cmd/gf/internal/cmd/cmddep/cmddep_z_unit_test.go @@ -41,7 +41,7 @@ func Test_FilterOptions_Normalize(t *testing.T) { IncludeStdLib: false, } opts.Normalize("github.com/gogf/gf/v2") - + // After normalization, internal should be included by default t.Assert(opts.IncludeInternal, true) t.Assert(opts.IncludeExternal, false) @@ -57,7 +57,7 @@ func Test_FilterOptions_ShouldInclude(t *testing.T) { IncludeExternal: false, IncludeStdLib: true, } - + internalPkg := &PackageInfo{ Kind: KindInternal, IsStdLib: false, @@ -70,7 +70,7 @@ func Test_FilterOptions_ShouldInclude(t *testing.T) { Kind: KindStdLib, IsStdLib: true, } - + t.Assert(opts.ShouldInclude(internalPkg), true) t.Assert(opts.ShouldInclude(externalPkg), false) t.Assert(opts.ShouldInclude(stdlibPkg), true) @@ -83,7 +83,7 @@ func Test_TraversalContext_Visit(t *testing.T) { ctx := &TraversalContext{ visited: make(map[string]bool), } - + // First visit should return false t.Assert(ctx.Visit("pkg1"), false) // Second visit should return true @@ -105,7 +105,7 @@ func Test_GuessModuleRoot(t *testing.T) { {"github.com/gogf/gf/v2/os/gfile", "github.com/gogf/gf/v2"}, {"github.com/gogf/gf/v2/os", "github.com/gogf/gf/v2"}, } - + for _, test := range tests { result := guessModuleRoot(test.input) t.AssertEQ(result, test.expect) @@ -117,7 +117,7 @@ func Test_GuessModuleRoot(t *testing.T) { func Test_ConvertInputToFilterOptions(t *testing.T) { gtest.C(t, func(t *gtest.T) { a := newAnalyzer() - + input := Input{ Internal: true, External: false, @@ -126,9 +126,9 @@ func Test_ConvertInputToFilterOptions(t *testing.T) { Direct: false, Depth: 3, } - + opts := a.convertInputToFilterOptions(input) - + t.Assert(opts.IncludeInternal, true) t.Assert(opts.IncludeExternal, false) t.Assert(opts.IncludeStdLib, false) // NoStd=true means !IncludeStdLib @@ -239,16 +239,16 @@ func Test_Dep_Group(t *testing.T) { func Test_ModuleLevel_Direct(t *testing.T) { gtest.C(t, func(t *gtest.T) { ctx := gctx.New() - + // Test module level with direct only in := Input{ Module: true, Direct: true, Format: "list", } - + t.Logf("Input.Module: %v, Input.Direct: %v", in.Module, in.Direct) - + _, err := Dep.Index(ctx, in) t.AssertNil(err) })