Skip to content

Commit 8a13825

Browse files
committed
Add support for vendoring gopherjs
* Determines whether there is an import path to a vendored version of gopherjs * If so, updates all import paths to gopherjs in generated code to use the vendored version * Updates runtime/runtime.go to use a string constant for its static reference to the gopherjs import path * Adds logic to update the string constant to be the vendored path during generation Fixes #415
1 parent 2b1d432 commit 8a13825

File tree

4 files changed

+137
-92
lines changed

4 files changed

+137
-92
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ GopherJS compiles Go code ([golang.org](https://golang.org/)) to pure JavaScript
1010
Give GopherJS a try on the [GopherJS Playground](http://gopherjs.github.io/playground/).
1111

1212
### What is supported?
13-
Nearly everything, including Goroutines ([compatibility table](https://github.com/gopherjs/gopherjs/blob/master/doc/packages.md)). Performance is quite good in most cases, see [HTML5 game engine benchmark](https://ajhager.github.io/engi/demos/botmark.html). Cgo is not supported. Using a vendored copy of GopherJS is currently not supported, see [#415](https://github.com/gopherjs/gopherjs/issues/415).
13+
Nearly everything, including Goroutines ([compatibility table](https://github.com/gopherjs/gopherjs/blob/master/doc/packages.md)). Performance is quite good in most cases, see [HTML5 game engine benchmark](https://ajhager.github.io/engi/demos/botmark.html). Cgo is not supported.
1414

1515
### Installation and Usage
1616
Get or update GopherJS and dependencies with:

build/build.go

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ func Import(path string, mode build.ImportMode, installSuffix string, buildTags
7272
return importWithSrcDir(path, wd, mode, installSuffix, buildTags)
7373
}
7474

75+
// TODO: figure out how we can determine this per project/per operation so that it can be set and unset properly rather
76+
// than maintaining it as package-level variable state.
77+
var vendoredGopherJS string
78+
7579
func importWithSrcDir(path string, srcDir string, mode build.ImportMode, installSuffix string, buildTags []string) (*PackageData, error) {
7680
buildContext := NewBuildContext(installSuffix, buildTags)
7781
if path == "syscall" { // syscall needs to use a typical GOARCH like amd64 to pick up definitions for _Socklen, BpfInsn, IFNAMSIZ, Timeval, BpfStat, SYS_FCNTL, Flock_t, etc.
@@ -81,14 +85,21 @@ func importWithSrcDir(path string, srcDir string, mode build.ImportMode, install
8185
buildContext.InstallSuffix += "_" + installSuffix
8286
}
8387
}
88+
89+
// if current path is for gopherjs import and a vendored path for gopherjs has previously been encountered, update
90+
// the path to be the vendored one
91+
if strings.HasPrefix(path, "github.com/gopherjs/gopherjs") && vendoredGopherJS != "" {
92+
path = vendoredGopherJS + strings.TrimPrefix(path, "github.com/gopherjs/gopherjs")
93+
}
94+
8495
pkg, err := buildContext.Import(path, srcDir, mode)
8596
if err != nil {
8697
return nil, err
8798
}
8899

89-
// TODO: Resolve issue #415 and remove this temporary workaround.
100+
// if gopherjs package path is vendored, store it so that we can update future paths
90101
if strings.HasSuffix(pkg.ImportPath, "/vendor/github.com/gopherjs/gopherjs/js") {
91-
return nil, fmt.Errorf("vendoring github.com/gopherjs/gopherjs/js package is not supported, see https://github.com/gopherjs/gopherjs/issues/415")
102+
vendoredGopherJS = strings.TrimSuffix(pkg.ImportPath, "/js")
92103
}
93104

94105
switch path {
@@ -249,6 +260,36 @@ func parseAndAugment(pkg *build.Package, isTest bool, fileSet *token.FileSet) ([
249260
panic(err)
250261
}
251262
r.Close()
263+
264+
if importPath == "runtime" && name == "runtime.go" && vendoredGopherJS != "" {
265+
// special case handling for #415: runtime.go contains a string constant named "gopherJSPath" that
266+
// contains the import path "github.com/gopherjs/gopherjs/js". If we are using a vendored version of
267+
// gopherjs, we must update the contents of the string constant to be the vendored path.
268+
for _, decl := range file.Decls {
269+
switch d := decl.(type) {
270+
case *ast.GenDecl:
271+
switch d.Tok {
272+
case token.CONST:
273+
for _, spec := range d.Specs {
274+
for i, name := range spec.(*ast.ValueSpec).Names {
275+
if name.Name != "gopherJSPath" {
276+
continue
277+
}
278+
if i < len(spec.(*ast.ValueSpec).Values) {
279+
constValue, ok := spec.(*ast.ValueSpec).Values[i].(*ast.BasicLit)
280+
if !ok {
281+
continue
282+
}
283+
// update value of constant to be "js" package within vendored gopherjs
284+
constValue.Value = fmt.Sprintf(`"%s/js"`, vendoredGopherJS)
285+
}
286+
}
287+
}
288+
}
289+
}
290+
}
291+
}
292+
252293
for _, decl := range file.Decls {
253294
switch d := decl.(type) {
254295
case *ast.FuncDecl:

0 commit comments

Comments
 (0)