Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add 'gno env' subcommand #1233

Merged
merged 28 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
485dd31
wip: add gnodev
gfanton Oct 11, 2023
08177f9
wip: move env to gnoenv package
gfanton Oct 11, 2023
b5ed456
fix: gnoroot integration naming
gfanton Oct 11, 2023
9f372d5
fix: move away homedir from tm2
gfanton Oct 11, 2023
b91abfd
fix: try to move HomeDir out of tm2
gfanton Oct 11, 2023
e706698
Merge remote-tracking branch 'origin/master' into feat/gno-env
gfanton Oct 18, 2023
609a30d
chore: lint comment
gfanton Oct 18, 2023
1142c08
chore: lint code
gfanton Oct 18, 2023
02eaefb
chore: lint
gfanton Oct 18, 2023
7234217
fix: test gnoenv
gfanton Oct 18, 2023
5258180
fix: gnoroot test
gfanton Oct 19, 2023
93792d8
Merge remote-tracking branch 'origin/master' into feat/gno-env
gfanton Oct 23, 2023
4cabaa8
chore: lint typo and comment
gfanton Oct 24, 2023
3bf298d
fix: add `gno env` test
gfanton Oct 24, 2023
c0a017d
chore: lint
gfanton Oct 24, 2023
8548d26
chore: lint comment
gfanton Oct 24, 2023
6bd0003
chore: cleanup test
gfanton Oct 25, 2023
ee2640c
Merge branch 'master' into feat/gno-env
gfanton Oct 25, 2023
807431e
Merge branch 'master' into feat/gno-env
gfanton Nov 6, 2023
d3341e0
Merge branch 'master' into feat/gno-env
gfanton Nov 6, 2023
fd81da3
Merge remote-tracking branch 'master' into feat/gno-env
gfanton Nov 7, 2023
54fb0ac
chore: fixup merge
gfanton Nov 7, 2023
93c3278
Merge branch 'master' into feat/gno-env
gfanton Nov 20, 2023
cc67ff4
fix: merge fixup
gfanton Nov 20, 2023
3bd97b5
chore: rename MustGuessRootDir to RootDir
gfanton Nov 20, 2023
f24d5ec
fix: use new root with config
gfanton Nov 20, 2023
bf522e9
Merge branch 'master' into feat/gno-env
gfanton Nov 20, 2023
e76b154
Merge branch 'master' into feat/gno-env
gfanton Nov 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion gno.land/cmd/gnokey/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,21 @@
"fmt"
"os"

"github.com/gnolang/gno/gnovm/pkg/gnoenv"
"github.com/gnolang/gno/tm2/pkg/commands"
"github.com/gnolang/gno/tm2/pkg/crypto/keys/client"
)

func main() {
cmd := client.NewRootCmd(commands.NewDefaultIO())
baseCfg := client.BaseOptions{
Home: gnoenv.HomeDir(),
Remote: "127.0.0.1:26657",
Quiet: false,
InsecurePasswordStdin: false,
Config: "",
}

cmd := client.NewRootCmdWithBaseConfig(commands.NewDefaultIO(), baseCfg)

Check warning on line 22 in gno.land/cmd/gnokey/main.go

View check run for this annotation

Codecov / codecov/patch

gno.land/cmd/gnokey/main.go#L14-L22

Added lines #L14 - L22 were not covered by tests

if err := cmd.ParseAndRun(context.Background(), os.Args[1:]); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "%+v\n", err)
Expand Down
3 changes: 2 additions & 1 deletion gno.land/cmd/gnoland/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"time"

"github.com/gnolang/gno/gno.land/pkg/gnoland"
"github.com/gnolang/gno/gnovm/pkg/gnoenv"
abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types"
"github.com/gnolang/gno/tm2/pkg/bft/config"
"github.com/gnolang/gno/tm2/pkg/bft/node"
Expand Down Expand Up @@ -59,7 +60,7 @@ func newStartCmd(io *commands.IO) *commands.Command {
}

