Closed kesmit13 closed 5 years ago
All packages outside Go standard library are currently imported by compiling and loading a plugin that wraps them, so it's the normal path.
In your specific case, compiling the plugin fails but the exact reason is not visible in the error message.
If the package you are trying to import is publicly available, please tell its full name so we can try to reproduce the problem.
Otherwise the only option coming to my mind is to download and install gomacro - the Go interpreter used internally by gophernotes - and try to import the same package from its command line: the error message produced by "go build -buildmode=plugin" should then be visible
It's not publicly available, but when I do try to build manually with plugin mode, I get the following:
-buildmode=plugin requires exactly one main package
Which is correct, I don't have a main package, but that's because it's simply a library.
That's correct and expected, the main package wrapping the library is autogenerated by gophernotes and written to "/Users/me/go/src/gomacro_imports/pkg" which is then compiled with "go -buildmode=plugin"
I see the problem now.
pkg.go:12:2: use of internal package pkg/internal/pb not allowed
That's unfortunate...
It means that your pkg exports an API that accepts/returns/publishes types from the internal package.
If you can avoid (indirectly) publishing the internal package, it should work.
Or in alternative, rename "internal" to some other name
This is really a limitation of gomacro. I was able to rework my package to not use internal variables in the API and it's working now.
I found the reason: when gomacro compiles a plugin in order to import a package, it declares a proxy for each interface found in the package.
For example, if package foo
contains the following
package foo
import "foo/internal"
type Fooer interface {
Bar() internal.Baz
}
Then gomacro creates a plugin containing
package main
import (
. "reflect"
foo "foo"
internal "foo/internal"
)
type Package = struct {
Binds map[string]Value
Types map[string]Type
// Untypeds ...
Proxies map[string]Type
}
var Packages = make(map[string]Package)
Now, filling Package.Binds
and Package.Types
is always easy - in this case, we just need to run
func init() {
Packages["foo"] = Package{
Binds: nil,
Types: map[string]Type{
"Fooer": TypeOf((foo.Fooer *)(nil)).Elem(),
},
Proxies: map[string]Type{
"Fooer": TypeOf((Proxy_Fooer *)(nil)).Elem(),
},
}
}
The difficult part is declaring a type Proxy_Fooer
that implements the interface Fooer
: it contains a function that returns an internal.Baz
, but Go compiler rejects any attempt to directly refer internal.*
so implementing such interface is not trivial, especially inside automatic code generation.
So yes, it's a gomacro limitation, and it's difficult to solve - except for the obvious solution of not declaring a proxy that implements an exported interface if such interface uses forbidden packages.
I'm getting an error when trying to do an 'import "pkg"' in my notebook. I'm not sure what is triggering the plugin build though since this package is simply a library, not a plugin. This is using Go 1.11.1 darwin. I've imported other libraries that work fine. Is there something within a package that makes gophernotes switch to plugin mode?