From 596000062d84d18339cb67c16959eccafa67b5c8 Mon Sep 17 00:00:00 2001 From: Pantani Date: Fri, 9 Feb 2024 08:20:14 -0300 Subject: [PATCH] add wasm commands --- official/wasm/cmd/cmd.go | 89 +++++++-- official/wasm/cmd/debug/main.go | 15 ++ official/wasm/cmd/hello.go | 14 -- official/wasm/go.mod | 10 +- official/wasm/go.sum | 22 ++ official/wasm/integration/app_test.go | 3 +- official/wasm/main.go | 29 ++- official/wasm/pkg/goanalysis/goanalysis.go | 188 ++++++++++++++++++ .../wasm/services/scaffolder/scaffolder.go | 86 ++++++++ 9 files changed, 406 insertions(+), 50 deletions(-) create mode 100644 official/wasm/cmd/debug/main.go delete mode 100644 official/wasm/cmd/hello.go create mode 100644 official/wasm/pkg/goanalysis/goanalysis.go create mode 100644 official/wasm/services/scaffolder/scaffolder.go diff --git a/official/wasm/cmd/cmd.go b/official/wasm/cmd/cmd.go index e9418ffc..7b4233ff 100644 --- a/official/wasm/cmd/cmd.go +++ b/official/wasm/cmd/cmd.go @@ -1,19 +1,78 @@ package cmd -import "github.com/ignite/cli/v28/ignite/services/plugin" - -// GetCommands returns the list of wasm app commands. -func GetCommands() []*plugin.Command { - return []*plugin.Command{ - { - Use: "wasm [command]", - Short: "wasm is an awesome Ignite application!", - Commands: []*plugin.Command{ - { - Use: "hello", - Short: "Say hello to the world of ignite!", - }, - }, - }, +import ( + "github.com/ignite/cli/v28/ignite/pkg/cliui/colors" + "github.com/ignite/cli/v28/ignite/pkg/xgenny" + "github.com/spf13/cobra" + "os" + "path/filepath" + "sort" + "strings" +) + +const ( + flagPath = "path" + + statusScaffolding = "Scaffolding..." +) + +var ( + modifyPrefix = colors.Modified("modify ") + createPrefix = colors.Success("create ") + removePrefix = func(s string) string { + return strings.TrimPrefix(strings.TrimPrefix(s, modifyPrefix), createPrefix) + } +) + +func flagGetPath(cmd *cobra.Command) (path string) { + path, _ = cmd.Flags().GetString(flagPath) + return +} + +func flagSetPath(cmd *cobra.Command) { + cmd.PersistentFlags().StringP(flagPath, "p", ".", "path of the app") +} + +func sourceModificationToString(sm xgenny.SourceModification) (string, error) { + // get file names and add prefix + var files []string + for _, modified := range sm.ModifiedFiles() { + // get the relative app path from the current directory + relativePath, err := relativePath(modified) + if err != nil { + return "", err + } + files = append(files, modifyPrefix+relativePath) + } + for _, created := range sm.CreatedFiles() { + // get the relative app path from the current directory + relativePath, err := relativePath(created) + if err != nil { + return "", err + } + files = append(files, createPrefix+relativePath) + } + + // sort filenames without prefix + sort.Slice(files, func(i, j int) bool { + s1 := removePrefix(files[i]) + s2 := removePrefix(files[j]) + + return strings.Compare(s1, s2) == -1 + }) + + return "\n" + strings.Join(files, "\n"), nil +} + +// relativePath return the relative app path from the current directory. +func relativePath(appPath string) (string, error) { + pwd, err := os.Getwd() + if err != nil { + return "", err + } + path, err := filepath.Rel(pwd, appPath) + if err != nil { + return "", err } + return path, nil } diff --git a/official/wasm/cmd/debug/main.go b/official/wasm/cmd/debug/main.go new file mode 100644 index 00000000..46b87c58 --- /dev/null +++ b/official/wasm/cmd/debug/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "fmt" + "os" + + "wasm/cmd" +) + +func main() { + if err := cmd.NewWasm().Execute(); err != nil { + _, _ = fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} diff --git a/official/wasm/cmd/hello.go b/official/wasm/cmd/hello.go deleted file mode 100644 index df3ae102..00000000 --- a/official/wasm/cmd/hello.go +++ /dev/null @@ -1,14 +0,0 @@ -package cmd - -import ( - "context" - "fmt" - - "github.com/ignite/cli/v28/ignite/services/plugin" -) - -// ExecuteHello executes the hello subcommand. -func ExecuteHello(ctx context.Context, cmd *plugin.ExecutedCommand) error { - fmt.Println("Hello, world!") - return nil -} diff --git a/official/wasm/go.mod b/official/wasm/go.mod index a32ae7b1..457c2992 100644 --- a/official/wasm/go.mod +++ b/official/wasm/go.mod @@ -5,8 +5,10 @@ go 1.21.1 toolchain go1.21.6 require ( + github.com/gobuffalo/genny/v2 v2.1.0 github.com/hashicorp/go-plugin v1.5.2 github.com/ignite/cli/v28 v28.1.1 + github.com/spf13/cobra v1.8.0 github.com/stretchr/testify v1.8.4 ) @@ -24,6 +26,7 @@ require ( filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.2 // indirect + github.com/AlecAivazis/survey/v2 v2.3.7 // indirect github.com/DataDog/datadog-go v3.2.0+incompatible // indirect github.com/DataDog/zstd v1.5.5 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect @@ -33,12 +36,14 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect github.com/blang/semver/v4 v4.0.0 // indirect + github.com/briandowns/spinner v1.23.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/charmbracelet/lipgloss v0.6.0 // indirect + github.com/chzyer/readline v1.5.1 // indirect github.com/cloudflare/circl v1.3.7 // indirect github.com/cockroachdb/errors v1.11.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect @@ -81,7 +86,6 @@ require ( github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/gobuffalo/flect v0.3.0 // indirect - github.com/gobuffalo/genny/v2 v2.1.0 // indirect github.com/gobuffalo/github_flavored_markdown v1.1.4 // indirect github.com/gobuffalo/helpers v0.6.7 // indirect github.com/gobuffalo/logger v1.0.7 // indirect @@ -123,6 +127,7 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jmhodges/levigo v1.0.0 // indirect + github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/klauspost/compress v1.17.4 // indirect github.com/kr/pretty v0.3.1 // indirect @@ -131,10 +136,12 @@ require ( github.com/linxGnu/grocksdb v1.8.6 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/magiconair/properties v1.8.7 // indirect + github.com/manifoldco/promptui v0.9.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect + github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect github.com/microcosm-cc/bluemonday v1.0.23 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -165,7 +172,6 @@ require ( github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e // indirect github.com/spf13/afero v1.9.5 // indirect github.com/spf13/cast v1.5.1 // indirect - github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.16.0 // indirect diff --git a/official/wasm/go.sum b/official/wasm/go.sum index ad770b0e..90ed7651 100644 --- a/official/wasm/go.sum +++ b/official/wasm/go.sum @@ -62,6 +62,8 @@ github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMb github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/99designs/keyring v1.2.2 h1:pZd3neh/EmUzWONb35LxQfvuY7kiSXAq3HQd97+XBn0= github.com/99designs/keyring v1.2.2/go.mod h1:wes/FrByc8j7lFOAGLGSNEg8f/PaI3cgTBqhFkHUrPk= +github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= +github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4= @@ -72,6 +74,8 @@ github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= +github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= @@ -116,6 +120,8 @@ github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2 github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/briandowns/spinner v1.23.0 h1:alDF2guRWqa/FOZZYWjlMIx2L6H0wyewPxo/CH4Pt2A= +github.com/briandowns/spinner v1.23.0/go.mod h1:rPG4gmXeN3wQV/TsAY4w8lPdIM6RX3yqeBQJSrbXjuE= github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/btcutil v1.1.3 h1:xfbtw8lwpp0G6NwSHb+UE67ryTFHJAiNuipusjXSohQ= @@ -140,10 +146,14 @@ github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/charmbracelet/lipgloss v0.6.0 h1:1StyZB9vBSOyuZxQUcUwGr17JmojPNm87inij9N3wJY= github.com/charmbracelet/lipgloss v0.6.0/go.mod h1:tHh2wr34xcHjC2HCXIlGSG1jaDF0S0atAUvBMP6Ppuk= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= +github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04= +github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= @@ -209,6 +219,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI= +github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= @@ -522,6 +534,8 @@ github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hdevalence/ed25519consensus v0.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7HsjsjeEZ6auqU= github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= +github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= +github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= @@ -563,6 +577,8 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= @@ -605,12 +621,14 @@ github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3v github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= @@ -627,6 +645,8 @@ github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.20/go.mod h1:yfBmMi8mxvaZut3Yytv+jTXRY8mxyjJ0/kQBTElld50= github.com/microcosm-cc/bluemonday v1.0.22/go.mod h1:ytNkv4RrDrLJ2pqlsSI46O6IVXmZOBBD4SaJyDwwTkM= github.com/microcosm-cc/bluemonday v1.0.23 h1:SMZe2IGa0NuHvnVNAZ+6B38gsTbi5e4sViiWJyDDqFY= @@ -1061,6 +1081,7 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1117,6 +1138,7 @@ golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/official/wasm/integration/app_test.go b/official/wasm/integration/app_test.go index 79a375ae..be735d07 100644 --- a/official/wasm/integration/app_test.go +++ b/official/wasm/integration/app_test.go @@ -6,12 +6,11 @@ import ( "path/filepath" "testing" - "github.com/stretchr/testify/require" - pluginsconfig "github.com/ignite/cli/v28/ignite/config/plugins" "github.com/ignite/cli/v28/ignite/pkg/cmdrunner/step" "github.com/ignite/cli/v28/ignite/services/plugin" envtest "github.com/ignite/cli/v28/integration" + "github.com/stretchr/testify/require" ) func TestWasm(t *testing.T) { diff --git a/official/wasm/main.go b/official/wasm/main.go index 442dc649..203c067d 100644 --- a/official/wasm/main.go +++ b/official/wasm/main.go @@ -2,33 +2,28 @@ package main import ( "context" - "fmt" + "os" hplugin "github.com/hashicorp/go-plugin" - "github.com/ignite/cli/v28/ignite/services/plugin" + "wasm/cmd" ) type app struct{} -func (app) Manifest(_ context.Context) (*plugin.Manifest, error) { - return &plugin.Manifest{ - Name: "wasm", - Commands: cmd.GetCommands(), - }, nil +func (app) Manifest(context.Context) (*plugin.Manifest, error) { + m := &plugin.Manifest{Name: "wasm"} + m.ImportCobraCommand(cmd.NewWasm(), "ignite") + return m, nil } -func (app) Execute(ctx context.Context, c *plugin.ExecutedCommand, _ plugin.ClientAPI) error { - // Remove the first two elements "ignite" and "wasm" from OsArgs. - args := c.OsArgs[2:] - - switch args[0] { - case "hello": - return cmd.ExecuteHello(ctx, c) - default: - return fmt.Errorf("unknown command: %s", c.Path) - } +func (app) Execute(_ context.Context, c *plugin.ExecutedCommand, _ plugin.ClientAPI) error { + // Run the "hermes" command as if it were a root command. To do + // so remove the first two arguments which are "ignite relayer" + // from OSArgs to treat "hermes" as the root command. + os.Args = c.OsArgs[2:] + return cmd.NewWasm().Execute() } func (app) ExecuteHookPre(_ context.Context, _ *plugin.ExecutedHook, _ plugin.ClientAPI) error { diff --git a/official/wasm/pkg/goanalysis/goanalysis.go b/official/wasm/pkg/goanalysis/goanalysis.go new file mode 100644 index 00000000..97736770 --- /dev/null +++ b/official/wasm/pkg/goanalysis/goanalysis.go @@ -0,0 +1,188 @@ +package goanalysis + +import ( + "bytes" + "go/ast" + "go/format" + "go/parser" + "go/token" + + "github.com/ignite/cli/v28/ignite/pkg/errors" +) + +// AppendImports inserts import statements into Go source code content. +func AppendImports(fileContent string, importStatements ...string) (modifiedContent string, err error) { + fileSet := token.NewFileSet() + + // Parse the Go source code content. + f, err := parser.ParseFile(fileSet, "", fileContent, parser.ParseComments) + if err != nil { + return "", err + } + + // Check if the import already exists. + existImports := make(map[string]struct{}) + for _, decl := range f.Decls { + genDecl, ok := decl.(*ast.GenDecl) + if !ok || genDecl.Tok != token.IMPORT || len(genDecl.Specs) == 0 { + continue + } + + for _, spec := range genDecl.Specs { + importSpec, ok := spec.(*ast.ImportSpec) + if !ok { + continue + } + existImports[importSpec.Path.Value] = struct{}{} + } + } + + newSpecs := make([]ast.Spec, 0) + for _, importStatement := range importStatements { + // Check if the import already exists. + if _, ok := existImports[`"`+importStatement+`"`]; ok { + continue + } + // Create a new import spec. + newSpecs = append(newSpecs, &ast.ImportSpec{ + Path: &ast.BasicLit{ + Kind: token.STRING, + Value: `"` + importStatement + `"`, + }, + }) + } + + if len(newSpecs) == 0 { + // No new imports to add. + return fileContent, nil + } + + // Create a new import declaration. + newImportDecl := &ast.GenDecl{ + Tok: token.IMPORT, + Specs: newSpecs, + } + + // Insert the new import declaration at the beginning of the file. + newDecls := append([]ast.Decl{newImportDecl}, f.Decls...) + + // Update the file's declarations. + f.Decls = newDecls + + // Write the modified AST to a buffer. + var buf bytes.Buffer + if err := format.Node(&buf, fileSet, f); err != nil { + return "", err + } + + return buf.String(), nil +} + +// AppendCode inserts code before the end or return of a function in Go source code content. +func AppendCode(fileContent, functionName, codeToInsert string) (modifiedContent string, err error) { + fileSet := token.NewFileSet() + + // Parse the Go source code content. + f, err := parser.ParseFile(fileSet, "", fileContent, parser.ParseComments) + if err != nil { + return "", err + } + + found := false + ast.Inspect(f, func(n ast.Node) bool { + if funcDecl, ok := n.(*ast.FuncDecl); ok { + // Check if the function has the name you want to replace. + if funcDecl.Name.Name == functionName { + // Insert the code before the end or return of the function. + insertionExpr, err := parser.ParseExpr(codeToInsert) + if err != nil { + return false + } + // Check if there is a return statement in the function. + if len(funcDecl.Body.List) > 0 { + lastStmt := funcDecl.Body.List[len(funcDecl.Body.List)-1] + switch lastStmt.(type) { + case *ast.ReturnStmt: + // If there is a return, insert before it. + funcDecl.Body.List = append(funcDecl.Body.List[:len(funcDecl.Body.List)-1], &ast.ExprStmt{X: insertionExpr}, lastStmt) + default: + // If there is no return, insert at the end of the function body. + funcDecl.Body.List = append(funcDecl.Body.List, &ast.ExprStmt{X: insertionExpr}) + } + } else { + // If there are no statements in the function body, insert at the end of the function body. + funcDecl.Body.List = append(funcDecl.Body.List, &ast.ExprStmt{X: insertionExpr}) + } + found = true + return false + } + } + return true + }) + + if !found { + return "", errors.Errorf("function %s not found", functionName) + } + + // Write the modified AST to a buffer. + var buf bytes.Buffer + if err := format.Node(&buf, fileSet, f); err != nil { + return "", err + } + + return buf.String(), nil +} + +// ReplaceReturn replaces return statements in a Go function with a new return statement. +func ReplaceReturn(fileContent, functionName, newReturnStatement string) (modifiedContent string, err error) { + fileSet := token.NewFileSet() + + // Parse the Go source code content. + f, err := parser.ParseFile(fileSet, "", fileContent, parser.ParseComments) + if err != nil { + return "", err + } + + found := false + ast.Inspect(f, func(n ast.Node) bool { + if funcDecl, ok := n.(*ast.FuncDecl); ok { + // Check if the function has the name you want to replace. + if funcDecl.Name.Name == functionName { + // Replace the return statements. + for _, stmt := range funcDecl.Body.List { + if retStmt, ok := stmt.(*ast.ReturnStmt); ok { + // Remove existing return statements. + retStmt.Results = nil + + // Parse the new return statement. + var buf bytes.Buffer + buf.WriteString(newReturnStatement) + returnExpr, err := parser.ParseExpr(buf.String()) + if err != nil { + return false + } + // Add the new return statement. + retStmt.Results = []ast.Expr{returnExpr} + + //retStmt.Results = append(retStmt.Results, newRetExpr) + } + } + found = true + return false + } + } + return true + }) + + if !found { + return "", errors.Errorf("function %s not found", functionName) + } + + // Write the modified AST to a buffer. + var buf bytes.Buffer + if err := format.Node(&buf, fileSet, f); err != nil { + return "", err + } + + return buf.String(), nil +} diff --git a/official/wasm/services/scaffolder/scaffolder.go b/official/wasm/services/scaffolder/scaffolder.go new file mode 100644 index 00000000..89619b41 --- /dev/null +++ b/official/wasm/services/scaffolder/scaffolder.go @@ -0,0 +1,86 @@ +// Package scaffolder initializes Ignite CLI apps and modifies existing ones +// to add more features in a later time. +package scaffolder + +import ( + "context" + "path/filepath" + + "github.com/ignite/cli/v28/ignite/pkg/cosmosanalysis" + "github.com/ignite/cli/v28/ignite/pkg/cosmosver" + "github.com/ignite/cli/v28/ignite/pkg/errors" + "github.com/ignite/cli/v28/ignite/pkg/gocmd" + "github.com/ignite/cli/v28/ignite/pkg/gomodulepath" +) + +const ( + errOldCosmosSDKVersionStr = `Your chain has been scaffolded with an older version of Cosmos SDK: %s + +Please, follow the migration guide to upgrade your chain to the latest version at https://docs.ignite.com/migration` +) + +// Scaffolder is Ignite CLI app scaffolder. +type Scaffolder struct { + // Version of the chain + Version cosmosver.Version + + // path of the app. + path string + + // modpath represents the go module path of the app. + modpath gomodulepath.Path +} + +// New creates a new scaffold app. +func New(appPath string) (Scaffolder, error) { + path, err := filepath.Abs(appPath) + if err != nil { + return Scaffolder{}, err + } + + modpath, path, err := gomodulepath.Find(path) + if err != nil { + return Scaffolder{}, err + } + + ver, err := cosmosver.Detect(path) + if err != nil { + return Scaffolder{}, err + } + + // Make sure that the app was scaffolded with a supported Cosmos SDK version + if err := AssertSupportedCosmosSDKVersion(ver); err != nil { + return Scaffolder{}, err + } + + if err := cosmosanalysis.IsChainPath(path); err != nil { + return Scaffolder{}, err + } + + s := Scaffolder{ + Version: ver, + path: path, + modpath: modpath, + } + + return s, nil +} + +// AssertSupportedCosmosSDKVersion asserts that a Cosmos SDK version is supported by Ignite CLI. +func AssertSupportedCosmosSDKVersion(v cosmosver.Version) error { + if v.LT(cosmosver.StargateFiftyVersion) { + return errors.Errorf(errOldCosmosSDKVersionStr, v) + } + return nil +} + +func finish(ctx context.Context, path string) error { + if err := gocmd.Fmt(ctx, path); err != nil { + return err + } + + // TODO this function will be available only in the next cli version + // _ = gocmd.GoImports(ctx, path) // goimports installation could fail, so ignore the error + + return gocmd.ModTidy(ctx, path) +}