func (c *startCfg) RegisterFlags(fs *flag.FlagSet) {
gnoroot := gnoland.MustGuessGnoRootDir()
gnoroot := gnoenv.MustGuessGnoRootDir()
defaultGenesisBalancesFile := filepath.Join(gnoroot, "gno.land", "genesis", "genesis_balances.txt")
defaultGenesisTxsFile := filepath.Join(gnoroot, "gno.land", "genesis", "genesis_txs.txt")

Expand Down
6 changes: 3 additions & 3 deletions gno.land/cmd/gnoweb/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"strings"
"testing"

"github.com/gnolang/gno/gno.land/pkg/gnoland"
"github.com/gnolang/gno/gno.land/pkg/integration"
"github.com/gnolang/gno/gnovm/pkg/gnoenv"
"github.com/gnolang/gno/tm2/pkg/log"
"github.com/gotuna/gotuna/test/assert"
)
Expand Down Expand Up @@ -44,7 +44,7 @@ func TestRoutes(t *testing.T) {
{"/404-not-found", notFound, "/404-not-found"},
}

config, _ := integration.TestingNodeConfig(t, gnoland.MustGuessGnoRootDir())
config, _ := integration.TestingNodeConfig(t, gnoenv.MustGuessGnoRootDir())
node, remoteAddr := integration.TestingInMemoryNode(t, log.NewNopLogger(), config)
defer node.Stop()

Expand Down Expand Up @@ -92,7 +92,7 @@ func TestAnalytics(t *testing.T) {
"/404-not-found",
}

config, _ := integration.TestingNodeConfig(t, gnoland.MustGuessGnoRootDir())
config, _ := integration.TestingNodeConfig(t, gnoenv.MustGuessGnoRootDir())
node, remoteAddr := integration.TestingInMemoryNode(t, log.NewNopLogger(), config)
defer node.Stop()

Expand Down
49 changes: 2 additions & 47 deletions gno.land/pkg/gnoland/app.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
package gnoland

import (
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"

"github.com/gnolang/gno/gno.land/pkg/sdk/vm"
"github.com/gnolang/gno/gnovm/pkg/gnoenv"
"github.com/gnolang/gno/tm2/pkg/amino"
abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types"
"github.com/gnolang/gno/tm2/pkg/crypto"
Expand Down Expand Up @@ -38,7 +35,7 @@
return &AppOptions{
Logger: log.NewNopLogger(),
DB: dbm.NewMemDB(),
GnoRootDir: MustGuessGnoRootDir(),
GnoRootDir: gnoenv.MustGuessGnoRootDir(),

Check warning on line 38 in gno.land/pkg/gnoland/app.go

View check run for this annotation

Codecov / codecov/patch

gno.land/pkg/gnoland/app.go#L38

Added line #L38 was not covered by tests
}
}

Expand Down Expand Up @@ -197,45 +194,3 @@
return abci.ResponseEndBlock{}
}
}

// XXX: all the method bellow should be removed in favor of
// https://github.com/gnolang/gno/pull/1233
func MustGuessGnoRootDir() string {
root, err := GuessGnoRootDir()
if err != nil {
panic(err)
}

return root
}

func GuessGnoRootDir() (string, error) {
// First try to get the root directory from the GNOROOT environment variable.
if rootdir := os.Getenv("GNOROOT"); rootdir != "" {
return filepath.Clean(rootdir), nil
}

// Try to guess GNOROOT using the nearest go.mod.
if gobin, err := exec.LookPath("go"); err == nil {
// If GNOROOT is not set, try to guess the root directory using the `go list` command.
cmd := exec.Command(gobin, "list", "-m", "-mod=mod", "-f", "{{.Dir}}", "github.com/gnolang/gno")
out, err := cmd.CombinedOutput()
if err == nil {
return strings.TrimSpace(string(out)), nil
}
}

// Try to guess GNOROOT using caller stack.
if _, filename, _, ok := runtime.Caller(1); ok && filepath.IsAbs(filename) {
if currentDir := filepath.Dir(filename); currentDir != "" {
// Gno root directory relative from `app.go` path:
// gno/ .. /gno.land/ .. /pkg/ .. /gnoland/app.go
rootdir, err := filepath.Abs(filepath.Join(currentDir, "..", "..", ".."))
if err == nil {
return rootdir, nil
}
}
}

return "", errors.New("unable to guess gno's root-directory")
}
4 changes: 2 additions & 2 deletions gno.land/pkg/integration/testing_integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"sync"
"testing"

