Skip to content

Commit 312096e

Browse files
committed
verify-pack: Add support for analysing go-git-fixtures
This is mostly useful when debugging go-git tests that are processing pack files that are contained within a go-git-fixture. Signed-off-by: Paulo Gomes <[email protected]>
1 parent e6fc649 commit 312096e

File tree

1 file changed

+75
-32
lines changed

1 file changed

+75
-32
lines changed

cmd/gogit/verify-pack.go

Lines changed: 75 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,32 @@ package main
22

33
import (
44
"crypto"
5+
"errors"
56
"fmt"
67
"io"
78
"log/slog"
89
"os"
9-
"path/filepath"
1010
"sort"
1111
"strings"
1212

13-
"github.com/go-git/go-billy/v6/osfs"
13+
"github.com/go-git/go-billy/v6"
14+
fixtures "github.com/go-git/go-git-fixtures/v5"
1415
"github.com/go-git/go-git/v6/plumbing"
1516
"github.com/go-git/go-git/v6/plumbing/format/idxfile"
1617
"github.com/go-git/go-git/v6/plumbing/format/packfile"
1718
"github.com/spf13/cobra"
1819
)
1920

20-
var verifyPackVerbose bool
21+
var (
22+
verifyPackVerbose bool
23+
verifyPackFixtureUrl bool
24+
verifyPackFixtureTag bool
25+
)
2126

2227
func init() {
2328
verifyPackCmd.Flags().BoolVarP(&verifyPackVerbose, "verbose", "v", false, "Show detailed object information")
29+
verifyPackCmd.Flags().BoolVarP(&verifyPackFixtureUrl, "fixture-url", "", false, "Use <file> as go-git-fixture url")
30+
verifyPackCmd.Flags().BoolVarP(&verifyPackFixtureTag, "fixture-tag", "", false, "Use <file> as go-git-fixture tag")
2431
rootCmd.AddCommand(verifyPackCmd)
2532
}
2633

@@ -46,59 +53,45 @@ type objectInfo struct {
4653
}
4754

