tailscale/tempfork/acme/sync_to_upstream_test.go
Brad Fitzpatrick 2691b9f6be tempfork/acme: add new package for x/crypto package acme fork, move
We've been maintaining temporary dev forks of golang.org/x/crypto/{acme,ssh}
in https://github.com/tailscale/golang-x-crypto instead of using
this repo's tempfork directory as we do with other packages. The reason we were
doing that was because x/crypto/ssh depended on x/crypto/ssh/internal/poly1305
and I hadn't noticed there are forwarding wrappers already available
in x/crypto/poly1305. It also depended internal/bcrypt_pbkdf but we don't use that
so it's easy to just delete that calling code in our tempfork/ssh.

Now that our SSH changes have been upstreamed, we can soon unfork from SSH.

That leaves ACME remaining.

This change copies our tailscale/golang-x-crypto/acme code to
tempfork/acme but adds a test that our vendored copied still matches
our tailscale/golang-x-crypto repo, where we can continue to do
development work and rebases with upstream. A comment on the new test
describes the expected workflow.

While we could continue to just import & use
tailscale/golang-x-crypto/acme, it seems a bit nicer to not have that
entire-fork-of-x-crypto visible at all in our transitive deps and the
questions that invites. Showing just a fork of an ACME client is much
less scary. It does add a step to the process of hacking on the ACME
client code, but we do that approximately never anyway, and the extra
step is very incremental compared to the existing tedious steps.

Updates #8593
Updates #10238

Change-Id: I8af4378c04c1f82e63d31bf4d16dba9f510f9199
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-01-27 21:32:26 +00:00

71 lines
2.1 KiB
Go

package acme
import (
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
_ "github.com/tailscale/golang-x-crypto/acme" // so it's on disk for the test
)
// Verify that the files tempfork/acme/*.go (other than this test file) match the
// files in "github.com/tailscale/golang-x-crypto/acme" which is where we develop
// our fork of golang.org/x/crypto/acme and merge with upstream, but then we vendor
// just its acme package into tailscale.com/tempfork/acme.
//
// Development workflow:
//
// - make a change in github.com/tailscale/golang-x-crypto/acme
// - merge it (ideally with golang.org/x/crypto/acme too)
// - rebase github.com/tailscale/golang-x-crypto/acme with upstream x/crypto/acme
// as needed
// - in the tailscale.com repo, run "go get github.com/tailscale/golang-x-crypto/acme@main"
// - run go test ./tempfork/acme to watch it fail; the failure includes
// a shell command you should run to copy the *.go files from tailscale/golang-x-crypto
// to tailscale.com.
// - watch tests pass. git add it all.
// - send PR to tailscale.com
func TestSyncedToUpstream(t *testing.T) {
const pkg = "github.com/tailscale/golang-x-crypto/acme"
out, err := exec.Command("go", "list", "-f", "{{.Dir}}", pkg).Output()
if err != nil {
t.Fatalf("failed to find %s's location o disk: %v", pkg, err)
}
xDir := strings.TrimSpace(string(out))
t.Logf("at %s", xDir)
scanDir := func(dir string) map[string]string {
m := map[string]string{} // filename => Go contents
ents, err := os.ReadDir(dir)
if err != nil {
t.Fatal(err)
}
for _, de := range ents {
name := de.Name()
if name == "sync_to_upstream_test.go" {
continue
}
if !strings.HasSuffix(name, ".go") {
continue
}
b, err := os.ReadFile(filepath.Join(dir, name))
if err != nil {
t.Fatal(err)
}
m[name] = string(b)
}
return m
}
want := scanDir(xDir)
got := scanDir(".")
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("files differ (-want +got):\n%s", diff)
t.Errorf("to fix, run from module root:\n\ncp %s/*.go ./tempfork/acme && ./tool/go mod tidy\n", xDir)
}
}