]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/distpack: sort files in standard walk order
authorRuss Cox <rsc@golang.org>
Fri, 21 Jul 2023 17:31:10 +0000 (13:31 -0400)
committerRuss Cox <rsc@golang.org>
Wed, 26 Jul 2023 19:28:08 +0000 (19:28 +0000)
The code was sorting files in the archives entirely by path string,
but that's not what fs.WalkDir would do. In a directory with
subdirectory foo/bar and file foo/bar.go, foo/bar gets visited
first, so foo/bar/baz appears before foo/bar.go, even though
"foo/bar/baz" > "foo/bar.go".

This CL replaces the string comparison with a path-aware
comparison that places foo/bar/baz before foo/bar.go,
so that if the tar file is extracted and then repacked using
fs.WalkDir, the files will remain in the same order.

This will make it easier to compare the pristine distpack-produced
tgz for darwin against the rebuilt tgz with signed binaries.

Before:
% tar tzvf /tmp/cmddist.tgz | grep -C1 runtime/cgo.go
-rw-r--r--  0 0      0       11122 Jul 13 15:00 go/src/runtime/callers_test.go
-rw-r--r--  0 0      0        2416 Jul 13 15:00 go/src/runtime/cgo.go
-rw-r--r--  0 0      0        2795 Jul 13 15:00 go/src/runtime/cgo/abi_amd64.h

After:
% tar tzvf pkg/distpack/go1.21rsc.src.tar.gz | grep -C1 runtime/cgo.go
-rw-r--r--  0 0      0        1848 Dec 31  1969 go/src/runtime/cgo/signal_ios_arm64.s
-rw-r--r--  0 0      0        2416 Dec 31  1969 go/src/runtime/cgo.go
-rw-r--r--  0 0      0        2479 Dec 31  1969 go/src/runtime/cgo_mmap.go

For #24904.
For #61513.

Change-Id: Ib7374bc0d6324377f81c561bef57fd87b2111b98
Reviewed-on: https://go-review.googlesource.com/c/go/+/511977
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/distpack/archive.go

index f731b3792f8c9fc2c6ee1c9ac73b1986f69f7484..8245381f90149319c72b91f821d133277869da58 100644 (file)
@@ -91,13 +91,29 @@ func (a *Archive) Add(name, src string, info fs.FileInfo) {
        })
 }
 
+func nameLess(x, y string) bool {
+       for i := 0; i < len(x) && i < len(y); i++ {
+               if x[i] != y[i] {
+                       // foo/bar/baz before foo/bar.go, because foo/bar is before foo/bar.go
+                       if x[i] == '/' {
+                               return true
+                       }
+                       if y[i] == '/' {
+                               return false
+                       }
+                       return x[i] < y[i]
+               }
+       }
+       return len(x) < len(y)
+}
+
 // Sort sorts the files in the archive.
 // It is only necessary to call Sort after calling Add or RenameGoMod.
-// ArchiveDir returns a sorted archive, and the other methods
+// NewArchive returns a sorted archive, and the other methods
 // preserve the sorting of the archive.
 func (a *Archive) Sort() {
        sort.Slice(a.Files, func(i, j int) bool {
-               return a.Files[i].Name < a.Files[j].Name
+               return nameLess(a.Files[i].Name, a.Files[j].Name)
        })
 }