diff --git a/ignite/pkg/cosmosanalysis/app/app.go b/ignite/pkg/cosmosanalysis/app/app.go index 41f284e4e2..85e54ab098 100644 --- a/ignite/pkg/cosmosanalysis/app/app.go +++ b/ignite/pkg/cosmosanalysis/app/app.go @@ -1,19 +1,25 @@ package app import ( + "context" + "errors" "fmt" "go/ast" "go/parser" "go/token" + "os" "path/filepath" "strings" + "github.com/ignite/cli/ignite/pkg/cosmosanalysis" + "github.com/ignite/cli/ignite/pkg/cosmosver" "github.com/ignite/cli/ignite/pkg/goanalysis" + "github.com/ignite/cli/ignite/pkg/gomodule" "github.com/ignite/cli/ignite/pkg/xast" - - "github.com/ignite/cli/ignite/pkg/cosmosanalysis" ) +const registerRoutesMethod = "RegisterAPIRoutes" + // CheckKeeper checks for the existence of the keeper with the provided name in the app structure. func CheckKeeper(path, keeperName string) error { // find app type @@ -84,58 +90,37 @@ func FindRegisteredModules(chainRoot string) ([]string, error) { return nil, err } - // Loop on package's files - var blankImports []string + // Search the app for the imported SDK modules var discovered []string for _, f := range appPkg.Files { - blankImports = append(blankImports, goanalysis.FindBlankImports(f)...) + discovered = append(discovered, goanalysis.FindBlankImports(f)...) fileImports := goanalysis.FormatImports(f) - d, err := FindKeepersModules(f, fileImports) + d, err := DiscoverModules(f, chainRoot, fileImports) if err != nil { return nil, err } discovered = append(discovered, d...) } - return mergeImports(blankImports, discovered), nil -} -// mergeImports merge all discovered imports into the blank imports found in the app files. -func mergeImports(blankImports, discovered []string) []string { - imports := make([]string, len(blankImports)) - copy(imports, blankImports) - for i, m := range discovered { - split := strings.Split(m, "/") - - j := len(split) - maxTrim := len(split) - 3 - LoopBack: - for j > maxTrim { - j-- - // x path means we are reaching the root of the module - if split[j] == "x" { - j = maxTrim - goto LoopBack - } - for _, imp := range blankImports { - // check if the import exist into the blank imports - if strings.Contains(imp, m) { - j = -1 - goto LoopBack - } - } - m = strings.TrimSuffix(m, "/"+split[j]) - } - if j == maxTrim { - imports = append(imports, discovered[i]) + // Discover IBC wired modules + // TODO: This can be removed once IBC modules use dependency injection + ibcPath := filepath.Join(chainRoot, "app", "ibc.go") + if _, err := os.Stat(ibcPath); err == nil { + m, err := discoverIBCModules(ibcPath) + if err != nil { + return nil, err } + + discovered = append(discovered, m...) } - return imports + + return removeDuplicateEntries(discovered), nil } -// FindKeepersModules find a map of import modules based on the keepers params on the App struct. -func FindKeepersModules(n ast.Node, fileImports map[string]string) ([]string, error) { +// DiscoverModules find a map of import modules based on the configured app. +func DiscoverModules(file *ast.File, chainRoot string, fileImports map[string]string) ([]string, error) { // find app type - appImpl := cosmosanalysis.FindImplementationInFile(n, cosmosanalysis.AppImplementation) + appImpl := cosmosanalysis.FindImplementationInFile(file, cosmosanalysis.AppImplementation) appTypeName := "App" switch { case len(appImpl) > 1: @@ -144,63 +129,245 @@ func FindKeepersModules(n ast.Node, fileImports map[string]string) ([]string, er appTypeName = appImpl[0] } - file, ok := n.(*ast.File) - if !ok { - return nil, nil + var discovered []string + for _, decl := range file.Decls { + switch x := decl.(type) { + case *ast.GenDecl: + discovered = append(discovered, discoverKeeperModules(x, appTypeName, fileImports)...) + case *ast.FuncDecl: + // The modules registered by Cosmos SDK `rumtime.App` are included + // when the app registers API modules though the `App` instance. + if isRuntimeAppCalled(x) { + m, err := discoverRuntimeAppModules(chainRoot) + if err != nil { + return nil, err + } + discovered = append(discovered, m...) + } + } } + return removeDuplicateEntries(discovered), nil +} - keeperParamsMap := make(map[string]struct{}) - for _, decl := range file.Decls { - genDecl, ok := decl.(*ast.GenDecl) +func removeDuplicateEntries(entries []string) (res []string) { + seen := make(map[string]struct{}) + for _, e := range entries { + if _, ok := seen[e]; ok { + continue + } + + seen[e] = struct{}{} + res = append(res, e) + } + return +} + +func discoverKeeperModules(d *ast.GenDecl, appTypeName string, imports map[string]string) []string { + var modules []string + for _, spec := range d.Specs { + typeSpec, ok := spec.(*ast.TypeSpec) if !ok { continue } - for _, spec := range genDecl.Specs { - typeSpec, ok := spec.(*ast.TypeSpec) - if !ok { + if typeSpec.Name.Name != appTypeName { + continue + } + structType, ok := typeSpec.Type.(*ast.StructType) + if !ok { + continue + } + for _, field := range structType.Fields.List { + f := field.Type + CheckSpec: + switch spec := f.(type) { + case *ast.StarExpr: + f, ok = spec.X.(*ast.SelectorExpr) + if !ok { + continue + } + goto CheckSpec + case *ast.SelectorExpr: + if !strings.HasSuffix(spec.Sel.Name, "Keeper") { + continue + } + ident, ok := spec.X.(*ast.Ident) + if !ok { + continue + } + fileImport, ok := imports[ident.Name] + if !ok { + continue + } + modules = append(modules, removeKeeperPkgPath(fileImport)) + } + } + } + return modules +} + +func discoverRuntimeAppModules(chainRoot string) ([]string, error) { + // Resolve the absolute path to the Cosmos SDK module + cosmosPath, err := resolveCosmosPackagePath(chainRoot) + if err != nil { + return nil, err + } + + var modules []string + + // When runtime package doesn't exists it means is an older Cosmos SDK version, + // so all the module API registrations are defined within user's app. + path := filepath.Join(cosmosPath, "runtime", "app.go") + if _, err := os.Stat(path); os.IsNotExist(err) { + return modules, nil + } + + f, _, err := xast.ParseFile(path) + if err != nil { + return nil, err + } + + imports := goanalysis.FormatImports(f) + err = xast.Inspect(f, func(n ast.Node) error { + if pkgs := findRegisterAPIRoutesRegistrations(n); pkgs != nil { + for _, p := range pkgs { + if m := imports[p]; m != "" { + modules = append(modules, m) + } + } + return xast.ErrStop + } + return nil + }) + + if err != nil { + return nil, err + } + return modules, nil +} + +func discoverIBCModules(ibcPath string) ([]string, error) { + f, _, err := xast.ParseFile(ibcPath) + if err != nil { + return nil, err + } + + var ( + names []string + imports = goanalysis.FormatImports(f) + ) + err = xast.Inspect(f, func(n ast.Node) error { + fn, _ := n.(*ast.FuncDecl) + if fn == nil { + return nil + } + + if fn.Name.Name != "AddIBCModuleManager" { + return nil + } + + for _, stmt := range fn.Body.List { + x, _ := stmt.(*ast.AssignStmt) + if x == nil { continue } - if typeSpec.Name.Name != appTypeName { + + if len(x.Rhs) == 0 { continue } - structType, ok := typeSpec.Type.(*ast.StructType) - if !ok { + + c, _ := x.Rhs[0].(*ast.CompositeLit) + if c == nil { continue } - for _, field := range structType.Fields.List { - f := field.Type - CheckSpec: - switch spec := f.(type) { - case *ast.StarExpr: - f, ok = spec.X.(*ast.SelectorExpr) - if !ok { - continue - } - goto CheckSpec - case *ast.SelectorExpr: - if !strings.HasSuffix(spec.Sel.Name, "Keeper") { - continue - } - ident, ok := spec.X.(*ast.Ident) - if !ok { - continue - } - fileImport, ok := fileImports[ident.Name] - if !ok { - continue - } - keeperParamsMap[removeKeeperPkgPath(fileImport)] = struct{}{} - } + + s, _ := c.Type.(*ast.SelectorExpr) + if s == nil || s.Sel.Name != "AppModule" { + continue } + + if m, _ := s.X.(*ast.Ident); m != nil { + names = append(names, m.Name) + } + } + + return xast.ErrStop + }) + if err != nil { + return nil, err + } + + var modules []string + for _, n := range names { + modules = append(modules, imports[n]) + } + return modules, nil +} + +func resolveCosmosPackagePath(chainRoot string) (string, error) { + modFile, err := gomodule.ParseAt(chainRoot) + if err != nil { + return "", err + } + + deps, err := gomodule.ResolveDependencies(modFile, false) + if err != nil { + return "", err + } + + var pkg string + for _, dep := range deps { + if dep.Path == cosmosver.CosmosModulePath { + pkg = dep.String() + break } } - keeperParams := make([]string, 0) - for param := range keeperParamsMap { - keeperParams = append(keeperParams, param) + if pkg == "" { + return "", errors.New("cosmos SDK package version not found") + } + + m, err := gomodule.FindModule(context.Background(), chainRoot, pkg) + if err != nil { + return "", err } + return m.Dir, nil +} - return keeperParams, nil +func findRegisterAPIRoutesRegistrations(n ast.Node) []string { + funcLitType, ok := n.(*ast.FuncDecl) + if !ok { + return nil + } + + if funcLitType.Name.Name != registerRoutesMethod { + return nil + } + + var packagesRegistered []string + for _, stmt := range funcLitType.Body.List { + exprStmt, ok := stmt.(*ast.ExprStmt) + if !ok { + continue + } + exprCall, ok := exprStmt.X.(*ast.CallExpr) + if !ok { + continue + } + exprFun, ok := exprCall.Fun.(*ast.SelectorExpr) + if !ok || exprFun.Sel.Name != "RegisterGRPCGatewayRoutes" { + continue + } + identType, ok := exprFun.X.(*ast.Ident) + if !ok { + continue + } + pkgName := identType.Name + if pkgName == "" { + continue + } + packagesRegistered = append(packagesRegistered, identType.Name) + } + return packagesRegistered } func removeKeeperPkgPath(pkg string) string { @@ -208,3 +375,40 @@ func removeKeeperPkgPath(pkg string) string { path = strings.TrimSuffix(path, "/controller") return strings.TrimSuffix(path, "/host") } + +func isRuntimeAppCalled(fn *ast.FuncDecl) bool { + if fn.Name.Name != registerRoutesMethod { + return false + } + + for _, stmt := range fn.Body.List { + exprStmt, ok := stmt.(*ast.ExprStmt) + if !ok { + continue + } + + exprCall, ok := exprStmt.X.(*ast.CallExpr) + if !ok { + continue + } + + exprFun, ok := exprCall.Fun.(*ast.SelectorExpr) + if !ok || exprFun.Sel.Name != registerRoutesMethod { + continue + } + + exprSel, ok := exprFun.X.(*ast.SelectorExpr) + if !ok || exprSel.Sel.Name != "App" { + continue + } + + identType, ok := exprSel.X.(*ast.Ident) + if !ok || identType.Name != "app" { + continue + } + + return true + } + + return false +} diff --git a/ignite/pkg/cosmosanalysis/app/app_test.go b/ignite/pkg/cosmosanalysis/app/app_test.go index 35545e3959..be4cf1aeb7 100644 --- a/ignite/pkg/cosmosanalysis/app/app_test.go +++ b/ignite/pkg/cosmosanalysis/app/app_test.go @@ -85,6 +85,9 @@ func TestFindRegisteredModules(t *testing.T) { "github.com/cosmos/cosmos-sdk/x/staking", "github.com/cosmos/cosmos-sdk/x/gov", "github.com/username/test/x/foo", + "github.com/cosmos/cosmos-sdk/x/auth/tx", + "github.com/cosmos/cosmos-sdk/client/grpc/tmservice", + "github.com/cosmos/cosmos-sdk/client/grpc/node", } cases := []struct { @@ -110,6 +113,8 @@ func TestFindRegisteredModules(t *testing.T) { "cosmossdk.io/x/evidence", "cosmossdk.io/x/feegrant/module", "cosmossdk.io/x/upgrade", + "github.com/cosmos/cosmos-sdk/x/auth", + "github.com/cosmos/cosmos-sdk/x/auth/tx", "github.com/cosmos/cosmos-sdk/x/auth/tx/config", "github.com/cosmos/cosmos-sdk/x/auth/vesting", "github.com/cosmos/cosmos-sdk/x/authz/module", @@ -125,6 +130,8 @@ func TestFindRegisteredModules(t *testing.T) { "github.com/ignite/mars/x/mars", "github.com/cosmos/cosmos-sdk/x/gov", "github.com/username/test/x/foo", + "github.com/cosmos/cosmos-sdk/client/grpc/tmservice", + "github.com/cosmos/cosmos-sdk/client/grpc/node", }, }, { @@ -191,6 +198,9 @@ func TestFindRegisteredModules(t *testing.T) { path: "testdata/modules/spn", expectedModules: []string{ "github.com/cosmos/cosmos-sdk/x/auth", + "github.com/cosmos/cosmos-sdk/x/auth/tx", + "github.com/cosmos/cosmos-sdk/client/grpc/tmservice", + "github.com/cosmos/cosmos-sdk/client/grpc/node", "github.com/cosmos/cosmos-sdk/x/bank", "github.com/cosmos/cosmos-sdk/x/capability", "github.com/cosmos/cosmos-sdk/x/staking", @@ -239,6 +249,9 @@ func TestFindRegisteredModules(t *testing.T) { "github.com/cosmos/cosmos-sdk/x/authz", "github.com/CosmWasm/wasmd/x/wasm", "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts", + "github.com/cosmos/cosmos-sdk/x/auth/tx", + "github.com/cosmos/cosmos-sdk/client/grpc/tmservice", + "github.com/cosmos/cosmos-sdk/client/grpc/node", }, }, } @@ -252,13 +265,16 @@ func TestFindRegisteredModules(t *testing.T) { } } -func TestFindKeepersModules(t *testing.T) { +func TestDiscoverModules(t *testing.T) { basicModules := []string{ "github.com/cosmos/cosmos-sdk/x/auth", "github.com/cosmos/cosmos-sdk/x/bank", "github.com/cosmos/cosmos-sdk/x/staking", "github.com/cosmos/cosmos-sdk/x/gov", "github.com/username/test/x/foo", + "github.com/cosmos/cosmos-sdk/x/auth/tx", + "github.com/cosmos/cosmos-sdk/client/grpc/tmservice", + "github.com/cosmos/cosmos-sdk/client/grpc/node", } cases := []struct { @@ -343,6 +359,9 @@ func TestFindKeepersModules(t *testing.T) { path: "testdata/modules/spn", expectedModules: []string{ "github.com/cosmos/cosmos-sdk/x/auth", + "github.com/cosmos/cosmos-sdk/x/auth/tx", + "github.com/cosmos/cosmos-sdk/client/grpc/tmservice", + "github.com/cosmos/cosmos-sdk/client/grpc/node", "github.com/cosmos/cosmos-sdk/x/bank", "github.com/cosmos/cosmos-sdk/x/capability", "github.com/cosmos/cosmos-sdk/x/staking", @@ -391,6 +410,9 @@ func TestFindKeepersModules(t *testing.T) { "github.com/cosmos/cosmos-sdk/x/authz", "github.com/CosmWasm/wasmd/x/wasm", "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts", + "github.com/cosmos/cosmos-sdk/x/auth/tx", + "github.com/cosmos/cosmos-sdk/client/grpc/tmservice", + "github.com/cosmos/cosmos-sdk/client/grpc/node", }, }, } @@ -403,7 +425,7 @@ func TestFindKeepersModules(t *testing.T) { got := make([]string, 0) for _, f := range appPkg.Files { fileImports := goanalysis.FormatImports(f) - modules, err := FindKeepersModules(f, fileImports) + modules, err := DiscoverModules(f, tt.path, fileImports) require.NoError(t, err) if modules != nil { got = append(got, modules...) @@ -414,122 +436,6 @@ func TestFindKeepersModules(t *testing.T) { } } -func Test_mergeImports(t *testing.T) { - tests := []struct { - name string - blankImports []string - discovered []string - want []string - }{ - { - name: "test nil imports", - blankImports: nil, - discovered: nil, - want: nil, - }, - { - name: "test empty imports", - blankImports: []string{}, - discovered: []string{}, - want: []string{}, - }, - { - name: "test only one blank import", - blankImports: []string{"github.com/cosmos/cosmos-sdk/x/auth"}, - discovered: []string{}, - want: []string{"github.com/cosmos/cosmos-sdk/x/auth"}, - }, - { - name: "test only one discovered import", - blankImports: []string{}, - discovered: []string{"github.com/cosmos/cosmos-sdk/x/auth"}, - want: []string{"github.com/cosmos/cosmos-sdk/x/auth"}, - }, - { - name: "test only one import", - blankImports: []string{"github.com/cosmos/cosmos-sdk/x/auth"}, - discovered: []string{"github.com/cosmos/cosmos-sdk/x/auth/keeper"}, - want: []string{"github.com/cosmos/cosmos-sdk/x/auth"}, - }, - { - name: "test only one keeper import", - blankImports: []string{"github.com/cosmos/cosmos-sdk/x/auth/module"}, - discovered: []string{"github.com/cosmos/cosmos-sdk/x/auth/keeper"}, - want: []string{"github.com/cosmos/cosmos-sdk/x/auth/module"}, - }, - { - name: "test two keeper import", - blankImports: []string{ - "github.com/cosmos/cosmos-sdk/x/auth/module", - "github.com/cosmos/cosmos-sdk/x/bank/module", - }, - discovered: []string{ - "github.com/cosmos/cosmos-sdk/x/auth/keeper", - "github.com/cosmos/cosmos-sdk/x/bank/keeper", - }, - want: []string{ - "github.com/cosmos/cosmos-sdk/x/auth/module", - "github.com/cosmos/cosmos-sdk/x/bank/module", - }, - }, - { - name: "test two keeper import", - blankImports: []string{ - "github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts", - }, - discovered: []string{ - "github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts/controller/keeper", - "github.com/cosmos/cosmos-sdk/x/bank/keeper", - }, - want: []string{ - "github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts", - "github.com/cosmos/cosmos-sdk/x/bank/keeper", - }, - }, - { - name: "test keeper imports", - blankImports: []string{ - "github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts", - "cosmossdk.io/x/feegrant/module", - }, - discovered: []string{ - "github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts/controller/keeper", - "github.com/cosmos/cosmos-sdk/x/bank/keeper", - "cosmossdk.io/x/feegrant/types", - "cosmossdk.io/x/feegrant", - "cosmossdk.io/x/foo", - }, - want: []string{ - "github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts", - "github.com/cosmos/cosmos-sdk/x/bank/keeper", - "cosmossdk.io/x/feegrant/module", - "cosmossdk.io/x/foo", - }, - }, - { - name: "test three keeper import", - blankImports: []string{ - "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts", - "github.com/cosmos/ibc-go/modules/capability", - }, - discovered: []string{ - "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts", - "github.com/cosmos/ibc-go/modules/capability", - }, - want: []string{ - "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts", - "github.com/cosmos/ibc-go/modules/capability", - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := mergeImports(tt.blankImports, tt.discovered) - require.ElementsMatch(t, tt.want, got) - }) - } -} - func Test_removeKeeperPkgPath(t *testing.T) { tests := []struct { name string diff --git a/ignite/pkg/cosmosanalysis/app/testdata/modules/app_config/go.mod b/ignite/pkg/cosmosanalysis/app/testdata/modules/app_config/go.mod new file mode 100644 index 0000000000..c740bc6ccb --- /dev/null +++ b/ignite/pkg/cosmosanalysis/app/testdata/modules/app_config/go.mod @@ -0,0 +1,30 @@ +module app + +go 1.20 + +require ( + cosmossdk.io/api v0.3.1 + cosmossdk.io/core v0.5.1 + cosmossdk.io/depinject v1.0.0-alpha.3 + cosmossdk.io/errors v1.0.0-beta.7 + cosmossdk.io/math v1.0.1 + github.com/bufbuild/buf v1.23.1 + github.com/cometbft/cometbft v0.37.2 + github.com/cometbft/cometbft-db v0.8.0 + github.com/cosmos/cosmos-proto v1.0.0-beta.2 + github.com/cosmos/cosmos-sdk v0.47.3 + github.com/cosmos/gogoproto v1.4.10 + github.com/cosmos/ibc-go/v7 v7.2.0 + github.com/golang/protobuf v1.5.3 + github.com/gorilla/mux v1.8.0 + github.com/grpc-ecosystem/grpc-gateway v1.16.0 + github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.2 + github.com/spf13/cast v1.5.1 + github.com/spf13/cobra v1.7.0 + github.com/spf13/pflag v1.0.5 + github.com/stretchr/testify v1.8.4 + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 + google.golang.org/grpc v1.55.0 + google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 + google.golang.org/protobuf v1.31.0 +) diff --git a/ignite/pkg/cosmosanalysis/app/testdata/modules/crescent/app.go b/ignite/pkg/cosmosanalysis/app/testdata/modules/crescent/app.go index 17455318e7..a01d492c2a 100644 --- a/ignite/pkg/cosmosanalysis/app/testdata/modules/crescent/app.go +++ b/ignite/pkg/cosmosanalysis/app/testdata/modules/crescent/app.go @@ -11,7 +11,6 @@ import ( "path/filepath" storetypes "cosmossdk.io/store/types" - "github.com/cosmos/cosmos-sdk/server" "cosmossdk.io/client/v2/autocli" "github.com/gorilla/mux" @@ -1031,13 +1030,3 @@ func (App) GetSubspace(moduleName string) paramstypes.Subspace { func (App) SimulationManager() *module.SimulationManager { return app.sm } - -// RegisterAPIRoutes registers all application module routes with the provided -// API server. -func (App) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) { - app.App.RegisterAPIRoutes(apiSvr, apiConfig) - // register swagger API in app.go so that other applications can override easily - if err := server.RegisterSwaggerAPI(apiSvr.ClientCtx, apiSvr.Router, apiConfig.Swagger); err != nil { - panic(err) - } -} diff --git a/ignite/pkg/cosmosanalysis/app/testdata/modules/crescent/go.mod b/ignite/pkg/cosmosanalysis/app/testdata/modules/crescent/go.mod new file mode 100644 index 0000000000..d0b47f88a3 --- /dev/null +++ b/ignite/pkg/cosmosanalysis/app/testdata/modules/crescent/go.mod @@ -0,0 +1,29 @@ +module github.com/crescent-network/crescent/v5 + +go 1.18 + +require ( + github.com/cosmos/cosmos-sdk v0.45.10 + github.com/cosmos/ibc-go/v3 v3.4.0 + github.com/gogo/protobuf v1.3.3 + github.com/golang/mock v1.6.0 + github.com/golang/protobuf v1.5.2 + github.com/golangci/golangci-lint v1.50.1 + github.com/gorilla/mux v1.8.0 + github.com/grpc-ecosystem/grpc-gateway v1.16.0 + github.com/grpc-ecosystem/grpc-gateway/v2 v2.13.0 + github.com/rakyll/statik v0.1.7 + github.com/regen-network/cosmos-proto v0.3.1 + github.com/spf13/cast v1.5.0 + github.com/spf13/cobra v1.6.0 + github.com/spf13/pflag v1.0.5 + github.com/stretchr/testify v1.8.0 + github.com/tendermint/tendermint v0.34.22 + github.com/tendermint/tm-db v0.6.7 + golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e + google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c + google.golang.org/grpc v1.50.1 + google.golang.org/protobuf v1.28.1 + gopkg.in/yaml.v2 v2.4.0 +) + diff --git a/ignite/pkg/cosmosanalysis/app/testdata/modules/gaia/app.go b/ignite/pkg/cosmosanalysis/app/testdata/modules/gaia/app.go index 27ee658340..e9c475528d 100644 --- a/ignite/pkg/cosmosanalysis/app/testdata/modules/gaia/app.go +++ b/ignite/pkg/cosmosanalysis/app/testdata/modules/gaia/app.go @@ -8,8 +8,6 @@ import ( "os" "path/filepath" - "github.com/cosmos/cosmos-sdk/server" - "cosmossdk.io/client/v2/autocli" sdkerrors "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/baseapp" @@ -1096,13 +1094,3 @@ func (GaiaApp) GetSubspace(moduleName string) paramstypes.Subspace { func (GaiaApp) SimulationManager() *module.SimulationManager { return app.sm } - -// RegisterAPIRoutes registers all application module routes with the provided -// API server. -func (GaiaApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) { - app.App.RegisterAPIRoutes(apiSvr, apiConfig) - // register swagger API in app.go so that other applications can override easily - if err := server.RegisterSwaggerAPI(apiSvr.ClientCtx, apiSvr.Router, apiConfig.Swagger); err != nil { - panic(err) - } -} diff --git a/ignite/pkg/cosmosanalysis/app/testdata/modules/gaia/go.mod b/ignite/pkg/cosmosanalysis/app/testdata/modules/gaia/go.mod new file mode 100644 index 0000000000..0851601f21 --- /dev/null +++ b/ignite/pkg/cosmosanalysis/app/testdata/modules/gaia/go.mod @@ -0,0 +1,28 @@ +module github.com/cosmos/gaia/v14 + +go 1.20 + +require ( + cosmossdk.io/errors v1.0.0 + cosmossdk.io/math v1.2.0 + github.com/cosmos/cosmos-sdk v0.45.16 + github.com/cosmos/go-bip39 v1.0.0 + github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v4 v4.1.1 + github.com/cosmos/ibc-go/v4 v4.4.2 + github.com/cosmos/interchain-security/v2 v2.0.0 + github.com/gogo/protobuf v1.3.3 + github.com/golang/protobuf v1.5.3 + github.com/google/gofuzz v1.2.0 + github.com/gorilla/mux v1.8.1 + github.com/grpc-ecosystem/grpc-gateway v1.16.0 + github.com/ory/dockertest/v3 v3.10.0 + github.com/rakyll/statik v0.1.7 + github.com/spf13/cast v1.5.1 + github.com/spf13/cobra v1.8.0 + github.com/spf13/viper v1.17.0 + github.com/stretchr/testify v1.8.4 + github.com/tendermint/tendermint v0.34.27 + github.com/tendermint/tm-db v0.6.7 + google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb + google.golang.org/grpc v1.58.2 +) diff --git a/ignite/pkg/cosmosanalysis/app/testdata/modules/juno/go.mod b/ignite/pkg/cosmosanalysis/app/testdata/modules/juno/go.mod new file mode 100644 index 0000000000..c3c0312603 --- /dev/null +++ b/ignite/pkg/cosmosanalysis/app/testdata/modules/juno/go.mod @@ -0,0 +1,33 @@ +module github.com/CosmosContracts/juno/v18 + +go 1.21 + +require ( + cosmossdk.io/api v0.3.1 + cosmossdk.io/errors v1.0.0 + cosmossdk.io/log v1.2.1 + cosmossdk.io/math v1.1.2 + cosmossdk.io/tools/rosetta v0.2.1 + github.com/CosmWasm/wasmd v0.45.0 + github.com/CosmWasm/wasmvm v1.5.0 + github.com/cometbft/cometbft v0.37.2 + github.com/cometbft/cometbft-db v0.8.0 + github.com/cosmos/cosmos-sdk v0.47.5 + github.com/cosmos/gogoproto v1.4.10 + github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7 v7.0.1 + github.com/cosmos/ibc-apps/modules/async-icq/v7 v7.0.0 + github.com/cosmos/ibc-apps/modules/ibc-hooks/v7 v7.0.0-20230803181732-7c8f814d3b79 + github.com/cosmos/ibc-go/v7 v7.3.1 + github.com/golang/protobuf v1.5.3 + github.com/gorilla/mux v1.8.0 + github.com/grpc-ecosystem/grpc-gateway v1.16.0 + github.com/prometheus/client_golang v1.16.0 + github.com/skip-mev/pob v1.0.4 + github.com/spf13/cast v1.5.1 + github.com/spf13/cobra v1.7.0 + github.com/spf13/viper v1.16.0 + github.com/stretchr/testify v1.8.4 + google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 + google.golang.org/grpc v1.58.3 + gopkg.in/yaml.v2 v2.4.0 +) diff --git a/ignite/pkg/cosmosanalysis/app/testdata/modules/single_app/go.mod b/ignite/pkg/cosmosanalysis/app/testdata/modules/single_app/go.mod new file mode 100644 index 0000000000..5db6c247a4 --- /dev/null +++ b/ignite/pkg/cosmosanalysis/app/testdata/modules/single_app/go.mod @@ -0,0 +1,32 @@ +module app + +go 1.20 + +require ( + cosmossdk.io/api v0.3.1 + cosmossdk.io/core v0.5.1 + cosmossdk.io/depinject v1.0.0-alpha.3 + cosmossdk.io/errors v1.0.0-beta.7 + cosmossdk.io/math v1.0.1 + github.com/bufbuild/buf v1.23.1 + github.com/cometbft/cometbft v0.37.2 + github.com/cometbft/cometbft-db v0.8.0 + github.com/cosmos/cosmos-proto v1.0.0-beta.2 + github.com/cosmos/cosmos-sdk v0.47.3 + github.com/cosmos/gogoproto v1.4.10 + github.com/cosmos/ibc-go/v7 v7.2.0 + github.com/golang/protobuf v1.5.3 + github.com/gorilla/mux v1.8.0 + github.com/grpc-ecosystem/grpc-gateway v1.16.0 + github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.2 + github.com/spf13/cast v1.5.1 + github.com/spf13/cobra v1.7.0 + github.com/spf13/pflag v1.0.5 + github.com/stretchr/testify v1.8.4 + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 + google.golang.org/grpc v1.55.0 + google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 + google.golang.org/protobuf v1.31.0 +) + + diff --git a/ignite/pkg/cosmosanalysis/app/testdata/modules/spn/go.mod b/ignite/pkg/cosmosanalysis/app/testdata/modules/spn/go.mod new file mode 100644 index 0000000000..39414c01ea --- /dev/null +++ b/ignite/pkg/cosmosanalysis/app/testdata/modules/spn/go.mod @@ -0,0 +1,343 @@ +module github.com/tendermint/spn + +go 1.19 + +require ( + cosmossdk.io/api v0.3.1 + cosmossdk.io/errors v1.0.0-beta.7 + cosmossdk.io/math v1.0.1 + github.com/aws/smithy-go v1.8.0 + github.com/bufbuild/buf v1.22.0 + github.com/cometbft/cometbft v0.37.2 + github.com/cometbft/cometbft-db v0.8.0 + github.com/cosmos/cosmos-proto v1.0.0-beta.2 + github.com/cosmos/cosmos-sdk v0.47.3 + github.com/cosmos/gogoproto v1.4.10 + github.com/cosmos/ibc-go/v7 v7.2.0 + github.com/gogo/protobuf v1.3.2 + github.com/golang/protobuf v1.5.3 + github.com/golangci/golangci-lint v1.50.1 + github.com/gorilla/mux v1.8.0 + github.com/grpc-ecosystem/grpc-gateway v1.16.0 + github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.2 + github.com/ignite/modules v0.0.2 + github.com/pkg/errors v0.9.1 + github.com/spf13/cast v1.5.1 + github.com/spf13/cobra v1.7.0 + github.com/spf13/pflag v1.0.5 + github.com/stretchr/testify v1.8.4 + github.com/tendermint/fundraising v0.4.1 + golang.org/x/tools v0.10.0 + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 + google.golang.org/grpc v1.55.0 + google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 + google.golang.org/protobuf v1.31.0 + gopkg.in/yaml.v2 v2.4.0 + mvdan.cc/gofumpt v0.5.0 +) + +replace github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 + +require ( + 4d63.com/gochecknoglobals v0.1.0 // indirect + cloud.google.com/go v0.110.0 // indirect + cloud.google.com/go/compute v1.19.1 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go/iam v1.0.0 // indirect + cloud.google.com/go/storage v1.30.1 // indirect + cosmossdk.io/core v0.5.1 // indirect + cosmossdk.io/depinject v1.0.0-alpha.3 // indirect + cosmossdk.io/log v1.1.0 // indirect + cosmossdk.io/simapp v0.0.0-20230323161446-0af178d721ff // indirect + cosmossdk.io/tools/rosetta v0.2.1 // indirect + filippo.io/edwards25519 v1.0.0 // indirect + github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect + github.com/99designs/keyring v1.2.1 // indirect + github.com/Abirdcfly/dupword v0.0.7 // indirect + github.com/Antonboom/errname v0.1.7 // indirect + github.com/Antonboom/nilnil v0.1.1 // indirect + github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect + github.com/BurntSushi/toml v1.2.1 // indirect + github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect + github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect + github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 // indirect + github.com/Masterminds/semver v1.5.0 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/OpenPeeDeeP/depguard v1.1.1 // indirect + github.com/alexkohler/prealloc v1.0.0 // indirect + github.com/alingse/asasalint v0.0.11 // indirect + github.com/armon/go-metrics v0.4.1 // indirect + github.com/ashanbrown/forbidigo v1.3.0 // indirect + github.com/ashanbrown/makezero v1.1.1 // indirect + github.com/aws/aws-sdk-go v1.44.244 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect + github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect + github.com/bkielbasa/cyclop v1.2.0 // indirect + github.com/blizzy78/varnamelen v0.8.0 // indirect + github.com/bombsimon/wsl/v3 v3.3.0 // indirect + github.com/breml/bidichk v0.2.3 // indirect + github.com/breml/errchkjson v0.3.0 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect + github.com/bufbuild/connect-go v1.8.0 // indirect + github.com/bufbuild/connect-opentelemetry-go v0.3.0 // indirect + github.com/bufbuild/protocompile v0.5.1 // indirect + github.com/butuzov/ireturn v0.1.1 // indirect + github.com/cenkalti/backoff/v4 v4.1.3 // indirect + github.com/cespare/xxhash v1.1.0 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/charithe/durationcheck v0.0.9 // indirect + github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 // indirect + github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/chzyer/readline v1.5.1 // indirect + github.com/cockroachdb/apd/v2 v2.0.2 // indirect + github.com/coinbase/rosetta-sdk-go/types v1.0.0 // indirect + github.com/confio/ics23/go v0.9.0 // indirect + github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect + github.com/cosmos/btcutil v1.0.5 // indirect + github.com/cosmos/go-bip39 v1.0.0 // indirect + github.com/cosmos/gogogateway v1.2.0 // indirect + github.com/cosmos/iavl v0.20.0 // indirect + github.com/cosmos/ics23/go v0.10.0 // indirect + github.com/cosmos/ledger-cosmos-go v0.12.1 // indirect + github.com/cosmos/rosetta-sdk-go v0.10.0 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/creachadair/taskgroup v0.4.2 // indirect + github.com/curioswitch/go-reassign v0.2.0 // indirect + github.com/daixiang0/gci v0.8.1 // indirect + github.com/danieljoos/wincred v1.1.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect + github.com/denis-tingaikin/go-header v0.4.3 // indirect + github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect + github.com/dgraph-io/badger/v2 v2.2007.4 // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect + github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect + github.com/docker/cli v24.0.2+incompatible // indirect + github.com/docker/distribution v2.8.2+incompatible // indirect + github.com/docker/docker v24.0.2+incompatible // indirect + github.com/docker/docker-credential-helpers v0.7.0 // indirect + github.com/docker/go-connections v0.4.0 // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/dvsekhvalnov/jose2go v1.5.0 // indirect + github.com/esimonov/ifshort v1.0.4 // indirect + github.com/ettle/strcase v0.1.1 // indirect + github.com/fatih/color v1.13.0 // indirect + github.com/fatih/structtag v1.2.0 // indirect + github.com/felixge/fgprof v0.9.3 // indirect + github.com/felixge/httpsnoop v1.0.2 // indirect + github.com/firefart/nonamedreturns v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/fzipp/gocyclo v0.6.0 // indirect + github.com/ghodss/yaml v1.0.0 // indirect + github.com/go-chi/chi/v5 v5.0.8 // indirect + github.com/go-critic/go-critic v0.6.5 // indirect + github.com/go-kit/kit v0.12.0 // indirect + github.com/go-kit/log v0.2.1 // indirect + github.com/go-logfmt/logfmt v0.6.0 // indirect + github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-toolsmith/astcast v1.0.0 // indirect + github.com/go-toolsmith/astcopy v1.0.2 // indirect + github.com/go-toolsmith/astequal v1.0.3 // indirect + github.com/go-toolsmith/astfmt v1.0.0 // indirect + github.com/go-toolsmith/astp v1.0.0 // indirect + github.com/go-toolsmith/strparse v1.0.0 // indirect + github.com/go-toolsmith/typep v1.0.2 // indirect + github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect + github.com/gobwas/glob v0.2.3 // indirect + github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect + github.com/gofrs/flock v0.8.1 // indirect + github.com/gofrs/uuid/v5 v5.0.0 // indirect + github.com/gogo/googleapis v1.4.1 // indirect + github.com/golang/glog v1.1.0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/mock v1.6.0 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect + github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect + github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe // indirect + github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 // indirect + github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 // indirect + github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca // indirect + github.com/golangci/misspell v0.3.5 // indirect + github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 // indirect + github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect + github.com/google/btree v1.1.2 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/go-containerregistry v0.15.2 // indirect + github.com/google/orderedcode v0.0.1 // indirect + github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect + github.com/google/s2a-go v0.1.3 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect + github.com/googleapis/gax-go/v2 v2.8.0 // indirect + github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect + github.com/gorilla/handlers v1.5.1 // indirect + github.com/gorilla/websocket v1.5.0 // indirect + github.com/gostaticanalysis/analysisutil v0.7.1 // indirect + github.com/gostaticanalysis/comment v1.4.2 // indirect + github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect + github.com/gostaticanalysis/nilerr v0.1.1 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect + github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect + github.com/gtank/merlin v0.1.1 // indirect + github.com/gtank/ristretto255 v0.1.2 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-getter v1.7.1 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-safetemp v1.0.0 // indirect + github.com/hashicorp/go-version v1.6.0 // indirect + github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/hdevalence/ed25519consensus v0.1.0 // indirect + github.com/hexops/gotextdiff v1.0.3 // indirect + github.com/huandu/skiplist v1.2.0 // indirect + github.com/improbable-eng/grpc-web v0.15.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jdxcode/netrc v0.0.0-20221124155335-4616370d1a84 // indirect + github.com/jgautheron/goconst v1.5.1 // indirect + github.com/jingyugao/rowserrcheck v1.1.1 // indirect + github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/jmhodges/levigo v1.0.0 // indirect + github.com/julz/importas v0.1.0 // indirect + github.com/kisielk/errcheck v1.6.2 // indirect + github.com/kisielk/gotool v1.0.0 // indirect + github.com/kkHAIKE/contextcheck v1.1.3 // indirect + github.com/klauspost/compress v1.16.6 // indirect + github.com/klauspost/pgzip v1.2.6 // indirect + github.com/kulti/thelper v0.6.3 // indirect + github.com/kunwardeep/paralleltest v1.0.6 // indirect + github.com/kyoh86/exportloopref v0.1.8 // indirect + github.com/ldez/gomoddirectives v0.2.3 // indirect + github.com/ldez/tagliatelle v0.3.1 // indirect + github.com/leonklingele/grouper v1.1.0 // indirect + github.com/lib/pq v1.10.7 // indirect + github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/linxGnu/grocksdb v1.7.16 // indirect + github.com/lufeee/execinquery v1.2.1 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/manifoldco/promptui v0.9.0 // indirect + github.com/maratori/testableexamples v1.0.0 // indirect + github.com/maratori/testpackage v1.1.0 // indirect + github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.18 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mbilski/exhaustivestruct v1.2.0 // indirect + github.com/mgechev/revive v1.2.4 // indirect + github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect + github.com/minio/highwayhash v1.0.2 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/moby/term v0.5.0 // indirect + github.com/moricho/tparallel v0.2.1 // indirect + github.com/morikuni/aec v1.0.0 // indirect + github.com/mtibben/percent v0.2.1 // indirect + github.com/nakabonne/nestif v0.3.1 // indirect + github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect + github.com/nishanths/exhaustive v0.8.3 // indirect + github.com/nishanths/predeclared v0.2.2 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0-rc3 // indirect + github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect + github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d // indirect + github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect + github.com/pkg/profile v1.7.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/polyfloyd/go-errorlint v1.0.5 // indirect + github.com/prometheus/client_golang v1.14.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.42.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect + github.com/quasilyte/go-ruleguard v0.3.18 // indirect + github.com/quasilyte/gogrep v0.0.0-20220828223005-86e4605de09f // indirect + github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect + github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect + github.com/rakyll/statik v0.1.7 // indirect + github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect + github.com/rs/cors v1.9.0 // indirect + github.com/rs/zerolog v1.29.1 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/ryancurrah/gomodguard v1.2.4 // indirect + github.com/ryanrolds/sqlclosecheck v0.3.0 // indirect + github.com/sanposhiho/wastedassign/v2 v2.0.6 // indirect + github.com/sasha-s/go-deadlock v0.3.1 // indirect + github.com/sashamelentyev/interfacebloat v1.1.0 // indirect + github.com/sashamelentyev/usestdlibvars v1.20.0 // indirect + github.com/securego/gosec/v2 v2.13.1 // indirect + github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/sivchari/containedctx v1.0.2 // indirect + github.com/sivchari/nosnakecase v1.7.0 // indirect + github.com/sivchari/tenv v1.7.0 // indirect + github.com/sonatard/noctx v0.0.1 // indirect + github.com/sourcegraph/go-diff v0.6.1 // indirect + github.com/spf13/afero v1.9.5 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/viper v1.16.0 // indirect + github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect + github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect + github.com/stretchr/objx v0.5.0 // indirect + github.com/subosito/gotenv v1.4.2 // indirect + github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect + github.com/tdakkota/asciicheck v0.1.1 // indirect + github.com/tendermint/go-amino v0.16.0 // indirect + github.com/tetafro/godot v1.4.11 // indirect + github.com/tetratelabs/wazero v1.2.1 // indirect + github.com/tidwall/btree v1.6.0 // indirect + github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 // indirect + github.com/timonwong/loggercheck v0.9.3 // indirect + github.com/tomarrell/wrapcheck/v2 v2.7.0 // indirect + github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ulikunitz/xz v0.5.11 // indirect + github.com/ultraware/funlen v0.0.3 // indirect + github.com/ultraware/whitespace v0.0.5 // indirect + github.com/uudashr/gocognit v1.0.6 // indirect + github.com/vbatts/tar-split v0.11.3 // indirect + github.com/yagipy/maintidx v1.0.0 // indirect + github.com/yeya24/promlinter v0.2.0 // indirect + github.com/zondax/hid v0.9.1 // indirect + github.com/zondax/ledger-go v0.14.1 // indirect + gitlab.com/bosi/decorder v0.2.3 // indirect + go.etcd.io/bbolt v1.3.7 // indirect + go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/otel v1.16.0 // indirect + go.opentelemetry.io/otel/metric v1.16.0 // indirect + go.opentelemetry.io/otel/sdk v1.16.0 // indirect + go.opentelemetry.io/otel/trace v1.16.0 // indirect + go.uber.org/atomic v1.11.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/crypto v0.10.0 // indirect + golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect + golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 // indirect + golang.org/x/mod v0.11.0 // indirect + golang.org/x/net v0.11.0 // indirect + golang.org/x/oauth2 v0.7.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.9.0 // indirect + golang.org/x/term v0.9.0 // indirect + golang.org/x/text v0.10.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + google.golang.org/api v0.122.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + honnef.co/go/tools v0.3.3 // indirect + mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect + mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect + mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 // indirect + nhooyr.io/websocket v1.8.6 // indirect + pgregory.net/rapid v0.5.5 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) diff --git a/ignite/pkg/cosmosanalysis/module/module.go b/ignite/pkg/cosmosanalysis/module/module.go index ba6e98f1b1..cdfe90e9d6 100644 --- a/ignite/pkg/cosmosanalysis/module/module.go +++ b/ignite/pkg/cosmosanalysis/module/module.go @@ -14,6 +14,7 @@ import ( "github.com/ignite/cli/ignite/pkg/cosmosanalysis/app" "github.com/ignite/cli/ignite/pkg/gomodule" "github.com/ignite/cli/ignite/pkg/protoanalysis" + "github.com/ignite/cli/ignite/pkg/xstrings" ) // Msgs is a module import path-sdk msgs pair. @@ -83,6 +84,12 @@ type moduleDiscoverer struct { registeredModules []string } +// IsCosmosSDKModulePkg check if a Go import path is a Cosmos SDK package module. +// These type of package have the "cosmossdk.io/x" prefix. +func IsCosmosSDKModulePkg(path string) bool { + return strings.Contains(path, "cosmossdk.io/x/") +} + // Discover discovers and returns modules and their types that are registered in the app // chainRoot is the root path of the chain // sourcePath is the root path of the go module which the proto dir is from @@ -92,7 +99,12 @@ type moduleDiscoverer struct { // 1. Getting all the registered Go modules from the app. // 2. Parsing the proto files to find services and messages. // 3. Check if the proto services are implemented in any of the registered modules. -func Discover(ctx context.Context, chainRoot, sourcePath, protoDir string) ([]Module, error) { +func Discover(ctx context.Context, chainRoot, sourcePath string, options ...DiscoverOption) ([]Module, error) { + var o discoverOptions + for _, apply := range options { + apply(&o) + } + // find out base Go import path of the blockchain. gm, err := gomodule.ParseAt(sourcePath) if err != nil { @@ -124,8 +136,18 @@ func Discover(ctx context.Context, chainRoot, sourcePath, protoDir string) ([]Mo return []Module{}, nil } + // Switch the proto path for "cosmossdk.io" module packages to the official Cosmos + // SDK package because the module packages doesn't contain the proto files. These + // files are only available from the Cosmos SDK package. + var protoPath string + if o.sdkDir != "" && IsCosmosSDKModulePkg(sourcePath) { + protoPath = switchCosmosSDKPackagePath(sourcePath, o.sdkDir) + } else { + protoPath = filepath.Join(sourcePath, o.protoDir) + } + md := &moduleDiscoverer{ - protoPath: filepath.Join(sourcePath, protoDir), + protoPath: protoPath, sourcePath: sourcePath, basegopath: basegopath, registeredModules: appModules, @@ -420,3 +442,11 @@ func hasPagination(msg protoanalysis.Message) bool { return false } + +func switchCosmosSDKPackagePath(srcPath, sdkDir string) string { + modName := xstrings.StringBetween(srcPath, "/x/", "@") + if modName == "" { + return srcPath + } + return filepath.Join(sdkDir, "proto", "cosmos", modName) +} diff --git a/ignite/pkg/cosmosanalysis/module/module_test.go b/ignite/pkg/cosmosanalysis/module/module_test.go index 0ba79a2f15..2db58c75fd 100644 --- a/ignite/pkg/cosmosanalysis/module/module_test.go +++ b/ignite/pkg/cosmosanalysis/module/module_test.go @@ -156,7 +156,7 @@ func TestDiscover(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - modules, err := module.Discover(ctx, sourcePath, tt.sourcePath, tt.protoDir) + modules, err := module.Discover(ctx, sourcePath, tt.sourcePath, module.WithProtoDir(tt.protoDir)) require.NoError(t, err) require.Equal(t, tt.want, modules) @@ -193,7 +193,7 @@ func TestDiscoverWithAppV2(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - modules, err := module.Discover(ctx, sourcePath, sourcePath, tt.protoDir) + modules, err := module.Discover(ctx, sourcePath, sourcePath, module.WithProtoDir(tt.protoDir)) require.NoError(t, err) require.Equal(t, tt.want, modules) diff --git a/ignite/pkg/cosmosanalysis/module/options.go b/ignite/pkg/cosmosanalysis/module/options.go new file mode 100644 index 0000000000..20820785f8 --- /dev/null +++ b/ignite/pkg/cosmosanalysis/module/options.go @@ -0,0 +1,22 @@ +package module + +// DiscoverOption configures calls to Discovery function. +type DiscoverOption func(*discoverOptions) + +type discoverOptions struct { + protoDir, sdkDir string +} + +// WithProtoDir sets the relative proto directory path. +func WithProtoDir(path string) DiscoverOption { + return func(o *discoverOptions) { + o.protoDir = path + } +} + +// WithSDKDir sets the absolute directory path to the Cosmos SDK Go package. +func WithSDKDir(path string) DiscoverOption { + return func(o *discoverOptions) { + o.sdkDir = path + } +} diff --git a/ignite/pkg/cosmosgen/cosmosgen.go b/ignite/pkg/cosmosgen/cosmosgen.go index 507a90c369..89a188eea5 100644 --- a/ignite/pkg/cosmosgen/cosmosgen.go +++ b/ignite/pkg/cosmosgen/cosmosgen.go @@ -123,6 +123,7 @@ type generator struct { gomodPath string opts *generateOptions sdkImport string + sdkDir string deps []gomodule.Version appModules []module.Module appIncludes protoIncludes diff --git a/ignite/pkg/cosmosgen/generate.go b/ignite/pkg/cosmosgen/generate.go index 840b100a8d..a6402671a9 100644 --- a/ignite/pkg/cosmosgen/generate.go +++ b/ignite/pkg/cosmosgen/generate.go @@ -34,7 +34,8 @@ const ( ) var ( - ErrBufConfig = errors.New("invalid Buf config") + ErrBufConfig = errors.New("invalid Buf config") + ErrMissingSDKDep = errors.New("cosmos SDK dependency not found") protocGlobalInclude = xfilepath.List( xfilepath.JoinFromHome(xfilepath.Path("local/include")), @@ -112,8 +113,15 @@ func (g *generator) setup(ctx context.Context) (err error) { return err } - // Discover any custom modules defined by the user's app - g.appModules, err = g.discoverModules(ctx, g.appPath, g.protoDir) + // Discover any custom modules defined by the user's app. + // Use the configured proto directory to locate app's proto files. + g.appModules, err = module.Discover( + ctx, + g.appPath, + g.appPath, + module.WithProtoDir(g.protoDir), + module.WithSDKDir(g.sdkDir), + ) if err != nil { return err } @@ -123,6 +131,19 @@ func (g *generator) setup(ctx context.Context) (err error) { return err } + dep, found := filterCosmosSDKModule(g.deps) + if !found { + return ErrMissingSDKDep + } + + // Find the full path to the Cosmos SDK Go package. + // The path is required to be able to discover proto packages for the + // set of "cosmossdk.io" packages that doesn't contain the proto files. + g.sdkDir, err = gomodule.LocatePath(ctx, g.cacheStorage, g.appPath, dep) + if err != nil { + return err + } + // Go through the Go dependencies of the user's app within go.mod, some of them // might be hosting Cosmos SDK modules that could be in use by user's blockchain. // @@ -153,8 +174,10 @@ func (g *generator) setup(ctx context.Context) (err error) { return err } - // Discover any modules defined by the package - modules, err := g.discoverModules(ctx, path, "") + // Discover any modules defined by the package. + // Use an empty string for proto directory because it will be + // discovered automatically within the dependency package path. + modules, err := module.Discover(ctx, g.appPath, path, module.WithSDKDir(g.sdkDir)) if err != nil { return err } @@ -243,14 +266,21 @@ func (g *generator) resolveIncludes(ctx context.Context, path string) (protoIncl includes := protoIncludes{Paths: paths} - // Check that the app/package proto directory exists - protoPath := filepath.Join(path, g.protoDir) - fi, err := os.Stat(protoPath) - if err != nil && !os.IsNotExist(err) { - return protoIncludes{}, false, err - } else if !fi.IsDir() { - // Just return the global includes when a proto directory doesn't exist - return includes, true, nil + // The "cosmossdk.io" module packages must use SDK's proto path which is + // where all proto files for there type of Go package are. + var protoPath string + if module.IsCosmosSDKModulePkg(path) { + protoPath = filepath.Join(g.sdkDir, "proto") + } else { + // Check that the app/package proto directory exists + protoPath = filepath.Join(path, g.protoDir) + fi, err := os.Stat(protoPath) + if err != nil && !os.IsNotExist(err) { + return protoIncludes{}, false, err + } else if !fi.IsDir() { + // Just return the global includes when a proto directory doesn't exist + return includes, true, nil + } } // Add app's proto path to the list of proto paths @@ -285,24 +315,6 @@ func (g *generator) resolveIncludes(ctx context.Context, path string) (protoIncl return includes, true, nil } -func (g *generator) discoverModules(ctx context.Context, path, protoDir string) ([]module.Module, error) { - var filteredModules []module.Module - modules, err := module.Discover(ctx, g.appPath, path, protoDir) - if err != nil { - return nil, err - } - - protoPath := filepath.Join(path, g.protoDir) - for _, m := range modules { - if !strings.HasPrefix(m.Pkg.Path, protoPath) { - continue - } - filteredModules = append(filteredModules, m) - } - - return filteredModules, nil -} - func (g generator) updateBufModule(ctx context.Context) error { for pkgPath, includes := range g.thirdModuleIncludes { // Skip third party dependencies without proto files @@ -472,3 +484,12 @@ func (g generator) vendorProtoPackage(pkgName, protoPath string) (err error) { return nil } + +func filterCosmosSDKModule(versions []gomodule.Version) (gomodule.Version, bool) { + for _, v := range versions { + if strings.HasPrefix(v.Path, cosmosver.CosmosModulePath) { + return v, true + } + } + return gomodule.Version{}, false +} diff --git a/ignite/pkg/cosmosgen/generate_typescript.go b/ignite/pkg/cosmosgen/generate_typescript.go index 328eb69b51..80ecd12997 100644 --- a/ignite/pkg/cosmosgen/generate_typescript.go +++ b/ignite/pkg/cosmosgen/generate_typescript.go @@ -196,7 +196,14 @@ func (g *tsGenerator) generateModuleTemplate( return err } - pp := filepath.Join(appPath, g.g.protoDir) + // All "cosmossdk.io" module packages must use SDK's + // proto path which is where the proto files are stored. + var pp string + if module.IsCosmosSDKModulePkg(appPath) { + pp = filepath.Join(g.g.sdkDir, "proto") + } else { + pp = filepath.Join(appPath, g.g.protoDir) + } return templateTSClientModule.Write(out, pp, struct { Module module.Module diff --git a/ignite/pkg/cosmosgen/templates/module/index.ts.tpl b/ignite/pkg/cosmosgen/templates/module/index.ts.tpl index c9dfa159ec..11faba741d 100644 --- a/ignite/pkg/cosmosgen/templates/module/index.ts.tpl +++ b/ignite/pkg/cosmosgen/templates/module/index.ts.tpl @@ -1,6 +1,6 @@ -import Module from './module'; +import IgntModule from './module'; import { txClient, queryClient, registry } from './module'; import { msgTypes } from './registry'; export * from "./types"; -export { Module, msgTypes, txClient, queryClient, registry }; +export { IgntModule, msgTypes, txClient, queryClient, registry }; diff --git a/ignite/pkg/cosmosgen/templates/module/module.ts.tpl b/ignite/pkg/cosmosgen/templates/module/module.ts.tpl index 4797df2b06..abb378e19b 100644 --- a/ignite/pkg/cosmosgen/templates/module/module.ts.tpl +++ b/ignite/pkg/cosmosgen/templates/module/module.ts.tpl @@ -119,7 +119,7 @@ class SDKModule { } }; -const Module = (test: IgniteClient) => { +const IgntModule = (test: IgniteClient) => { return { module: { {{ camelCaseUpperSta .Module.Pkg.Name }}: new SDKModule(test) @@ -127,4 +127,4 @@ const Module = (test: IgniteClient) => { registry: msgTypes } } -export default Module; \ No newline at end of file +export default IgntModule; \ No newline at end of file diff --git a/ignite/pkg/cosmosgen/templates/root/client.ts.tpl b/ignite/pkg/cosmosgen/templates/root/client.ts.tpl index a7b30495b6..a9088ce67b 100644 --- a/ignite/pkg/cosmosgen/templates/root/client.ts.tpl +++ b/ignite/pkg/cosmosgen/templates/root/client.ts.tpl @@ -8,7 +8,7 @@ import { import { SigningStargateClient, StdFee } from "@cosmjs/stargate"; import { Env } from "./env"; import { UnionToIntersection, Return, Constructor } from "./helpers"; -import { Module } from "./modules"; +import { IgntModule } from "./modules"; import { EventEmitter } from "events"; import { ChainInfo } from "@keplr-wallet/types"; @@ -18,11 +18,11 @@ const defaultFee = { }; export class IgniteClient extends EventEmitter { - static plugins: Module[] = []; + static plugins: IgntModule[] = []; env: Env; signer?: OfflineSigner; registry: Array<[string, GeneratedType]> = []; - static plugin(plugin: T) { + static plugin(plugin: T) { const currentPlugins = this.plugins; class AugmentedClient extends this { diff --git a/ignite/pkg/cosmosgen/templates/root/index.ts.tpl b/ignite/pkg/cosmosgen/templates/root/index.ts.tpl index 8c71febfe1..b2cd682a81 100644 --- a/ignite/pkg/cosmosgen/templates/root/index.ts.tpl +++ b/ignite/pkg/cosmosgen/templates/root/index.ts.tpl @@ -2,7 +2,7 @@ import { Registry } from '@cosmjs/proto-signing' import { IgniteClient } from "./client"; import { MissingWalletError } from "./helpers"; -{{ range .Modules }}import { Module as {{ camelCaseUpperSta .Pkg.Name }}, msgTypes as {{ camelCaseUpperSta .Pkg.Name }}MsgTypes } from './{{ .Pkg.Name }}' +{{ range .Modules }}import { IgntModule as {{ camelCaseUpperSta .Pkg.Name }}, msgTypes as {{ camelCaseUpperSta .Pkg.Name }}MsgTypes } from './{{ .Pkg.Name }}' {{ end }} const Client = IgniteClient.plugin([ diff --git a/ignite/pkg/cosmosgen/templates/root/modules.ts.tpl b/ignite/pkg/cosmosgen/templates/root/modules.ts.tpl index 634b83c125..e8e4a78272 100644 --- a/ignite/pkg/cosmosgen/templates/root/modules.ts.tpl +++ b/ignite/pkg/cosmosgen/templates/root/modules.ts.tpl @@ -1,5 +1,5 @@ import { IgniteClient } from "./client"; import { GeneratedType } from "@cosmjs/proto-signing"; -export type ModuleInterface = { [key: string]: any } -export type Module = (instance: IgniteClient) => { module: ModuleInterface, registry: [string, GeneratedType][] } +export type IgntModuleInterface = { [key: string]: any } +export type IgntModule = (instance: IgniteClient) => { module: IgntModuleInterface, registry: [string, GeneratedType][] } diff --git a/ignite/pkg/cosmosgen/templates/root/package.json.tpl b/ignite/pkg/cosmosgen/templates/root/package.json.tpl index 8cd8cdea6b..b0babc1b29 100644 --- a/ignite/pkg/cosmosgen/templates/root/package.json.tpl +++ b/ignite/pkg/cosmosgen/templates/root/package.json.tpl @@ -15,8 +15,7 @@ "access": "public" }, "scripts": { - "build": "NODE_OPTIONS='--max-old-space-size=16384' tsc", - "postinstall": "npm run build" + "build": "NODE_OPTIONS='--max-old-space-size=16384' tsc" }, "dependencies": { "@cosmjs/proto-signing": "0.31.1", diff --git a/ignite/pkg/gocmd/gocmd.go b/ignite/pkg/gocmd/gocmd.go index f9a99c7330..0d043568cf 100644 --- a/ignite/pkg/gocmd/gocmd.go +++ b/ignite/pkg/gocmd/gocmd.go @@ -33,6 +33,9 @@ const ( // CommandModVerify represents go mod "verify" command. CommandModVerify = "verify" + // CommandModDownload represents go mod "download" command. + CommandModDownload = "download" + // CommandFmt represents go "fmt" command. CommandFmt = "fmt" @@ -105,6 +108,15 @@ func ModVerify(ctx context.Context, path string, options ...exec.Option) error { return exec.Exec(ctx, []string{Name(), CommandMod, CommandModVerify}, append(options, exec.StepOption(step.Workdir(path)))...) } +// ModDownload runs go mod download on a path with options. +func ModDownload(ctx context.Context, path string, json bool, options ...exec.Option) error { + command := []string{Name(), CommandMod, CommandModDownload} + if json { + command = append(command, "-json") + } + return exec.Exec(ctx, command, append(options, exec.StepOption(step.Workdir(path)))...) +} + // BuildPath runs go install on cmd folder with options. func BuildPath(ctx context.Context, output, binary, path string, flags []string, options ...exec.Option) error { binaryOutput, err := binaryPath(output, binary) diff --git a/ignite/pkg/gomodule/gomodule.go b/ignite/pkg/gomodule/gomodule.go index 1418079fcb..2c4d0af13a 100644 --- a/ignite/pkg/gomodule/gomodule.go +++ b/ignite/pkg/gomodule/gomodule.go @@ -10,19 +10,41 @@ import ( "io/fs" "os" "path/filepath" + "strings" "golang.org/x/mod/modfile" "golang.org/x/mod/module" "github.com/ignite/cli/ignite/pkg/cache" - "github.com/ignite/cli/ignite/pkg/cmdrunner" + "github.com/ignite/cli/ignite/pkg/cmdrunner/exec" "github.com/ignite/cli/ignite/pkg/cmdrunner/step" + "github.com/ignite/cli/ignite/pkg/gocmd" ) const pathCacheNamespace = "gomodule.path" -// ErrGoModNotFound returned when go.mod file cannot be found for an app. -var ErrGoModNotFound = errors.New("go.mod not found") +var ( + // ErrGoModNotFound returned when go.mod file cannot be found for an app. + ErrGoModNotFound = errors.New("go.mod not found") + + // ErrModuleNotFound is returned when a Go module is not found. + ErrModuleNotFound = errors.New("module not found") +) + +// Version is an alias to the module version type. +type Version = module.Version + +// Module contains Go module info. +type Module struct { + // Path is the Go module path. + Path string + + // Version is the module version. + Version string + + // Dir is the absolute path to the Go module. + Dir string +} // ParseAt finds and parses go.mod at app's path. func ParseAt(path string) (*modfile.File, error) { @@ -37,8 +59,8 @@ func ParseAt(path string) (*modfile.File, error) { } // FilterVersions filters dependencies under require section by their paths. -func FilterVersions(dependencies []module.Version, paths ...string) []module.Version { - var filtered []module.Version +func FilterVersions(dependencies []Version, paths ...string) []Version { + var filtered []Version for _, dep := range dependencies { for _, path := range paths { @@ -52,10 +74,10 @@ func FilterVersions(dependencies []module.Version, paths ...string) []module.Ver return filtered } -func ResolveDependencies(f *modfile.File, includeIndirect bool) ([]module.Version, error) { - var versions []module.Version +func ResolveDependencies(f *modfile.File, includeIndirect bool) ([]Version, error) { + var versions []Version - isReplacementAdded := func(rv module.Version) bool { + isReplacementAdded := func(rv Version) bool { for _, rep := range f.Replace { if rv.Path == rep.Old.Path { versions = append(versions, rep.New) @@ -80,7 +102,7 @@ func ResolveDependencies(f *modfile.File, includeIndirect bool) ([]module.Versio } // LocatePath locates pkg's absolute path managed by 'go mod' on the local filesystem. -func LocatePath(ctx context.Context, cacheStorage cache.Storage, src string, pkg module.Version) (path string, err error) { +func LocatePath(ctx context.Context, cacheStorage cache.Storage, src string, pkg Version) (path string, err error) { // can be a local package. if pkg.Version == "" { // indicates that this is a local package. if filepath.IsAbs(pkg.Path) { @@ -100,37 +122,72 @@ func LocatePath(ctx context.Context, cacheStorage cache.Storage, src string, pkg } // otherwise, it is hosted. - out := &bytes.Buffer{} - - if err := cmdrunner. - New(). - Run(ctx, step.New( - step.Exec("go", "mod", "download", "-json"), - step.Workdir(src), - step.Stdout(out), - )); err != nil { + m, err := FindModule(ctx, src, pkg.String()) + if err != nil { return "", err } - d := json.NewDecoder(out) + if err = pathCache.Put(cacheKey, m.Dir); err != nil { + return "", err + } + return m.Dir, nil +} - for { - var mod struct { - Path, Version, Dir string - } - if err := d.Decode(&mod); err != nil { +// SplitPath splits a Go import path into an URI path and version. +// Version is an empty string when the path doesn't contain a version suffix. +// Versioned paths use the "path@version" format. +func SplitPath(path string) (string, string) { + if len(path) == 0 || path[0] == '@' { + return "", "" + } + + parts := strings.SplitN(path, "@", 2) + if len(parts) == 2 { + return parts[0], parts[1] + } + return parts[0], "" +} + +// JoinPath joins a Go import path URI to a version. +// The result path have the "path@version" format. +func JoinPath(path, version string) string { + if path == "" { + return "" + } + + if version == "" { + return path + } + + return fmt.Sprintf("%s@%s", path, version) +} + +// FindModule returns the Go module info for an import path. +// The module is searched within the dependencies of the module defined in root dir. +func FindModule(ctx context.Context, rootDir, path string) (Module, error) { + var stdout bytes.Buffer + err := gocmd.ModDownload(ctx, rootDir, true, exec.StepOption(step.Stdout(&stdout))) + if err != nil { + return Module{}, err + } + + dec := json.NewDecoder(&stdout) + p, version := SplitPath(path) + + for dec.More() { + var m Module + if dec.Decode(&m); err != nil { if errors.Is(err, io.EOF) { break } - return "", err + + return Module{}, err } - if mod.Path == pkg.Path && mod.Version == pkg.Version { - if err := pathCache.Put(cacheKey, mod.Dir); err != nil { - return "", err - } - return mod.Dir, nil + + if m.Path == p && (version == "" || version == m.Version) { + return m, nil } } - return "", fmt.Errorf("module %q not found", pkg.Path) + return Module{}, fmt.Errorf("%w: %s", ErrModuleNotFound, path) } diff --git a/ignite/pkg/gomodule/gomodule_test.go b/ignite/pkg/gomodule/gomodule_test.go new file mode 100644 index 0000000000..42ff3e6d2a --- /dev/null +++ b/ignite/pkg/gomodule/gomodule_test.go @@ -0,0 +1,97 @@ +package gomodule_test + +import ( + "context" + "strings" + "testing" + + "github.com/ignite/cli/ignite/pkg/gomodule" + "github.com/stretchr/testify/require" +) + +func TestSplitPath(t *testing.T) { + cases := []struct { + name string + path string + wantPath string + wantVersion string + }{ + { + name: "path with version", + path: "foo@v0.1.0", + wantPath: "foo", + wantVersion: "v0.1.0", + }, + { + name: "path without version", + path: "foo", + wantPath: "foo", + }, + { + name: "invalid path", + path: "@v0.1.0", + }, + { + name: "empty path", + }, + } + + for _, tt := range cases { + t.Run(tt.name, func(t *testing.T) { + // Act + p, v := gomodule.SplitPath(tt.path) + + // Assert + require.Equal(t, tt.wantPath, p) + require.Equal(t, tt.wantVersion, v) + }) + } +} + +func TestJoinPath(t *testing.T) { + require.Equal(t, "foo@v0.1.0", gomodule.JoinPath("foo", "v0.1.0")) + require.Equal(t, "", gomodule.JoinPath("", "v0.1.0")) + require.Equal(t, "foo", gomodule.JoinPath("foo", "")) +} + +func TestFindModule(t *testing.T) { + cases := []struct { + name string + importPath string + version string + wantErr error + }{ + { + name: "module exists", + importPath: "github.com/gorilla/mux", + version: "v1.8.0", + }, + { + name: "module missing", + importPath: "github.com/foo/bar", + version: "v0.1.0", + wantErr: gomodule.ErrModuleNotFound, + }, + } + + for _, tt := range cases { + t.Run(tt.name, func(t *testing.T) { + // Arrange + ctx := context.Background() + path := gomodule.JoinPath(tt.importPath, tt.version) + + // Act + m, err := gomodule.FindModule(ctx, "testdata/module", path) + + // Assert + if tt.wantErr != nil { + require.ErrorIs(t, err, tt.wantErr) + } else { + require.NoError(t, err) + require.Equal(t, tt.importPath, m.Path) + require.Equal(t, tt.version, m.Version) + require.True(t, strings.HasSuffix(m.Dir, path)) + } + }) + } +} diff --git a/ignite/pkg/gomodule/testdata/module/go.mod b/ignite/pkg/gomodule/testdata/module/go.mod new file mode 100644 index 0000000000..6b0c1f1e4c --- /dev/null +++ b/ignite/pkg/gomodule/testdata/module/go.mod @@ -0,0 +1,8 @@ +module github.com/ignite/cli/ignite/pkg/gomodule + +go 1.21.0 + +require ( + github.com/gorilla/mux v1.8.0 + github.com/stretchr/testify v1.8.2 +) diff --git a/ignite/pkg/xstrings/xstrings.go b/ignite/pkg/xstrings/xstrings.go index ff038a95db..7924443e33 100644 --- a/ignite/pkg/xstrings/xstrings.go +++ b/ignite/pkg/xstrings/xstrings.go @@ -70,3 +70,25 @@ func Title(s string) string { func ToUpperFirst(s string) string { return strings.ToUpper(s[:1]) + s[1:] } + +// StringBetween returns the string between two other strings. +// The comparison is not greedy so the between result includes the +// string between the start value and the first match of the end value. +func StringBetween(s, start, end string) string { + if s == "" || start == "" || end == "" { + return "" + } + + i := strings.Index(s, start) + if i == -1 { + return "" + } + + s = s[i+len(start):] + i = strings.Index(s, end) + if i == -1 { + return "" + } + + return s[:i] +} diff --git a/ignite/pkg/xstrings/xstrings_test.go b/ignite/pkg/xstrings/xstrings_test.go index c2da08be2c..0087b4e6ce 100644 --- a/ignite/pkg/xstrings/xstrings_test.go +++ b/ignite/pkg/xstrings/xstrings_test.go @@ -18,3 +18,11 @@ func TestNoNumberPrefix(t *testing.T) { require.Equal(t, "_0foo", xstrings.NoNumberPrefix("0foo")) require.Equal(t, "_999foo", xstrings.NoNumberPrefix("999foo")) } + +func TestStringBetween(t *testing.T) { + require.Equal(t, "bar", xstrings.StringBetween("foobarbaz", "foo", "baz")) + require.Equal(t, "bar", xstrings.StringBetween("0foobarbaz1", "foo", "baz")) + require.Equal(t, "", xstrings.StringBetween("0foo", "0", "")) + require.Equal(t, "", xstrings.StringBetween("foo0", "", "0")) + require.Equal(t, "", xstrings.StringBetween("", "0", "1")) +}