Skip to content

Commit 079e572

Browse files
bumping to go1.20 master
1 parent 381c232 commit 079e572

12 files changed

Lines changed: 237649 additions & 1548 deletions

File tree

go.work

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
go 1.19
1+
go 1.20
22

33
use (
44
./playground

playground/go.mod

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
module github.com/gopherjs/gopherjs.github.io/playground
22

3-
go 1.19
3+
go 1.20
44

55
require (
66
github.com/google/go-cmp v0.5.8
7-
github.com/gopherjs/gopherjs v1.19.0-beta2.0.20251008200541-113c92b42b18
7+
github.com/gopherjs/gopherjs v1.19.0-beta2.0.20260112215734-09f0b7ce5c99
88
golang.org/x/tools v0.16.0
99
honnef.co/go/js/xhr v0.0.0-20150307031022-00e3346113ae
1010
)
1111

1212
require (
1313
github.com/evanw/esbuild v0.25.4 // indirect
1414
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86 // indirect
15+
github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c // indirect
1516
github.com/sirupsen/logrus v1.8.3 // indirect
1617
github.com/stretchr/testify v1.11.1 // indirect
1718
golang.org/x/sys v0.10.0 // indirect

playground/go.sum

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
module github.com/grantnelson-wf/gopherjs.github.io/playground/internal/cmd/precompile
22

3-
go 1.19
3+
go 1.20
44

55
require (
6-
github.com/gopherjs/gopherjs v1.19.0-beta2.0.20251008200541-113c92b42b18
7-
github.com/sirupsen/logrus v1.8.1
6+
github.com/gopherjs/gopherjs v1.19.0-beta2.0.20260112215734-09f0b7ce5c99
7+
github.com/sirupsen/logrus v1.8.3
88
)
99

1010
require (
@@ -17,5 +17,3 @@ require (
1717
golang.org/x/sys v0.10.0 // indirect
1818
golang.org/x/tools v0.16.0 // indirect
1919
)
20-
21-
replace github.com/gopherjs/gopherjs => /Users/grantnelson/go/src/github.com/Workiva/gopherjs // TODO(grantnelson-wf): REMOVE

playground/internal/cmd/precompile/go.sum

Lines changed: 10 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

playground/internal/cmd/precompile/precompile.go

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@ type logLevelFlag struct{ log.Level }
3232

3333
func (l *logLevelFlag) Set(raw string) error { return l.UnmarshalText([]byte(raw)) }
3434

35-
var (
36-
logLevel logLevelFlag = logLevelFlag{Level: log.ErrorLevel}
37-
)
35+
var logLevel logLevelFlag = logLevelFlag{Level: log.ErrorLevel}
3836

3937
func init() {
4038
flag.Var(&logLevel, "log_level", "Default logging level.")
@@ -63,14 +61,9 @@ func run() error {
6361
return fmt.Errorf("failed to get build package for %s: %w", path, err)
6462
}
6563

66-
var srcs *sources.Sources
67-
if srcs, err = s.LoadPackages(pkg); err != nil {
64+
if _, err = s.LoadPackages(pkg); err != nil {
6865
return fmt.Errorf("failed to prepackaged package %q: %w", pkg, err)
6966
}
70-
71-
if _, err := s.PrepareAndCompilePackages(srcs); err != nil {
72-
return fmt.Errorf("failed to compile package %q: %w", pkg, err)
73-
}
7467
}
7568

7669
target, err := targetDir(s)

playground/internal/react/globals.go

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,31 @@
1+
// The globals are the global objects used by the react components.
2+
//
3+
// Since passing Go structs through React props will cause problems
4+
// because of how React serializes props, even if we wrap it in a Ref
5+
// the GopherJS will convert structs to JS objects,
6+
// instead we use a global singleton instead to pass around global state.
7+
//
8+
// This could be problematic if we ever want to have multiple code editors
9+
// on the same page, but that is not a use case we currently have to support.
110
package react
211

312
import (
413
"sync"
514

615
"github.com/gopherjs/gopherjs.github.io/playground/internal/common"
16+
"github.com/gopherjs/gopherjs.github.io/playground/internal/runner"
717
"github.com/gopherjs/gopherjs.github.io/playground/internal/snippets"
818
"github.com/gopherjs/gopherjs.github.io/playground/internal/undoRedo"
919
)
1020

11-
// Globals is the global objects used by the react components.
12-
//
13-
// Since passing Go structs through React props will cause problems
14-
// because of how React serializes props, even if we wrap it in a Ref
15-
// the GopherJS will convert structs to JS objects,
16-
// instead we use a global singleton instead to pass around global state.
17-
//
18-
// This could be problematic if we ever want to have multiple code editors
19-
// on the same page, but that is not a use case we currently have to support.
20-
var globals = &struct {
21+
var globals = struct {
2122
UndoRedo func() common.UndoRedoStack
2223
SnippetsStore func() common.SnippetStore
24+
Runner func() common.Runner
2325
}{
24-
UndoRedo: OnceValue(undoRedo.NewUndoRedoStack),
26+
UndoRedo: OnceValue(undoRedo.NewStack),
2527
SnippetsStore: OnceValue(snippets.NewStore),
28+
Runner: OnceValue(func() common.Runner { return runner.New(runner.NewFetcher()) }),
2629
}
2730

2831
// OnceValue initializes a value on the first call

playground/internal/react/playground.go

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package react
22

3-
import "github.com/gopherjs/gopherjs/js"
3+
import (
4+
"github.com/gopherjs/gopherjs/compiler"
5+
"github.com/gopherjs/gopherjs/js"
6+
)
47

58
func Playground() *Element {
69
return CreateElement(playgroundComponent, nil)
@@ -13,10 +16,9 @@ func playgroundComponent(props Props) *Element {
1316
output, setOutput = UseState([]any{})
1417
fmtImports, setFmtImports = UseState(true)
1518
lightTheme, setLightTheme = UseStateLazy(getDefaultToLightTheme)
19+
runButtonRef = UseRef()
1620
)
1721

18-
version := UseMemo(func() string { return `vx.x.x` }, []any{}) // TODO(grantnelson-wf): Replace with `UseMemo(compiler.Version)`
19-
2022
UseEffect(func() {
2123
setDataTheme(lightTheme)
2224
}, []any{lightTheme})
@@ -46,12 +48,17 @@ func playgroundComponent(props Props) *Element {
4648
})
4749
*/
4850

49-
onSaveKeyPress := UseCallback(func() {
50-
println("Save key pressed") // TODO(grantnelson-wf): Implement
51+
onEscapeCode := UseCallback(func() {
52+
// Escape will move focus to the run button.
53+
// This is for eccessability so that users can easily run the
54+
// code after editing. Or at minimum, users can exit the text area
55+
// like they would be able to with tab stops but our editor is consuming
56+
// tab key presses so tab stops won't work when in the text area.
57+
runButtonRef.Call(`focus`)
5158
}, []any{})
5259

53-
onEscapeCode := UseCallback(func() {
54-
println("Escape code pressed") // TODO(grantnelson-wf): Implement to change focus to the run button or something
60+
onSaveKeyPress := UseCallback(func() {
61+
println("Save key pressed") // TODO(grantnelson-wf): Implement by running format (and maybe sharing)
5562
}, []any{})
5663

5764
onRunClick := UseCallback(func() {
@@ -70,11 +77,11 @@ func playgroundComponent(props Props) *Element {
7077
Div(Props{
7178
`id`: `banner`,
7279
},
73-
BannerTitle(version),
80+
BannerTitle(compiler.Version),
7481
Span(Props{
7582
`id`: `controls`,
7683
},
77-
Button(`run-button`, `Run`, nil, onRunClick),
84+
Button(`run-button`, `Run`, Props{`ref`: runButtonRef}, onRunClick),
7885
Button(`format-button`, `Format`, nil, onFormatClick),
7986
ToggleBox(`format-imports`, `Rewrite imports on Format`, `Imports`, fmtImports, setFmtImports),
8087
ShareUrlControl(shareUrl, onShareClick),
Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package runner
22

33
import (
4+
"fmt"
45
"sync"
56

67
"github.com/gopherjs/gopherjs.github.io/playground/internal/common"
@@ -16,68 +17,90 @@ const (
1617
)
1718

1819
type packageCache struct {
19-
output common.Output
2020
fetcher common.Fetcher
2121
cached map[string]*sources.Sources
2222
inprogress map[string]chan struct{}
2323
lock sync.Mutex
2424
}
2525

26-
func newPackageCache(output common.Output, fetcher common.Fetcher) *packageCache {
26+
func newPackageCache(fetcher common.Fetcher) *packageCache {
2727
return &packageCache{
28-
output: output,
2928
fetcher: fetcher,
3029
cached: make(map[string]*sources.Sources),
3130
inprogress: make(map[string]chan struct{}),
3231
}
3332
}
3433

35-
func (pc *packageCache) Load(importPath string) (*sources.Sources, loadResult) {
34+
func (pc *packageCache) Load(importPath string) (*sources.Sources, loadResult, error) {
3635
srcs := &sources.Sources{}
37-
result := pc.syncLoad(importPath)(srcs)
38-
return srcs, result
36+
result, err := pc.syncLoad(importPath)(srcs)
37+
return srcs, result, err
3938
}
4039

40+
type syncLoadFunc func(srcs *sources.Sources) (loadResult, error)
41+
4142
// syncLoad returns a function to complete loading the package.
4243
//
4344
// The returned function may either return the cached package immediately,
4445
// wait for an in-progress load to complete, or perform the load itself.
4546
// syncLoad will not block, but the returned function may block.
46-
func (pc *packageCache) syncLoad(importPath string) func(srcs *sources.Sources) loadResult {
47+
//
48+
// If the returned function is run and returns loadFailed, the error will be non-nil
49+
// and if the error is non-nil, the loadResult will be loadFailed.
50+
func (pc *packageCache) syncLoad(importPath string) syncLoadFunc {
4751
pc.lock.Lock()
4852
defer pc.lock.Unlock()
4953

5054
if cached, found := pc.cached[importPath]; found {
51-
return func(srcs *sources.Sources) loadResult {
52-
*srcs = *cached // Copy the cached sources.
53-
return loadCached
54-
}
55+
return pc.alreadyLoaded(cached)
5556
}
5657

5758
// Load is already in progress, wait for it to complete.
5859
if ch, loading := pc.inprogress[importPath]; loading {
59-
return func(srcs *sources.Sources) loadResult {
60-
<-ch // Wait for the in-progress load to complete.
61-
62-
pc.lock.Lock()
63-
defer pc.lock.Unlock()
64-
65-
if cached, found := pc.cached[importPath]; found {
66-
*srcs = *cached // Copy the cached sources.
67-
return loadCached
68-
}
69-
return loadFailed
70-
}
60+
return pc.alreadyInprogress(importPath, ch)
7161
}
7262

7363
// Load is not in progress, start it now.
7464
ch := make(chan struct{})
7565
pc.inprogress[importPath] = ch
76-
return func(srcs *sources.Sources) loadResult {
66+
return pc.startLoading(importPath, ch)
67+
}
68+
69+
// alreadyLoaded returns a syncLoadFunc that immediately returns the cached sources.
70+
// The given cached sources must be the sources that are already loaded in the cache.
71+
func (pc *packageCache) alreadyLoaded(cached *sources.Sources) syncLoadFunc {
72+
return func(srcs *sources.Sources) (loadResult, error) {
73+
*srcs = *cached // Copy the cached sources.
74+
return loadCached, nil
75+
}
76+
}
77+
78+
// alreadyInprogress returns a syncLoadFunc that waits for an in-progress load to complete.
79+
// The given channel will be waited on until it is closed, indicating the load is complete
80+
// and the sources should now be in the cache.
81+
func (pc *packageCache) alreadyInprogress(importPath string, ch chan struct{}) syncLoadFunc {
82+
return func(srcs *sources.Sources) (loadResult, error) {
83+
<-ch // Wait for the in-progress load to complete.
84+
85+
pc.lock.Lock()
86+
defer pc.lock.Unlock()
87+
88+
if cached, found := pc.cached[importPath]; found {
89+
*srcs = *cached // Copy the cached sources.
90+
return loadCached, nil
91+
}
92+
return loadFailed, fmt.Errorf(`failed to find package %q in cache after waiting load`, importPath)
93+
}
94+
}
95+
96+
// startLoading returns a syncLoadFunc that performs the package load.
97+
// The given channel will be closed when the load is complete to indicate to any
98+
// other processed waiting on the load that it is done.
99+
func (pc *packageCache) startLoading(importPath string, ch chan struct{}) syncLoadFunc {
100+
return func(srcs *sources.Sources) (loadResult, error) {
77101
fetched, err := pc.fetcher.FetchPackage(importPath)
78102
if err != nil {
79-
pc.output.AddError(err)
80-
return loadFailed
103+
return loadFailed, err
81104
}
82105

83106
pc.lock.Lock()
@@ -87,6 +110,6 @@ func (pc *packageCache) syncLoad(importPath string) func(srcs *sources.Sources)
87110
*srcs = *fetched // Copy the fetched sources.
88111
delete(pc.inprogress, importPath)
89112
close(ch)
90-
return loadFetched
113+
return loadFetched, nil
91114
}
92115
}

0 commit comments

Comments
 (0)