feat: files in webhook payload (#1013)

eb/code-1016-2
Abhinav Singh 2024-02-06 02:06:43 +00:00 committed by Harness
parent 646c8fbe75
commit e0f8248ead
12 changed files with 340 additions and 100 deletions

View File

@ -23,6 +23,7 @@ import (
pullreqevents "github.com/harness/gitness/app/events/pullreq"
"github.com/harness/gitness/events"
"github.com/harness/gitness/git"
"github.com/harness/gitness/git/enum"
)
// handleFileViewedOnBranchUpdate handles pull request Branch Updated events.
@ -63,15 +64,16 @@ func (s *Service) handleFileViewedOnBranchUpdate(ctx context.Context,
// UPDATED: mark as obsolete - in case pr is closed file SHA is handling it
// This strategy leads to a behavior very similar to what github is doing
switch fileDiff.Status {
case git.FileDiffStatusAdded:
case enum.FileDiffStatusAdded:
obsoletePaths = append(obsoletePaths, fileDiff.Path)
case git.FileDiffStatusDeleted:
case enum.FileDiffStatusDeleted:
obsoletePaths = append(obsoletePaths, fileDiff.OldPath)
case git.FileDiffStatusRenamed:
case enum.FileDiffStatusRenamed:
obsoletePaths = append(obsoletePaths, fileDiff.OldPath, fileDiff.Path)
case git.FileDiffStatusModified:
case enum.FileDiffStatusModified:
obsoletePaths = append(obsoletePaths, fileDiff.Path)
case git.FileDiffStatusUndefined:
case enum.FileDiffStatusCopied:
case enum.FileDiffStatusUndefined:
// other cases we don't care
}
}

View File

@ -26,6 +26,8 @@ import (
"github.com/harness/gitness/types/enum"
)
const MaxWebhookCommitFileStats = 20
// ReferencePayload describes the payload of Reference related webhook triggers.
// Note: Use same payload for all reference operations to make it easier for consumers.
type ReferencePayload struct {
@ -61,8 +63,9 @@ func (s *Service) handleEventBranchCreated(ctx context.Context,
},
},
ReferenceDetailsSegment: ReferenceDetailsSegment{
SHA: event.Payload.SHA,
Commit: &commitInfo,
SHA: event.Payload.SHA,
Commit: &commitInfo,
HeadCommit: &commitInfo,
},
ReferenceUpdateSegment: ReferenceUpdateSegment{
OldSHA: types.NilSHA,
@ -79,10 +82,13 @@ func (s *Service) handleEventBranchUpdated(ctx context.Context,
return s.triggerForEventWithRepo(ctx, enum.WebhookTriggerBranchUpdated,
event.ID, event.Payload.PrincipalID, event.Payload.RepoID,
func(principal *types.Principal, repo *types.Repository) (any, error) {
commitInfo, err := s.fetchCommitInfoForEvent(ctx, repo.GitUID, event.Payload.NewSHA)
commitsInfo, totalCommits, err := s.fetchCommitsInfoForEvent(ctx, repo.GitUID,
event.Payload.OldSHA, event.Payload.NewSHA)
if err != nil {
return nil, err
}
commitInfo := commitsInfo[0]
repoInfo := repositoryInfoFrom(repo, s.urlProvider)
return &ReferencePayload{
@ -98,8 +104,11 @@ func (s *Service) handleEventBranchUpdated(ctx context.Context,
},
},
ReferenceDetailsSegment: ReferenceDetailsSegment{
SHA: event.Payload.NewSHA,
Commit: &commitInfo,
SHA: event.Payload.NewSHA,
Commit: &commitInfo,
HeadCommit: &commitInfo,
Commits: &commitsInfo,
TotalCommitsCount: totalCommits,
},
ReferenceUpdateSegment: ReferenceUpdateSegment{
OldSHA: event.Payload.OldSHA,
@ -152,13 +161,46 @@ func (s *Service) fetchCommitInfoForEvent(ctx context.Context, repoUID string, s
if errors.AsStatus(err) == errors.StatusNotFound {
// this could happen if the commit has been deleted and garbage collected by now
// or if the sha doesn't point to an event - either way discard the event.
return CommitInfo{}, events.NewDiscardEventErrorf("commit with sha '%s' doesn't exist", sha)
// or if the targetSha doesn't point to an event - either way discard the event.
return CommitInfo{}, events.NewDiscardEventErrorf("commit with targetSha '%s' doesn't exist", sha)
}
if err != nil {
return CommitInfo{}, fmt.Errorf("failed to get commit with sha '%s': %w", sha, err)
return CommitInfo{}, fmt.Errorf("failed to get commit with targetSha '%s': %w", sha, err)
}
return commitInfoFrom(out.Commit), nil
}
func (s *Service) fetchCommitsInfoForEvent(
ctx context.Context,
repoUID string,
oldSHA string,
newSHA string,
) ([]CommitInfo, int, error) {
listCommitsParams := git.ListCommitsParams{
ReadParams: git.ReadParams{RepoUID: repoUID},
GitREF: newSHA,
After: oldSHA,
Page: 0,
Limit: MaxWebhookCommitFileStats,
IncludeFileStats: true,
}
listCommitsOutput, err := s.git.ListCommits(ctx, &listCommitsParams)
if errors.AsStatus(err) == errors.StatusNotFound {
// this could happen if the commit has been deleted and garbage collected by now
// or if the targetSha doesn't point to an event - either way discard the event.
return []CommitInfo{}, 0, events.NewDiscardEventErrorf("commit with targetSha '%s' doesn't exist", newSHA)
}
if err != nil {
return []CommitInfo{}, 0, fmt.Errorf("failed to get commit with targetSha '%s': %w", newSHA, err)
}
if len(listCommitsOutput.Commits) == 0 {
return nil, 0, fmt.Errorf("no commit found between %s and %s", oldSHA, newSHA)
}
return commitsInfoFrom(listCommitsOutput.Commits), listCommitsOutput.TotalCommits, nil
}

View File

@ -75,8 +75,9 @@ func (s *Service) handleEventPullReqCreated(ctx context.Context,
},
},
ReferenceDetailsSegment: ReferenceDetailsSegment{
SHA: event.Payload.SourceSHA,
Commit: &commitInfo,
SHA: event.Payload.SourceSHA,
Commit: &commitInfo,
HeadCommit: &commitInfo,
},
}, nil
})
@ -122,8 +123,9 @@ func (s *Service) handleEventPullReqReopened(ctx context.Context,
},
},
ReferenceDetailsSegment: ReferenceDetailsSegment{
SHA: event.Payload.SourceSHA,
Commit: &commitInfo,
SHA: event.Payload.SourceSHA,
Commit: &commitInfo,
HeadCommit: &commitInfo,
},
}, nil
})
@ -147,10 +149,13 @@ func (s *Service) handleEventPullReqBranchUpdated(ctx context.Context,
return s.triggerForEventWithPullReq(ctx, enum.WebhookTriggerPullReqBranchUpdated,
event.ID, event.Payload.PrincipalID, event.Payload.PullReqID,
func(principal *types.Principal, pr *types.PullReq, targetRepo, sourceRepo *types.Repository) (any, error) {
commitInfo, err := s.fetchCommitInfoForEvent(ctx, sourceRepo.GitUID, event.Payload.NewSHA)
commitsInfo, totalCommits, err := s.fetchCommitsInfoForEvent(ctx, sourceRepo.GitUID,
event.Payload.OldSHA, event.Payload.NewSHA)
if err != nil {
return nil, err
}
commitInfo := commitsInfo[0]
targetRepoInfo := repositoryInfoFrom(targetRepo, s.urlProvider)
sourceRepoInfo := repositoryInfoFrom(sourceRepo, s.urlProvider)
@ -176,8 +181,11 @@ func (s *Service) handleEventPullReqBranchUpdated(ctx context.Context,
},
},
ReferenceDetailsSegment: ReferenceDetailsSegment{
SHA: event.Payload.NewSHA,
Commit: &commitInfo,
SHA: event.Payload.NewSHA,
Commit: &commitInfo,
HeadCommit: &commitInfo,
Commits: &commitsInfo,
TotalCommitsCount: totalCommits,
},
ReferenceUpdateSegment: ReferenceUpdateSegment{
OldSHA: event.Payload.OldSHA,
@ -230,8 +238,9 @@ func (s *Service) handleEventPullReqClosed(ctx context.Context,
},
},
ReferenceDetailsSegment: ReferenceDetailsSegment{
SHA: event.Payload.SourceSHA,
Commit: &commitInfo,
SHA: event.Payload.SourceSHA,
Commit: &commitInfo,
HeadCommit: &commitInfo,
},
}, nil
})
@ -280,8 +289,9 @@ func (s *Service) handleEventPullReqMerged(ctx context.Context,
},
},
ReferenceDetailsSegment: ReferenceDetailsSegment{
SHA: event.Payload.SourceSHA,
Commit: &commitInfo,
SHA: event.Payload.SourceSHA,
Commit: &commitInfo,
HeadCommit: &commitInfo,
},
}, nil
})
@ -336,8 +346,9 @@ func (s *Service) handleEventPullReqComment(
},
},
ReferenceDetailsSegment: ReferenceDetailsSegment{
SHA: event.Payload.SourceSHA,
Commit: &commitInfo,
SHA: event.Payload.SourceSHA,
Commit: &commitInfo,
HeadCommit: &commitInfo,
},
PullReqCommentSegment: PullReqCommentSegment{
CommentInfo: CommentInfo{

View File

@ -49,8 +49,9 @@ func (s *Service) handleEventTagCreated(ctx context.Context,
},
},
ReferenceDetailsSegment: ReferenceDetailsSegment{
SHA: event.Payload.SHA,
Commit: &commitInfo,
SHA: event.Payload.SHA,
Commit: &commitInfo,
HeadCommit: &commitInfo,
},
ReferenceUpdateSegment: ReferenceUpdateSegment{
OldSHA: types.NilSHA,
@ -67,10 +68,16 @@ func (s *Service) handleEventTagUpdated(ctx context.Context,
return s.triggerForEventWithRepo(ctx, enum.WebhookTriggerTagUpdated,
event.ID, event.Payload.PrincipalID, event.Payload.RepoID,
func(principal *types.Principal, repo *types.Repository) (any, error) {
commitInfo, err := s.fetchCommitInfoForEvent(ctx, repo.GitUID, event.Payload.NewSHA)
commitsInfo, totalCommits, err := s.fetchCommitsInfoForEvent(ctx, repo.GitUID,
event.Payload.OldSHA, event.Payload.NewSHA)
if err != nil {
return nil, err
}
commitInfo := CommitInfo{}
if len(commitsInfo) > 0 {
commitInfo = commitsInfo[0]
}
repoInfo := repositoryInfoFrom(repo, s.urlProvider)
return &ReferencePayload{
@ -86,8 +93,11 @@ func (s *Service) handleEventTagUpdated(ctx context.Context,
},
},
ReferenceDetailsSegment: ReferenceDetailsSegment{
SHA: event.Payload.NewSHA,
Commit: &commitInfo,
SHA: event.Payload.NewSHA,
Commit: &commitInfo,
HeadCommit: &commitInfo,
Commits: &commitsInfo,
TotalCommitsCount: totalCommits,
},
ReferenceUpdateSegment: ReferenceUpdateSegment{
OldSHA: event.Payload.OldSHA,

View File

@ -42,9 +42,16 @@ type ReferenceSegment struct {
Ref ReferenceInfo `json:"ref"`
}
// ReferenceDetailsSegment contains extra defails for reference related payloads for webhooks.
// ReferenceDetailsSegment contains extra details for reference related payloads for webhooks.
type ReferenceDetailsSegment struct {
SHA string `json:"sha"`
SHA string `json:"sha"`
HeadCommit *CommitInfo `json:"head_commit,omitempty"`
Commits *[]CommitInfo `json:"commits,omitempty"`
TotalCommitsCount int `json:"total_commits_count,omitempty"`
// Deprecated
Commit *CommitInfo `json:"commit,omitempty"`
}
@ -168,6 +175,10 @@ type CommitInfo struct {
Message string `json:"message"`
Author SignatureInfo `json:"author"`
Committer SignatureInfo `json:"committer"`
Added []string `json:"added"`
Removed []string `json:"removed"`
Modified []string `json:"modified"`
}
// commitInfoFrom gets the CommitInfo from a git.Commit.
@ -177,9 +188,21 @@ func commitInfoFrom(commit git.Commit) CommitInfo {
Message: commit.Message,
Author: signatureInfoFrom(commit.Author),
Committer: signatureInfoFrom(commit.Committer),
Added: commit.FileStats.Added,
Removed: commit.FileStats.Removed,
Modified: commit.FileStats.Modified,
}
}
// commitsInfoFrom gets the ExtendedCommitInfo from a []git.Commit.
func commitsInfoFrom(commits []git.Commit) []CommitInfo {
commitsInfo := make([]CommitInfo, len(commits))
for i, commit := range commits {
commitsInfo[i] = commitInfoFrom(commit)
}
return commitsInfo
}
// SignatureInfo describes the commit signature related info for a webhook payload.
// NOTE: don't use types package as we want webhook payload to be independent from API calls.
type SignatureInfo struct {

View File

@ -55,8 +55,14 @@ type Adapter interface {
opts *types.WalkReferencesOptions) error
GetCommit(ctx context.Context, repoPath string, ref string) (*types.Commit, error)
GetCommits(ctx context.Context, repoPath string, refs []string) ([]types.Commit, error)
ListCommits(ctx context.Context, repoPath string,
ref string, page int, limit int, filter types.CommitFilter) ([]types.Commit, []types.PathRenameDetails, error)
ListCommits(
ctx context.Context,
repoPath string,
ref string,
page int,
limit int,
includeFileStats bool,
filter types.CommitFilter) ([]types.Commit, []types.PathRenameDetails, error)
ListCommitSHAs(ctx context.Context, repoPath string,
ref string, page int, limit int, filter types.CommitFilter) ([]string, error)
GetLatestCommit(ctx context.Context, repoPath string, ref string, treePath string) (*types.Commit, error)

View File

@ -24,9 +24,11 @@ import (
"github.com/harness/gitness/errors"
"github.com/harness/gitness/git/command"
"github.com/harness/gitness/git/enum"
"github.com/harness/gitness/git/types"
gitea "code.gitea.io/gitea/modules/git"
"github.com/rs/zerolog/log"
)
// GetLatestCommit gets the latest commit of a path relative from the provided revision.
@ -135,11 +137,13 @@ func (a Adapter) ListCommitSHAs(
// ListCommits lists the commits reachable from ref.
// Note: ref & afterRef can be Branch / Tag / CommitSHA.
// Note: commits returned are [ref->...->afterRef).
func (a Adapter) ListCommits(ctx context.Context,
func (a Adapter) ListCommits(
ctx context.Context,
repoPath string,
ref string,
page int,
limit int,
includeFileStats bool,
filter types.CommitFilter,
) ([]types.Commit, []types.PathRenameDetails, error) {
if repoPath == "" {
@ -169,10 +173,17 @@ func (a Adapter) ListCommits(ctx context.Context,
return nil, nil, err
}
commits[i] = *commit
if includeFileStats {
err = includeFileStatsInCommits(ctx, giteaRepo, commits)
if err != nil {
return nil, nil, err
}
}
}
if len(filter.Path) != 0 {
renameDetailsList, err := getRenameDetails(giteaRepo, commits, filter.Path)
renameDetailsList, err := getRenameDetails(ctx, giteaRepo, commits, filter.Path)
if err != nil {
return nil, nil, err
}
@ -183,6 +194,52 @@ func (a Adapter) ListCommits(ctx context.Context,
return commits, nil, nil
}
func includeFileStatsInCommits(
ctx context.Context,
giteaRepo *gitea.Repository,
commits []types.Commit,
) error {
for i, commit := range commits {
fileStats, err := getFileStats(ctx, giteaRepo, commit.SHA)
if err != nil {
return fmt.Errorf("failed to get file stat: %w", err)
}
commits[i].FileStats = fileStats
}
return nil
}
func getFileStats(
ctx context.Context,
giteaRepo *gitea.Repository,
sha string,
) (types.CommitFileStats, error) {
changeInfos, err := getChangeInfos(ctx, giteaRepo, sha)
if err != nil {
return types.CommitFileStats{}, fmt.Errorf("failed to get change infos: %w", err)
}
fileStats := types.CommitFileStats{
Added: make([]string, 0),
Removed: make([]string, 0),
Modified: make([]string, 0),
}
for _, c := range changeInfos {
switch {
case c.ChangeType == enum.FileDiffStatusModified || c.ChangeType == enum.FileDiffStatusRenamed:
fileStats.Modified = append(fileStats.Modified, c.Path)
case c.ChangeType == enum.FileDiffStatusDeleted:
fileStats.Removed = append(fileStats.Removed, c.Path)
case c.ChangeType == enum.FileDiffStatusAdded || c.ChangeType == enum.FileDiffStatusCopied:
fileStats.Added = append(fileStats.Added, c.Path)
case c.ChangeType == enum.FileDiffStatusUndefined:
default:
log.Ctx(ctx).Warn().Msgf("unknown change type %q for path %q",
c.ChangeType, c.Path)
}
}
return fileStats, nil
}
// In case of rename of a file, same commit will be listed twice - Once in old file and second time in new file.
// Hence, we are making it a pattern to only list it as part of new file and not as part of old file.
func cleanupCommitsForRename(
@ -203,6 +260,7 @@ func cleanupCommitsForRename(
}
func getRenameDetails(
ctx context.Context,
giteaRepo *gitea.Repository,
commits []types.Commit,
path string,
@ -213,7 +271,7 @@ func getRenameDetails(
renameDetailsList := make([]types.PathRenameDetails, 0, 2)
renameDetails, err := giteaGetRenameDetails(giteaRepo, commits[0].SHA, path)
renameDetails, err := giteaGetRenameDetails(ctx, giteaRepo, commits[0].SHA, path)
if err != nil {
return nil, err
}
@ -226,7 +284,7 @@ func getRenameDetails(
return renameDetailsList, nil
}
renameDetailsLast, err := giteaGetRenameDetails(giteaRepo, commits[len(commits)-1].SHA, path)
renameDetailsLast, err := giteaGetRenameDetails(ctx, giteaRepo, commits[len(commits)-1].SHA, path)
if err != nil {
return nil, err
}
@ -239,10 +297,33 @@ func getRenameDetails(
}
func giteaGetRenameDetails(
ctx context.Context,
giteaRepo *gitea.Repository,
ref string,
path string,
) (*types.PathRenameDetails, error) {
changeInfos, err := getChangeInfos(ctx, giteaRepo, ref)
if err != nil {
return &types.PathRenameDetails{}, fmt.Errorf("failed to get change infos %w", err)
}
for _, c := range changeInfos {
if c.ChangeType == enum.FileDiffStatusRenamed && (c.Path == path || c.NewPath == path) {
return &types.PathRenameDetails{
OldPath: c.Path,
NewPath: c.NewPath,
}, nil
}
}
return &types.PathRenameDetails{}, nil
}
func getChangeInfos(
ctx context.Context,
giteaRepo *gitea.Repository,
ref string,
) ([]changeInfo, error) {
cmd := command.New("log",
command.WithArg(ref),
command.WithFlag("--name-status"),
@ -253,38 +334,60 @@ func giteaGetRenameDetails(
if err != nil {
return nil, fmt.Errorf("failed to trigger log command: %w", err)
}
lines := parseLinesToSlice(output.Bytes())
changeType, oldPath, newPath, err := getFileChangeTypeFromLog(lines, path)
changeInfos, err := getFileChangeTypeFromLog(ctx, lines)
if err != nil {
return nil, err
}
return changeInfos, nil
}
if strings.HasPrefix(*changeType, "R") {
return &types.PathRenameDetails{
OldPath: *oldPath,
NewPath: *newPath,
}, nil
}
return &types.PathRenameDetails{}, nil
type changeInfo struct {
ChangeType enum.FileDiffStatus
Path string
// populated only in case of renames
NewPath string
}
func getFileChangeTypeFromLog(
ctx context.Context,
changeStrings []string,
filePath string,
) (*string, *string, *string, error) {
for _, changeString := range changeStrings {
if strings.Contains(changeString, filePath) {
changeInfo := strings.Split(changeString, "\t")
if len(changeInfo) != 3 {
return &changeInfo[0], nil, nil, nil
}
return &changeInfo[0], &changeInfo[1], &changeInfo[2], nil
) ([]changeInfo, error) {
changeInfos := make([]changeInfo, len(changeStrings))
for i, changeString := range changeStrings {
changeStringSplit := strings.Split(changeString, "\t")
if len(changeStringSplit) < 1 {
return changeInfos, fmt.Errorf("could not parse changeString %q", changeString)
}
c := changeInfo{}
c.ChangeType = convertChangeType(ctx, changeStringSplit[0])
c.Path = changeStringSplit[1]
if len(changeStringSplit) == 3 {
c.NewPath = changeStringSplit[2]
}
changeInfos[i] = c
}
return changeInfos, nil
}
func convertChangeType(ctx context.Context, c string) enum.FileDiffStatus {
switch {
case strings.HasPrefix(c, "A"):
return enum.FileDiffStatusAdded
case strings.HasPrefix(c, "C"):
return enum.FileDiffStatusCopied
case strings.HasPrefix(c, "D"):
return enum.FileDiffStatusDeleted
case strings.HasPrefix(c, "M"):
return enum.FileDiffStatusModified
case strings.HasPrefix(c, "R"):
return enum.FileDiffStatusRenamed
default:
log.Ctx(ctx).Warn().Msgf("encountered unknown change type %s", c)
return enum.FileDiffStatusUndefined
}
return nil, nil, nil, fmt.Errorf("could not parse change for the file '%s'", filePath)
}
// GetCommit returns the (latest) commit for a specific revision.

View File

@ -30,11 +30,12 @@ type GetCommitParams struct {
}
type Commit struct {
SHA string `json:"sha"`
Title string `json:"title"`
Message string `json:"message,omitempty"`
Author Signature `json:"author"`
Committer Signature `json:"committer"`
SHA string `json:"sha"`
Title string `json:"title"`
Message string `json:"message,omitempty"`
Author Signature `json:"author"`
Committer Signature `json:"committer"`
FileStats CommitFileStats `json:"file_stats,omitempty"`
}
type GetCommitOutput struct {
@ -105,6 +106,9 @@ type ListCommitsParams struct {
// Committer allows to filter for commits based on the committer - Optional, ignored if string is empty.
Committer string
// IncludeFileStats allows you to include information about files changed, added and modified.
IncludeFileStats bool
}
type RenameDetails struct {
@ -120,6 +124,12 @@ type ListCommitsOutput struct {
TotalCommits int
}
type CommitFileStats struct {
Added []string
Modified []string
Removed []string
}
func (s *Service) ListCommits(ctx context.Context, params *ListCommitsParams) (*ListCommitsOutput, error) {
if params == nil {
return nil, ErrNoParamsProvided
@ -133,6 +143,7 @@ func (s *Service) ListCommits(ctx context.Context, params *ListCommitsParams) (*
params.GitREF,
int(params.Page),
int(params.Limit),
params.IncludeFileStats,
types.CommitFilter{
AfterRef: params.After,
Path: params.Path,

View File

@ -24,6 +24,7 @@ import (
"github.com/harness/gitness/errors"
"github.com/harness/gitness/git/diff"
"github.com/harness/gitness/git/enum"
"github.com/harness/gitness/git/types"
"golang.org/x/sync/errgroup"
@ -296,44 +297,31 @@ func (s *Service) DiffCut(ctx context.Context, params *DiffCutParams) (DiffCutOu
}
type FileDiff struct {
SHA string `json:"sha"`
OldSHA string `json:"old_sha,omitempty"`
Path string `json:"path"`
OldPath string `json:"old_path,omitempty"`
Status FileDiffStatus `json:"status"`
Additions int64 `json:"additions"`
Deletions int64 `json:"deletions"`
Changes int64 `json:"changes"`
Patch []byte `json:"patch,omitempty"`
IsBinary bool `json:"is_binary"`
IsSubmodule bool `json:"is_submodule"`
SHA string `json:"sha"`
OldSHA string `json:"old_sha,omitempty"`
Path string `json:"path"`
OldPath string `json:"old_path,omitempty"`
Status enum.FileDiffStatus `json:"status"`
Additions int64 `json:"additions"`
Deletions int64 `json:"deletions"`
Changes int64 `json:"changes"`
Patch []byte `json:"patch,omitempty"`
IsBinary bool `json:"is_binary"`
IsSubmodule bool `json:"is_submodule"`
}
type FileDiffStatus string
const (
// NOTE: keeping values upper case for now to stay consistent with current API.
// TODO: change drone/go-scm (and potentially new dependencies) to case insensitive.
FileDiffStatusUndefined FileDiffStatus = "UNDEFINED"
FileDiffStatusAdded FileDiffStatus = "ADDED"
FileDiffStatusModified FileDiffStatus = "MODIFIED"
FileDiffStatusDeleted FileDiffStatus = "DELETED"
FileDiffStatusRenamed FileDiffStatus = "RENAMED"
)
func parseFileDiffStatus(ftype diff.FileType) FileDiffStatus {
func parseFileDiffStatus(ftype diff.FileType) enum.FileDiffStatus {
switch ftype {
case diff.FileAdd:
return FileDiffStatusAdded
return enum.FileDiffStatusAdded
case diff.FileDelete:
return FileDiffStatusDeleted
return enum.FileDiffStatusDeleted
case diff.FileChange:
return FileDiffStatusModified
return enum.FileDiffStatusModified
case diff.FileRename:
return FileDiffStatusRenamed
return enum.FileDiffStatusRenamed
default:
return FileDiffStatusUndefined
return enum.FileDiffStatusUndefined
}
}

29
git/enum/diff.go Normal file
View File

@ -0,0 +1,29 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package enum
type FileDiffStatus string
const (
// NOTE: keeping values upper case for now to stay consistent with current API.
// TODO: change drone/go-scm (and potentially new dependencies) to case insensitive.
FileDiffStatusUndefined FileDiffStatus = "UNDEFINED"
FileDiffStatusAdded FileDiffStatus = "ADDED"
FileDiffStatusModified FileDiffStatus = "MODIFIED"
FileDiffStatusDeleted FileDiffStatus = "DELETED"
FileDiffStatusRenamed FileDiffStatus = "RENAMED"
FileDiffStatusCopied FileDiffStatus = "COPIED"
)

View File

@ -55,16 +55,24 @@ func mapCommit(c *types.Commit) (*Commit, error) {
if err != nil {
return nil, fmt.Errorf("failed to map rpc committer: %w", err)
}
return &Commit{
SHA: c.SHA,
Title: c.Title,
Message: c.Message,
Author: *author,
Committer: *comitter,
FileStats: *mapFileStats(&c.FileStats),
}, nil
}
func mapFileStats(s *types.CommitFileStats) *CommitFileStats {
return &CommitFileStats{
Added: s.Added,
Modified: s.Modified,
Removed: s.Removed,
}
}
func mapSignature(s *types.Signature) (*Signature, error) {
if s == nil {
return nil, fmt.Errorf("rpc signature is nil")

View File

@ -141,11 +141,18 @@ type WalkReferencesOptions struct {
}
type Commit struct {
SHA string `json:"sha"`
Title string `json:"title"`
Message string `json:"message,omitempty"`
Author Signature `json:"author"`
Committer Signature `json:"committer"`
SHA string `json:"sha"`
Title string `json:"title"`
Message string `json:"message,omitempty"`
Author Signature `json:"author"`
Committer Signature `json:"committer"`
FileStats CommitFileStats `json:"file_stats,omitempty"`
}
type CommitFileStats struct {
Added []string
Modified []string
Removed []string
}
type Branch struct {