livebud / bud

The Full-Stack Web Framework for Go
MIT License
5.58k stars 179 forks source link

bud run fails right after adding controller following video #369

Closed mysiar closed 1 year ago

mysiar commented 1 year ago

error message:

| genfs: open "bud/internal/web/web.go". genfs: open "bud/internal/web/controller/controller.go". framework/controller: unable to load. controller: unable to load: di: unable to wire "change.me/bud/controller".loadController function. parser: unable to find import path for "hackernews" in "controller/controller.go"

my go env

GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/piotr/.cache/go-build"
GOENV="/home/piotr/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/piotr/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/piotr/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.19.5"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/piotr/WORK/mysiar/go/hacker-news/go.mod"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build3793912841=/tmp/go-build -gno-record-gcc-switches"

any suggestion ho to solve it is more than welcome

matthewmueller commented 1 year ago

Hey @mysiar, thanks for trying out Bud! Can you share your controller/controller.go file?

I think you're missing "github.com/matthewmueller/hackernews" at the top. Might not be clear in the video but my IDE is running goimports upon save.

matthewmueller commented 1 year ago

I'd also recommend bumping to v0.2.8 with curl -sf https://raw.githubusercontent.com/livebud/bud/main/install.sh | sh. While testing this, I ran into a regression that's fixed in v0.2.8 :)

qindj commented 1 year ago

same issue, v0.2.7

tested under WSL 2 (Ubuntu 22.04) on WIN11 22H2 and Ubuntu 22.04 VM under Hyper-V

looks like the file "bud/internal/web/web.go" (and the bud/internal/web folder) was removed after run "bud new contoller xxx"

i'll test v0.2.8 today

it is the same using v0.2.8, bud/internal/web is missing after run bud new controller

matthewmueller commented 1 year ago

it is the same using v0.2.8, bud/internal/web is missing after run bud new controller

Hmm, that's really odd. I was able to reproduce that in v0.2.7, but not in v0.2.8. Are you able to reliably reproduce bud/internal/web getting removed? If you restart bud run when encountering this, what happens?

qindj commented 1 year ago

it is the same using v0.2.8, bud/internal/web is missing after run bud new controller

Hmm, that's really odd. I was able to reproduce that in v0.2.7, but not in v0.2.8. Are you able to reliably reproduce bud/internal/web getting removed? If you restart bud run when encountering this, what happens?

made a recording(new controller when bud run):

asciicast

and I also tried to run new controller when bud not running , the same issue

matthewmueller commented 1 year ago

Hey @qindj, that's interesting. It's definitely different than the original post, like the context package can't be imported for some reason. Can you share your go env? I have a hunch it's related to #78.

qindj commented 1 year ago

you are right ,sorry, it's maybe not the same issue.

my go env under WSL 2:

➜ ~ go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/root/.cache/go-build" GOENV="/root/.config/go/env" GOEXE="" GOEXPERIMENT="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GOMODCACHE="/root/go/pkg/mod" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/root/go" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/usr/lib/go-1.19" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/lib/go-1.19/pkg/tool/linux_amd64" GOVCS="" GOVERSION="go1.19.5" GCCGO="gccgo" GOAMD64="v1" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="/dev/null" GOWORK="" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build4158922842=/tmp/go-build -gno-record-gcc-switches" ➜ ~

Fuerback commented 1 year ago

@qindj shouldn't GOPATH be the {your_path)/go/bin?

qindj commented 1 year ago

@qindj shouldn't GOPATH be the {your_path)/go/bin?

GOPATH should be $HOME/go

see: The install directory is controlled by the GOPATH and GOBIN [environment variables](https://go.dev/cmd/go/#hdr-Environment_variables). If GOBIN is set, binaries are installed to that directory. If GOPATH is set, binaries are installed to the bin subdirectory of the first directory in the GOPATH list. Otherwise, binaries are installed to the bin subdirectory of the default GOPATH ($HOME/go or %USERPROFILE%\go).

from https://go.dev/doc/code#Workspaces

matthewmueller commented 1 year ago

@qindj do you know what /usr/share/go-1.19/src is in your video?

So the error is right here: https://github.com/livebud/bud/blob/da81926777e4c288359ff38e099d9a660adf0dea/package/gomod/module.go#L99

Bud is mapping the context package to /usr/lib/go-1.19/src/context here: https://github.com/livebud/bud/blob/da81926777e4c288359ff38e099d9a660adf0dea/package/gomod/module.go#L105

There seems to be an issue turning /usr/lib/go-1.19/src/context back into context here: https://github.com/livebud/bud/blob/da81926777e4c288359ff38e099d9a660adf0dea/framework/controller/loader.go#L335

Would you have time to look into this? If so, the contributing guide can help you install Bud locally. I feel like if you're able to fmt.Println in a few of the spots above, we could narrow it down.

qindj commented 1 year ago

@matthewmueller

i'll have a try to find the problem

btw: should we start a new issue?

matthewmueller commented 1 year ago

I think it's fine to keep it in this issue, but whatever you prefer.

qindj commented 1 year ago

@matthewmueller

I think i found the "problem"

under Ubuntu 22.04 , Golang is installed under /usr/share/go-1.1x, and some symbolic links are created under /usr/lib/go-1.1x

image

mod will translate the symbolic links to real path https://github.com/livebud/bud/blob/061c0f135037f65d3ed7ee16671d79052d29f0b4/package/gomod/mod.go#L158

that's why /usr/lib/go-1.19 became /usr/share/go-1.19

matthewmueller commented 1 year ago

Supppper helpful @qindj, thank you! It seems like the parser's package directory doesn't match up with the more correct module directory.

Do you mind changing the following and trying again?

diff --git a/package/parser/parser.go b/package/parser/parser.go
index 693793d..efd04bc 100644
--- a/package/parser/parser.go
+++ b/package/parser/parser.go
@@ -53,7 +53,7 @@ func (p *Parser) Parse(dir string) (*Package, error) {
                }
                parsedPackage.Files[filename] = parsedFile
        }
