diff options
author | Eric Ju <eju@gitlab.com> | 2024-01-12 06:46:34 +0300 |
---|---|---|
committer | Eric Ju <eju@gitlab.com> | 2024-01-12 06:46:34 +0300 |
commit | 8c27ef08646d1ed1a1f3493955d4f3c5e6912e88 (patch) | |
tree | 81522cd79847cc69badfe1b386c2486b69b1dc35 | |
parent | 686929072dce472eb062521cf63f0e1bda4d310f (diff) |
repository: GetFileAttributes supports get all attributes for a pathej/5772/GetFileAttributes-get-all-attributes-for-a-path
During the processing of replacing GetInfoAttributes by
GitFileAttributes in Rails.We come across a function, attributes(path)
in lib/gitlab/git/repository.rb. It queries all the attributes
for a given path.
This MR add the ability to query all the attributes for a given path.
-rw-r--r-- | internal/git/gitattributes/check_attr.go | 31 | ||||
-rw-r--r-- | internal/gitaly/service/repository/file_attributes_test.go | 27 |
2 files changed, 46 insertions, 12 deletions
diff --git a/internal/git/gitattributes/check_attr.go b/internal/git/gitattributes/check_attr.go index 8596efaa3..f8e1bb232 100644 --- a/internal/git/gitattributes/check_attr.go +++ b/internal/git/gitattributes/check_attr.go @@ -20,8 +20,6 @@ type CheckAttrCmd struct { stdout *bufio.Reader stdin *bufio.Writer - count int - m *sync.Mutex } @@ -31,14 +29,22 @@ func CheckAttr(ctx context.Context, repo git.RepositoryExecutor, revision git.Re return nil, nil, structerr.NewInvalidArgument("empty list of attribute names") } + flags := []git.Option{ + git.Flag{Name: "--stdin"}, + git.Flag{Name: "-z"}, + git.ValueFlag{Name: "--source", Value: revision.String()}, + } + + // Special attribute "*" retrieves all attributes + if len(names) == 1 && names[0] == "*" { + flags = append(flags, git.Flag{Name: "-a"}) + names = nil + } + cmd, err := repo.Exec(ctx, git.Command{ - Name: "check-attr", - Flags: []git.Option{ - git.Flag{Name: "--stdin"}, - git.Flag{Name: "-z"}, - git.ValueFlag{Name: "--source", Value: revision.String()}, - }, - Args: names, + Name: "check-attr", + Flags: flags, + Args: names, }, git.WithSetupStdin(), git.WithSetupStdout(), @@ -51,7 +57,6 @@ func CheckAttr(ctx context.Context, repo git.RepositoryExecutor, revision git.Re cmd: cmd, stdout: bufio.NewReader(cmd), stdin: bufio.NewWriter(cmd), - count: len(names), m: &sync.Mutex{}, } @@ -79,7 +84,7 @@ func (c CheckAttrCmd) Check(path string) (Attributes, error) { // Using git-check-attr(1) with -z will return data in the format: // <path> NUL <attribute> NUL <info> NUL ... - for i := 0; i < c.count; { + for { word, err := c.stdout.ReadBytes('\000') if err != nil { return nil, fmt.Errorf("read line: %w", err) @@ -98,8 +103,10 @@ func (c CheckAttrCmd) Check(path string) (Attributes, error) { attrs = append(attrs, Attribute{Name: buf[1], State: buf[2]}) } - i++ buf = buf[:0] + if c.stdout.Buffered() == 0 { + break + } } return attrs, nil diff --git a/internal/gitaly/service/repository/file_attributes_test.go b/internal/gitaly/service/repository/file_attributes_test.go index 747263437..4d55c36ea 100644 --- a/internal/gitaly/service/repository/file_attributes_test.go +++ b/internal/gitaly/service/repository/file_attributes_test.go @@ -94,6 +94,33 @@ func TestGetFileAttributes(t *testing.T) { }, }, { + desc: "returns multiple attributes for a file successfully", + setup: func(t *testing.T) setupData { + return setupData{ + request: &gitalypb.GetFileAttributesRequest{ + Repository: repoProto, + Revision: []byte("main"), + Attributes: []string{"*"}, + Paths: []string{"example.go"}, + }, + expectedResponse: &gitalypb.GetFileAttributesResponse{ + AttributeInfos: []*gitalypb.GetFileAttributesResponse_AttributeInfo{ + { + Path: string("example.go"), + Attribute: string("diff"), + Value: string("go"), + }, + { + Path: string("example.go"), + Attribute: string("text"), + Value: string("set"), + }, + }, + }, + } + }, + }, + { desc: "returns empty response when there are no matching attributes for the given path", setup: func(t *testing.T) setupData { return setupData{ |