diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 142c49313..c782715c4 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -45,14 +45,17 @@ jobs: vet: runs-on: ubuntu-latest steps: + - name: Check out code + uses: actions/checkout@v3 + - name: Set up Go uses: actions/setup-go@v3 with: - go-version: 1.19 - - name: Check out code - uses: actions/checkout@v3 + go-version-file: go.mod + - name: Run go vet run: go vet ./... + - uses: k0kubun/action-slack@v2.0.0 with: payload: | @@ -79,13 +82,14 @@ jobs: goarch: 386 steps: + - name: Check out code + uses: actions/checkout@v3 + - name: Set up Go uses: actions/setup-go@v3 with: - go-version: 1.19 + go-version-file: go.mod - - name: Check out code - uses: actions/checkout@v3 - name: Install staticcheck run: "GOBIN=~/.local/bin go install honnef.co/go/tools/cmd/staticcheck" diff --git a/Dockerfile b/Dockerfile index 4d990737b..9c6b2bd6d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,7 +31,7 @@ # $ docker exec tailscaled tailscale status -FROM golang:1.19-alpine AS build-env +FROM golang:1.20-alpine AS build-env WORKDIR /go/src/tailscale diff --git a/Makefile b/Makefile index 6453f1916..9a6bf51ac 100644 --- a/Makefile +++ b/Makefile @@ -12,13 +12,17 @@ tidy: ./tool/go mod tidy updatedeps: - ./tool/go run github.com/tailscale/depaware --update \ + # depaware (via x/tools/go/packages) shells back to "go", so make sure the "go" + # it finds in its $$PATH is the right one. + PATH="$$(./tool/go env GOROOT)/bin:$$PATH" ./tool/go run github.com/tailscale/depaware --update \ tailscale.com/cmd/tailscaled \ tailscale.com/cmd/tailscale \ tailscale.com/cmd/derper depaware: - ./tool/go run github.com/tailscale/depaware --check \ + # depaware (via x/tools/go/packages) shells back to "go", so make sure the "go" + # it finds in its $$PATH is the right one. + PATH="$$(./tool/go env GOROOT)/bin:$$PATH" ./tool/go run github.com/tailscale/depaware --check \ tailscale.com/cmd/tailscaled \ tailscale.com/cmd/tailscale \ tailscale.com/cmd/derper diff --git a/README.md b/README.md index f29c246e3..a76a0c326 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ not open source. ## Building -We always require the latest Go release, currently Go 1.19. (While we build +We always require the latest Go release, currently Go 1.20. (While we build releases with our [Go fork](https://github.com/tailscale/go/), its use is not required.) diff --git a/client/tailscale/required_version.go b/client/tailscale/required_version.go index 21a539e23..4b44bf270 100644 --- a/client/tailscale/required_version.go +++ b/client/tailscale/required_version.go @@ -1,10 +1,10 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build !go1.19 +//go:build !go1.20 package tailscale func init() { - you_need_Go_1_19_to_compile_Tailscale() + you_need_Go_1_20_to_compile_Tailscale() } diff --git a/cmd/derper/depaware.txt b/cmd/derper/depaware.txt index 13848d5b6..c4a3803c6 100644 --- a/cmd/derper/depaware.txt +++ b/cmd/derper/depaware.txt @@ -82,7 +82,6 @@ tailscale.com/cmd/derper dependencies: (generated by github.com/tailscale/depawa tailscale.com/util/lineread from tailscale.com/hostinfo+ tailscale.com/util/mak from tailscale.com/syncs tailscale.com/util/singleflight from tailscale.com/net/dnscache - tailscale.com/util/strs from tailscale.com/hostinfo+ tailscale.com/util/vizerror from tailscale.com/tsweb W 💣 tailscale.com/util/winutil from tailscale.com/hostinfo+ tailscale.com/version from tailscale.com/derp+ @@ -97,7 +96,7 @@ tailscale.com/cmd/derper dependencies: (generated by github.com/tailscale/depawa golang.org/x/crypto/chacha20poly1305 from crypto/tls golang.org/x/crypto/cryptobyte from crypto/ecdsa+ golang.org/x/crypto/cryptobyte/asn1 from crypto/ecdsa+ - golang.org/x/crypto/curve25519 from crypto/tls+ + golang.org/x/crypto/curve25519 from golang.org/x/crypto/nacl/box+ golang.org/x/crypto/hkdf from crypto/tls golang.org/x/crypto/nacl/box from tailscale.com/types/key golang.org/x/crypto/nacl/secretbox from golang.org/x/crypto/nacl/box @@ -135,6 +134,7 @@ tailscale.com/cmd/derper dependencies: (generated by github.com/tailscale/depawa crypto/cipher from crypto/aes+ crypto/des from crypto/tls+ crypto/dsa from crypto/x509 + crypto/ecdh from crypto/ecdsa+ crypto/ecdsa from crypto/tls+ crypto/ed25519 from crypto/tls+ crypto/elliptic from crypto/ecdsa+ diff --git a/cmd/derper/mesh.go b/cmd/derper/mesh.go index 8744f1055..5356fbaf4 100644 --- a/cmd/derper/mesh.go +++ b/cmd/derper/mesh.go @@ -16,7 +16,6 @@ import ( "tailscale.com/derp/derphttp" "tailscale.com/types/key" "tailscale.com/types/logger" - "tailscale.com/util/strs" ) func startMesh(s *derp.Server) error { @@ -50,7 +49,7 @@ func startMeshWithHost(s *derp.Server, host string) error { } var d net.Dialer var r net.Resolver - if base, ok := strs.CutSuffix(host, ".tailscale.com"); ok && port == "443" { + if base, ok := strings.CutSuffix(host, ".tailscale.com"); ok && port == "443" { subCtx, cancel := context.WithTimeout(ctx, 2*time.Second) defer cancel() vpcHost := base + "-vpc.tailscale.com" diff --git a/cmd/tailscale/cli/debug.go b/cmd/tailscale/cli/debug.go index 5f8aac444..cd2b265a4 100644 --- a/cmd/tailscale/cli/debug.go +++ b/cmd/tailscale/cli/debug.go @@ -39,7 +39,6 @@ import ( "tailscale.com/types/key" "tailscale.com/types/logger" "tailscale.com/util/must" - "tailscale.com/util/strs" ) var debugCmd = &ffcli.Command{ @@ -259,7 +258,7 @@ func runDebug(ctx context.Context, args []string) error { e.Encode(wfs) return nil } - if name, ok := strs.CutPrefix(debugArgs.file, "delete:"); ok { + if name, ok := strings.CutPrefix(debugArgs.file, "delete:"); ok { return localClient.DeleteWaitingFile(ctx, name) } rc, size, err := localClient.GetWaitingFile(ctx, debugArgs.file) diff --git a/cmd/tailscale/cli/file.go b/cmd/tailscale/cli/file.go index fc1581553..e583a977f 100644 --- a/cmd/tailscale/cli/file.go +++ b/cmd/tailscale/cli/file.go @@ -31,7 +31,6 @@ import ( "tailscale.com/net/tsaddr" "tailscale.com/tailcfg" "tailscale.com/util/quarantine" - "tailscale.com/util/strs" "tailscale.com/version" ) @@ -90,7 +89,7 @@ func runCp(ctx context.Context, args []string) error { return errors.New("usage: tailscale file cp :") } files, target := args[:len(args)-1], args[len(args)-1] - target, ok := strs.CutSuffix(target, ":") + target, ok := strings.CutSuffix(target, ":") if !ok { return fmt.Errorf("final argument to 'tailscale file cp' must end in colon") } diff --git a/cmd/tailscale/cli/up.go b/cmd/tailscale/cli/up.go index 0cbd80e8e..bd1d04c81 100644 --- a/cmd/tailscale/cli/up.go +++ b/cmd/tailscale/cli/up.go @@ -34,7 +34,6 @@ import ( "tailscale.com/tailcfg" "tailscale.com/types/logger" "tailscale.com/types/preftype" - "tailscale.com/util/strs" "tailscale.com/version" "tailscale.com/version/distro" ) @@ -174,7 +173,7 @@ type upArgsT struct { func (a upArgsT) getAuthKey() (string, error) { v := a.authKeyOrFile - if file, ok := strs.CutPrefix(v, "file:"); ok { + if file, ok := strings.CutPrefix(v, "file:"); ok { b, err := os.ReadFile(file) if err != nil { return "", err diff --git a/cmd/tailscale/depaware.txt b/cmd/tailscale/depaware.txt index 967b4b279..65b161f5c 100644 --- a/cmd/tailscale/depaware.txt +++ b/cmd/tailscale/depaware.txt @@ -115,7 +115,6 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep tailscale.com/util/must from tailscale.com/cmd/tailscale/cli tailscale.com/util/quarantine from tailscale.com/cmd/tailscale/cli tailscale.com/util/singleflight from tailscale.com/net/dnscache - tailscale.com/util/strs from tailscale.com/hostinfo+ 💣 tailscale.com/util/winutil from tailscale.com/hostinfo+ tailscale.com/version from tailscale.com/cmd/tailscale/cli+ tailscale.com/version/distro from tailscale.com/cmd/tailscale/cli+ @@ -127,7 +126,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep golang.org/x/crypto/chacha20poly1305 from crypto/tls+ golang.org/x/crypto/cryptobyte from crypto/ecdsa+ golang.org/x/crypto/cryptobyte/asn1 from crypto/ecdsa+ - golang.org/x/crypto/curve25519 from crypto/tls+ + golang.org/x/crypto/curve25519 from golang.org/x/crypto/nacl/box+ golang.org/x/crypto/hkdf from crypto/tls+ golang.org/x/crypto/nacl/box from tailscale.com/types/key golang.org/x/crypto/nacl/secretbox from golang.org/x/crypto/nacl/box @@ -170,6 +169,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep crypto/cipher from crypto/aes+ crypto/des from crypto/tls+ crypto/dsa from crypto/x509 + crypto/ecdh from crypto/ecdsa+ crypto/ecdsa from crypto/tls+ crypto/ed25519 from crypto/tls+ crypto/elliptic from crypto/ecdsa+ diff --git a/cmd/tailscaled/depaware.txt b/cmd/tailscaled/depaware.txt index 6555b544d..63ddd94ab 100644 --- a/cmd/tailscaled/depaware.txt +++ b/cmd/tailscaled/depaware.txt @@ -302,7 +302,6 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de tailscale.com/util/racebuild from tailscale.com/logpolicy tailscale.com/util/set from tailscale.com/health+ tailscale.com/util/singleflight from tailscale.com/control/controlclient+ - tailscale.com/util/strs from tailscale.com/hostinfo+ tailscale.com/util/systemd from tailscale.com/control/controlclient+ tailscale.com/util/uniq from tailscale.com/wgengine/magicsock+ tailscale.com/util/vizerror from tailscale.com/tsweb @@ -331,7 +330,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de golang.org/x/crypto/chacha20poly1305 from crypto/tls+ golang.org/x/crypto/cryptobyte from crypto/ecdsa+ golang.org/x/crypto/cryptobyte/asn1 from crypto/ecdsa+ - golang.org/x/crypto/curve25519 from crypto/tls+ + golang.org/x/crypto/curve25519 from github.com/tailscale/golang-x-crypto/ssh+ LD golang.org/x/crypto/ed25519 from golang.org/x/crypto/ssh+ golang.org/x/crypto/hkdf from crypto/tls+ golang.org/x/crypto/nacl/box from tailscale.com/types/key @@ -381,6 +380,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de crypto/cipher from crypto/aes+ crypto/des from crypto/tls+ crypto/dsa from crypto/x509+ + crypto/ecdh from crypto/ecdsa+ crypto/ecdsa from crypto/tls+ crypto/ed25519 from crypto/tls+ crypto/elliptic from crypto/ecdsa+ diff --git a/cmd/tailscaled/required_version.go b/cmd/tailscaled/required_version.go index 17be5ab8b..06995475d 100644 --- a/cmd/tailscaled/required_version.go +++ b/cmd/tailscaled/required_version.go @@ -1,10 +1,10 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build !go1.19 +//go:build !go1.20 package main func init() { - you_need_Go_1_19_to_compile_Tailscale() + you_need_Go_1_20_to_compile_Tailscale() } diff --git a/derp/derphttp/derphttp_client.go b/derp/derphttp/derphttp_client.go index e02fd62c0..4a1427c4c 100644 --- a/derp/derphttp/derphttp_client.go +++ b/derp/derphttp/derphttp_client.go @@ -23,6 +23,7 @@ import ( "net/netip" "net/url" "runtime" + "strings" "sync" "time" @@ -37,7 +38,6 @@ import ( "tailscale.com/tailcfg" "tailscale.com/types/key" "tailscale.com/types/logger" - "tailscale.com/util/strs" ) // Client is a DERP-over-HTTP client. @@ -1028,7 +1028,7 @@ var ErrClientClosed = errors.New("derphttp.Client closed") func parseMetaCert(certs []*x509.Certificate) (serverPub key.NodePublic, serverProtoVersion int) { for _, cert := range certs { // Look for derpkey prefix added by initMetacert() on the server side. - if pubHex, ok := strs.CutPrefix(cert.Subject.CommonName, "derpkey"); ok { + if pubHex, ok := strings.CutPrefix(cert.Subject.CommonName, "derpkey"); ok { var err error serverPub, err = key.ParseNodePublicUntyped(mem.S(pubHex)) if err == nil && cert.SerialNumber.BitLen() <= 8 { // supports up to version 255 diff --git a/disco/disco_test.go b/disco/disco_test.go index f8ebed7fa..67bd1561a 100644 --- a/disco/disco_test.go +++ b/disco/disco_test.go @@ -7,11 +7,11 @@ import ( "fmt" "net/netip" "reflect" + "strings" "testing" "go4.org/mem" "tailscale.com/types/key" - "tailscale.com/util/strs" ) func TestMarshalAndParse(t *testing.T) { @@ -71,7 +71,7 @@ func TestMarshalAndParse(t *testing.T) { t.Run(tt.name, func(t *testing.T) { foo := []byte("foo") got := string(tt.m.AppendMarshal(foo)) - got, ok := strs.CutPrefix(got, "foo") + got, ok := strings.CutPrefix(got, "foo") if !ok { t.Fatalf("didn't start with foo: got %q", got) } diff --git a/go.mod b/go.mod index eb35ed50c..51cf341de 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module tailscale.com -go 1.19 +go 1.20 require ( filippo.io/mkcert v1.4.3 @@ -77,11 +77,11 @@ require ( golang.org/x/sys v0.4.0 golang.org/x/term v0.4.0 golang.org/x/time v0.0.0-20220609170525-579cf78fd858 - golang.org/x/tools v0.2.0 + golang.org/x/tools v0.4.1-0.20221208213631-3f74d914ae6d golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 golang.zx2c4.com/wireguard/windows v0.5.3 gvisor.dev/gvisor v0.0.0-20221203005347-703fd9b7fbc0 - honnef.co/go/tools v0.4.0-0.dev.0.20220517111757-f4a2f64ce238 + honnef.co/go/tools v0.4.0-0.dev.0.20230130122044-c30b15588105 inet.af/peercred v0.0.0-20210906144145-0893ea02156a inet.af/wf v0.0.0-20220728202103-50d96caab2f6 k8s.io/api v0.25.0 @@ -300,9 +300,9 @@ require ( github.com/yeya24/promlinter v0.1.0 // indirect go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect - golang.org/x/exp/typeparams v0.0.0-20220328175248-053ad81199eb // indirect + golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a // indirect golang.org/x/image v0.0.0-20201208152932-35266b937fa6 // indirect - golang.org/x/mod v0.6.0 // indirect + golang.org/x/mod v0.7.0 // indirect golang.org/x/text v0.6.0 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index 0077ac290..9b9d1a44b 100644 --- a/go.sum +++ b/go.sum @@ -1348,8 +1348,8 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o= golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -golang.org/x/exp/typeparams v0.0.0-20220328175248-053ad81199eb h1:fP6C8Xutcp5AlakmT/SkQot0pMicROAsEX7OfNPuG10= -golang.org/x/exp/typeparams v0.0.0-20220328175248-053ad81199eb/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a h1:Jw5wfR+h9mnIYH+OtGT2im5wV1YGGDora5vTv/aa5bE= +golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20201208152932-35266b937fa6 h1:nfeHNc1nAqecKCy2FCy4HY+soOOe5sDLJ/gZLbx6GYI= @@ -1379,8 +1379,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= -golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1719,8 +1719,8 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/tools v0.1.8-0.20211102182255-bb4add04ddef/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= -golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.4.1-0.20221208213631-3f74d914ae6d h1:9ZNWAi4CYhNv60mXGgAncgq7SGc5qa7C8VZV8Tg7Ggs= +golang.org/x/tools v0.4.1-0.20221208213631-3f74d914ae6d/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1926,8 +1926,8 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.6/go.mod h1:pyyisuGw24ruLjrr1ddx39WE0y9OooInRzEYLhQB2YY= honnef.co/go/tools v0.2.1/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= -honnef.co/go/tools v0.4.0-0.dev.0.20220517111757-f4a2f64ce238 h1:8Vr1KP9OTjoKQSSeLefzibQgDV4s2ujJElKHqMi7nsA= -honnef.co/go/tools v0.4.0-0.dev.0.20220517111757-f4a2f64ce238/go.mod h1:DCQzo6aCmhYDJH+We7BIU38vNvVkaOKa6s57pewKdvI= +honnef.co/go/tools v0.4.0-0.dev.0.20230130122044-c30b15588105 h1:2OzOQ+1scFmv2dt7x+wNxgikA/Rn2qKrvc/CJCVuAJM= +honnef.co/go/tools v0.4.0-0.dev.0.20230130122044-c30b15588105/go.mod h1:36ZgoUOrqOk1GxwHhyryEkq8FQWkUO2xGuSMhUCcdvA= howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= diff --git a/hostinfo/hostinfo_linux.go b/hostinfo/hostinfo_linux.go index 8d647872c..6c2ab8ff8 100644 --- a/hostinfo/hostinfo_linux.go +++ b/hostinfo/hostinfo_linux.go @@ -13,7 +13,6 @@ import ( "golang.org/x/sys/unix" "tailscale.com/types/ptr" "tailscale.com/util/lineread" - "tailscale.com/util/strs" "tailscale.com/version/distro" ) @@ -73,7 +72,7 @@ func linuxDeviceModel() string { func getQnapQtsVersion(versionInfo string) string { for _, field := range strings.Fields(versionInfo) { - if suffix, ok := strs.CutPrefix(field, "QTSFW_"); ok { + if suffix, ok := strings.CutPrefix(field, "QTSFW_"); ok { return suffix } } diff --git a/ipn/ipnlocal/peerapi.go b/ipn/ipnlocal/peerapi.go index adbba0eda..a699b8f02 100644 --- a/ipn/ipnlocal/peerapi.go +++ b/ipn/ipnlocal/peerapi.go @@ -48,7 +48,6 @@ import ( "tailscale.com/tailcfg" "tailscale.com/util/clientmetric" "tailscale.com/util/multierr" - "tailscale.com/util/strs" "tailscale.com/wgengine" "tailscale.com/wgengine/filter" ) @@ -164,7 +163,7 @@ func (s *peerAPIServer) hasFilesWaiting() bool { if strings.HasSuffix(name, partialSuffix) { continue } - if name, ok := strs.CutSuffix(name, deletedSuffix); ok { // for Windows + tests + if name, ok := strings.CutSuffix(name, deletedSuffix); ok { // for Windows + tests // After we're done looping over files, then try // to delete this file. Don't do it proactively, // as the OS may return "foo.jpg.deleted" before "foo.jpg" @@ -223,7 +222,7 @@ func (s *peerAPIServer) WaitingFiles() (ret []apitype.WaitingFile, err error) { if strings.HasSuffix(name, partialSuffix) { continue } - if name, ok := strs.CutSuffix(name, deletedSuffix); ok { // for Windows + tests + if name, ok := strings.CutSuffix(name, deletedSuffix); ok { // for Windows + tests if deleted == nil { deleted = map[string]bool{} } @@ -946,7 +945,7 @@ func (h *peerAPIHandler) handlePeerPut(w http.ResponseWriter, r *http.Request) { return } rawPath := r.URL.EscapedPath() - suffix, ok := strs.CutPrefix(rawPath, "/v0/put/") + suffix, ok := strings.CutPrefix(rawPath, "/v0/put/") if !ok { http.Error(w, "misconfigured internals", 500) return diff --git a/ipn/ipnlocal/profiles.go b/ipn/ipnlocal/profiles.go index 55df0b60d..904ab7a4a 100644 --- a/ipn/ipnlocal/profiles.go +++ b/ipn/ipnlocal/profiles.go @@ -10,6 +10,7 @@ import ( "math/rand" "net/netip" "runtime" + "strings" "time" "golang.org/x/exp/slices" @@ -18,7 +19,6 @@ import ( "tailscale.com/tailcfg" "tailscale.com/types/logger" "tailscale.com/util/clientmetric" - "tailscale.com/util/strs" "tailscale.com/util/winutil" "tailscale.com/version" ) @@ -520,7 +520,7 @@ func newProfileManagerWithGOOS(store ipn.StateStore, logf logger.Logf, goos stri } } if pm.currentProfile == nil { - if suf, ok := strs.CutPrefix(string(stateKey), "user-"); ok { + if suf, ok := strings.CutPrefix(string(stateKey), "user-"); ok { pm.currentUserID = ipn.WindowsUserID(suf) } pm.NewProfile() diff --git a/ipn/ipnlocal/serve.go b/ipn/ipnlocal/serve.go index 6e12c4b0f..faf63c22e 100644 --- a/ipn/ipnlocal/serve.go +++ b/ipn/ipnlocal/serve.go @@ -31,7 +31,6 @@ import ( "tailscale.com/tailcfg" "tailscale.com/types/logger" "tailscale.com/util/mak" - "tailscale.com/util/strs" "tailscale.com/version" ) @@ -552,7 +551,7 @@ func expandProxyArg(s string) (targetURL string, insecureSkipVerify bool) { if strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://") { return s, false } - if rest, ok := strs.CutPrefix(s, "https+insecure://"); ok { + if rest, ok := strings.CutPrefix(s, "https+insecure://"); ok { return "https://" + rest, true } if allNumeric(s) { diff --git a/ipn/localapi/cert.go b/ipn/localapi/cert.go index 06dd46baa..447c3bc3c 100644 --- a/ipn/localapi/cert.go +++ b/ipn/localapi/cert.go @@ -8,9 +8,9 @@ package localapi import ( "fmt" "net/http" + "strings" "tailscale.com/ipn/ipnlocal" - "tailscale.com/util/strs" ) func (h *Handler) serveCert(w http.ResponseWriter, r *http.Request) { @@ -18,7 +18,7 @@ func (h *Handler) serveCert(w http.ResponseWriter, r *http.Request) { http.Error(w, "cert access denied", http.StatusForbidden) return } - domain, ok := strs.CutPrefix(r.URL.Path, "/localapi/v0/cert/") + domain, ok := strings.CutPrefix(r.URL.Path, "/localapi/v0/cert/") if !ok { http.Error(w, "internal handler config wired wrong", 500) return diff --git a/ipn/localapi/localapi.go b/ipn/localapi/localapi.go index e651ab060..8689d5023 100644 --- a/ipn/localapi/localapi.go +++ b/ipn/localapi/localapi.go @@ -43,7 +43,6 @@ import ( "tailscale.com/util/clientmetric" "tailscale.com/util/httpm" "tailscale.com/util/mak" - "tailscale.com/util/strs" "tailscale.com/version" ) @@ -213,7 +212,7 @@ func handlerForPath(urlPath string) (h localAPIHandler, ok bool) { if urlPath == "/" { return (*Handler).serveLocalAPIRoot, true } - suff, ok := strs.CutPrefix(urlPath, "/localapi/v0/") + suff, ok := strings.CutPrefix(urlPath, "/localapi/v0/") if !ok { // Currently all LocalAPI methods start with "/localapi/v0/" to signal // to people that they're not necessarily stable APIs. In practice we'll @@ -886,7 +885,7 @@ func (h *Handler) serveFiles(w http.ResponseWriter, r *http.Request) { http.Error(w, "file access denied", http.StatusForbidden) return } - suffix, ok := strs.CutPrefix(r.URL.EscapedPath(), "/localapi/v0/files/") + suffix, ok := strings.CutPrefix(r.URL.EscapedPath(), "/localapi/v0/files/") if !ok { http.Error(w, "misconfigured", http.StatusInternalServerError) return @@ -1008,7 +1007,7 @@ func (h *Handler) serveFilePut(w http.ResponseWriter, r *http.Request) { return } - upath, ok := strs.CutPrefix(r.URL.EscapedPath(), "/localapi/v0/file-put/") + upath, ok := strings.CutPrefix(r.URL.EscapedPath(), "/localapi/v0/file-put/") if !ok { http.Error(w, "misconfigured", http.StatusInternalServerError) return @@ -1448,7 +1447,7 @@ func (h *Handler) serveProfiles(w http.ResponseWriter, r *http.Request) { http.Error(w, "profiles access denied", http.StatusForbidden) return } - suffix, ok := strs.CutPrefix(r.URL.EscapedPath(), "/localapi/v0/profiles/") + suffix, ok := strings.CutPrefix(r.URL.EscapedPath(), "/localapi/v0/profiles/") if !ok { http.Error(w, "misconfigured", http.StatusInternalServerError) return diff --git a/net/dns/publicdns/publicdns.go b/net/dns/publicdns/publicdns.go index f089bcbc4..806dea431 100644 --- a/net/dns/publicdns/publicdns.go +++ b/net/dns/publicdns/publicdns.go @@ -13,8 +13,6 @@ import ( "sort" "strings" "sync" - - "tailscale.com/util/strs" ) // dohOfIP maps from public DNS IPs to their DoH base URL. @@ -82,7 +80,7 @@ func DoHIPsOfBase(dohBase string) []netip.Addr { if s := dohIPsOfBase[dohBase]; len(s) > 0 { return s } - if hexStr, ok := strs.CutPrefix(dohBase, "https://dns.nextdns.io/"); ok { + if hexStr, ok := strings.CutPrefix(dohBase, "https://dns.nextdns.io/"); ok { // The path is of the form /[///...] // or /? // but only the is required. Ignore the rest: diff --git a/net/dns/resolvconffile/resolvconffile.go b/net/dns/resolvconffile/resolvconffile.go index 914a5eb72..753000f6d 100644 --- a/net/dns/resolvconffile/resolvconffile.go +++ b/net/dns/resolvconffile/resolvconffile.go @@ -20,7 +20,6 @@ import ( "strings" "tailscale.com/util/dnsname" - "tailscale.com/util/strs" ) // Path is the canonical location of resolv.conf. @@ -69,7 +68,7 @@ func Parse(r io.Reader) (*Config, error) { line, _, _ = strings.Cut(line, "#") // remove any comments line = strings.TrimSpace(line) - if s, ok := strs.CutPrefix(line, "nameserver"); ok { + if s, ok := strings.CutPrefix(line, "nameserver"); ok { nameserver := strings.TrimSpace(s) if len(nameserver) == len(s) { return nil, fmt.Errorf("missing space after \"nameserver\" in %q", line) @@ -82,7 +81,7 @@ func Parse(r io.Reader) (*Config, error) { continue } - if s, ok := strs.CutPrefix(line, "search"); ok { + if s, ok := strings.CutPrefix(line, "search"); ok { domains := strings.TrimSpace(s) if len(domains) == len(s) { // No leading space?! diff --git a/net/dns/resolver/tsdns.go b/net/dns/resolver/tsdns.go index 1baa7c522..2da72fa0c 100644 --- a/net/dns/resolver/tsdns.go +++ b/net/dns/resolver/tsdns.go @@ -33,7 +33,6 @@ import ( "tailscale.com/util/clientmetric" "tailscale.com/util/cloudenv" "tailscale.com/util/dnsname" - "tailscale.com/util/strs" "tailscale.com/wgengine/monitor" ) @@ -1215,7 +1214,7 @@ func (r *Resolver) respond(query []byte) ([]byte, error) { // unARPA maps from "4.4.8.8.in-addr.arpa." to "8.8.4.4", etc. func unARPA(a string) (ipStr string, ok bool) { const suf4 = ".in-addr.arpa." - if s, ok := strs.CutSuffix(a, suf4); ok { + if s, ok := strings.CutSuffix(a, suf4); ok { // Parse and reverse octets. ip, err := netip.ParseAddr(s) if err != nil || !ip.Is4() { diff --git a/net/netcheck/netcheck_test.go b/net/netcheck/netcheck_test.go index ab22040ce..31f50ab6b 100644 --- a/net/netcheck/netcheck_test.go +++ b/net/netcheck/netcheck_test.go @@ -22,7 +22,6 @@ import ( "tailscale.com/net/stun" "tailscale.com/net/stun/stuntest" "tailscale.com/tailcfg" - "tailscale.com/util/strs" ) func TestHairpinSTUN(t *testing.T) { @@ -621,7 +620,7 @@ func TestLogConciseReport(t *testing.T) { var buf bytes.Buffer c := &Client{Logf: func(f string, a ...any) { fmt.Fprintf(&buf, f, a...) }} c.logConciseReport(tt.r, dm) - if got, ok := strs.CutPrefix(buf.String(), "[v1] report: "); !ok { + if got, ok := strings.CutPrefix(buf.String(), "[v1] report: "); !ok { t.Errorf("unexpected result.\n got: %#q\nwant: %#q\n", got, tt.want) } }) diff --git a/ssh/tailssh/incubator.go b/ssh/tailssh/incubator.go index a21c23d30..85c0c0ed6 100644 --- a/ssh/tailssh/incubator.go +++ b/ssh/tailssh/incubator.go @@ -41,7 +41,6 @@ import ( "tailscale.com/tempfork/gliderlabs/ssh" "tailscale.com/types/logger" "tailscale.com/util/lineread" - "tailscale.com/util/strs" "tailscale.com/version/distro" ) @@ -653,7 +652,7 @@ func pathFromPAMEnvLine(line []byte, u *user.User) (path string) { return "" } rest := strings.TrimSpace(strings.TrimPrefix(string(line), "PATH")) - if quoted, ok := strs.CutPrefix(rest, "DEFAULT="); ok { + if quoted, ok := strings.CutPrefix(rest, "DEFAULT="); ok { if path, err := strconv.Unquote(quoted); err == nil { return expandDefaultPathTmpl(path, u) } diff --git a/ssh/tailssh/tailssh_test.go b/ssh/tailssh/tailssh_test.go index 9cb8a4148..bdd237376 100644 --- a/ssh/tailssh/tailssh_test.go +++ b/ssh/tailssh/tailssh_test.go @@ -42,7 +42,6 @@ import ( "tailscale.com/util/cibuild" "tailscale.com/util/lineread" "tailscale.com/util/must" - "tailscale.com/util/strs" "tailscale.com/version/distro" "tailscale.com/wgengine" ) @@ -286,7 +285,7 @@ func (ts *localState) WhoIs(ipp netip.AddrPort) (n *tailcfg.Node, u tailcfg.User func (ts *localState) DoNoiseRequest(req *http.Request) (*http.Response, error) { rec := httptest.NewRecorder() - k, ok := strs.CutPrefix(req.URL.Path, "/ssh-action/") + k, ok := strings.CutPrefix(req.URL.Path, "/ssh-action/") if !ok { rec.WriteHeader(http.StatusNotFound) } diff --git a/tsweb/tsweb.go b/tsweb/tsweb.go index 23034ec6f..a5fbb99e2 100644 --- a/tsweb/tsweb.go +++ b/tsweb/tsweb.go @@ -31,7 +31,6 @@ import ( "tailscale.com/metrics" "tailscale.com/net/tsaddr" "tailscale.com/types/logger" - "tailscale.com/util/strs" "tailscale.com/util/vizerror" "tailscale.com/version" ) @@ -753,7 +752,7 @@ func structTypeSortedFields(t reflect.Type) []sortedStructField { // removed. func removeTypePrefixes(s string) string { for _, prefix := range prefixesToTrim { - if trimmed, ok := strs.CutPrefix(s, prefix); ok { + if trimmed, ok := strings.CutPrefix(s, prefix); ok { return trimmed } } diff --git a/util/deephash/deephash_test.go b/util/deephash/deephash_test.go index df70bcd44..159cc2a5c 100644 --- a/util/deephash/deephash_test.go +++ b/util/deephash/deephash_test.go @@ -1001,11 +1001,11 @@ func FuzzTime(f *testing.F) { ) { t1 := time.Unix(s1, ns1) if loc1 { - t1.In(time.FixedZone(name1, off1)) + _ = t1.In(time.FixedZone(name1, off1)) } t2 := time.Unix(s2, ns2) if loc2 { - t2.In(time.FixedZone(name2, off2)) + _ = t2.In(time.FixedZone(name2, off2)) } got := Hash(&t1) == Hash(&t2) want := t1.Format(time.RFC3339Nano) == t2.Format(time.RFC3339Nano) diff --git a/util/strs/strs.go b/util/strs/strs.go deleted file mode 100644 index 6ecdc7403..000000000 --- a/util/strs/strs.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package strs contains string-related utility funcs. -package strs - -import "strings" - -// CutPrefix returns s without the provided leading prefix string -// and reports whether it found the prefix. -// If s doesn't start with prefix, CutPrefix returns s, false. -// If prefix is the empty string, CutPrefix returns s, true. -// -// TODO: remove this once Go 1.20 is out with it. -// See https://github.com/tailscale/tailscale/issues/5309 -func CutPrefix(s, prefix string) (after string, found bool) { - if !strings.HasPrefix(s, prefix) { - return s, false - } - return s[len(prefix):], true -} - -// CutSuffix returns s without the provided ending suffix string -// and reports whether it found the suffix. -// If s doesn't end with suffix, CutSuffix returns s, false. -// If suffix is the empty string, CutSuffix returns s, true. -// -// See https://github.com/tailscale/tailscale/issues/5309 -// TODO: remove this once Go 1.20 is out with it. -func CutSuffix(s, suffix string) (before string, found bool) { - if !strings.HasSuffix(s, suffix) { - return s, false - } - return s[:len(s)-len(suffix)], true -} diff --git a/util/strs/strs_test.go b/util/strs/strs_test.go deleted file mode 100644 index 893eac035..000000000 --- a/util/strs/strs_test.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package strs - -import "testing" - -func TestCut(t *testing.T) { - tests := []struct { - fn func(string, string) (string, bool) - in1, in2 string - want string - wantOK bool - }{ - {CutPrefix, "foo", "fo", "o", true}, - {CutPrefix, "bar", "fo", "bar", false}, - {CutSuffix, "foo", "o", "fo", true}, - {CutSuffix, "bar", "fo", "bar", false}, - } - for i, tt := range tests { - got, gotOK := tt.fn(tt.in1, tt.in2) - if got != tt.want { - t.Errorf("%d. got %q; want %q", i, got, tt.want) - } - if gotOK != tt.wantOK { - t.Errorf("%d. got %v; want %v", i, gotOK, tt.wantOK) - } - } -} diff --git a/version/cmdname.go b/version/cmdname.go index f60f72cfc..51e065438 100644 --- a/version/cmdname.go +++ b/version/cmdname.go @@ -14,8 +14,6 @@ import ( "path" "path/filepath" "strings" - - "tailscale.com/util/strs" ) // CmdName returns either the base name of the current binary @@ -42,7 +40,7 @@ func cmdName(exe string) string { // v is like: // "path\ttailscale.com/cmd/tailscale\nmod\ttailscale.com\t(devel)\t\ndep\tgithub.com/apenwarr/fixconsole\tv0.0.0-20191012055117-5a9f6489cc29\th1:muXWUcay7DDy1/hEQWrYlBy+g0EuwT70sBHg65SeUc4=\ndep\tgithub.... for _, line := range strings.Split(info, "\n") { - if goPkg, ok := strs.CutPrefix(line, "path\t"); ok { // like "tailscale.com/cmd/tailscale" + if goPkg, ok := strings.CutPrefix(line, "path\t"); ok { // like "tailscale.com/cmd/tailscale" ret = path.Base(goPkg) // goPkg is always forward slashes; use path, not filepath break }