-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathsub.go
More file actions
89 lines (74 loc) · 2.62 KB
/
Copy pathsub.go
File metadata and controls
89 lines (74 loc) · 2.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
//go:build !goeval.offline
/*
Copyright 2025-2026 Olivier Mengué.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"bytes"
_ "embed"
"io"
"os"
"os/exec"
)
func registerOnlineFlags() {
// TODO allow to optionally set a different endpoint
flagAction("play", actionPlay, nil, "run the code remotely on https://go.dev/play")
flagAction("share", actionShare, nil, "share the code on https://go.dev/play and print the URL.")
}
var (
//go:embed sub/play/play.go
playSubSource string
//go:embed sub/share/share.go
shareSubSource string
)
// prepareSubPlay prepare the source code for compilation and execution of sub/play/play.go.
func prepareSubPlay() (stdin *bytes.Buffer, tail func() error, cleanup func(), err error) {
return prepareSub(playSubSource)
}
// prepareSubPlay prepare the source code for compilation and execution of sub/share/share.go.
func prepareSubShare() (stdin *bytes.Buffer, tail func() error, cleanup func(), err error) {
return prepareSub(shareSubSource)
}
// prepareSub prepares execution of a sub command via a "go run".
// The returned stdin buffer may be filled with data.
// cleanup must be called after cmd.Run() to clean the tempoary go source created.
func prepareSub(appCode string) (stdin *bytes.Buffer, tail func() error, cleanup func(), err error) {
f, err := os.CreateTemp("", "*.go")
if err != nil {
return nil, nil, nil, err
}
defer f.Close()
fName := f.Name()
cleanup = func() {
os.Remove(fName)
}
if _, err := io.WriteString(f, appCode); err != nil {
cleanup()
return nil, nil, nil, err
}
// Prepare input that will be filled before executing the command
stdin = new(bytes.Buffer)
// Run "go run" with the code submitted on stdin and the userAgent as first argument
cmd := exec.Command(goCmd, "run", fName, getUserAgent())
cmd.Env = append(
os.Environ(), // We must not use the 'env' built for local run here
"GO111MODULE=off", // Sub command use only stdlib
"GOEXPERIMENT=", // Clear GOEXPERIMENT which has been forwarded in a comment
)
cmd.Stdin = stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
tail = func() error {
return run(cmd)
}
return
}