drone/types/pullreq_activity.go

169 lines
5.2 KiB
Go

// 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 types
import (
"bytes"
"encoding/json"
"fmt"
"github.com/harness/gitness/types/enum"
)
// PullReqActivity represents a pull request activity.
type PullReqActivity struct {
ID int64 `json:"id"`
Version int64 `json:"-"` // not returned, it's an internal field
CreatedBy int64 `json:"-"` // not returned, because the author info is in the Author field
Created int64 `json:"created"`
Updated int64 `json:"updated"` // we need updated to determine the latest version reliably.
Edited int64 `json:"edited"`
Deleted *int64 `json:"deleted,omitempty"`
ParentID *int64 `json:"parent_id"`
RepoID int64 `json:"repo_id"`
PullReqID int64 `json:"pullreq_id"`
Order int64 `json:"order"`
SubOrder int64 `json:"sub_order"`
ReplySeq int64 `json:"-"` // not returned, because it's a server's internal field
Type enum.PullReqActivityType `json:"type"`
Kind enum.PullReqActivityKind `json:"kind"`
Text string `json:"text"`
PayloadRaw json.RawMessage `json:"payload"`
Metadata *PullReqActivityMetadata `json:"metadata,omitempty"`
ResolvedBy *int64 `json:"-"` // not returned, because the resolver info is in the Resolver field
Resolved *int64 `json:"resolved,omitempty"`
Author PrincipalInfo `json:"author"`
Resolver *PrincipalInfo `json:"resolver,omitempty"`
CodeComment *CodeCommentFields `json:"code_comment,omitempty"`
Mentions map[int64]*PrincipalInfo `json:"mentions,omitempty"` // used only in response
}
func (a *PullReqActivity) IsValidCodeComment() bool {
return a.Type == enum.PullReqActivityTypeCodeComment &&
a.Kind == enum.PullReqActivityKindChangeComment &&
a.CodeComment != nil
}
func (a *PullReqActivity) AsCodeComment() *CodeComment {
if !a.IsValidCodeComment() {
return &CodeComment{}
}
return &CodeComment{
ID: a.ID,
Version: a.Version,
Updated: a.Updated,
CodeCommentFields: CodeCommentFields{
Outdated: a.CodeComment.Outdated,
MergeBaseSHA: a.CodeComment.MergeBaseSHA,
SourceSHA: a.CodeComment.SourceSHA,
Path: a.CodeComment.Path,
LineNew: a.CodeComment.LineNew,
SpanNew: a.CodeComment.SpanNew,
LineOld: a.CodeComment.LineOld,
SpanOld: a.CodeComment.SpanOld,
},
}
}
func (a *PullReqActivity) IsReplyable() bool {
return (a.Type == enum.PullReqActivityTypeComment || a.Type == enum.PullReqActivityTypeCodeComment) &&
a.SubOrder == 0
}
func (a *PullReqActivity) IsReply() bool {
return a.SubOrder > 0
}
// IsBlocking returns true if the pull request activity (comment/code-comment) is blocking the pull request merge.
func (a *PullReqActivity) IsBlocking() bool {
return a.SubOrder == 0 && a.Resolved == nil && a.Deleted == nil && a.Kind != enum.PullReqActivityKindSystem
}
// SetPayload sets the payload and verifies it's of correct type for the activity.
func (a *PullReqActivity) SetPayload(payload PullReqActivityPayload) error {
if payload == nil {
a.PayloadRaw = json.RawMessage(nil)
return nil
}
if payload.ActivityType() != a.Type {
return fmt.Errorf("wrong payload type %T for activity %s, payload is for %s",
payload, a.Type, payload.ActivityType())
}
var err error
if a.PayloadRaw, err = json.Marshal(payload); err != nil {
return fmt.Errorf("failed to marshal payload: %w", err)
}
return nil
}
// GetPayload returns the payload of the activity.
// An error is returned in case there's an issue retrieving the payload from its raw value.
// NOTE: To ensure rawValue gets changed always use SetPayload() with the updated payload.
func (a *PullReqActivity) GetPayload() (PullReqActivityPayload, error) {
// jsonMessage could also contain "null" - we still want to return ErrNoPayload in that case
if a.PayloadRaw == nil ||
bytes.Equal(a.PayloadRaw, jsonRawMessageNullBytes) {
return nil, ErrNoPayload
}
payload, err := newPayloadForActivity(a.Type)
if err != nil {
return nil, fmt.Errorf("failed to create new payload: %w", err)
}
if err = json.Unmarshal(a.PayloadRaw, payload); err != nil {
return nil, fmt.Errorf("failed to unmarshal payload: %w", err)
}
return payload, nil
}
// UpdateMetadata updates the metadata with the provided options.
func (a *PullReqActivity) UpdateMetadata(updates ...PullReqActivityMetadataUpdate) {
if a.Metadata == nil {
a.Metadata = &PullReqActivityMetadata{}
}
for _, update := range updates {
update.apply(a.Metadata)
}
if a.Metadata.IsEmpty() {
a.Metadata = nil
}
}
// PullReqActivityFilter stores pull request activity query parameters.
type PullReqActivityFilter struct {
After int64 `json:"after"`
Before int64 `json:"before"`
Limit int `json:"limit"`
Types []enum.PullReqActivityType `json:"type"`
Kinds []enum.PullReqActivityKind `json:"kind"`
}