1
0
mirror of https://github.com/golang/go synced 2024-09-23 17:10:13 -06:00

cmd/distpack: sort files in standard walk order

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>
This commit is contained in:
Russ Cox 2023-07-21 13:31:10 -04:00
parent e4fdb437f6
commit 3afa5daabd

View 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)
})
}