Skip to content

Commit

Permalink
cat: better binary display
Browse files Browse the repository at this point in the history
  • Loading branch information
fcharlie committed Dec 20, 2024
1 parent f84067a commit e5cb949
Show file tree
Hide file tree
Showing 35 changed files with 1,332 additions and 182 deletions.
1 change: 1 addition & 0 deletions cmd/zeta/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type App struct {
LsFiles command.LsFiles `cmd:"ls-files" help:"Show information about files in the index and the working tree"`
HashObject command.HashObject `cmd:"hash-object" help:"Compute hash or create object"`
MergeFile command.MergeFile `cmd:"merge-file" help:"Run a three-way file merge"`
Show command.Show `cmd:"show" help:"Show various types of objects"`
Version command.Version `cmd:"version" help:"Display version information"`
Debug bool `name:"debug" help:"Enable debug mode; analyze timing"`
}
Expand Down
12 changes: 6 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ require (
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2
github.com/ProtonMail/go-crypto v1.1.3
github.com/aws/aws-sdk-go-v2 v1.32.7
github.com/aws/aws-sdk-go-v2/config v1.28.6
github.com/aws/aws-sdk-go-v2/credentials v1.17.47
github.com/aws/aws-sdk-go-v2/config v1.28.7
github.com/aws/aws-sdk-go-v2/credentials v1.17.48
github.com/aws/aws-sdk-go-v2/service/s3 v1.71.1
github.com/creack/pty v1.1.24
github.com/danieljoos/wincred v1.2.2
Expand Down Expand Up @@ -43,7 +43,7 @@ require (
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect
Expand All @@ -52,9 +52,9 @@ require (
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.7 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.7 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.24.7 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.33.2 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.24.8 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.33.3 // indirect
github.com/aws/smithy-go v1.22.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cloudflare/circl v1.5.0 // indirect
Expand Down
24 changes: 12 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ github.com/aws/aws-sdk-go-v2 v1.32.7 h1:ky5o35oENWi0JYWUZkB7WYvVPP+bcRF5/Iq7JWSb
github.com/aws/aws-sdk-go-v2 v1.32.7/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 h1:lL7IfaFzngfx0ZwUGOZdsFFnQ5uLvR0hWqqhyE7Q9M8=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7/go.mod h1:QraP0UcVlQJsmHfioCrveWOC1nbiWUl3ej08h4mXWoc=
github.com/aws/aws-sdk-go-v2/config v1.28.6 h1:D89IKtGrs/I3QXOLNTH93NJYtDhm8SYa9Q5CsPShmyo=
github.com/aws/aws-sdk-go-v2/config v1.28.6/go.mod h1:GDzxJ5wyyFSCoLkS+UhGB0dArhb9mI+Co4dHtoTxbko=
github.com/aws/aws-sdk-go-v2/credentials v1.17.47 h1:48bA+3/fCdi2yAwVt+3COvmatZ6jUDNkDTIsqDiMUdw=
github.com/aws/aws-sdk-go-v2/credentials v1.17.47/go.mod h1:+KdckOejLW3Ks3b0E3b5rHsr2f9yuORBum0WPnE5o5w=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21 h1:AmoU1pziydclFT/xRV+xXE/Vb8fttJCLRPv8oAkprc0=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21/go.mod h1:AjUdLYe4Tgs6kpH4Bv7uMZo7pottoyHMn4eTcIcneaY=
github.com/aws/aws-sdk-go-v2/config v1.28.7 h1:GduUnoTXlhkgnxTD93g1nv4tVPILbdNQOzav+Wpg7AE=
github.com/aws/aws-sdk-go-v2/config v1.28.7/go.mod h1:vZGX6GVkIE8uECSUHB6MWAUsd4ZcG2Yq/dMa4refR3M=
github.com/aws/aws-sdk-go-v2/credentials v1.17.48 h1:IYdLD1qTJ0zanRavulofmqut4afs45mOWEI+MzZtTfQ=
github.com/aws/aws-sdk-go-v2/credentials v1.17.48/go.mod h1:tOscxHN3CGmuX9idQ3+qbkzrjVIx32lqDSU1/0d/qXs=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22 h1:kqOrpojG71DxJm/KDPO+Z/y1phm1JlC8/iT+5XRmAn8=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22/go.mod h1:NtSFajXVVL8TA2QNngagVZmUtXciyrHOt7xgz4faS/M=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26 h1:I/5wmGMffY4happ8NOCuIUEWGUvvFp5NSeQcXl9RHcI=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26/go.mod h1:FR8f4turZtNy6baO0KJ5FJUmXH/cSkI9fOngs0yl6mA=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26 h1:zXFLuEuMMUOvEARXFUVJdfqZ4bvvSgdGRq/ATcrQxzM=
Expand All @@ -40,12 +40,12 @@ github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7 h1:Hi0KGbrnr57bEH
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7/go.mod h1:wKNgWgExdjjrm4qvfbTorkvocEstaoDl4WCvGfeCy9c=
github.com/aws/aws-sdk-go-v2/service/s3 v1.71.1 h1:aOVVZJgWbaH+EJYPvEgkNhCEbXXvH7+oML36oaPK3zE=
github.com/aws/aws-sdk-go-v2/service/s3 v1.71.1/go.mod h1:r+xl5yzMk9083rMR+sJ5TYj9Tihvf/l1oxzZXDgGj2Q=
github.com/aws/aws-sdk-go-v2/service/sso v1.24.7 h1:rLnYAfXQ3YAccocshIH5mzNNwZBkBo+bP6EhIxak6Hw=
github.com/aws/aws-sdk-go-v2/service/sso v1.24.7/go.mod h1:ZHtuQJ6t9A/+YDuxOLnbryAmITtr8UysSny3qcyvJTc=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6 h1:JnhTZR3PiYDNKlXy50/pNeix9aGMo6lLpXwJ1mw8MD4=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6/go.mod h1:URronUEGfXZN1VpdktPSD1EkAL9mfrV+2F4sjH38qOY=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.2 h1:s4074ZO1Hk8qv65GqNXqDjmkf4HSQqJukaLuuW0TpDA=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.2/go.mod h1:mVggCnIWoM09jP71Wh+ea7+5gAp53q+49wDFs1SW5z8=
github.com/aws/aws-sdk-go-v2/service/sso v1.24.8 h1:CvuUmnXI7ebaUAhbJcDy9YQx8wHR69eZ9I7q5hszt/g=
github.com/aws/aws-sdk-go-v2/service/sso v1.24.8/go.mod h1:XDeGv1opzwm8ubxddF0cgqkZWsyOtw4lr6dxwmb6YQg=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7 h1:F2rBfNAL5UyswqoeWv9zs74N/NanhK16ydHW1pahX6E=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7/go.mod h1:JfyQ0g2JG8+Krq0EuZNnRwX0mU0HrwY/tG6JNfcqh4k=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.3 h1:Xgv/hyNgvLda/M9l9qxXc4UFSgppnRczLxlMs5Ae/QY=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.3/go.mod h1:5Gn+d+VaaRgsjewpMvGazt0WfcFO+Md4wLOuBfGR9Bc=
github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro=
github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
Expand Down
24 changes: 22 additions & 2 deletions modules/diferenco/text.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,17 +94,37 @@ func readRawText(r io.Reader, size int) (string, error) {
return unsafe.String(unsafe.SliceData(content), len(content)), nil
}

func ReadUnifiedText(r io.Reader, size int64, textConv bool) (content string, charset string, err error) {
func ReadUnifiedText(r io.Reader, size int64, textconv bool) (content string, charset string, err error) {
if size > MAX_DIFF_SIZE {
return "", "", ErrNonTextContent
}
if textConv {
if textconv {
return readUnifiedText(r)
}
content, err = readRawText(r, int(size))
return content, UTF8, err
}

func NewUnifiedReaderEx(r io.Reader, textconv bool) (io.Reader, string, error) {
sniffBytes, err := streamio.ReadMax(r, sniffLen)
if err != nil {
return nil, "", err
}
reader := io.MultiReader(bytes.NewReader(sniffBytes), r)
if !textconv {
if bytes.IndexByte(sniffBytes, 0) != -1 {
return reader, BINARY, nil
}
return reader, UTF8, nil
}
charset := detectCharset(sniffBytes)
// binary or UTF-8 not need convert
if charset == BINARY || strings.EqualFold(charset, UTF8) {
return reader, charset, nil
}
return chardet.NewReader(reader, charset), charset, nil
}

func NewUnifiedReader(r io.Reader) (io.Reader, error) {
sniffBytes, err := streamio.ReadMax(r, sniffLen)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion modules/streamio/bytes.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func PutByteSlice(buf *[]byte) {
}

// GetBytesBuffer returns a *bytes.Buffer that is managed by a sync.Pool.
// Returns a buffer that is resetted and ready for use.
// Returns a buffer that is reset and ready for use.
//
// After use, the *bytes.Buffer should be put back into the sync.Pool
// by calling PutBytesBuffer.
Expand Down
4 changes: 2 additions & 2 deletions modules/streamio/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ var bufioReader = sync.Pool{
}

// GetBufioReader returns a *bufio.Reader that is managed by a sync.Pool.
// Returns a bufio.Reader that is resetted with reader and ready for use.
// Returns a bufio.Reader that is reset with reader and ready for use.
//
// After use, the *bufio.Reader should be put back into the sync.Pool
// by calling PutBufioReader.
Expand All @@ -39,7 +39,7 @@ var bufferWriter = sync.Pool{
}

// GetBufferWriter returns a *bufio.Writer that is managed by a sync.Pool.
// Returns a bufio.Writer that is resetted with writer and ready for use.
// Returns a bufio.Writer that is reset with writer and ready for use.
//
// After use, the *bufio.Writer should be put back into the sync.Pool
// by calling PutBufferWriter.
Expand Down
4 changes: 2 additions & 2 deletions modules/streamio/zlib.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type ZLibReader struct {
}

// GetZlibReader returns a ZLibReader that is managed by a sync.Pool.
// Returns a ZLibReader that is resetted using a dictionary that is
// Returns a ZLibReader that is reset using a dictionary that is
// also managed by a sync.Pool.
//
// After use, the ZLibReader should be put back into the sync.Pool
Expand All @@ -58,7 +58,7 @@ func PutZlibReader(z *ZLibReader) {
}

// GetZlibWriter returns a *zlib.Writer that is managed by a sync.Pool.
// Returns a writer that is resetted with w and ready for use.
// Returns a writer that is reset with w and ready for use.
//
// After use, the *zlib.Writer should be put back into the sync.Pool
// by calling PutZlibWriter.
Expand Down
4 changes: 2 additions & 2 deletions modules/streamio/zstd.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type ZstdDecoder struct {
}

// GetZstdReader returns a ZstdDecoder that is managed by a sync.Pool.
// Returns a ZLibReader that is resetted using a dictionary that is
// Returns a ZLibReader that is reset using a dictionary that is
// also managed by a sync.Pool.
//
// After use, the ZstdDecoder should be put back into the sync.Pool
Expand All @@ -55,7 +55,7 @@ type ZstdEncoder struct {
}

// GetZstdWriter returns a *ztsd.Encoder that is managed by a sync.Pool.
// Returns a writer that is resetted with w and ready for use.
// Returns a writer that is reset with w and ready for use.
//
// After use, the *ztsd.Encoder should be put back into the sync.Pool
// by calling PutZstdWriter.
Expand Down
11 changes: 11 additions & 0 deletions modules/zeta/object/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,17 @@ func (c *Commit) Root(ctx context.Context) (*Tree, error) {
return resolveTree(ctx, c.b, c.Tree)
}

// File returns the file with the specified "path" in the commit and a
// nil error if the file exists. If the file does not exist, it returns
// a nil file and the ErrFileNotFound error.
func (c *Commit) File(ctx context.Context, path string) (*File, error) {
tree, err := c.Root(ctx)
if err != nil {
return nil, err
}
return tree.File(ctx, path)
}

// StatsContext returns the stats of a commit. Error will be return if context
// expires. Provided context must be non-nil.
func (c *Commit) StatsContext(ctx context.Context, m noder.Matcher, opts *PatchOptions) (FileStats, error) {
Expand Down
27 changes: 21 additions & 6 deletions modules/zeta/object/patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"errors"
"fmt"
"io"
"path"
"strconv"
"strings"

Expand All @@ -21,14 +22,28 @@ var (

type PatchOptions struct {
Algorithm diferenco.Algorithm
TextConv bool
Textconv bool
Match func(string) bool
}

func sizeOverflow(f *File) bool {
return f != nil && f.Size > diferenco.MAX_DIFF_SIZE
}

func PathRenameCombine(from, to string) string {
fromPaths := strings.Split(from, "/")
toPaths := strings.Split(to, "/")
n := min(len(fromPaths), len(toPaths))
i := 0
for i < n && fromPaths[i] == toPaths[i] {
i++
}
if i == 0 {
return fmt.Sprintf("%s => %s", from, to)
}
return fmt.Sprintf("%s/{%s => %s}", path.Join(fromPaths[0:i]...), path.Join(fromPaths[i:]...), path.Join(toPaths[i:]...))
}

func fileStatName(from, to *File) string {
if from == nil {
// New File is created.
Expand All @@ -40,7 +55,7 @@ func fileStatName(from, to *File) string {
}
if from.Path != to.Path {
// File is renamed.
return fmt.Sprintf("%s => %s", from.Path, to.Path)
return PathRenameCombine(from.Path, to.Path)
}
return from.Path
}
Expand All @@ -63,14 +78,14 @@ func fileStatWithContext(ctx context.Context, opts *PatchOptions, c *Change) (*F
if sizeOverflow(from) || sizeOverflow(to) {
return s, nil
}
fromContent, err := from.UnifiedText(ctx, opts.TextConv)
fromContent, err := from.UnifiedText(ctx, opts.Textconv)
if plumbing.IsNoSuchObject(err) || err == diferenco.ErrNonTextContent {
return s, nil
}
if err != nil {
return nil, err
}
toContent, err := to.UnifiedText(ctx, opts.TextConv)
toContent, err := to.UnifiedText(ctx, opts.Textconv)
if plumbing.IsNoSuchObject(err) || err == diferenco.ErrNonTextContent {
return s, nil
}
Expand Down Expand Up @@ -121,14 +136,14 @@ func filePatchWithContext(ctx context.Context, opts *PatchOptions, c *Change) (*
if sizeOverflow(from) || sizeOverflow(to) {
return &diferenco.Unified{From: from.asFile(), To: to.asFile(), IsBinary: true}, nil
}
fromContent, err := from.UnifiedText(ctx, opts.TextConv)
fromContent, err := from.UnifiedText(ctx, opts.Textconv)
if plumbing.IsNoSuchObject(err) || err == diferenco.ErrNonTextContent {
return &diferenco.Unified{From: from.asFile(), To: to.asFile(), IsBinary: true}, nil
}
if err != nil {
return nil, err
}
toContent, err := to.UnifiedText(ctx, opts.TextConv)
toContent, err := to.UnifiedText(ctx, opts.Textconv)
if plumbing.IsNoSuchObject(err) || err == diferenco.ErrNonTextContent {
return &diferenco.Unified{From: from.asFile(), To: to.asFile(), IsBinary: true}, nil
}
Expand Down
30 changes: 30 additions & 0 deletions modules/zeta/object/patch_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package object

import (
"fmt"
"os"
"testing"
)

func TestPathRenameCombine(t *testing.T) {
pp := []struct {
A, B string
}{
{
"a.txt",
"b.txt",
},
{
"pkg/command/command_merge_file.go",
"pkg/command/merge.go",
},
{
"pkg/command/command_merge_file.go",
"pkg/merge.go",
},
}
for _, i := range pp {
d := PathRenameCombine(i.A, i.B)
fmt.Fprintf(os.Stderr, "%s => %s|%s\n", i.A, i.B, d)
}
}
10 changes: 10 additions & 0 deletions modules/zeta/object/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,16 @@ func resolveTree(ctx context.Context, b Backend, h plumbing.Hash) (*Tree, error)
return t, nil
}

// File returns the hash of the file identified by the `path` argument.
// The path is interpreted as relative to the tree receiver.
func (t *Tree) File(ctx context.Context, path string) (*File, error) {
e, err := t.FindEntry(ctx, path)
if err != nil {
return nil, &ErrEntryNotFound{entry: path}
}
return newFile(e.Name, path, e.Mode, e.Hash, e.Size, t.b), nil
}

// Diff returns a list of changes between this tree and the provided one
func (t *Tree) Diff(to *Tree, m noder.Matcher) (Changes, error) {
return t.DiffContext(context.Background(), to, m)
Expand Down
24 changes: 14 additions & 10 deletions pkg/command/command_cat.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ import (
)

type Cat struct {
Hash string `arg:"" name:"object" help:"The name of the object to show"`
WriteMax int64 `name:"max" short:"m" optional:"" help:"Blob output size limit; use 0 for unlimited. Units: KB, MB, GB, K, M, G" default:"20m" type:"size"`
Object string `arg:"" name:"object" help:"The name of the object to show"`
T bool `name:"type" short:"t" help:"Show object type"`
DisplaySize bool `name:":" short:"s" help:"Show object size"`
JSON bool `name:"json" short:"j" help:"Returns data as JSON; limited to commits, trees, fragments, and tags"`
Textconv bool `name:"textconv" help:"Output text as Unicode; blobs only"`
Textconv bool `name:"textconv" help:"Converting text to Unicode"`
Direct bool `name:"direct" help:"View files directly"`
Verify bool `name:"verify" help:"Verify object hash"`
Limit int64 `name:"limit" short:"L" help:"Omits blobs larger than n bytes or units. n may be zero. supported units: KB,MB,GB,K,M,G" default:"-1" type:"size"`
Output string `name:"output" help:"Output to a specific file instead of stdout" placeholder:"<file>"`
}

func (c *Cat) Run(g *Globals) error {
Expand All @@ -30,12 +32,14 @@ func (c *Cat) Run(g *Globals) error {
}
defer r.Close()
return r.Cat(context.Background(), &zeta.CatOptions{
Hash: c.Hash,
SizeMax: c.WriteMax,
Type: c.T,
DisplaySize: c.DisplaySize,
Textconv: c.Textconv,
FormatJSON: c.JSON,
Verify: c.Verify,
Object: c.Object,
Limit: c.Limit,
Type: c.T,
PrintSize: c.DisplaySize,
Textconv: c.Textconv,
Direct: c.Direct,
PrintJSON: c.JSON,
Verify: c.Verify,
Output: c.Output,
})
}
Loading

0 comments on commit e5cb949

Please sign in to comment.