Skip to content

Commit d8f7c30

Browse files
authored
Remove interrupt package and make app not depend on other private/pkg packages (#3827)
1 parent 705a37b commit d8f7c30

File tree

12 files changed

+114
-123
lines changed

12 files changed

+114
-123
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ require (
1010
buf.build/gen/go/bufbuild/registry/connectrpc/go v1.18.1-20250424215339-a457693b5db4.1
1111
buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.6-20250424215339-a457693b5db4.1
1212
buf.build/go/bufplugin v0.9.0
13+
buf.build/go/interrupt v1.1.0
1314
buf.build/go/protovalidate v0.12.0
1415
buf.build/go/protoyaml v0.6.0
1516
buf.build/go/spdx v0.2.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ buf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.36.6-20241007202033-c
1010
buf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.36.6-20241007202033-cf42259fcbfc.1/go.mod h1:OUbhXurY+VHFGn9FBxcRy8UB7HXk9NvJ2qCgifOMypQ=
1111
buf.build/go/bufplugin v0.9.0 h1:ktZJNP3If7ldcWVqh46XKeiYJVPxHQxCfjzVQDzZ/lo=
1212
buf.build/go/bufplugin v0.9.0/go.mod h1:Z0CxA3sKQ6EPz/Os4kJJneeRO6CjPeidtP1ABh5jPPY=
13+
buf.build/go/interrupt v1.1.0 h1:olBuhgv9Sav4/9pkSLoxgiOsZDgM5VhRhvRpn3DL0lE=
14+
buf.build/go/interrupt v1.1.0/go.mod h1:ql56nXPG1oHlvZa6efNC7SKAQ/tUjS6z0mhJl0gyeRM=
1315
buf.build/go/protovalidate v0.12.0 h1:4GKJotbspQjRCcqZMGVSuC8SjwZ/FmgtSuKDpKUTZew=
1416
buf.build/go/protovalidate v0.12.0/go.mod h1:q3PFfbzI05LeqxSwq+begW2syjy2Z6hLxZSkP1OH/D0=
1517
buf.build/go/protoyaml v0.6.0 h1:Nzz1lvcXF8YgNZXk+voPPwdU8FjDPTUV4ndNTXN0n2w=

private/pkg/app/app.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import (
3434
"sort"
3535
"strconv"
3636

37-
"github.com/bufbuild/buf/private/pkg/interrupt"
37+
"buf.build/go/interrupt"
3838
)
3939

4040
// EnvContainer provides environment variables.

private/pkg/app/appcmd/appcmdtesting/appcmdtesting.go

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ import (
2727

2828
"github.com/bufbuild/buf/private/pkg/app"
2929
"github.com/bufbuild/buf/private/pkg/app/appcmd"
30-
"github.com/bufbuild/buf/private/pkg/slicesext"
31-
"github.com/bufbuild/buf/private/pkg/stringutil"
3230
"github.com/stretchr/testify/require"
3331
)
3432

@@ -117,16 +115,16 @@ func Run(
117115
if runOptions.expectedStdoutPresent {
118116
require.Equal(
119117
t,
120-
stringutil.TrimLines(runOptions.expectedStdout),
121-
stringutil.TrimLines(stdoutBuffer.String()),
118+
trimLines(runOptions.expectedStdout),
119+
trimLines(stdoutBuffer.String()),
122120
requireErrorMessage(runOptions.args, stdoutBuffer, stderrBuffer),
123121
)
124122
}
125123
if runOptions.expectedStderrPresent {
126124
require.Equal(
127125
t,
128-
stringutil.TrimLines(runOptions.expectedStderr),
129-
stringutil.TrimLines(stderrBuffer.String()),
126+
trimLines(runOptions.expectedStderr),
127+
trimLines(stderrBuffer.String()),
130128
requireErrorMessage(runOptions.args, stdoutBuffer, stderrBuffer),
131129
)
132130
}
@@ -245,23 +243,37 @@ func WithExpectedExitCodes(expectedExitCodes ...int) RunOption {
245243
// *** PRIVATE ***
246244

247245
func requireErrorMessage(args []string, stdout *bytes.Buffer, stderr *bytes.Buffer) string {
246+
quotedArgs := make([]string, len(args))
247+
for i, arg := range args {
248+
// To make the args copy-pastable.
249+
quotedArgs[i] = `'` + arg + `'`
250+
}
248251
return fmt.Sprintf(
249252
"args: %s\nstdout: %s\nstderr: %s",
250-
strings.Join(
251-
slicesext.Map(
252-
args,
253-
// To make the args copy-pastable.
254-
func(arg string) string {
255-
return `'` + arg + `'`
256-
},
257-
),
258-
" ",
259-
),
260-
stringutil.TrimLines(stdout.String()),
261-
stringutil.TrimLines(stderr.String()),
253+
strings.Join(quotedArgs, " "),
254+
trimLines(stdout.String()),
255+
trimLines(stderr.String()),
262256
)
263257
}
264258

259+
// trimLines splits the output into individual lines and trims the spaces from each line.
260+
//
261+
// This also trims the start and end spaces from the original output.
262+
func trimLines(output string) string {
263+
return strings.TrimSpace(strings.Join(splitTrimLines(output), "\n"))
264+
}
265+
266+
// splitTrimLines splits the output into individual lines and trims the spaces from each line.
267+
func splitTrimLines(output string) []string {
268+
// this should work for windows as well as \r will be trimmed
269+
split := strings.Split(output, "\n")
270+
lines := make([]string, len(split))
271+
for i, line := range split {
272+
lines[i] = strings.TrimSpace(line)
273+
}
274+
return lines
275+
}
276+
265277
type runOptions struct {
266278
newEnv func(use string) map[string]string
267279
stdin io.Reader

private/pkg/app/appext/appext.go

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package appext
1717

1818
import (
19+
"bytes"
1920
"context"
2021
"errors"
2122
"fmt"
@@ -26,8 +27,8 @@ import (
2627
"time"
2728

2829
"github.com/bufbuild/buf/private/pkg/app"
29-
"github.com/bufbuild/buf/private/pkg/encoding"
3030
"github.com/spf13/pflag"
31+
"gopkg.in/yaml.v3"
3132
)
3233

3334
const (
@@ -167,7 +168,7 @@ func ReadConfig(container NameContainer, value any) error {
167168
if err != nil {
168169
return fmt.Errorf("could not read %s configuration file at %s: %w", container.AppName(), configFilePath, err)
169170
}
170-
if err := encoding.UnmarshalYAMLStrict(data, value); err != nil {
171+
if err := unmarshalYAMLStrict(data, value); err != nil {
171172
return fmt.Errorf("invalid %s configuration file: %w", container.AppName(), err)
172173
}
173174
}
@@ -186,7 +187,7 @@ func ReadConfigNonStrict(container NameContainer, value any) error {
186187
if err != nil {
187188
return fmt.Errorf("could not read %s configuration file at %s: %w", container.AppName(), configFilePath, err)
188189
}
189-
if err := encoding.UnmarshalYAMLNonStrict(data, value); err != nil {
190+
if err := unmarshalYAMLNonStrict(data, value); err != nil {
190191
return fmt.Errorf("invalid %s configuration file: %w", container.AppName(), err)
191192
}
192193
}
@@ -210,7 +211,7 @@ func ReadSecret(container NameContainer, name string) (string, error) {
210211
// The directory is created if it does not exist.
211212
// The value should be a pointer to marshal.
212213
func WriteConfig(container NameContainer, value any) error {
213-
data, err := encoding.MarshalYAML(value)
214+
data, err := marshalYAML(value)
214215
if err != nil {
215216
return err
216217
}
@@ -239,3 +240,48 @@ func Listen(ctx context.Context, container NameContainer, defaultPort uint16) (n
239240
var listenConfig net.ListenConfig
240241
return listenConfig.Listen(ctx, "tcp", fmt.Sprintf("0.0.0.0:%d", port))
241242
}
243+
244+
// *** PRIVATE ***
245+
246+
// marshalYAML marshals the given value into YAML.
247+
func marshalYAML(v any) (_ []byte, retErr error) {
248+
buffer := bytes.NewBuffer(nil)
249+
yamlEncoder := yaml.NewEncoder(buffer)
250+
yamlEncoder.SetIndent(2)
251+
defer func() {
252+
retErr = errors.Join(retErr, yamlEncoder.Close())
253+
}()
254+
if err := yamlEncoder.Encode(v); err != nil {
255+
return nil, err
256+
}
257+
return buffer.Bytes(), nil
258+
}
259+
260+
// unmarshalYAMLStrict unmarshals the data as YAML, returning a user error on failure.
261+
//
262+
// If the data length is 0, this is a no-op.
263+
func unmarshalYAMLStrict(data []byte, v any) error {
264+
if len(data) == 0 {
265+
return nil
266+
}
267+
yamlDecoder := yaml.NewDecoder(bytes.NewReader(data))
268+
yamlDecoder.KnownFields(true)
269+
if err := yamlDecoder.Decode(v); err != nil {
270+
return fmt.Errorf("could not unmarshal as YAML: %v", err)
271+
}
272+
return nil
273+
}
274+
275+
// unmarshalYAMLNonStrict unmarshals the data as YAML, returning a user error on failure.
276+
//
277+
// If the data length is 0, this is a no-op.
278+
func unmarshalYAMLNonStrict(data []byte, v any) error {
279+
if len(data) == 0 {
280+
return nil
281+
}
282+
yamlDecoder := yaml.NewDecoder(bytes.NewReader(data))
283+
if err := yamlDecoder.Decode(v); err != nil {
284+
return fmt.Errorf("could not unmarshal as YAML: %v", err)
285+
}
286+
return nil
287+
}
Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,14 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
// Generated. DO NOT EDIT.
15+
package app
1616

17-
package interrupt
17+
import (
18+
"io"
19+
)
1820

19-
import _ "github.com/bufbuild/buf/private/usage"
21+
type discardReader struct{}
22+
23+
func (discardReader) Read([]byte) (int, error) {
24+
return 0, io.EOF
25+
}
Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,25 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
//go:build unix
16-
17-
package interrupt
15+
package app
1816

1917
import (
20-
"os"
21-
"syscall"
18+
"io"
19+
"sync"
2220
)
2321

24-
// Signals are all interrupt signals.
25-
//
26-
// As opposed to os.Interrupt, this adds syscall.SIGTERM for unix-like platforms. For
27-
// other platforms, this is just os.Interrupt
28-
var Signals = []os.Signal{os.Interrupt, syscall.SIGTERM}
22+
type lockedWriter struct {
23+
writer io.Writer
24+
lock sync.Mutex
25+
}
26+
27+
func newLockedWriter(writer io.Writer) *lockedWriter {
28+
return &lockedWriter{writer: writer}
29+
}
30+
31+
func (l *lockedWriter) Write(p []byte) (int, error) {
32+
l.lock.Lock()
33+
n, err := l.writer.Write(p)
34+
l.lock.Unlock()
35+
return n, err
36+
}

private/pkg/app/stderr_container.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ package app
1616

1717
import (
1818
"io"
19-
20-
"github.com/bufbuild/buf/private/pkg/ioext"
2119
)
2220

2321
type stderrContainer struct {
@@ -29,7 +27,7 @@ func newStderrContainer(writer io.Writer) *stderrContainer {
2927
writer = io.Discard
3028
}
3129
return &stderrContainer{
32-
writer: ioext.LockedWriter(writer),
30+
writer: newLockedWriter(writer),
3331
}
3432
}
3533

private/pkg/app/stdin_container.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ package app
1616

1717
import (
1818
"io"
19-
20-
"github.com/bufbuild/buf/private/pkg/ioext"
2119
)
2220

2321
type stdinContainer struct {
@@ -26,7 +24,7 @@ type stdinContainer struct {
2624

2725
func newStdinContainer(reader io.Reader) *stdinContainer {
2826
if reader == nil {
29-
reader = ioext.DiscardReader
27+
reader = discardReader{}
3028
}
3129
return &stdinContainer{
3230
reader: reader,

private/pkg/app/stdout_container.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ package app
1616

1717
import (
1818
"io"
19-
20-
"github.com/bufbuild/buf/private/pkg/ioext"
2119
)
2220

2321
type stdoutContainer struct {
@@ -29,7 +27,7 @@ func newStdoutContainer(writer io.Writer) *stdoutContainer {
2927
writer = io.Discard
3028
}
3129
return &stdoutContainer{
32-
writer: ioext.LockedWriter(writer),
30+
writer: newLockedWriter(writer),
3331
}
3432
}
3533

0 commit comments

Comments
 (0)