Skip to content

Commit

Permalink
cmd/distpack: sort files in standard walk order
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Heschi Kreinick <[email protected]>
Run-TryBot: Russ Cox <[email protected]>
TryBot-Result: Gopher Robot <[email protected]>
  • Loading branch information
rsc committed Jul 26, 2023
1 parent e4fdb43 commit 3afa5da
Showing 1 changed file with 18 additions and 2 deletions.
20 changes: 18 additions & 2 deletions src/cmd/distpack/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
})
}

Expand Down

0 comments on commit 3afa5da

Please sign in to comment.