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

Support Go1.12 #900

Merged
merged 27 commits into from Mar 28, 2019
Merged

Support Go1.12 #900

merged 27 commits into from Mar 28, 2019

Conversation

hajimehoshi
Copy link
Member

This PR fixes implementation and tests in order to support Go 1.12.

Fixes #887

PTAL

circle.yml Outdated
- run: go tool vet *.go # Go package in root directory.
- run: for d in */; do echo $d; done | grep -v tests/ | grep -v third_party/ | xargs go tool vet # All subdirectories except "tests", "third_party".
- run: go vet *.go # Go package in root directory.
- run: for d in */; do echo ./$d...; done | grep -v ./doc | grep -v ./test | grep -v ./node | xargs go vet # All subdirectories except "doc", "tests", "node*".
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please explain this change.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • go tool vet is deprecated and go vet is the substitute. (Error)
  • It looked like go vet required the relative paths for local packages. I thought this line tries to go vet against part of the local directories. Is that correct?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change makes sense to me, as @hajimehoshi described above.

A few questions/suggestions:

  1. I suspect the go tool vet *.go line can be simplified even further to just go vet, or go vet ., to run vet on the Go package with the import path github.com/gopherjs/gopherjs. It was *.go previously because go tool vet did not accept import paths, only files and directories.

  2. Does doc directory need to be skipped? It has just 2 .md files, so the import path pattern ./doc/... should not be matching any packages.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

go vet ./doc/... fails with the exit code non-zero, and I thought I needed to avoid.

Would go vet ./... work btw?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hajimehoshi@Hajimes-MacBook-Pro ~/go/src/github.com/gopherjs/gopherjs
$ go vet ./doc/...
go: warning: "./doc/..." matched no packages
no packages to vet

hajimehoshi@Hajimes-MacBook-Pro ~/go/src/github.com/gopherjs/gopherjs
$ echo $?
1

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would go vet ./... work btw?

I don't think it would, because the intention is to skip "tests" directory from being vetted.

