Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(buildtool): support go1.18+ #1483

Merged
merged 4 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions internal/logmodel/logmodel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Package logmodel contains the core log model.
//
// This package has been separated from the ./internal/model package
// so that ./internal/cmd/buildtool can support go1.18+.
//
// See https://github.com/ooni/probe/issues/2664 for context.
package logmodel

// DebugLogger is a logger emitting only debug messages.
type DebugLogger interface {
// Debug emits a debug message.
Debug(msg string)

// Debugf formats and emits a debug message.
Debugf(format string, v ...interface{})
}

// InfoLogger is a logger emitting debug and infor messages.
type InfoLogger interface {
// An InfoLogger is also a DebugLogger.
DebugLogger

// Info emits an informational message.
Info(msg string)

// Infof formats and emits an informational message.
Infof(format string, v ...interface{})
}

// Logger defines the common interface that a logger should have. It is
// out of the box compatible with `log.Log` in `apex/log`.
type Logger interface {
// A Logger is also an InfoLogger.
InfoLogger

// Warn emits a warning message.
Warn(msg string)

// Warnf formats and emits a warning message.
Warnf(format string, v ...interface{})
}
8 changes: 4 additions & 4 deletions internal/logx/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ import (
"sync"
"time"

"github.com/ooni/probe-cli/v3/internal/model"
"github.com/ooni/probe-cli/v3/internal/logmodel"
)