-       pkg := newPackage(dir, p, p.module, parsedPackage)
+       pkg := newPackage(imported.Dir, p, p.module, parsedPackage)
        return pkg, nil
 }

I think if we use Go's import system it will eval symlinks already, but if not, I have another idea.

qindj commented 1 year ago

Supppper helpful @qindj, thank you! It seems like the parser's package directory doesn't match up with the more correct module directory.

Do you mind changing the following and trying again?

diff --git a/package/parser/parser.go b/package/parser/parser.go
index 693793d..efd04bc 100644
--- a/package/parser/parser.go
+++ b/package/parser/parser.go
@@ -53,7 +53,7 @@ func (p *Parser) Parse(dir string) (*Package, error) {
                }
                parsedPackage.Files[filename] = parsedFile
        }
-       pkg := newPackage(dir, p, p.module, parsedPackage)
+       pkg := newPackage(imported.Dir, p, p.module, parsedPackage)
        return pkg, nil
 }

I think if we use Go's import system it will eval symlinks already, but if not, I have another idea.

Tested, not working, both of dir and imported.Dir are ../../../lib/go-1.19/src/context

matthewmueller commented 1 year ago

Thanks for testing! I guess build.Package doesn't actually resolve symlinks.

I was able to reproduce this in a Docker container. Could you check if this is working as expected?

diff --git a/package/gomod/module.go b/package/gomod/module.go
index c6d90c6..c573626 100644
--- a/package/gomod/module.go
+++ b/package/gomod/module.go
@@ -91,12 +91,23 @@ func (m *Module) ReadDir(name string) ([]fs.DirEntry, error) {
 }

 // ResolveImport returns an import path from a local directory.
-func (m *Module) ResolveImport(directory string) (importPath string, err error) {
-       relPath, err := filepath.Rel(m.dir, filepath.Clean(directory))
+func (m *Module) ResolveImport(dir string) (importPath string, err error) {
+       return m.resolveImport(dir, true)
+}
+
+func (m *Module) resolveImport(dir string, evalSymlinks bool) (string, error) {
+       relPath, err := filepath.Rel(m.dir, dir)
        if err != nil {
                return "", err
        } else if strings.HasPrefix(relPath, "..") {
-               return "", fmt.Errorf("%q can't be outside the module directory %q", directory, m.dir)
+               if !evalSymlinks {
+                       return "", fmt.Errorf("module: unable to resolve import. %q can't be outside the module directory %q", dir, m.dir)
+               }
+               // Maybe the directory is a symlink, resolve that symlink and try again.
+               if dir, err = filepath.EvalSymlinks(dir); err != nil {
+                       return "", fmt.Errorf("module: unable to resolve import for %q. %w", dir, err)
+               }
+               return m.resolveImport(dir, false)
        }
        return m.Import(relPath), nil
 }
qindj commented 1 year ago

Thanks for testing! I guess build.Package doesn't actually resolve symlinks.

I was able to reproduce this in a Docker container. Could you check if this is working as expected?

diff --git a/package/gomod/module.go b/package/gomod/module.go
index c6d90c6..c573626 100644
--- a/package/gomod/module.go
+++ b/package/gomod/module.go
@@ -91,12 +91,23 @@ func (m *Module) ReadDir(name string) ([]fs.DirEntry, error) {
 }

 // ResolveImport returns an import path from a local directory.
-func (m *Module) ResolveImport(directory string) (importPath string, err error) {
-       relPath, err := filepath.Rel(m.dir, filepath.Clean(directory))
+func (m *Module) ResolveImport(dir string) (importPath string, err error) {
+       return m.resolveImport(dir, true)
+}
+
+func (m *Module) resolveImport(dir string, evalSymlinks bool) (string, error) {
+       relPath, err := filepath.Rel(m.dir, dir)
        if err != nil {
                return "", err
        } else if strings.HasPrefix(relPath, "..") {
-               return "", fmt.Errorf("%q can't be outside the module directory %q", directory, m.dir)
+               if !evalSymlinks {
+                       return "", fmt.Errorf("module: unable to resolve import. %q can't be outside the module directory %q", dir, m.dir)
+               }
+               // Maybe the directory is a symlink, resolve that symlink and try again.
+               if dir, err = filepath.EvalSymlinks(dir); err != nil {
+                       return "", fmt.Errorf("module: unable to resolve import for %q. %w", dir, err)
+               }
+               return m.resolveImport(dir, false)
        }
        return m.Import(relPath), nil
 }

tested and confirmed, it's working! Thank you!

matthewmueller commented 1 year ago

Glad to hear it! Thanks for bringing this to my attention. It triggered another couple fixes around the DX.

Since I haven't heard from @mysiar in a bit, I'm going to close this issue. Feel free to re-open if this is still a problem for you @mysiar!