compiler/natives/src/syscall/syscall_unix.go Outdated Show resolved Hide resolved
compiler/version_check.go Outdated Show resolved Hide resolved
kv = iter.last
} else {
// Compare the index and the size of the actual key set, and check if the iterator is already exhausted.
if iter.i >= js.Global.Call("$keys", iter.m).Length() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling $keys again does not look right at first glance. Which bug is this supposed to fix?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Value tries to access mapiterkeys at the second and later Next call (code, and iter.keys can be already not synced with $keys by deleting keys in a loop.

On second thought, my fix might not work with the below code:

iter := ValueOf(m).MapRange()
for iter.Next() {
    delete(m, iter.Key())
}
if len(m) != 0 {
    panic("not reached")
}

Let me think...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Copy link
Member Author

@hajimehoshi hajimehoshi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

circle.yml Outdated
- run: go tool vet *.go # Go package in root directory.
- run: for d in */; do echo $d; done | grep -v tests/ | grep -v third_party/ | xargs go tool vet # All subdirectories except "tests", "third_party".
- run: go vet *.go # Go package in root directory.
- run: for d in */; do echo ./$d...; done | grep -v ./doc | grep -v ./test | grep -v ./node | xargs go vet # All subdirectories except "doc", "tests", "node*".
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • go tool vet is deprecated and go vet is the substitute. (Error)
  • It looked like go vet required the relative paths for local packages. I thought this line tries to go vet against part of the local directories. Is that correct?

kv = iter.last
} else {
// Compare the index and the size of the actual key set, and check if the iterator is already exhausted.
if iter.i >= js.Global.Call("$keys", iter.m).Length() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Value tries to access mapiterkeys at the second and later Next call (code, and iter.keys can be already not synced with $keys by deleting keys in a loop.

On second thought, my fix might not work with the below code:

iter := ValueOf(m).MapRange()
for iter.Next() {
    delete(m, iter.Key())
}
if len(m) != 0 {
    panic("not reached")
}

Let me think...

compiler/natives/src/syscall/syscall_unix.go Outdated Show resolved Hide resolved
compiler/version_check.go Outdated Show resolved Hide resolved
@hajimehoshi
Copy link
Member Author

I found another problem: the test doesn't work well on macOS (e.g. go run -tags=gopherjsdev . test --short reflect takes forever). I'll fix this later before merging this.

@hajimehoshi
Copy link
Member Author

hajimehoshi commented Mar 5, 2019

In the current situation:

hajimehoshi@Hajimes-MacBook-Pro ~/go/src/github.com/gopherjs/gopherjs
$ go build . && env GOOS=linux ./gopherjs test -v github.com/gopherjs/gopherjs/tests/main
gopherjs: Source maps disabled. Install source-map-support module for nice stack traces. See https://github.com/gopherjs/gopherjs#gopherjs-run-gopherjs-test.                                                                             
=== RUN   TestNotRunMain
--- PASS: TestNotRunMain (0.00s)
PASS
fatal error: all goroutines are asleep - deadlock!
FAIL    github.com/gopherjs/gopherjs/tests/main 0.268s
hajimehoshi@Hajimes-MacBook-Pro ~/go/src/github.com/gopherjs/gopherjs

$ go build . && env GOOS=darwin ./gopherjs test -v github.com/gopherjs/gopherjs/tests/main
gopherjs: Source maps disabled. Install source-map-support module for nice stack traces. See https://github.com/gopherjs/gopherjs#gopherjs-run-gopherjs-test.                                                                             
warning: system calls not available, see https://github.com/gopherjs/gopherjs/blob/master/doc/syscalls.md
fatal error: all goroutines are asleep - deadlock!
FAIL    github.com/gopherjs/gopherjs/tests/main 0.246s

Now I'm investigating why the tests don't work on Darwin.

EDIT: This was a syscall issue. Fixed!

@dmitshur
Copy link
Member

dmitshur commented Mar 5, 2019

Did you install source-map-support module and syscall module? The ones mentioned at https://github.com/gopherjs/gopherjs#gopherjs-run-gopherjs-test. They used to be more optional but by now I think they're mandatory for some tests.

@hajimehoshi
Copy link
Member Author

Did you install source-map-support module and syscall module?

No, but I think the cause was that the write implementation was not used on Darwin and I fixed syscall infrastructure for Darwin.

@hajimehoshi
Copy link
Member Author

Now all the known issues have been solved. Please take another look. Thank you!

@myitcv
Copy link
Member

myitcv commented Mar 8, 2019

Just adding some notes based on us applying roughly the same patch to myitcv#41:

  • I think the *_js.go files need to be renamed and build constraints used
  • Because the CircleCI config file specifies the standard library tests to run (as opposed to a set negation approach) this PR is not running tests in some of the new standard library packages, crucially internal/fmtsort, so the fact the tests are passing for this PR is (I think) currently a false positive
$ diff -wu 1.11 1.12
--- 1.11        2019-03-08 18:46:10.181963351 +0000
+++ 1.12        2019-03-08 18:46:02.570274117 +0000
@@ -88,6 +88,8 @@
 index/suffixarray
 internal/bytealg
 internal/cpu
+internal/fmtsort
+internal/goroot
 internal/nettrace
 internal/poll
 internal/race
@@ -99,6 +101,27 @@
 internal/testenv
 internal/testlog
 internal/trace
+internal/x/crypto/chacha20poly1305
+internal/x/crypto/cryptobyte
+internal/x/crypto/cryptobyte/asn1
+internal/x/crypto/curve25519
+internal/x/crypto/hkdf
+internal/x/crypto/internal/chacha20
+internal/x/crypto/poly1305
+internal/x/net/dns/dnsmessage
+internal/x/net/http/httpguts
+internal/x/net/http/httpproxy
+internal/x/net/http2/hpack
+internal/x/net/idna
+internal/x/net/internal/nettest
+internal/x/net/nettest
+internal/x/text/secure
+internal/x/text/secure/bidirule
+internal/x/text/transform
+internal/x/text/unicode
+internal/x/text/unicode/bidi
+internal/x/text/unicode/norm
+internal/xcoff
 io
 io/ioutil
 log
@@ -143,6 +166,7 @@
 runtime/cgo
 runtime/debug
 runtime/internal/atomic
+runtime/internal/math
 runtime/internal/sys
 runtime/pprof
 runtime/pprof/internal/profile
@@ -167,22 +191,3 @@
 unicode/utf16
 unicode/utf8
 unsafe
-vendor/golang_org/x/crypto/chacha20poly1305
-vendor/golang_org/x/crypto/cryptobyte
-vendor/golang_org/x/crypto/cryptobyte/asn1
-vendor/golang_org/x/crypto/curve25519
-vendor/golang_org/x/crypto/internal/chacha20
-vendor/golang_org/x/crypto/poly1305
-vendor/golang_org/x/net/dns/dnsmessage
-vendor/golang_org/x/net/http/httpguts
-vendor/golang_org/x/net/http/httpproxy
-vendor/golang_org/x/net/http2/hpack
-vendor/golang_org/x/net/idna
-vendor/golang_org/x/net/internal/nettest
-vendor/golang_org/x/net/nettest
-vendor/golang_org/x/text/secure
-vendor/golang_org/x/text/secure/bidirule
-vendor/golang_org/x/text/transform
-vendor/golang_org/x/text/unicode
-vendor/golang_org/x/text/unicode/bidi
-vendor/golang_org/x/text/unicode/norm

@hajimehoshi
Copy link
Member Author

@myitcv Thank you! For the above diff, the original master's circle.yml doesn't include a lot of tests like internal/cpu. Would it be possible to decide to care such packages in another PR if needed?

I think the *_js.go files need to be renamed and build constraints used

Done.

@myitcv
Copy link
Member

myitcv commented Mar 9, 2019

@hajimehoshi

For the above diff, the original master's circle.yml doesn't include a lot of tests like internal/cpu. Would it be possible to decide to care such packages in another PR if needed?

I'd suggest switching to the negation-based approach. We can even do that ahead of the Go 1.12 changes.

It's a simple, easy to understand change that means we won't have to manually keep track of new packages. Packages like internal/fmtsort which, per myitcv#41, seem to have caught an issue.

@hajimehoshi
Copy link
Member Author

I'd suggest switching to the negation-based approach. We can even do that ahead of the Go 1.12 changes.

A blacklist instead of the current whitelist makes sense.

image/color/palette
image/internal/imageutil
internal/cpu
internal/fmtsort
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A better starting point for this blacklist is the list of packages that were not tested as part of the 1.11 cycle (hence why I suggested we could/should do that as part of a separate, simple PR).

That would then highlight that you're including internal/fmtsort in this file, i.e. it would be an additional package we're ignoring for Go 1.12.

I still think we should understand why this package in particular is failing, because it's fundamental to the sorting changes in the fmt package and other places:

Package fmtsort provides a general stable ordering mechanism for maps, on behalf of the fmt and text/template packages.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. As I merged your PR, I'll be investigating why internal/fmtsort tests failed. I agree fmtsort is so fundamental that we need to care.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The root cause is that getting pointer values from a slice is now counterintuitive

https://gopherjs.github.io/playground/#/jvnZoFsINA

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha, nice, my guess is that conversion an integer from a pointer (in reflect?) causes this issue

https://gopherjs.github.io/playground/#/fN4zm6Wj4W

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made the tests pass with these fixes:

  • For pointers and channels, the current GopherJS cannot treat them well for sorting. Skip this.
  • GopherJS cannot treat nil key in a map well. Skip this.

myitcv added a commit to myitcv/gopherjs that referenced this pull request Mar 9, 2019
Using a black list is a more effective mechanism for expressing those
standard library packages we don't want to test because it means we
don't need to manually check whether new standard library packages have
been added that would otherwise need to be added to the white list.

See the discussion in gopherjs#900 for
more context.
myitcv added a commit to myitcv/gopherjs that referenced this pull request Mar 9, 2019
So that we can then see the true diff that the Go 1.12 changes in
gopherjs#900 will introduce.
@myitcv myitcv mentioned this pull request Mar 9, 2019
hajimehoshi pushed a commit that referenced this pull request Mar 9, 2019
…902)

Using a black list is a more effective mechanism for expressing those
standard library packages we don't want to test because it means we
don't need to manually check whether new standard library packages have
been added that would otherwise need to be added to the white list.

See the discussion in #900 for
more context.
myitcv added a commit to myitcv/gopherjs that referenced this pull request Mar 9, 2019
So that we can then see the true diff that the Go 1.12 changes in
gopherjs#900 will introduce.
myitcv added a commit that referenced this pull request Mar 9, 2019
So that we can then see the true diff that the Go 1.12 changes in
#900 will introduce.
@hajimehoshi
Copy link
Member Author

Friendly ping

Copy link
Member

@dmitshur dmitshur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for working on this @hajimehoshi, you did a great job implementing support for Go 1.12!

I've reviewed this and did not find any issues or significant opportunities for improvement. I left a few comments about some minor things.

I've also tested it with various GopherJS programs on macOS and they all ran without problems. The generated file sizes have increased by about 5-7% (depending on which standard library packages are imported), which is unfortunate but within normal range of new Go releases.

compiler/natives/src/reflect/reflect.go Show resolved Hide resolved
compiler/natives/fs_vfsdata.go Outdated Show resolved Hide resolved
compiler/natives/fs_vfsdata.go Outdated Show resolved Hide resolved
compiler/version_check.go Outdated Show resolved Hide resolved
@hajimehoshi
Copy link
Member Author

@dmitshur Thank you for reviewing! I appreciate your careful work.

Should we squash the commits, or not? My preference is to squash them, but I'd like to obey the policy of GopherJS.

@dmitshur
Copy link
Member

dmitshur commented Mar 28, 2019

When you ask if we should squash the commits, can you clarify what exactly you mean? I can't answer your question directly because I'm not sure what you meant, so I'll describe this in full.

When merging this PR, we should use the "create a merge commit" merge strategy:

When creating the merge commit, we can follow the same pattern as in previous merge commits, e.g., 0210a2f. You'll have to edit the subject and body fields accordingly. E.g.:

image

We should not use the "squash and merge" merge strategy. Doing so would squash all commits in this PR into a single commit. Such a commit would be massive, it would include all generated code, and it's not viable to meaningfully describe the changes that went into adding Go 1.12 support.

However, before doing the merge, it is completely acceptable and in fact preferable to re-write the PR history to clean it up and squash redundant commits, so that it consists of clean logical well-described changes. At the very least:

  • all the generated commits can be squashed into a single commit at the end that re-generates all data; see third-last commit in PR Go 1.11 support. #853 that added Go 1.11 support as an example of this

If any of the other commits are redundant or WIP (e.g., where you tried one thing, but ended up overwriting it a future commit) and can be squashed into a single logical commit with a descriptive commit message, that's great too.

Of course, re-writing the history involves a force push to this PR branch, so be careful, and do a diff of the final result against the starting point (i.e., the latest commit is a02f42a right now) to ensure the end result is unchanged.

Finally, feel free to look over the previous PRs to get an idea of how it was done historically. I've linked them all in #900 (comment).

Cleaning up the PR history and writing more descriptive commit messages is great, but optional. Feel free to do as much or as little before merging this PR. Thanks again @hajimehoshi!

@hajimehoshi
Copy link
Member Author

We should not use the "squash and merge" merge strategy.

What I wanted to ask is whether we should use this strategy. Sorry for my unclear question. Thanks!

@hajimehoshi
Copy link
Member Author

I removes some redundant commits, but I couldn't integrate go-generating into one commit. That's not perfect, but I believe that's acceptable.

@hajimehoshi hajimehoshi merged commit bb26745 into master Mar 28, 2019
@hajimehoshi hajimehoshi deleted the go1.12 branch March 28, 2019 17:07
dmitshur added a commit to gopherjs/gopherjs.github.io that referenced this pull request Mar 29, 2019
Done on darwin/amd64 environment.

Regenerated with:

	go generate github.com/gopherjs/gopherjs.github.io/playground

Follows gopherjs/gopherjs#900.
@dmitshur dmitshur mentioned this pull request Mar 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support for Go 1.12
5 participants