From e849a365882a4004887e7870dd29fa15916916ca Mon Sep 17 00:00:00 2001 From: Norman Meier Date: Tue, 22 Aug 2023 16:07:11 +0200 Subject: [PATCH 1/6] feat: gnodeploy cmd Signed-off-by: Norman Meier --- .gitignore | 1 + gno.land/cmd/gnodeploy/main.go | 349 +++++++++++++++++++++++++++++++++ go.mod | 4 +- go.sum | 4 + 4 files changed, 357 insertions(+), 1 deletion(-) create mode 100644 gno.land/cmd/gnodeploy/main.go diff --git a/.gitignore b/.gitignore index d7e6d7eb9a4..6f6c5ec254d 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ pbbindings.go *# cover.out coverage.out +/.deploy/ \ No newline at end of file diff --git a/gno.land/cmd/gnodeploy/main.go b/gno.land/cmd/gnodeploy/main.go new file mode 100644 index 00000000000..e7634ac5e99 --- /dev/null +++ b/gno.land/cmd/gnodeploy/main.go @@ -0,0 +1,349 @@ +package main + +import ( + "bytes" + "flag" + "fmt" + "io" + "net/http" + "os" + "os/exec" + "path/filepath" + "regexp" + "strconv" + "strings" + + expect "github.com/Netflix/go-expect" + "github.com/peterbourgon/ff/v3" + "github.com/pkg/errors" +) + +func main() { + fs := flag.NewFlagSet("gnodeploy", flag.ContinueOnError) + var ( + packagesRootFlag = fs.String("root", "examples", "root directory of packages") + targetsPkgPathFlag = fs.String("targets", "", "targets package paths") + remoteGnowebFlag = fs.String("remote-gnoweb", "https://testnet.gno.teritori.com", "remote gnoweb node") + remoteGnoFlag = fs.String("remote-gno", "testnet.gno.teritori.com:26657", "remote gno node") + chainIdFlag = fs.String("chain-id", "teritori-1", "remote chain id") + walletNameFlag = fs.String("wallet", "tester", "wallet name") + depositFlag = fs.String("deposit", "1ugnot", "deposit") + gasFeeFlag = fs.String("gas-fee", "1ugnot", "gas fee") + gasWantedFlag = fs.String("gas-wanted", "10000000", "gas wanted") + ) + + err := ff.Parse(fs, os.Args[1:]) + if err != nil { + panic(err) + } + + if targetsPkgPathFlag == nil || *targetsPkgPathFlag == "" { + panic("target package path is required") + } + targetsPkgPath := strings.Split(*targetsPkgPathFlag, ",") + for i, targetPkgPath := range targetsPkgPath { + targetsPkgPath[i] = strings.TrimSpace(targetPkgPath) + } + + if packagesRootFlag == nil || *packagesRootFlag == "" { + panic("packages root is required") + } + packagesRoot := *packagesRootFlag + + if remoteGnowebFlag == nil || *remoteGnowebFlag == "" { + panic("remote gnoweb node is required") + } + remoteGnoweb := *remoteGnowebFlag + + if remoteGnoFlag == nil || *remoteGnoFlag == "" { + panic("remote gno node is required") + } + remoteGno := *remoteGnoFlag + + if chainIdFlag == nil || *chainIdFlag == "" { + panic("chain id is required") + } + chainId := *chainIdFlag + + if walletNameFlag == nil || *walletNameFlag == "" { + panic("wallet name is required") + } + walletName := *walletNameFlag + + if depositFlag == nil || *depositFlag == "" { + panic("deposit is required") + } + deposit := *depositFlag + + if gasFeeFlag == nil || *gasFeeFlag == "" { + panic("gas fee is required") + } + gasFee := *gasFeeFlag + + if gasWantedFlag == nil || *gasWantedFlag == "" { + panic("gas wanted is required") + } + gasWanted := *gasWantedFlag + + fmt.Print("Target packages:\n\n") + for _, targetPkgPath := range targetsPkgPath { + fmt.Println(targetPkgPath) + } + + allGnoMods := map[string]struct{}{} + if err := filepath.Walk(packagesRoot, func(path string, info os.FileInfo, err error) error { + if err != nil { + fmt.Println("error during walk:", err) + return nil + } + if info.IsDir() || info.Name() != "gno.mod" { + return nil + } + + allGnoMods[path] = struct{}{} + + return nil + }); err != nil { + panic(errors.Wrap(err, "failed to walk packages")) + } + + for _, targetPkgPath := range targetsPkgPath { + targetPackageFSPath := filepath.Join(packagesRoot, targetPkgPath) + targetPackageGnoModPath := filepath.Join(targetPackageFSPath, "gno.mod") + if _, ok := allGnoMods[targetPackageGnoModPath]; !ok { + panic("target package " + targetPkgPath + " not found") + } + } + + requires := map[string][]string{} + requiredBy := map[string][]string{} + for gnoModPath := range allGnoMods { + deps, err := gnoModDeps(gnoModPath) + if err != nil { + panic(errors.Wrap(err, "failed to parse "+gnoModPath)) + } + + pkgPath := strings.TrimSuffix(strings.TrimPrefix(gnoModPath, packagesRoot+"/"), "/gno.mod") // FIXME: brittle, not cross-platform + + requires[pkgPath] = deps + for _, dep := range deps { + requiredBy[dep] = append(requiredBy[dep], pkgPath) + } + } + + upgrades := map[string]string{} + + fmt.Println("\nFetching versions from remote...") + + roots := targetsPkgPath + seen := map[string]struct{}{} + for len(roots) > 0 { + pkgPath := roots[0] + roots = roots[1:] + if _, ok := seen[pkgPath]; ok { + continue + } + seen[pkgPath] = struct{}{} + roots = append(roots, requiredBy[pkgPath]...) + + // find highest version on remote + nextVersion := 2 + for { + resp, err := http.Get(fmt.Sprintf("%s/%s_v%d/", remoteGnoweb, strings.TrimPrefix(pkgPath, "gno.land/"), nextVersion)) // last slash is important so we query sources and don't run into problems with render errors in realms + if err != nil { + panic(errors.Wrap(err, "failed to get "+pkgPath)) + } + if resp.StatusCode == 500 { + break + } + if resp.StatusCode != 200 { + panic("unexpected status code: " + strconv.Itoa(resp.StatusCode)) + } + nextVersion++ + } + + newPkgPath := fmt.Sprintf("%s_v%d", pkgPath, nextVersion) + upgrades[pkgPath] = newPkgPath + } + + fmt.Println("\nWill upgrade", len(upgrades), "packages") + + fmt.Println("\nCopying root to temporary directory...") + tmpDir := ".deploy" + if err := os.RemoveAll(tmpDir); err != nil { + panic(errors.Wrap(err, "failed to remove "+tmpDir)) + } + cmd := exec.Command("cp", "-r", packagesRoot, tmpDir) + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + panic(errors.Wrap(err, "failed to copy "+packagesRoot)) + } + + // preversedPackagesRoot := packagesRoot + packagesRoot = tmpDir + + fmt.Print("\nBumping:\n\n") + + for oldPkgPath, newPkgPath := range upgrades { + fmt.Println(oldPkgPath, "->", newPkgPath) + + r := regexp.MustCompile(oldPkgPath) + + // change module name in gno.mod + gnoModPath := filepath.Join(packagesRoot, oldPkgPath, "gno.mod") + data, err := os.ReadFile(gnoModPath) + if err != nil { + panic(errors.Wrap(err, "failed to read "+gnoModPath)) + } + edited := r.ReplaceAll(data, []byte(newPkgPath)) + if err := os.WriteFile(gnoModPath, edited, 0644); err != nil { + panic(errors.Wrap(err, "failed to write "+gnoModPath)) + } + + for _, child := range requiredBy[oldPkgPath] { + // change import paths in dependent .gno files + if err := filepath.Walk(filepath.Join(packagesRoot, child), func(path string, info os.FileInfo, err error) error { + if err != nil { + fmt.Println("error during walk:", err) + return nil + } + + if info.IsDir() || !strings.HasSuffix(path, ".gno") { + return nil + } + + // replace oldPkgPath with newPkgPath in file + data, err := os.ReadFile(path) + if err != nil { + return errors.Wrap(err, "failed to read "+path) + } + edited := r.ReplaceAll(data, []byte(newPkgPath)) + if err := os.WriteFile(path, edited, 0644); err != nil { + return errors.Wrap(err, "failed to write "+path) + } + + return nil + }); err != nil { + panic(errors.Wrap(err, "failed to walk packages")) + } + + // change import paths in dependent gno.mod files + gnoModPath := filepath.Join(packagesRoot, child, "gno.mod") + data, err := os.ReadFile(gnoModPath) + if err != nil { + panic(errors.Wrap(err, "failed to read "+gnoModPath)) + } + edited := r.ReplaceAll(data, []byte(newPkgPath)) + if err := os.WriteFile(gnoModPath, edited, 0644); err != nil { + panic(errors.Wrap(err, "failed to write "+gnoModPath)) + } + } + } + + for oldPkgPath, newPkgPath := range upgrades { + // rename directory + if err := os.Rename(filepath.Join(packagesRoot, oldPkgPath), filepath.Join(packagesRoot, newPkgPath)); err != nil { + panic(errors.Wrap(err, "failed to rename "+oldPkgPath)) + } + } + + fmt.Print("\nDeploying:\n\n") + + // deploy packages in dependency order + deployed := map[string]struct{}{} + remaining := map[string]struct{}{} + for pkgPath := range upgrades { + remaining[pkgPath] = struct{}{} + } + for len(remaining) > 0 { + leafs := map[string]struct{}{} + for pkgPath := range remaining { + deps := requires[pkgPath] + if len(deps) == 0 { + leafs[pkgPath] = struct{}{} + } + hasDep := false + for _, dep := range deps { + if _, ok := upgrades[dep]; ok { + if _, ok := deployed[dep]; !ok { + hasDep = true + break + } + } + } + if !hasDep { + leafs[pkgPath] = struct{}{} + } + } + + if len(leafs) == 0 { + panic("no leafs found, probably a cylic dependency") + } + + for leaf := range leafs { + fmt.Println(upgrades[leaf]) + c, err := expect.NewConsole() + if err != nil { + panic(errors.Wrap(err, "failed to create console")) + } + cmd := exec.Command("gnokey", "maketx", "addpkg", + "-deposit="+deposit, + "-gas-fee="+gasFee, + "-gas-wanted="+gasWanted, + "-broadcast=true", + "-remote="+remoteGno, + "-chainid="+chainId, + "-pkgdir="+filepath.Join(packagesRoot, upgrades[leaf]), + "-pkgpath="+upgrades[leaf], + walletName, + ) + + buf := bytes.NewBuffer(nil) + multiWriter := io.MultiWriter(c.Tty(), buf) + cmd.Stderr = multiWriter + cmd.Stdout = multiWriter + cmd.Stdin = c.Tty() + + go func() { + c.ExpectString("Enter password.") + c.SendLine("") + }() + + if err := cmd.Run(); err != nil { + fmt.Println("\n" + buf.String()) + panic(errors.Wrap(err, "failed to deploy "+upgrades[leaf])) + } + + deployed[leaf] = struct{}{} + delete(remaining, leaf) + } + } +} + +func gnoModDeps(gnoModPath string) ([]string, error) { + data, err := os.ReadFile(gnoModPath) + if err != nil { + return nil, errors.Wrap(err, "failed to read "+gnoModPath) + } + r := regexp.MustCompile(`(?s)require.+?\((.+?)\)`) + submatches := r.FindAllStringSubmatch(string(data), -1) + if len(submatches) < 1 || len(submatches[0]) < 2 { + return nil, nil + } + lines := strings.Split(submatches[0][1], "\n") + depEntries := []string{} + for _, line := range lines { + line = strings.TrimSpace(line) + if line == "" { + continue + } + depR := regexp.MustCompile(`"(.+)"`) + submatches := depR.FindAllStringSubmatch(line, -1) + if len(submatches) < 1 || len(submatches[0]) < 2 { + return nil, fmt.Errorf("failed to parse dep line: %q", line) + } + depEntry := submatches[0][1] + depEntries = append(depEntries, depEntry) + } + return depEntries, nil +} diff --git a/go.mod b/go.mod index eb7c3b9a277..eb29c0ee45c 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/gnolang/gno go 1.19 require ( + github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c github.com/btcsuite/btcd/btcutil v1.1.1 github.com/btcsuite/btcutil v1.0.2 @@ -26,6 +27,7 @@ require ( github.com/mattn/go-runewidth v0.0.15 github.com/pelletier/go-toml v1.9.5 github.com/peterbourgon/ff/v3 v3.4.0 + github.com/pkg/errors v0.9.1 github.com/pmezard/go-difflib v1.0.0 github.com/rogpeppe/go-internal v1.11.0 github.com/stretchr/testify v1.8.4 @@ -44,6 +46,7 @@ require ( require ( github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.1.1 // indirect + github.com/creack/pty v1.1.17 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c // indirect @@ -61,7 +64,6 @@ require ( github.com/kr/text v0.2.0 // indirect github.com/lib/pq v1.10.7 // indirect github.com/lucasb-eyer/go-colorful v1.0.3 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/rivo/uniseg v0.2.0 // indirect go.opencensus.io v0.22.5 // indirect go.uber.org/atomic v1.7.0 // indirect diff --git a/go.sum b/go.sum index c51f8d91df2..00ef5d53a2e 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +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 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= @@ -35,6 +37,8 @@ github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8Nz github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= 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/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= From 5eac3a61b829a05f963216cbce9f1840268c6a07 Mon Sep 17 00:00:00 2001 From: Norman Meier Date: Tue, 22 Aug 2023 18:53:41 +0200 Subject: [PATCH 2/6] feat(gnodeploy): parametrize password Signed-off-by: Norman Meier --- gno.land/cmd/gnodeploy/main.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gno.land/cmd/gnodeploy/main.go b/gno.land/cmd/gnodeploy/main.go index e7634ac5e99..c6ebb0d6056 100644 --- a/gno.land/cmd/gnodeploy/main.go +++ b/gno.land/cmd/gnodeploy/main.go @@ -30,6 +30,7 @@ func main() { depositFlag = fs.String("deposit", "1ugnot", "deposit") gasFeeFlag = fs.String("gas-fee", "1ugnot", "gas fee") gasWantedFlag = fs.String("gas-wanted", "10000000", "gas wanted") + passwordFlag = fs.String("password", "", "password") ) err := ff.Parse(fs, os.Args[1:]) @@ -85,6 +86,9 @@ func main() { } gasWanted := *gasWantedFlag + // empty password is ok + password := *passwordFlag + fmt.Print("Target packages:\n\n") for _, targetPkgPath := range targetsPkgPath { fmt.Println(targetPkgPath) @@ -306,7 +310,7 @@ func main() { go func() { c.ExpectString("Enter password.") - c.SendLine("") + c.SendLine(password) }() if err := cmd.Run(); err != nil { From f8650089210a8578c9b1a9f5bf5ab99bc1d8e981 Mon Sep 17 00:00:00 2001 From: Norman Meier Date: Wed, 23 Aug 2023 16:38:54 +0200 Subject: [PATCH 3/6] feat: also upgrades deps of targets Signed-off-by: Norman Meier --- gno.land/cmd/gnodeploy/main.go | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/gno.land/cmd/gnodeploy/main.go b/gno.land/cmd/gnodeploy/main.go index c6ebb0d6056..5dfe0075f26 100644 --- a/gno.land/cmd/gnodeploy/main.go +++ b/gno.land/cmd/gnodeploy/main.go @@ -139,8 +139,28 @@ func main() { fmt.Println("\nFetching versions from remote...") - roots := targetsPkgPath + // recursively get deps of targets seen := map[string]struct{}{} + roots := targetsPkgPath + targetsAndDeps := map[string]struct{}{} + for len(roots) > 0 { + pkgPath := roots[0] + roots = roots[1:] + if _, ok := seen[pkgPath]; ok { + continue + } + seen[pkgPath] = struct{}{} + roots = append(roots, requires[pkgPath]...) + targetsAndDeps[pkgPath] = struct{}{} + } + + roots = []string{} + for pkgPath := range targetsAndDeps { + roots = append(roots, pkgPath) + } + + // find versions and upgrades + seen = map[string]struct{}{} for len(roots) > 0 { pkgPath := roots[0] roots = roots[1:] From 00e666dcfa4425809fda79ea9ef94a0c38bbb773 Mon Sep 17 00:00:00 2001 From: Norman Meier Date: Fri, 25 Aug 2023 20:11:35 +0200 Subject: [PATCH 4/6] feat: add ignore flag Signed-off-by: Norman Meier --- gno.land/cmd/gnodeploy/main.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/gno.land/cmd/gnodeploy/main.go b/gno.land/cmd/gnodeploy/main.go index 5dfe0075f26..f080980bafe 100644 --- a/gno.land/cmd/gnodeploy/main.go +++ b/gno.land/cmd/gnodeploy/main.go @@ -31,6 +31,7 @@ func main() { gasFeeFlag = fs.String("gas-fee", "1ugnot", "gas fee") gasWantedFlag = fs.String("gas-wanted", "10000000", "gas wanted") passwordFlag = fs.String("password", "", "password") + ignoreFlag = fs.String("ignore", "", "ignore packages") ) err := ff.Parse(fs, os.Args[1:]) @@ -46,6 +47,13 @@ func main() { targetsPkgPath[i] = strings.TrimSpace(targetPkgPath) } + ignoreParts := strings.Split(*ignoreFlag, ",") + ignores := map[string]struct{}{} + for i, ignore := range ignoreParts { + ignoreParts[i] = strings.TrimSpace(ignore) + ignores[ignore] = struct{}{} + } + if packagesRootFlag == nil || *packagesRootFlag == "" { panic("packages root is required") } @@ -112,6 +120,9 @@ func main() { } for _, targetPkgPath := range targetsPkgPath { + if _, ok := ignores[targetPkgPath]; ok { + panic("target package " + targetPkgPath + " is ignored") + } targetPackageFSPath := filepath.Join(packagesRoot, targetPkgPath) targetPackageGnoModPath := filepath.Join(targetPackageFSPath, "gno.mod") if _, ok := allGnoMods[targetPackageGnoModPath]; !ok { @@ -150,6 +161,9 @@ func main() { continue } seen[pkgPath] = struct{}{} + if _, ok := ignores[pkgPath]; ok { + continue + } roots = append(roots, requires[pkgPath]...) targetsAndDeps[pkgPath] = struct{}{} } @@ -168,6 +182,9 @@ func main() { continue } seen[pkgPath] = struct{}{} + if _, ok := ignores[pkgPath]; ok { + continue + } roots = append(roots, requiredBy[pkgPath]...) // find highest version on remote From 734ca2ab1ff64d8d582c3d9dc6a5a4d2a8dfafc0 Mon Sep 17 00:00:00 2001 From: Norman Meier Date: Fri, 25 Aug 2023 20:12:18 +0200 Subject: [PATCH 5/6] feat: ignore avl by default Signed-off-by: Norman Meier --- gno.land/cmd/gnodeploy/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gno.land/cmd/gnodeploy/main.go b/gno.land/cmd/gnodeploy/main.go index f080980bafe..70e89304586 100644 --- a/gno.land/cmd/gnodeploy/main.go +++ b/gno.land/cmd/gnodeploy/main.go @@ -31,7 +31,7 @@ func main() { gasFeeFlag = fs.String("gas-fee", "1ugnot", "gas fee") gasWantedFlag = fs.String("gas-wanted", "10000000", "gas wanted") passwordFlag = fs.String("password", "", "password") - ignoreFlag = fs.String("ignore", "", "ignore packages") + ignoreFlag = fs.String("ignore", "gno.land/p/demo/avl", "ignore packages") ) err := ff.Parse(fs, os.Args[1:]) From 5f4c0a122461ec4e1e9a3220c822149ef0aaaf65 Mon Sep 17 00:00:00 2001 From: Norman Meier Date: Thu, 14 Sep 2023 14:07:50 +0200 Subject: [PATCH 6/6] feat: add dry-run flag Signed-off-by: Norman Meier --- gno.land/cmd/gnodeploy/main.go | 37 +++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/gno.land/cmd/gnodeploy/main.go b/gno.land/cmd/gnodeploy/main.go index 70e89304586..0f60317f05b 100644 --- a/gno.land/cmd/gnodeploy/main.go +++ b/gno.land/cmd/gnodeploy/main.go @@ -32,6 +32,7 @@ func main() { gasWantedFlag = fs.String("gas-wanted", "10000000", "gas wanted") passwordFlag = fs.String("password", "", "password") ignoreFlag = fs.String("ignore", "gno.land/p/demo/avl", "ignore packages") + dryRunFlag = fs.Bool("dry-run", false, "dry run") ) err := ff.Parse(fs, os.Args[1:]) @@ -97,6 +98,8 @@ func main() { // empty password is ok password := *passwordFlag + dryRun := *dryRunFlag + fmt.Print("Target packages:\n\n") for _, targetPkgPath := range targetsPkgPath { fmt.Println(targetPkgPath) @@ -209,25 +212,31 @@ func main() { fmt.Println("\nWill upgrade", len(upgrades), "packages") - fmt.Println("\nCopying root to temporary directory...") - tmpDir := ".deploy" - if err := os.RemoveAll(tmpDir); err != nil { - panic(errors.Wrap(err, "failed to remove "+tmpDir)) - } - cmd := exec.Command("cp", "-r", packagesRoot, tmpDir) - cmd.Stderr = os.Stderr - if err := cmd.Run(); err != nil { - panic(errors.Wrap(err, "failed to copy "+packagesRoot)) - } + if !dryRun { + fmt.Println("\nCopying root to temporary directory...") + tmpDir := ".deploy" + if err := os.RemoveAll(tmpDir); err != nil { + panic(errors.Wrap(err, "failed to remove "+tmpDir)) + } + cmd := exec.Command("cp", "-r", packagesRoot, tmpDir) + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + panic(errors.Wrap(err, "failed to copy "+packagesRoot)) + } - // preversedPackagesRoot := packagesRoot - packagesRoot = tmpDir + // preversedPackagesRoot := packagesRoot + packagesRoot = tmpDir + } fmt.Print("\nBumping:\n\n") for oldPkgPath, newPkgPath := range upgrades { fmt.Println(oldPkgPath, "->", newPkgPath) + if dryRun { + continue + } + r := regexp.MustCompile(oldPkgPath) // change module name in gno.mod @@ -281,6 +290,10 @@ func main() { } } + if dryRun { + return + } + for oldPkgPath, newPkgPath := range upgrades { // rename directory if err := os.Rename(filepath.Join(packagesRoot, oldPkgPath), filepath.Join(packagesRoot, newPkgPath)); err != nil {