/
main.go
112 lines (97 loc) · 1.85 KB
/
main.go
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package main
import (
"flag"
"fmt"
"go/build"
"log"
"net"
"net/http"
"os"
"os/exec"
"path/filepath"
"github.com/jcorbin/gorunwasm/handler"
)
var (
listen = "localhost:0"
gen bool // server:skip
srcDir = ""
path = "." // server:skip
)
func main() {
flag.StringVar(&listen, "listen", listen, "listen address for http server")
flag.BoolVar(&gen, "gen", false, "generate server main code rather than run a generic server")
flag.Parse()
if args := flag.Args(); len(args) > 0 {
path = args[0]
if filepath.IsAbs(path) {
srcDir = args[0]
path = "."
}
}
var err error
if gen {
err = genServer()
} else {
err = serve()
}
if err != nil {
log.Fatalln(err)
}
}
func genServer() error {
// resolve target package
if srcDir == "" {
var err error
srcDir, err = os.Getwd()
if err != nil {
return err
}
}
pkg, err := build.Default.Import(path, srcDir, build.FindOnly)
if err != nil {
return err
}
out, err := os.Create(filepath.Join(pkg.Dir, "server.go"))
if err != nil {
return err
}
defer out.Close()
// execute template to stdout through gofmt
r, w, err := os.Pipe()
if err != nil {
return err
}
cmd := exec.Command("gofmt")
cmd.Stdin = r
cmd.Stdout = out
cmd.Stderr = os.Stderr
err = cmd.Start()
_ = r.Close()
if err == nil {
err = tmpl.Execute(w, pkg)
if cerr := w.Close(); err == nil {
err = cerr
}
if werr := cmd.Wait(); err == nil {
err = werr
}
}
if err == nil {
log.Printf("generated %v", out.Name())
}
return err
}
func serve() error {
wh, err := handler.Handle("", srcDir, path)
if err != nil {
return err
}
defer wh.Close()
ln, err := net.Listen("tcp", listen)
if err != nil {
return fmt.Errorf("listen %q failed: %v", listen, err)
}
log.Printf("listening on http://%v", ln.Addr())
log.Printf("Serving %v on http://%s", wh, ln.Addr())
return http.Serve(ln, nil)
}