1
2
3
4
5 package load
6
7 import (
8 "cmd/go/internal/base"
9 "cmd/go/internal/cfg"
10 "encoding/json"
11 "fmt"
12 "io"
13 "os"
14 "strings"
15 "sync"
16 )
17
18
19 type Printer interface {
20
21
22
23
24
25
26
27
28 Printf(pkg *Package, format string, args ...any)
29
30
31
32
33
34
35
36
37
38
39
40
41 Errorf(pkg *Package, format string, args ...any)
42 }
43
44
45 func DefaultPrinter() Printer {
46 return defaultPrinter()
47 }
48
49 var defaultPrinter = sync.OnceValue(func() Printer {
50 if cfg.BuildJSON {
51 return NewJSONPrinter(os.Stdout)
52 }
53 return &TextPrinter{os.Stderr}
54 })
55
56 func ensureNewline(s string) string {
57 if s == "" {
58 return ""
59 }
60 if strings.HasSuffix(s, "\n") {
61 return s
62 }
63 return s + "\n"
64 }
65
66
67 type TextPrinter struct {
68 Writer io.Writer
69 }
70
71 func (p *TextPrinter) Printf(_ *Package, format string, args ...any) {
72 fmt.Fprintf(p.Writer, format, args...)
73 }
74
75 func (p *TextPrinter) Errorf(_ *Package, format string, args ...any) {
76 fmt.Fprint(p.Writer, ensureNewline(fmt.Sprintf(format, args...)))
77 base.SetExitStatus(1)
78 }
79
80
81 type JSONPrinter struct {
82 enc *json.Encoder
83 }
84
85 func NewJSONPrinter(w io.Writer) *JSONPrinter {
86 return &JSONPrinter{json.NewEncoder(w)}
87 }
88
89 type jsonBuildEvent struct {
90 ImportPath string
91 Action string
92 Output string `json:",omitempty"`
93 }
94
95 func (p *JSONPrinter) Printf(pkg *Package, format string, args ...any) {
96 ev := &jsonBuildEvent{
97 Action: "build-output",
98 Output: fmt.Sprintf(format, args...),
99 }
100 if ev.Output == "" {
101
102 return
103 }
104 if pkg != nil {
105 ev.ImportPath = pkg.Desc()
106 }
107 p.enc.Encode(ev)
108 }
109
110 func (p *JSONPrinter) Errorf(pkg *Package, format string, args ...any) {
111 s := ensureNewline(fmt.Sprintf(format, args...))
112
113 for len(s) > 0 {
114 i := strings.IndexByte(s, '\n')
115 p.Printf(pkg, "%s", s[:i+1])
116 s = s[i+1:]
117 }
118 ev := &jsonBuildEvent{
119 Action: "build-fail",
120 }
121 if pkg != nil {
122 ev.ImportPath = pkg.Desc()
123 }
124 p.enc.Encode(ev)
125 base.SetExitStatus(1)
126 }
127
View as plain text