[code-1016] Replacing gitea commands with new command package (#1003)

eb/code-1016-2
Enver Bisevac 2024-02-01 11:58:48 +00:00 committed by Harness
parent a4f36c17ce
commit 1fe29b6d42
3 changed files with 61 additions and 63 deletions

View File

@ -17,16 +17,15 @@ package adapter
import (
"bytes"
"context"
"errors"
"fmt"
"io"
"strconv"
"strings"
"time"
"github.com/harness/gitness/errors"
"github.com/harness/gitness/git/command"
"github.com/harness/gitness/git/types"
gitea "code.gitea.io/gitea/modules/git"
)
const (
@ -43,7 +42,7 @@ func (a Adapter) GetAnnotatedTag(
if repoPath == "" {
return nil, ErrRepositoryPathEmpty
}
tags, err := giteaGetAnnotatedTags(ctx, repoPath, []string{sha})
tags, err := getAnnotatedTags(ctx, repoPath, []string{sha})
if err != nil || len(tags) == 0 {
return nil, processGiteaErrorf(err, "failed to get annotated tag with sha '%s'", sha)
}
@ -60,7 +59,7 @@ func (a Adapter) GetAnnotatedTags(
if repoPath == "" {
return nil, ErrRepositoryPathEmpty
}
return giteaGetAnnotatedTags(ctx, repoPath, shas)
return getAnnotatedTags(ctx, repoPath, shas)
}
// CreateTag creates the tag pointing at the provided SHA (could be any type, e.g. commit, tag, blob, ...)
@ -74,40 +73,29 @@ func (a Adapter) CreateTag(
if repoPath == "" {
return ErrRepositoryPathEmpty
}
args := []string{
"tag",
}
env := []string{}
cmd := command.New("tag")
if opts != nil && opts.Message != "" {
args = append(args,
"-m",
opts.Message,
)
env = append(env,
"GIT_COMMITTER_NAME="+opts.Tagger.Identity.Name,
"GIT_COMMITTER_EMAIL="+opts.Tagger.Identity.Email,
"GIT_COMMITTER_DATE="+opts.Tagger.When.Format(time.RFC3339),
cmd.Add(command.WithFlag("-m", opts.Message))
cmd.Add(
command.WithCommitter(
opts.Tagger.Identity.Name,
opts.Tagger.Identity.Email,
),
)
cmd.Add(command.WithEnv(command.GitCommitterDate, opts.Tagger.When.Format(time.RFC3339)))
}
args = append(args,
"--",
name,
targetSHA,
)
cmd := gitea.NewCommand(ctx, args...)
_, _, err := cmd.RunStdString(&gitea.RunOpts{Dir: repoPath, Env: env})
cmd.Add(command.WithArg(name, targetSHA))
err := cmd.Run(ctx, command.WithDir(repoPath))
if err != nil {
return processGiteaErrorf(err, "Service failed to create a tag")
}
return nil
}
// giteaGetAnnotatedTag is a custom implementation to retrieve an annotated tag from a sha.
// getAnnotatedTag is a custom implementation to retrieve an annotated tag from a sha.
// The code is following parts of the gitea implementation.
func giteaGetAnnotatedTags(
func getAnnotatedTags(
ctx context.Context,
repoPath string,
shas []string,
@ -116,7 +104,7 @@ func giteaGetAnnotatedTags(
return nil, ErrRepositoryPathEmpty
}
// The tag is an annotated tag with a message.
writer, reader, cancel := gitea.CatFileBatch(ctx, repoPath)
writer, reader, cancel := CatFileBatch(ctx, repoPath)
defer func() {
cancel()
_ = writer.Close()
@ -128,9 +116,9 @@ func giteaGetAnnotatedTags(
if _, err := writer.Write([]byte(sha + "\n")); err != nil {
return nil, err
}
tagSha, typ, size, err := gitea.ReadBatchLine(reader)
tagSha, typ, size, err := ReadBatchHeaderLine(reader)
if err != nil {
if errors.Is(err, io.EOF) || gitea.IsErrNotExist(err) {
if errors.Is(err, io.EOF) || errors.IsNotFound(err) {
return nil, fmt.Errorf("tag with sha %s does not exist", sha)
}
return nil, err
@ -168,13 +156,13 @@ func parseTagDataFromCatFile(data []byte) (tag types.Tag, err error) {
p := 0
// parse object Id
tag.TargetSha, p, err = giteaParseCatFileLine(data, p, "object")
tag.TargetSha, p, err = parseCatFileLine(data, p, "object")
if err != nil {
return tag, err
}
// parse object type
rawType, p, err := giteaParseCatFileLine(data, p, "type")
rawType, p, err := parseCatFileLine(data, p, "type")
if err != nil {
return tag, err
}
@ -185,13 +173,13 @@ func parseTagDataFromCatFile(data []byte) (tag types.Tag, err error) {
}
// parse tag name
tag.Name, p, err = giteaParseCatFileLine(data, p, "tag")
tag.Name, p, err = parseCatFileLine(data, p, "tag")
if err != nil {
return tag, err
}
// parse tagger
rawTaggerInfo, p, err := giteaParseCatFileLine(data, p, "tagger")
rawTaggerInfo, p, err := parseCatFileLine(data, p, "tagger")
if err != nil {
return tag, err
}
@ -224,7 +212,7 @@ func parseTagDataFromCatFile(data []byte) (tag types.Tag, err error) {
return tag, nil
}
func giteaParseCatFileLine(data []byte, start int, header string) (string, int, error) {
func parseCatFileLine(data []byte, start int, header string) (string, int, error) {
// for simplicity only look at data from start onwards
data = data[start:]

View File

@ -25,9 +25,9 @@ import (
"strings"
"github.com/harness/gitness/errors"
"github.com/harness/gitness/git/command"
"github.com/harness/gitness/git/types"
gitea "code.gitea.io/gitea/modules/git"
"github.com/rs/zerolog/log"
)
@ -80,24 +80,31 @@ func lsTree(
if repoPath == "" {
return nil, ErrRepositoryPathEmpty
}
args := []string{"ls-tree", "-z", rev, treePath}
output, stderr, err := gitea.NewCommand(ctx, args...).RunStdString(&gitea.RunOpts{Dir: repoPath})
if strings.Contains(stderr, "fatal: Not a valid object name") {
return nil, errors.NotFound("revision %q not found", rev)
}
cmd := command.New("ls-tree",
command.WithFlag("-z"),
command.WithArg(rev),
command.WithArg(treePath),
)
output := &bytes.Buffer{}
err := cmd.Run(ctx,
command.WithDir(repoPath),
command.WithStdout(output),
)
if err != nil {
if strings.Contains(err.Error(), "fatal: Not a valid object name") {
return nil, errors.NotFound("revision %q not found", rev)
}
return nil, fmt.Errorf("failed to run git ls-tree: %w", err)
}
if output == "" {
if output.Len() == 0 {
return nil, &types.PathNotFoundError{Path: treePath}
}
n := strings.Count(output, "\x00")
n := bytes.Count(output.Bytes(), []byte{'\x00'})
list := make([]types.TreeNode, 0, n)
scan := bufio.NewScanner(strings.NewReader(output))
scan := bufio.NewScanner(output)
scan.Split(scanZeroSeparated)
for scan.Scan() {
line := scan.Text()
@ -105,7 +112,7 @@ func lsTree(
columns := regexpLsTreeColumns.FindStringSubmatch(line)
if columns == nil {
log.Ctx(ctx).Error().
Str("ls-tree", output). // logs the whole directory listing for the additional context
Str("ls-tree", output.String()). // logs the whole directory listing for the additional context
Str("line", line).
Msg("unrecognized format of git directory listing")
return nil, fmt.Errorf("unrecognized format of git directory listing: %q", line)
@ -179,20 +186,24 @@ func (a Adapter) GetTreeNode(ctx context.Context, repoPath, rev, treePath string
if repoPath == "" {
return nil, ErrRepositoryPathEmpty
}
args := []string{"show", "--no-patch", "--format=" + fmtTreeHash, rev}
treeSHA, stderr, err := gitea.NewCommand(ctx, args...).RunStdString(&gitea.RunOpts{Dir: repoPath})
if strings.Contains(stderr, "ambiguous argument") {
return nil, errors.NotFound("could not resolve git revision: %s", rev)
}
cmd := command.New("show",
command.WithFlag("--no-patch"),
command.WithFlag("--format="+fmtTreeHash),
command.WithArg(rev),
)
output := &bytes.Buffer{}
err := cmd.Run(ctx, command.WithDir(repoPath), command.WithStdout(output))
if err != nil {
if strings.Contains(err.Error(), "ambiguous argument") {
return nil, errors.NotFound("could not resolve git revision: %s", rev)
}
return nil, fmt.Errorf("failed to get root tree node: %w", err)
}
return &types.TreeNode{
NodeType: types.TreeNodeTypeTree,
Mode: types.TreeNodeModeTree,
Sha: treeSHA,
Sha: strings.TrimSpace(output.String()),
Name: "",
Path: "",
}, err
@ -226,15 +237,12 @@ func (a Adapter) ReadTree(
if repoPath == "" {
return ErrRepositoryPathEmpty
}
errbuf := bytes.Buffer{}
if err := gitea.NewCommand(ctx, append([]string{"read-tree", ref}, args...)...).
Run(&gitea.RunOpts{
Dir: repoPath,
Stdout: w,
Stderr: &errbuf,
}); err != nil {
return fmt.Errorf("unable to read %s in to the index: %w\n%s",
ref, err, errbuf.String())
cmd := command.New("read-tree",
command.WithArg(ref),
command.WithArg(args...),
)
if err := cmd.Run(ctx, command.WithDir(repoPath), command.WithStdout(w)); err != nil {
return fmt.Errorf("unable to read %s in to the index: %w", ref, err)
}
return nil
}

View File

@ -17,8 +17,10 @@ package command
const (
GitCommitterName = "GIT_COMMITTER_NAME"
GitCommitterEmail = "GIT_COMMITTER_EMAIL"
GitCommitterDate = "GIT_COMMITTER_DATE"
GitAuthorName = "GIT_AUTHOR_NAME"
GitAuthorEmail = "GIT_AUTHOR_EMAIL"
GitAuthorDate = "GIT_AUTHOR_DATE"
GitTrace = "GIT_TRACE"
GitTracePack = "GIT_TRACE_PACK_ACCESS"