"github.com/gnolang/gno/gno.land/pkg/gnoland"
"github.com/gnolang/gno/gnovm/pkg/gnoenv"
"github.com/gnolang/gno/tm2/pkg/bft/node"
"github.com/gnolang/gno/tm2/pkg/commands"
"github.com/gnolang/gno/tm2/pkg/crypto/keys"
Expand Down Expand Up @@ -41,7 +41,7 @@ func SetupGnolandTestScript(t *testing.T, txtarDir string) testscript.Params {

// `gnoRootDir` should point to the local location of the gno repository.
// It serves as the gno equivalent of GOROOT.
gnoRootDir := gnoland.MustGuessGnoRootDir()
gnoRootDir := gnoenv.MustGuessGnoRootDir()

// `gnoHomeDir` should be the local directory where gnokey stores keys.
gnoHomeDir := filepath.Join(tmpdir, "gno")
Expand Down
9 changes: 7 additions & 2 deletions gnovm/Makefile
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
GNOROOT_DIR ?= $(abspath $(lastword $(MAKEFILE_LIST))/../../)

.PHONY: help
help:
@echo "Available make commands:"
@cat Makefile | grep '^[a-z][^:]*:' | cut -d: -f1 | sort | sed 's/^/ /'

rundep=go run -modfile ../misc/devdeps/go.mod

# We can't use '-trimpath' yet as amino use absolute path from call stack
# to find some directory: see #1236
GOBUILD_FLAGS := -ldflags "-X github.com/gnolang/gno/gnovm/pkg/gnoenv._GNOROOT=$(GNOROOT_DIR)"
.PHONY: build
build:
go build -o build/gno ./cmd/gno
go build $(GOBUILD_FLAGS) -o build/gno ./cmd/gno

.PHONY: install
install:
go install ./cmd/gno
go install $(GOBUILD_FLAGS) ./cmd/gno

.PHONY: clean
clean:
Expand Down
4 changes: 2 additions & 2 deletions gnovm/cmd/gno/clean.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
"path/filepath"
"strings"

"github.com/gnolang/gno/gnovm/pkg/gnoenv"
"github.com/gnolang/gno/gnovm/pkg/gnomod"
"github.com/gnolang/gno/tm2/pkg/commands"
"github.com/gnolang/gno/tm2/pkg/crypto/keys/client"
)

type cleanCfg struct {
Expand Down Expand Up @@ -82,7 +82,7 @@
}

