-
Notifications
You must be signed in to change notification settings - Fork 357
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: support for Go modules to imports [needs unit test review] #1265
base: master
Are you sure you want to change the base?
Conversation
switchupcb seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
UpdateI can confirm that the import is found. However, I still receive an error while running when I run the interpreter without the imported symbols.
StackTrace
|
This was solved with the following code: i := interp.New(interp.Options{GoPath: os.Getenv("GOPATH"), GoCache: goCache, GoToolDir: build.ToolDir})
i.Use(stdlib.Symbols)
if _, err := i.Eval(source); err != nil {
return nil, fmt.Errorf("An error occurred loading the template file: %v\n%v", absfilepath, err)
} Therefore, the |
I'm pretty sure this pull request works. My only trouble now is with the library: // an error occurs here.
bar := v.Interface().(func(string) string)
|
UpdateThis pull request can use Go Module imports without an issue finding the source. If @mpl can let me know all the edge cases he is solving in ErrorWhen you attempt to use an object (not loaded by symbols) from the import, you will receive:
This is solved by using the following code. if err := i.Use(unsafe.Symbols); err != nil {
// ...
} |
When a user attempts to print an object from the Go Module, this error occurs in
These users understand |
How far did you get with this? Is this at least working on your machine? I really hope this got more traction and get merged eventually. |
I will test it with the next update of Copygen but that issue is a responsibility of those users (as they coded |
Any Update @mvertes |
When a user attempts to print an object from the Go Module, this error occurs in cfg.go at line 475. This happens when you call fmt.Println() with a custom module type (string alias): package template
import (
"fmt"
"github.com/switchupcb/copygen/cli/generator" // third party module
"github.com/switchupcb/copygen/cli/models" // extracted module
)
func Generate(gen *models.Generator) (string, error) {
content := string(gen.Keep) + "\n"
fmt.Println(generator.GenerateFunction) // custom type in third party module
for i := range gen.Functions {
content += Function(&gen.Functions[i]) + "\n"
}
return content, nil
} Stacktracepanic: runtime error: index out of range [3] with length 3 [recovered]
panic: C:\Program Files\Go\src\unsafe\unsafe.go:192:1: CFG post-order panic: runtime error: index out of range [3] with length 3
goroutine 1 [running]:
github.com/traefik/yaegi/interp.(*Interpreter).cfg.func2.1()
C:/Users/User/go/pkg/mod/github.com/traefik/yaegi/interp/cfg.go:475 +0x78
panic({0x10b9620, 0xc001408ba0})
C:/Program Files/Go/src/runtime/panic.go:1038 +0x215
...see comment edit for full stacktrace |
@switchupcb So I'm getting an error:
while setting options as such:
any ideas? |
@zale144 I'm not sure that If it's already |
Thanks for the quick reply. I tried it and the same problem persists. |
@zale144 > #1265 (comment) |
Silly me, I haven't added the dependency in the go.mod file. However, in order to keep it there, I need to have it imported, which for me kind of defeats the purpose, so I'll just probably go with something like git submodules and have it available locally. Though, this error remains (from the current latest):
So at this point I might just get back to the go plugins torture. Thanks anyway! |
@zale144 You don't need the dependency in your go.mod file, but it has to be located on the machine. Otherwise, there is nothing to interpret.
This is an error indicating a problem with the package you're attempting to import. Does the import work without an interpreter? If so, the error is from the interpreter itself. |
It's puwl wequest wednesday. |
Hi, How can I help to push this forward? Should I rebase it? These days pretty much every Go package runs on Gomodules, so it's difficult to use yaegi on any real world project without it. |
@tonyalaribe Sure! I'm not sure why your comment was marked as off-topic, but I have updated the branch. Here is a description of the current state of this pull request. TLDR: Maintainers need to approve workflows/review. I will run another Go Module test around the release of Copygen v0.4, but the general idea is to create a file that uses a non-extracted third-party module and determine if that code runs. Note that you must Specifically, I'm confident that the current state of this pull-request fixes the issue with importing; as the original code was platform-specific and unfinished (according to @mpl's comments). If that statement is correct, the errors I'm facing are edge cases within the interpreter, which is NOT necessarily in the scope of this pull request. In other words, this pull request is finished and those errors should be solved in a separate pull request. The main issue is that this pull request has gone 9 months without a comment from the maintainers; let alone workflow approval. In addition, it has the "needs design review" label which seems to historically be placed on pull requests that are never merged. In this case, the best way to move this forward is to bring this pull request to the attention of the maintainers @mvertes, @mpl. A discussion involving this pull request was addressed by @ldez in #1292 but nothing happened since that time. |
I was forced to squash your commits. I will insist on the fact to address changes as commits and use rebase (not squash) instead of merge. $ git remote -v
origin [email protected]:switchupcb/yaegi.git (fetch)
origin [email protected]:switchupcb/yaegi.git (push)
upstream [email protected]:traefik/yaegi.git (fetch)
upstream [email protected]:traefik/yaegi.git (push)
$ git fetch upstream
$ git rebase upstream/master I created a backup of the previous content here: https://github.com/ldez/yaegi/tree/backup/switchupcb-master |
b154b4e
to
4b1426b
Compare
Great! I can fix that. |
To update your local branch with my changes: $ git remote -v
origin [email protected]:switchupcb/yaegi.git (fetch)
origin [email protected]:switchupcb/yaegi.git (push)
upstream [email protected]:traefik/yaegi.git (fetch)
upstream [email protected]:traefik/yaegi.git (push)
$ git switch master
$ git fetch origin
$ git reset --hard origin/master |
To be specific, I believe In the other case,
I will ensure an absolute path is used in whichever function is causing that error. |
I can begin the work for those fixes tommorow. |
Started the work now. RealizationWhat I have realized is that both the old and new approaches simply address the happy path, but don't fundamentally address the main issue. The old approach by @mpl attempts to do what the I looked at the
Basically, these 6 environment variables can determine how a module is loaded, and where it needs to be loaded from. Issue RevisitedIn the current version of Adding the The following code represents the required variables that are passed into vars := map[string]*string{
"GOCACHE": &envVars.gocache,
"GOPATH": &envVars.gopath,
"GOROOT": &envVars.goroot,
"GOPRIVATE": &envVars.goprivate,
"GOMODCACHE": &envVars.gomodcache,
"GO111MODULE": &envVars.go111module,
} The final issue is that the tests (of yaegi) do not cover every detail involved with importing a module. It is no surprise that there were issues with the old approach, and no surprise that the current approach is flawed. SolutionAs a result, a real solution that will work in every case is allowing the user to define these 6 environment variables as required. Implementation
TODO
|
For backwards compatibility purposes, I have left the Interpreter NOTE: This is related to Line 170 of |
I am not confident in setting the MAKEFILE according to the repository standard. I ask that @ldez or another maintainer complete that task (context in #1265 (comment) and #1265 (comment)). In any case, I can run another integration test to create a valid README example for the documentation around the release of Copygen 0.5. As a result, I have re-marked this PR as a draft (since it won't pass CI without the correct environment variables). |
@switchupcb I will once again clean your PR, please read my previous comment to learn how to rebase. Note: the GOPATH mode must be kept because it's a requirement for the plugin system of Traefik. |
I was once again forced to squash your commits. To update your local branch with my changes, you can follow this previous comment. |
@ldez Great, thanks. Steps didn't work the first time for some reason. The reason that the tests for CI didn't pass is described. 1.
As an example, i := interp.New(interp.Options{GoPath: "./_pkg"})
if err := i.Use(stdlib.Symbols); err != nil {
t.Fatal(err)
} SolutionObviously, the complaint from the 2
As stated in #1265 (comment), this error occurs because the Github Runner (not Makefile) has an undefined SolutionSetup GOCACHE in Github Action. Use it in the test files. - name: Setup GOCACHE
run: go env -w GOCACHE=${{ github.workspace }}/<INSERT CACHE DIR HERE> I don't have an Ubuntu or Linux so I am not sure about the value to expect for the "CACHE DIR". I guessed using a setup go guide; so if it's wrong it will throw a (different) error. OtherFollowing these fixes, it becomes obvious why the administrator error occurs. When
SolutionRun in administrator (or in a mode that gives file creation permissions in that directory). Once I did this, the only issue I experienced was not having the actual package I needed to be imported. Alternatively, I'd experience issues with tests such as
It wants a specific string for the error but got a different error. In this case, it's obvious that the issue comes from running the test without the fake package. However, I've noted this issue in case a mismatch in error formatting is present in the next CI run. DisclaimerEven with the In other words, UNIT TESTS THAT DON'T SETUP THE INTERPRETER CORRECTLY WILL INCORRECTLY FAIL with In addition, I do not have the fake packages and don't want to go through the effort of setting them up. As a result of the above issues, it may be a better idea may be to have an actual maintainer complete the PR from here. |
To answer the quoted question in full, please consider the following information. The main master branch of yaegi (unforked) does not allow you to import third party modules: Any attempt to do so will be met with an error. This PR (fork) will allow you to import those third party modules, but does not guarantee anything beyond that (i.e usage of the imported code). For the switchupcb master branch of yaegi (fork), #1265 (comment) goes into depth on the limitations of third party module imports. In short, you must have valid permissions on the machine (of the interpreter), and must pass valid Go environment variables to the interpreter via the Will the import work? Yes. Will the code you imported work? I'm not sure. I haven't tested it in a thorough manner. ContributionIf you are interested in contributing to this pull request, what needs to be done? You must fix the unit tests such that they use This can be done with the following steps.
After these steps, the scope of this pull request is technically completed. |
dunno if this helps anyone but I've been carrying a patch for yaegi to support go modules go 2ish years which uses golang builtin tooling to resolve imports. (along with another fix for an erroneous error message that claims imports already imported when an import fails to import properly) I think the long term solution here will be to allow users to provide a resolving function. and have a the current implementation as the default and the go modules one as a swap in replacement. I'd be willing to do the lifting to get it over the line if there is interest. |
Great, all you have to do is fix up the unit tests as stated in #1265 (comment). The root method (of the old implementation) isn't sufficient (and doesn't work on Windows) for reasons explained in #1265 (comment).
The current implementation allows users to provide the environment variables required to resolve imports correctly. This is how |
Great work @james-lawrence! There's definitely interest to have Go mod support in Yaegi! What is needed to get your local branch up to speed with the latest version of Yaegi? Cheers, |
@mewmew its up to date. i just havent had the time to sit down and make a PR and ensure I still had the test hanging around. likely won't get to this for awhile given current life plans. |
That's fair. Life comes first. Wish you a good start of the Spring James! Cheers, |
As a reminder, this pull request is waiting on "UNIT TESTS THAT DON'T SETUP THE INTERPRETER CORRECTLY" (by not using I will review this pull request again prior to the next update of Copygen which is coming soon. |
any update on this? |
Timeline
A timeline of this pull request has been created.
Support Go Modules in Imports
This pull request aims to solve these issues:
These give the error
error: unable to find source related to: "github.com/switchupcb/copygen/cli/models". Either the GOPATH environment variable, or the Interpreter.Options.GoPath needs to be set.
Problem
There were a few issues with the
pkgDir
method.OUTPUT of PROBLEM CODE
pkgDir(), previousRoot(), effectivePkg()
RPATH
generator\vendorDIR
src\generator\vendor\github.com\switchupcb\copygen\cli\modelsgoPath
importPath
github.com/switchupcb/copygen/cli/modelseffectivePkg()
generator\github.com\switchupcb\copygen\cli\modelsRPATH
vendorDIR
src\vendor\github.com\switchupcb\copygen\cli\modelsgoPath
importPath
github.com/switchupcb/copygen/cli/modelsEFFECTIVE
github.com\switchupcb\copygen\cli\modelsRPATH
vendorDIR
src\vendor\github.com\switchupcb\copygen\cli\modelsgoPath
importPath
github.com/switchupcb/copygen/cli/modelseffectivePkg()
github.com\switchupcb\copygen\cli\modelsprevRoot
interp.opt.filesystem
&{}FRAG
github.com\switchupcb\copygen\cli\modelsTHE PROGRAM HANGS ON THIS FUNCTION WHEN GOPATH IS SET
Fix
filepath.Join
.Solution
Go modules are located in
$GOPATH/pkg/mod
. Vendor files are located somewhere in the project relative to thego.mod
file. You state that "In all other cases, absolute import paths are resolved from the GOPATH and the nested "vendor" directories." Therefore, we only need to search in a few places.go get
or placed.For 1, 2, and 4: https://pkg.go.dev/golang.org/x/tools/go/packages#Package gives a list of files we can filter for the absolute import path. 3 is untouched, BUT should work with the given method. For #856 specifically, the
unsafe
issue is fixed by searching in theGOTOOLDIR
(completed with 9605bc7).The following code finds a relative path's absolute path from the current working directory. The other code regarding relative path wasn't commented, so I did not implement it.
Test
If GOCACHE is not set, you will get this error:
While running the interpreter, you might receive
IF an import can't be found AND you aren't in administrator (from the command line).
Note: Did not run install.sh cause its not supported.
Disclaimer
These changes allow me to use yaegi imports without yaegi extract.