// NewOperationLogger creates a new logger that logs
// about an in-progress operation. If it takes too much
// time to emit the result of the operation, the code
// will emit an interim log message mentioning that the
// operation is currently in progress.
func NewOperationLogger(logger model.Logger, format string, v ...any) *OperationLogger {
func NewOperationLogger(logger logmodel.Logger, format string, v ...any) *OperationLogger {
return newOperationLogger(500*time.Millisecond, logger, format, v...)
}

func newOperationLogger(maxwait time.Duration, logger model.Logger, format string, v ...any) *OperationLogger {
func newOperationLogger(maxwait time.Duration, logger logmodel.Logger, format string, v ...any) *OperationLogger {
ol := &OperationLogger{
logger: logger,
maxwait: maxwait,
Expand All @@ -35,7 +35,7 @@ func newOperationLogger(maxwait time.Duration, logger model.Logger, format strin
// OperationLogger keeps state required to log about an in-progress
// operation as documented by [NewOperationLogger].
type OperationLogger struct {
logger model.Logger
logger logmodel.Logger
maxwait time.Duration
message string
once *sync.Once
Expand Down
6 changes: 3 additions & 3 deletions internal/logx/prefix.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package logx

import "github.com/ooni/probe-cli/v3/internal/model"
import "github.com/ooni/probe-cli/v3/internal/logmodel"

// PrefixLogger is a logger with a prefix.
type PrefixLogger struct {
Prefix string
Logger model.Logger
Logger logmodel.Logger
}

var _ model.Logger = &PrefixLogger{}
var _ logmodel.Logger = &PrefixLogger{}

// Debug implements DebugLogger.Debug
func (p *PrefixLogger) Debug(msg string) {
Expand Down
6 changes: 3 additions & 3 deletions internal/logx/scrubber.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ package logx
import (
"fmt"

"github.com/ooni/probe-cli/v3/internal/model"
"github.com/ooni/probe-cli/v3/internal/logmodel"
"github.com/ooni/probe-cli/v3/internal/scrubber"
)

// ScrubberLogger is a [model.Logger] with scrubbing. All messages are scrubbed including the ones
// ScrubberLogger is a [logmodel.Logger] with scrubbing. All messages are scrubbed including the ones
// that won't be emitted. As such, this logger is less efficient than a logger without scrubbing.
//
// The zero value is invalid; please init all MANDATORY fields.
type ScrubberLogger struct {
// Logger is the MANDATORY underlying logger to use.
Logger model.Logger
Logger logmodel.Logger
}

// Debug scrubs and emits a debug message.
Expand Down
32 changes: 5 additions & 27 deletions internal/model/logger.go
Original file line number Diff line number Diff line change
@@ -1,42 +1,20 @@
package model

import "github.com/ooni/probe-cli/v3/internal/logmodel"

//
// Logger
//

// DebugLogger is a logger emitting only debug messages.
type DebugLogger interface {
// Debug emits a debug message.
Debug(msg string)

// Debugf formats and emits a debug message.
Debugf(format string, v ...interface{})
}
type DebugLogger = logmodel.DebugLogger

// InfoLogger is a logger emitting debug and infor messages.
type InfoLogger interface {
// An InfoLogger is also a DebugLogger.
DebugLogger

// Info emits an informational message.
Info(msg string)

// Infof formats and emits an informational message.
Infof(format string, v ...interface{})
}
type InfoLogger = logmodel.InfoLogger

// Logger defines the common interface that a logger should have. It is
// out of the box compatible with `log.Log` in `apex/log`.
type Logger interface {
// A Logger is also an InfoLogger.
InfoLogger

// Warn emits a warning message.
Warn(msg string)

// Warnf formats and emits a warning message.
Warnf(format string, v ...interface{})
}
type Logger = logmodel.Logger

// DiscardLogger is the default logger that discards its input
var DiscardLogger Logger = logDiscarder{}
Expand Down
8 changes: 4 additions & 4 deletions internal/must/must.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"net/url"
"os"

"github.com/ooni/probe-cli/v3/internal/model"
"github.com/ooni/probe-cli/v3/internal/logmodel"
"github.com/ooni/probe-cli/v3/internal/runtimex"
"github.com/ooni/probe-cli/v3/internal/shellx"
)
Expand Down Expand Up @@ -108,7 +108,7 @@ func SplitHostPort(hostport string) (host string, port string) {
}

// Run is like [shellx.Run] but calls [runtimex.PanicOnError] on failure.
func Run(logger model.Logger, command string, args ...string) {
func Run(logger logmodel.Logger, command string, args ...string) {
err := shellx.Run(logger, command, args...)
runtimex.PanicOnError(err, "shellx.Run failed")
}
Expand All @@ -121,7 +121,7 @@ func RunQuiet(command string, args ...string) {

// RunCommandLine is like [shellx.RunCommandLine] but calls
// [runtimex.PanicOnError] on failure.
func RunCommandLine(logger model.Logger, cmdline string) {
func RunCommandLine(logger logmodel.Logger, cmdline string) {
err := shellx.RunCommandLine(logger, cmdline)
runtimex.PanicOnError(err, "shellx.RunCommandLine failed")
}
Expand Down Expand Up @@ -159,7 +159,7 @@ func FirstLineBytes(data []byte) []byte {

// RunOutput is like [shellx.Output] but calls
// [runtimex.PanicOnError] on failure.
func RunOutput(logger model.Logger, command string, args ...string) []byte {
func RunOutput(logger logmodel.Logger, command string, args ...string) []byte {
out, err := shellx.Output(logger, command, args...)
runtimex.PanicOnError(err, "shellx.Output failed")
return out
Expand Down
29 changes: 14 additions & 15 deletions internal/shellx/shellx.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@
package shellx

import (
"context"
"errors"
"fmt"
"io"
"io/fs"
"os"
"strings"

"github.com/google/shlex"
"github.com/ooni/probe-cli/v3/internal/fsx"
"github.com/ooni/probe-cli/v3/internal/model"
"github.com/ooni/probe-cli/v3/internal/netxlite"
"github.com/ooni/probe-cli/v3/internal/logmodel"
"golang.org/x/sys/execabs"
)

Expand Down Expand Up @@ -109,7 +108,7 @@ const (
// Config contains config for executing programs.
type Config struct {
// Logger is the OPTIONAL logger to use.
Logger model.Logger
Logger logmodel.Logger

// Flags contains OPTIONAL binary flags to configure the program.
Flags int64
Expand Down Expand Up @@ -155,7 +154,7 @@ func OutputEx(config *Config, argv *Argv, envp *Envp) ([]byte, error) {
}

// output is the common implementation of [Output] and [OutputQuiet].
func output(logger model.Logger, flags int64, command string, args ...string) ([]byte, error) {
func output(logger logmodel.Logger, flags int64, command string, args ...string) ([]byte, error) {
argv, err := NewArgv(command, args...)
if err != nil {
return nil, err
Expand All @@ -176,7 +175,7 @@ func OutputQuiet(command string, args ...string) ([]byte, error) {

// Output is like [OutputQuiet] except that it logs the command to be executed
// and the environment variables specific to this command.
func Output(logger model.Logger, command string, args ...string) ([]byte, error) {
func Output(logger logmodel.Logger, command string, args ...string) ([]byte, error) {
return output(logger, FlagShowStdoutStderr, command, args...)
}

Expand All @@ -191,7 +190,7 @@ func RunEx(config *Config, argv *Argv, envp *Envp) error {
}

// run is the common implementation of [Run] and [RunQuiet].
func run(logger model.Logger, flags int64, command string, args ...string) error {
func run(logger logmodel.Logger, flags int64, command string, args ...string) error {
argv, err := NewArgv(command, args...)
if err != nil {
return err
Expand All @@ -212,13 +211,13 @@ func RunQuiet(command string, args ...string) error {
// Run is like [RunQuiet] except that it also logs the command to
// exec, the environment variables specific to this command, the text
// logged to stdout and stderr.
func Run(logger model.Logger, command string, args ...string) error {
func Run(logger logmodel.Logger, command string, args ...string) error {
return run(logger, FlagShowStdoutStderr, command, args...)
}

// runCommandLine is the common implementation of
// [RunCommandLineQuiet] and [RunCommandLine].
func runCommandLine(logger model.Logger, flags int64, cmdline string) error {
func runCommandLine(logger logmodel.Logger, flags int64, cmdline string) error {
argv, err := ParseCommandLine(cmdline)
if err != nil {
return err
Expand All @@ -238,13 +237,13 @@ func RunCommandLineQuiet(cmdline string) error {

// RunCommandLine is like [RunCommandLineQuiet] but logs the command to
// execute as well as the command-specific environment variables.
func RunCommandLine(logger model.Logger, cmdline string) error {
func RunCommandLine(logger logmodel.Logger, cmdline string) error {
return runCommandLine(logger, FlagShowStdoutStderr, cmdline)
}

// outputCommandLine is the common implementation
// of [OutputCommandLineQuiet] and [OutputCommandLine].
func outputCommandLine(logger model.Logger, flags int64, cmdline string) ([]byte, error) {
func outputCommandLine(logger logmodel.Logger, flags int64, cmdline string) ([]byte, error) {
argv, err := ParseCommandLine(cmdline)
if err != nil {
return nil, err
Expand All @@ -264,7 +263,7 @@ func OutputCommandLineQuiet(cmdline string) ([]byte, error) {

// OutputCommandLine is like OutputCommandLineQuiet but logs the command to
// execute as well as the command-specific environment variables.
func OutputCommandLine(logger model.Logger, cmdline string) ([]byte, error) {
func OutputCommandLine(logger logmodel.Logger, cmdline string) ([]byte, error) {
return outputCommandLine(logger, FlagShowStdoutStderr, cmdline)
}

Expand Down Expand Up @@ -300,8 +299,8 @@ var fsxOpenFile = fsx.OpenFile
// osOpenFile is the generic function to open a file.
var osOpenFile = os.OpenFile

// netxliteCopyContext is the generic function to copy content.
var netxliteCopyContext = netxlite.CopyContext
// ioCopy is the generic function to copy content.
var ioCopy = io.Copy

// CopyFile copies [source] to [dest].
func CopyFile(source, dest string, perms fs.FileMode) error {
Expand All @@ -314,7 +313,7 @@ func CopyFile(source, dest string, perms fs.FileMode) error {
if err != nil {
return err
}
if _, err := netxliteCopyContext(context.Background(), destfp, sourcefp); err != nil {
if _, err := ioCopy(destfp, sourcefp); err != nil {
destfp.Close()
return err
}
Expand Down
6 changes: 2 additions & 4 deletions internal/shellx/shellx_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package shellx

import (
"context"
"errors"
"io"
"io/fs"
Expand All @@ -16,7 +15,6 @@ import (
"github.com/ooni/probe-cli/v3/internal/fsx"
"github.com/ooni/probe-cli/v3/internal/mocks"
"github.com/ooni/probe-cli/v3/internal/model"
"github.com/ooni/probe-cli/v3/internal/netxlite"
)

// testGolangExe is the golang exe to use in this test suite
Expand Down Expand Up @@ -479,11 +477,11 @@ func TestCopyFile(t *testing.T) {
dest := filepath.Join("testdata", "copy.txt")
defer os.Remove(dest)
expected := errors.New("mocked error")
netxliteCopyContext = func(ctx context.Context, dst io.Writer, src io.Reader) (int64, error) {
ioCopy = func(dst io.Writer, src io.Reader) (int64, error) {
return 0, expected
}
defer func() {
netxliteCopyContext = netxlite.CopyContext
ioCopy = io.Copy
}()
if err := CopyFile(source, dest, 0600); !errors.Is(err, expected) {
t.Fatal("unexpected error", err)
Expand Down
14 changes: 14 additions & 0 deletions script/nocopyreadall.bash
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,20 @@ for file in $(find . -type f -name \*.go); do
continue
fi

if [ "$file" = "./internal/shellx/shellx.go" ]; then
# We're allowed to use ReadAll and Copy in this file to
# avoid depending on netxlite, given that netxlite's does
# not compile with go1.18 due to the quic dependency.
continue
fi

if [ "$file" = "./internal/shellx/shellx_test.go" ]; then
# We're allowed to use ReadAll and Copy in this file to
# avoid depending on netxlite, given that netxlite's does
# not compile with go1.18 due to the quic dependency.
continue
fi

if [ "$file" = "./internal/testingsocks5/request.go" ]; then
# We're allowed to use ReadAll and Copy in this file because
# it's code that we only use for testing purposes.
Expand Down
Loading