if cfg.modCache {
modCacheDir := filepath.Join(client.HomeDir(), "pkg", "mod")
modCacheDir := filepath.Join(gnoenv.HomeDir(), "pkg", "mod")

Check warning on line 85 in gnovm/cmd/gno/clean.go

View check run for this annotation

Codecov / codecov/patch

gnovm/cmd/gno/clean.go#L85

Added line #L85 was not covered by tests
if !cfg.dryRun {
if err := os.RemoveAll(modCacheDir); err != nil {
return err
Expand Down
3 changes: 2 additions & 1 deletion gnovm/cmd/gno/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"path/filepath"

"github.com/gnolang/gno/gnovm/pkg/doc"
"github.com/gnolang/gno/gnovm/pkg/gnoenv"
"github.com/gnolang/gno/gnovm/pkg/gnomod"
"github.com/gnolang/gno/tm2/pkg/commands"
)
Expand Down Expand Up @@ -77,7 +78,7 @@ func (c *docCfg) RegisterFlags(fs *flag.FlagSet) {
func execDoc(cfg *docCfg, args []string, io *commands.IO) error {
// guess opts.RootDir
if cfg.rootDir == "" {
cfg.rootDir = guessRootDir()
cfg.rootDir = gnoenv.MustGuessGnoRootDir()
}

wd, err := os.Getwd()
Expand Down
122 changes: 122 additions & 0 deletions gnovm/cmd/gno/env.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package main

import (
"context"
"flag"

"github.com/gnolang/gno/gnovm/pkg/gnoenv"
"github.com/gnolang/gno/tm2/pkg/commands"
)

type envCfg struct {
json bool
}

func newEnvCmd(io *commands.IO) *commands.Command {
c := &envCfg{}
return commands.NewCommand(
commands.Metadata{
Name: "env",
ShortUsage: "env [flags] <pkgsym>",
ShortHelp: "`env` prints Gno environment information",
},
c,
func(_ context.Context, args []string) error {
return execEnv(c, args, io)
},
)
}

func (c *envCfg) RegisterFlags(fs *flag.FlagSet) {
fs.BoolVar(
&c.json,
"json",
false,
"Prints the environment in JSON format instead of as a shell script.",
)
}

type envVar struct {
Key string
Value string
}

func getEnvVar(vars []envVar, key string) string {
for _, env := range vars {
if env.Key == key {
return env.Value
}

Check warning on line 48 in gnovm/cmd/gno/env.go

View check run for this annotation

Codecov / codecov/patch

gnovm/cmd/gno/env.go#L44-L48

Added lines #L44 - L48 were not covered by tests
}
return ""

Check warning on line 50 in gnovm/cmd/gno/env.go

View check run for this annotation

Codecov / codecov/patch

gnovm/cmd/gno/env.go#L50

Added line #L50 was not covered by tests
}

func findEnv(env []envVar, name string) string {
for _, e := range env {
if e.Key == name {
return e.Value
}
}
return ""
}

type envPrinter func(vars []envVar, io *commands.IO)

func execEnv(cfg *envCfg, args []string, io *commands.IO) error {
envs := []envVar{
// GNOROOT Should point to the local location of the GNO repository.
// It serves as the gno equivalent of `GOROOT`.
{Key: "GNOROOT", Value: gnoenv.MustGuessGnoRootDir()},
// GNOHOME Should point to the user local configuration.
// The most common place for this should be $HOME/gno.
{Key: "GNOHOME", Value: gnoenv.HomeDir()},
}

// Setup filters
filters := make([]envVar, len(args))
for i, arg := range args {
filters[i] = envVar{Key: arg, Value: findEnv(envs, arg)}
}

// Setup printer
var printerEnv envPrinter
if cfg.json {
printerEnv = printJSON
} else {
printerEnv = getPrinterShell(len(args) == 0)
}

// Print environements
if len(filters) > 0 {
printerEnv(filters, io)
} else {
printerEnv(envs, io)
}

return nil
}

func getPrinterShell(printkeys bool) envPrinter {
return func(vars []envVar, io *commands.IO) {
for _, env := range vars {
if printkeys {
io.Printf("%s=%q\n", env.Key, env.Value)
} else {
io.Printf("%s\n", env.Value)
}
}
}
}

func printJSON(vars []envVar, io *commands.IO) {
io.Println("{")
for i, env := range vars {
io.Printf("\t%q: %q", env.Key, env.Value)
if i != len(vars)-1 {
io.Printf(",")
}

// Jump to next line
io.Printf("\n")
}
io.Println("}")
}
43 changes: 43 additions & 0 deletions gnovm/cmd/gno/env_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package main

import (
"fmt"
"testing"
)

func TestEnvApp(t *testing.T) {
const (
testGnoRootEnv = "/faster/better/stronger"
testGnoHomeEnv = "/around/the/world"
)

t.Setenv("GNOROOT", testGnoRootEnv)
t.Setenv("GNOHOME", testGnoHomeEnv)
tc := []testMainCase{
// shell
{args: []string{"env", "foo"}, stdoutShouldBe: "\n"},
{args: []string{"env", "foo", "bar"}, stdoutShouldBe: "\n\n"},
{args: []string{"env", "GNOROOT"}, stdoutShouldBe: testGnoRootEnv + "\n"},
{args: []string{"env", "GNOHOME", "storm"}, stdoutShouldBe: testGnoHomeEnv + "\n\n"},
{args: []string{"env"}, stdoutShouldContain: fmt.Sprintf("GNOROOT=%q", testGnoRootEnv)},
{args: []string{"env"}, stdoutShouldContain: fmt.Sprintf("GNOHOME=%q", testGnoHomeEnv)},

// json
{args: []string{"env", "-json"}, stdoutShouldContain: fmt.Sprintf("\"GNOROOT\": %q", testGnoRootEnv)},
{args: []string{"env", "-json"}, stdoutShouldContain: fmt.Sprintf("\"GNOHOME\": %q", testGnoHomeEnv)},
{
args: []string{"env", "-json", "GNOROOT"},
stdoutShouldBe: fmt.Sprintf("{\n\t\"GNOROOT\": %q\n}\n", testGnoRootEnv),
},
{
args: []string{"env", "-json", "GNOROOT", "storm"},
stdoutShouldBe: fmt.Sprintf("{\n\t\"GNOROOT\": %q,\n\t\"storm\": \"\"\n}\n", testGnoRootEnv),
},
{
args: []string{"env", "-json", "storm"},
stdoutShouldBe: "{\n\t\"storm\": \"\"\n}\n",
},
}

testMainCaseRun(t, tc)
}
Loading
Loading