Skip to content

Commit

Permalink
fix(gnodev): fix the use of filepath instead of path on windows (#3737)
Browse files Browse the repository at this point in the history
fix #3722

Using `filepath` to work with the `path` creates some obvious issues on
Windows, primarily because the `Clean` function replaces `/` with `\\`.
This PR updates the usage of `filepath` to `path` where necessary.

At some point, adapting path-specific tests on Windows would be very
helpful.

---

@Milosevic02, can you confirm that this fix resolves most of your issues
with gnodev?

**EDIT:** It seems that the fix is effective:
#3722 (comment)

---------

Signed-off-by: gfanton <[email protected]>
  • Loading branch information
gfanton authored Feb 13, 2025
1 parent e9e04ea commit 70b8a70
Show file tree
Hide file tree
Showing 18 changed files with 101 additions and 68 deletions.
5 changes: 2 additions & 3 deletions contribs/gnodev/cmd/gnobro/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"net/url"
"os"
"os/signal"
"path/filepath"
gopath "path"
"strings"
"time"

Expand Down Expand Up @@ -239,7 +239,6 @@ func runLocal(ctx context.Context, gnocl *gnoclient.Client, cfg *broCfg, bcfg br
)

var errgs errgroup.Group

if cfg.dev {
devpoint, err := getDevEndpoint(cfg)
if err != nil {
Expand Down Expand Up @@ -453,7 +452,7 @@ func ValidatePathCommandMiddleware(pathPrefix string) wish.Middleware {
return
case 1: // check for valid path
path := cmd[0]
if strings.HasPrefix(path, pathPrefix) && filepath.Clean(path) == path {
if strings.HasPrefix(path, pathPrefix) && gopath.Clean(path) == path {
s.Context().SetValue("path", path)
next(s)
return
Expand Down
3 changes: 2 additions & 1 deletion contribs/gnodev/cmd/gnodev/command_staging.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"context"
"flag"
"path"
"path/filepath"

"github.com/gnolang/gno/contribs/gnodev/pkg/packages"
Expand All @@ -28,7 +29,7 @@ var defaultStagingOptions = AppConfig{
interactive: false,
unsafeAPI: false,
lazyLoader: false,
paths: filepath.Join(DefaultDomain, "/**"), // Load every package under the main domain},
paths: path.Join(DefaultDomain, "/**"), // Load every package under the main domain},

// As we have no reason to configure this yet, set this to random port
// to avoid potential conflict with other app
Expand Down
3 changes: 2 additions & 1 deletion contribs/gnodev/cmd/gnodev/setup_loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"fmt"
"log/slog"
gopath "path"
"path/filepath"
"regexp"
"strings"
Expand Down Expand Up @@ -103,5 +104,5 @@ func guessPath(cfg *AppConfig, dir string) (path string) {
}

rname := reInvalidChar.ReplaceAllString(filepath.Base(dir), "-")
return filepath.Join(cfg.chainDomain, "/r/dev/", rname)
return gopath.Join(cfg.chainDomain, "/r/dev/", rname)
}
4 changes: 2 additions & 2 deletions contribs/gnodev/pkg/browser/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"errors"
"fmt"
"log/slog"
"path/filepath"
gopath "path"
"regexp"
"strings"

Expand Down Expand Up @@ -576,5 +576,5 @@ func (m *model) getCurrentPath() string {
return m.urlPrefix
}

return filepath.Join(m.urlPrefix, path)
return gopath.Join(m.urlPrefix, path)
}
4 changes: 2 additions & 2 deletions contribs/gnodev/pkg/browser/utils.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package browser

import (
"path/filepath"
gopath "path"
"strings"

"github.com/gnolang/gno/gno.land/pkg/gnoweb"
Expand All @@ -27,7 +27,7 @@ func cleanupRealmPath(prefix, realm string) string {
// trim any slash
path = strings.TrimPrefix(path, "/")
// clean up path
path = filepath.Clean(path)
path = gopath.Clean(path)

return path
}
4 changes: 2 additions & 2 deletions contribs/gnodev/pkg/dev/query_path.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package dev
import (
"fmt"
"net/url"
"path/filepath"
"path"

"github.com/gnolang/gno/contribs/gnodev/pkg/address"
"github.com/gnolang/gno/tm2/pkg/crypto"
Expand All @@ -24,7 +24,7 @@ func ResolveQueryPath(bk *address.Book, query string) (QueryPath, error) {
return qpath, fmt.Errorf("malformed path/query: %w", err)
}

qpath.Path = filepath.Clean(upath.Path)
qpath.Path = path.Clean(upath.Path)

// Check for creator option
creator := upath.Query().Get("creator")
Expand Down
4 changes: 2 additions & 2 deletions contribs/gnodev/pkg/events/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ type PackagesUpdate struct {
}

type PackageUpdate struct {
Package string `json:"package"`
Files []string `json:"files"`
PackageDir string `json:"package"`
Files []string `json:"files"`
}

func (PackagesUpdate) Type() Type { return EvtPackagesUpdate }
Expand Down
17 changes: 10 additions & 7 deletions contribs/gnodev/pkg/packages/loader_glob.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"go/token"
"io/fs"
"os"
"path"
"path/filepath"
"strings"
)
Expand Down Expand Up @@ -33,7 +34,7 @@ func (l GlobLoader) MatchPaths(globs ...string) ([]string, error) {

mpaths := []string{}
for _, input := range globs {
cleanInput := filepath.Clean(input)
cleanInput := path.Clean(input)
gpath, err := Parse(cleanInput)
if err != nil {
return nil, fmt.Errorf("invalid glob path %q: %w", input, err)
Expand All @@ -45,18 +46,20 @@ func (l GlobLoader) MatchPaths(globs ...string) ([]string, error) {
continue
}

// root := filepath.Join(l.Root, base)
root := l.Root
err = filepath.WalkDir(root, func(dirpath string, d fs.DirEntry, err error) error {
if err != nil {
return err
}

relPath, relErr := filepath.Rel(root, dirpath)
if relErr != nil {
return relErr
path, err := filepath.Rel(root, dirpath)
if err != nil {
return err
}

// normalize filepath to path
path = NormalizeFilepathToPath(path)

if !d.IsDir() {
return nil
}
Expand All @@ -65,8 +68,8 @@ func (l GlobLoader) MatchPaths(globs ...string) ([]string, error) {
return fs.SkipDir
}

if gpath.Match(relPath) {
mpaths = append(mpaths, relPath)
if gpath.Match(path) {
mpaths = append(mpaths, path)
}

return nil
Expand Down
3 changes: 2 additions & 1 deletion contribs/gnodev/pkg/packages/resolver_local.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package packages
import (
"fmt"
"go/token"
"path"
"path/filepath"
"strings"
)
Expand All @@ -20,7 +21,7 @@ func NewLocalResolver(path, dir string) *LocalResolver {
}

func (r *LocalResolver) Name() string {
return fmt.Sprintf("local<%s>", filepath.Base(r.Dir))
return fmt.Sprintf("local<%s>", path.Base(r.Dir))
}

func (r LocalResolver) IsValid() bool {
Expand Down
4 changes: 2 additions & 2 deletions contribs/gnodev/pkg/packages/resolver_remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"fmt"
"go/parser"
"go/token"
"path/filepath"
gopath "path"
"strings"

"github.com/gnolang/gno/gno.land/pkg/sdk/vm"
Expand Down Expand Up @@ -56,7 +56,7 @@ func (res *remoteResolver) Resolve(fset *token.FileSet, path string) (*Package,
files := bytes.Split(qres.Response.Data, []byte{'\n'})
for _, filename := range files {
fname := string(filename)
fpath := filepath.Join(path, fname)
fpath := gopath.Join(path, fname)
qres, err := res.RPCClient.ABCIQuery(qpath, []byte(fpath))
if err != nil {
return nil, fmt.Errorf("unable to query path")
Expand Down
9 changes: 9 additions & 0 deletions contribs/gnodev/pkg/packages/utils_other.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//go:build !windows
// +build !windows

package packages

// NormalizeFilepathToPath normalize path an unix like path
func NormalizeFilepathToPath(path string) string {
return path
}
11 changes: 11 additions & 0 deletions contribs/gnodev/pkg/packages/utils_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//go:build windows
// +build windows

package packages

import "strings"

// NormalizeFilepathToPath normalize path an unix like path
func NormalizeFilepathToPath(path string) string {
return strings.ReplaceAll(path, "\\", "/")
}
25 changes: 16 additions & 9 deletions contribs/gnodev/pkg/proxy/path_interceptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"log/slog"
"net"
"net/http"
"path/filepath"
gopath "path"
"strings"
"sync"

Expand Down Expand Up @@ -220,7 +220,11 @@ func (upaths uniqPaths) list() []string {
return paths
}

func (upaths uniqPaths) add(path string) { upaths[path] = struct{}{} }
// Add a path to
func (upaths uniqPaths) add(path string) {
path = cleanupPath(path)
upaths[path] = struct{}{}
}

// handleRequest parses and processes the RPC request body.
func (proxy *PathInterceptor) handleRequest(body []byte) error {
Expand Down Expand Up @@ -312,13 +316,6 @@ func handleQuery(path string, data []byte, upaths uniqPaths) error {

case "vm/qrender", "vm/qfile", "vm/qfuncs", "vm/qeval":
path, _, _ := strings.Cut(string(data), ":") // Cut arguments out
path = filepath.Clean(path)

// If path is a file, grab the directory instead
if ext := filepath.Ext(path); ext != "" {
path = filepath.Dir(path)
}

upaths.add(path)
return nil

Expand All @@ -328,3 +325,13 @@ func handleQuery(path string, data []byte, upaths uniqPaths) error {

// XXX: handle more cases
}

func cleanupPath(path string) string {
path = gopath.Clean(path)
// If path is a file, grab the directory instead
if ext := gopath.Ext(path); ext != "" {
path = gopath.Dir(path)
}

return path
}
3 changes: 2 additions & 1 deletion contribs/gnodev/pkg/proxy/path_interceptor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package proxy_test
import (
"net"
"net/http"
"path"
"path/filepath"
"testing"

Expand Down Expand Up @@ -86,7 +87,7 @@ func TestProxy(t *testing.T) {
cli, err := client.NewHTTPClient(interceptor.TargetAddress())
require.NoError(t, err)

res, err := cli.ABCIQuery("vm/qfile", []byte(filepath.Join(targetPath, "foo.gno")))
res, err := cli.ABCIQuery("vm/qfile", []byte(path.Join(targetPath, "foo.gno")))
require.NoError(t, err)
assert.Nil(t, res.Response.Error)

Expand Down
Loading

0 comments on commit 70b8a70

Please sign in to comment.