4855
func verifyPack(path string, verbose bool) error {
49-
idxPath := path
50-
packPath := path
51-
52-
if strings.HasSuffix(path, ".idx") {
53-
packPath = strings.TrimSuffix(path, ".idx") + ".pack"
54-
} else if strings.HasSuffix(path, ".pack") {
55-
idxPath = strings.TrimSuffix(path, ".pack") + ".idx"
56-
} else {
57-
return fmt.Errorf("file must have .idx or .pack extension")
58-
}
59-
60-
idxFile, err := os.Open(idxPath)
56+
idxFile, packFile, err := openPack(path)
6157
if err != nil {
62-
return fmt.Errorf("failed to open index file: %w", err)
58+
return err
6359
}
60+
6461
defer func() {
6562
err = idxFile.Close()
6663
if err != nil {
6764
slog.Debug("failed to close idx file", "error", err)
6865
}
6966
}()
7067

71-
idx := idxfile.NewMemoryIndex(crypto.SHA1.Size())
72-
dec := idxfile.NewDecoder(idxFile)
73-
if err := dec.Decode(idx); err != nil {
74-
return fmt.Errorf("failed to decode index file: %w", err)
75-
}
76-
77-
fs := osfs.New(filepath.Dir(packPath))
78-
packFile, err := fs.Open(filepath.Base(packPath))
79-
if err != nil {
80-
return fmt.Errorf("failed to open pack file: %w", err)
81-
}
8268
defer func() {
8369
err = packFile.Close()
8470
if err != nil {
8571
slog.Debug("failed to close pack file", "error", err)
8672
}
8773
}()
8874

75+
idx := idxfile.NewMemoryIndex(crypto.SHA1.Size())
76+
77+
dec := idxfile.NewDecoder(idxFile)
78+
if err := dec.Decode(idx); err != nil {
79+
return fmt.Errorf("failed to decode index file: %w", err)
80+
}
81+
8982
pf := packfile.NewPackfile(
9083
packFile,
9184
packfile.WithIdx(idx),
92-
packfile.WithFs(fs),
9385
)
86+
9487
defer func() {
95-
err = pf.Close()
88+
err := pf.Close()
9689
if err != nil {
9790
slog.Debug("failed to close Packfile object", "error", err)
9891
}
9992
}()
10093

101-
scanner, err := pf.Scanner() //nolint:staticcheck
94+
scanner, err := pf.Scanner()
10295
if err != nil {
10396
return fmt.Errorf("failed to get scanner: %w", err)
10497
}
@@ -112,9 +105,10 @@ func verifyPack(path string, verbose bool) error {
112105

113106
for {
114107
entry, err := entries.Next()
115-
if err == io.EOF {
108+
if errors.Is(err, io.EOF) {
116109
break
117110
}
111+
118112
if err != nil {
119113
return fmt.Errorf("failed to read entry: %w", err)
120114
}
@@ -164,6 +158,7 @@ func verifyPack(path string, verbose bool) error {
164158
if err != nil {
165159
return fmt.Errorf("failed to get object at offset %d: %w", objects[i].offset, err)
166160
}
161+
167162
objects[i].typ = obj.Type()
168163
}
169164

@@ -196,6 +191,7 @@ func verifyPack(path string, verbose bool) error {
196191

197192
// Calculate delta chain depth.
198193
depth := 1
194+
199195
var baseHash plumbing.Hash
200196

201197
switch header.Type {
@@ -227,9 +223,11 @@ func verifyPack(path string, verbose bool) error {
227223
if err != nil {
228224
break
229225
}
226+
230227
if !scanner.Scan() {
231228
break
232229
}
230+
233231
baseHeader := scanner.Data().Value().(packfile.ObjectHeader)
234232

235233
depth++
@@ -294,19 +292,64 @@ func verifyPack(path string, verbose bool) error {
294292
for length := range chainLengths {
295293
lengths = append(lengths, length)
296294
}
295+
297296
sort.Ints(lengths)
298297

299298
for _, length := range lengths {
300299
count := chainLengths[length]
300+
301301
objWord := "objects"
302302
if count == 1 {
303303
objWord = "object"
304304
}
305+
305306
fmt.Printf("chain length = %d: %d %s\n", length, count, objWord)
306307
}
307308
}
308309

309-
fmt.Printf("%s: ok\n", packPath)
310+
fmt.Printf("%s: ok\n", path)
310311

311312
return nil
312313
}
314+
315+
func openPack(path string) (billy.File, billy.File, error) {
316+
if verifyPackFixtureUrl || verifyPackFixtureTag {
317+
var f fixtures.Fixtures
318+
if verifyPackFixtureUrl {
319+
f = fixtures.ByURL(path)
320+
}
321+
if verifyPackFixtureTag {
322+
f = fixtures.ByTag(path)
323+
}
324+
325+
if len(f) == 0 {
326+
return nil, nil, fmt.Errorf("no fixture found for %q", path)
327+
}
328+
329+
fixture := f.One()
330+
return fixture.Idx(), fixture.Packfile(), nil
331+
}
332+
333+
idxPath := path
334+
packPath := path
335+
336+
if before, ok := strings.CutSuffix(path, ".idx"); ok {
337+
packPath = before + ".pack"
338+
} else if before, ok := strings.CutSuffix(path, ".pack"); ok {
339+
idxPath = before + ".idx"
340+
} else {
341+
return nil, nil, errors.New("file must have .idx or .pack extension")
342+
}
343+
344+
idxFile, err := os.Open(idxPath)
345+
if err != nil {
346+
return nil, nil, fmt.Errorf("failed to open index file: %w", err)
347+
}
348+
349+
packFile, err := os.Open(packPath)
350+
if err != nil {
351+
return nil, nil, fmt.Errorf("failed to open pack file: %w", err)
352+
}
353+
354+
return idxFile, packFile, nil
355+
}

0 commit comments

Comments
 (0)