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

bud run fails right after adding controller following video #369

Closed
mysiar opened this issue Jan 28, 2023 · 18 comments · Fixed by #375
Closed

bud run fails right after adding controller following video #369

mysiar opened this issue Jan 28, 2023 · 18 comments · Fixed by #375
Labels
waiting for info We're waiting for a response

Comments

@mysiar
Copy link

mysiar commented Jan 28, 2023

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
Copy link
Contributor

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
Copy link
Contributor

matthewmueller commented Jan 28, 2023

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 :)

@matthewmueller matthewmueller added the waiting for info We're waiting for a response label Jan 28, 2023
@qindj
Copy link

qindj commented Jan 29, 2023

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
Copy link
Contributor

matthewmueller commented Jan 29, 2023

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
Copy link

qindj commented Jan 30, 2023

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
Copy link
Contributor

matthewmueller commented Jan 31, 2023

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
Copy link

qindj commented Jan 31, 2023

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
Copy link

Fuerback commented Feb 1, 2023

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

@qindj
Copy link

qindj commented Feb 2, 2023

@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
Copy link
Contributor

matthewmueller commented Feb 2, 2023

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

So the error is right here:

return "", fmt.Errorf("%q can't be outside the module directory %q", directory, m.dir)

Bud is mapping the context package to /usr/lib/go-1.19/src/context here:

var stdDir = filepath.Join(findGoRoot(), "src")

There seems to be an issue turning /usr/lib/go-1.19/src/context back into context here:

importPath, err := dec.Package().Import()

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
Copy link

qindj commented Feb 2, 2023

@matthewmueller

i'll have a try to find the problem

btw: should we start a new issue?

@matthewmueller
Copy link
Contributor

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

@qindj
Copy link

qindj commented Feb 3, 2023

@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

return filepath.EvalSymlinks(dir)

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

@matthewmueller
Copy link
Contributor

matthewmueller commented Feb 6, 2023

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
Copy link

qindj commented Feb 6, 2023

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
Copy link
Contributor

matthewmueller commented Feb 6, 2023

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
Copy link

qindj commented Feb 6, 2023

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
Copy link
Contributor

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
waiting for info We're waiting for a response
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants