merge changes from main

eb/code-1016-2
enver 2024-03-21 15:25:06 +01:00
commit 6d649d041a
17 changed files with 66 additions and 45 deletions

View File

@ -100,7 +100,7 @@ delete-tools: ## Delete the tools
# Install golangci-lint # Install golangci-lint
$(GOBIN)/golangci-lint: $(GOBIN)/golangci-lint:
@echo "🔘 Installing golangci-lint... (`date '+%H:%M:%S'`)" @echo "🔘 Installing golangci-lint... (`date '+%H:%M:%S'`)"
@curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GOBIN) @curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GOBIN) v1.56.2
# Install goimports to format code # Install goimports to format code
$(GOBIN)/goimports: $(GOBIN)/goimports:

View File

@ -17,6 +17,7 @@ package pullreq
import ( import (
"context" "context"
"fmt" "fmt"
"strings"
"time" "time"
apiauth "github.com/harness/gitness/app/api/auth" apiauth "github.com/harness/gitness/app/api/auth"
@ -42,6 +43,8 @@ import (
type MergeInput struct { type MergeInput struct {
Method enum.MergeMethod `json:"method"` Method enum.MergeMethod `json:"method"`
SourceSHA string `json:"source_sha"` SourceSHA string `json:"source_sha"`
Title string `json:"title"`
Message string `json:"message"`
BypassRules bool `json:"bypass_rules"` BypassRules bool `json:"bypass_rules"`
DryRun bool `json:"dry_run"` DryRun bool `json:"dry_run"`
} }
@ -64,6 +67,14 @@ func (in *MergeInput) sanitize() error {
in.Method = method in.Method = method
} }
// cleanup title / message (NOTE: git doesn't support white space only)
in.Title = strings.TrimSpace(in.Title)
in.Message = strings.TrimSpace(in.Message)
if in.Method == enum.MergeMethodRebase && (in.Title != "" || in.Message != "") {
return usererror.BadRequest("rebase doesn't support customizing commit title and message")
}
return nil return nil
} }
@ -306,15 +317,16 @@ func (c *Controller) Merge(
committer = identityFromPrincipalInfo(*session.Principal.ToPrincipalInfo()) committer = identityFromPrincipalInfo(*session.Principal.ToPrincipalInfo())
} }
var mergeTitle string // backfill commit title if none provided
if in.Title == "" {
switch in.Method { switch in.Method {
case enum.MergeMethodMerge: case enum.MergeMethodMerge:
mergeTitle = fmt.Sprintf("Merge branch '%s' of %s (#%d)", pr.SourceBranch, sourceRepo.Path, pr.Number) in.Title = fmt.Sprintf("Merge branch '%s' of %s (#%d)", pr.SourceBranch, sourceRepo.Path, pr.Number)
case enum.MergeMethodSquash: case enum.MergeMethodSquash:
mergeTitle = fmt.Sprintf("%s (#%d)", pr.Title, pr.Number) in.Title = fmt.Sprintf("%s (#%d)", pr.Title, pr.Number)
case enum.MergeMethodRebase: case enum.MergeMethodRebase:
mergeTitle = "" // Not used. // Not used.
}
} }
// create merge commit(s) // create merge commit(s)
@ -327,8 +339,8 @@ func (c *Controller) Merge(
BaseBranch: pr.TargetBranch, BaseBranch: pr.TargetBranch,
HeadRepoUID: sourceRepo.GitUID, HeadRepoUID: sourceRepo.GitUID,
HeadBranch: pr.SourceBranch, HeadBranch: pr.SourceBranch,
Title: mergeTitle, Title: in.Title,
Message: "", Message: in.Message,
Committer: committer, Committer: committer,
CommitterDate: &now, CommitterDate: &now,
Author: author, Author: author,

View File

@ -36,6 +36,7 @@ import (
"github.com/harness/gitness/lock" "github.com/harness/gitness/lock"
"github.com/harness/gitness/store/database/dbtx" "github.com/harness/gitness/store/database/dbtx"
"github.com/harness/gitness/types" "github.com/harness/gitness/types"
"github.com/harness/gitness/types/check"
"github.com/harness/gitness/types/enum" "github.com/harness/gitness/types/enum"
) )
@ -64,6 +65,7 @@ type Controller struct {
indexer keywordsearch.Indexer indexer keywordsearch.Indexer
resourceLimiter limiter.ResourceLimiter resourceLimiter limiter.ResourceLimiter
mtxManager lock.MutexManager mtxManager lock.MutexManager
identifierCheck check.RepoIdentifier
} }
func NewController( func NewController(
@ -85,6 +87,7 @@ func NewController(
indexer keywordsearch.Indexer, indexer keywordsearch.Indexer,
limiter limiter.ResourceLimiter, limiter limiter.ResourceLimiter,
mtxManager lock.MutexManager, mtxManager lock.MutexManager,
identifierCheck check.RepoIdentifier,
) *Controller { ) *Controller {
return &Controller{ return &Controller{
defaultBranch: config.Git.DefaultBranch, defaultBranch: config.Git.DefaultBranch,
@ -106,6 +109,7 @@ func NewController(
indexer: indexer, indexer: indexer,
resourceLimiter: limiter, resourceLimiter: limiter,
mtxManager: mtxManager, mtxManager: mtxManager,
identifierCheck: identifierCheck,
} }
} }

View File

@ -164,7 +164,7 @@ func (c *Controller) sanitizeCreateInput(in *CreateInput) error {
return err return err
} }
if err := check.RepoIdentifier(in.Identifier); err != nil { if err := c.identifierCheck(in.Identifier); err != nil {
return err return err
} }

View File

@ -22,7 +22,6 @@ import (
"github.com/harness/gitness/app/auth" "github.com/harness/gitness/app/auth"
"github.com/harness/gitness/app/services/importer" "github.com/harness/gitness/app/services/importer"
"github.com/harness/gitness/types" "github.com/harness/gitness/types"
"github.com/harness/gitness/types/check"
) )
type ImportInput struct { type ImportInput struct {
@ -98,7 +97,7 @@ func (c *Controller) sanitizeImportInput(in *ImportInput) error {
return err return err
} }
if err := check.RepoIdentifier(in.Identifier); err != nil { if err := c.identifierCheck(in.Identifier); err != nil {
return err return err
} }

View File

@ -22,7 +22,6 @@ import (
"github.com/harness/gitness/app/api/usererror" "github.com/harness/gitness/app/api/usererror"
"github.com/harness/gitness/app/auth" "github.com/harness/gitness/app/auth"
"github.com/harness/gitness/types" "github.com/harness/gitness/types"
"github.com/harness/gitness/types/check"
"github.com/harness/gitness/types/enum" "github.com/harness/gitness/types/enum"
) )
@ -93,7 +92,7 @@ func (c *Controller) sanitizeMoveInput(in *MoveInput) error {
} }
if in.Identifier != nil { if in.Identifier != nil {
if err := check.RepoIdentifier(*in.Identifier); err != nil { if err := c.identifierCheck(*in.Identifier); err != nil {
return err return err
} }
} }

View File

@ -28,6 +28,7 @@ import (
"github.com/harness/gitness/lock" "github.com/harness/gitness/lock"
"github.com/harness/gitness/store/database/dbtx" "github.com/harness/gitness/store/database/dbtx"
"github.com/harness/gitness/types" "github.com/harness/gitness/types"
"github.com/harness/gitness/types/check"
"github.com/google/wire" "github.com/google/wire"
) )
@ -56,10 +57,11 @@ func ProvideController(
indexer keywordsearch.Indexer, indexer keywordsearch.Indexer,
limiter limiter.ResourceLimiter, limiter limiter.ResourceLimiter,
mtxManager lock.MutexManager, mtxManager lock.MutexManager,
identifierCheck check.RepoIdentifier,
) *Controller { ) *Controller {
return NewController(config, tx, urlProvider, return NewController(config, tx, urlProvider,
authorizer, repoStore, authorizer, repoStore,
spaceStore, pipelineStore, spaceStore, pipelineStore,
principalStore, ruleStore, principalInfoCache, protectionManager, principalStore, ruleStore, principalInfoCache, protectionManager,
rpcClient, importer, codeOwners, reporeporter, indexer, limiter, mtxManager) rpcClient, importer, codeOwners, reporeporter, indexer, limiter, mtxManager, identifierCheck)
} }

View File

@ -131,7 +131,7 @@ func mapFileStats(c *git.Commit) []types.CommitFileStats {
fileStats[i] = types.CommitFileStats{ fileStats[i] = types.CommitFileStats{
Path: fStat.Path, Path: fStat.Path,
OldPath: fStat.OldPath, OldPath: fStat.OldPath,
Status: fStat.ChangeType, Status: fStat.Status,
ChangeStats: types.ChangeStats{ ChangeStats: types.ChangeStats{
Insertions: fStat.Insertions, Insertions: fStat.Insertions,
Deletions: fStat.Deletions, Deletions: fStat.Deletions,

View File

@ -192,18 +192,18 @@ func commitInfoFrom(commit git.Commit) CommitInfo {
for _, stat := range commit.FileStats { for _, stat := range commit.FileStats {
switch { switch {
case stat.ChangeType == gitenum.FileDiffStatusModified: case stat.Status == gitenum.FileDiffStatusModified:
modified = append(modified, stat.Path) modified = append(modified, stat.Path)
case stat.ChangeType == gitenum.FileDiffStatusRenamed: case stat.Status == gitenum.FileDiffStatusRenamed:
added = append(added, stat.Path) added = append(added, stat.Path)
removed = append(removed, stat.OldPath) removed = append(removed, stat.OldPath)
case stat.ChangeType == gitenum.FileDiffStatusDeleted: case stat.Status == gitenum.FileDiffStatusDeleted:
removed = append(removed, stat.Path) removed = append(removed, stat.Path)
case stat.ChangeType == gitenum.FileDiffStatusAdded || stat.ChangeType == gitenum.FileDiffStatusCopied: case stat.Status == gitenum.FileDiffStatusAdded || stat.Status == gitenum.FileDiffStatusCopied:
added = append(added, stat.Path) added = append(added, stat.Path)
case stat.ChangeType == gitenum.FileDiffStatusUndefined: case stat.Status == gitenum.FileDiffStatusUndefined:
default: default:
log.Warn().Msgf("unknown change type %q for path %q", stat.ChangeType, stat.Path) log.Warn().Msgf("unknown status %q for path %q", stat.Status, stat.Path)
} }
} }

View File

@ -187,7 +187,8 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
if err != nil { if err != nil {
return nil, err return nil, err
} }
repoController := repo.ProvideController(config, transactor, provider, authorizer, repoStore, spaceStore, pipelineStore, principalStore, ruleStore, principalInfoCache, protectionManager, gitInterface, repository, codeownersService, reporter, indexer, resourceLimiter, mutexManager) repoIdentifier := check.ProvideRepoIdentifierCheck()
repoController := repo.ProvideController(config, transactor, provider, authorizer, repoStore, spaceStore, pipelineStore, principalStore, ruleStore, principalInfoCache, protectionManager, gitInterface, repository, codeownersService, reporter, indexer, resourceLimiter, mutexManager, repoIdentifier)
executionStore := database.ProvideExecutionStore(db) executionStore := database.ProvideExecutionStore(db)
checkStore := database.ProvideCheckStore(db, principalInfoCache) checkStore := database.ProvideCheckStore(db, principalInfoCache)
stageStore := database.ProvideStageStore(db) stageStore := database.ProvideStageStore(db)

View File

@ -268,7 +268,7 @@ func getCommitFileStats(
fileStats[i] = CommitFileStats{ fileStats[i] = CommitFileStats{
Path: changeInfoTypes[path].Path, Path: changeInfoTypes[path].Path,
OldPath: changeInfoTypes[path].OldPath, OldPath: changeInfoTypes[path].OldPath,
ChangeType: changeInfoTypes[path].ChangeType, ChangeType: changeInfoTypes[path].Status,
Insertions: info.Insertions, Insertions: info.Insertions,
Deletions: info.Deletions, Deletions: info.Deletions,
} }
@ -345,7 +345,7 @@ func gitGetRenameDetails(
} }
for _, c := range changeInfos { for _, c := range changeInfos {
if c.ChangeType == enum.FileDiffStatusRenamed && (c.OldPath == path || c.Path == path) { if c.Status == enum.FileDiffStatusRenamed && (c.OldPath == path || c.Path == path) {
return &PathRenameDetails{ return &PathRenameDetails{
OldPath: c.OldPath, OldPath: c.OldPath,
Path: c.Path, Path: c.Path,
@ -360,8 +360,8 @@ func gitLogNameStatus(ctx context.Context, repoPath string, sha sha.SHA) ([]stri
cmd := command.New("log", cmd := command.New("log",
command.WithFlag("--name-status"), command.WithFlag("--name-status"),
command.WithFlag("--format="), command.WithFlag("--format="),
command.WithArg(sha.String()),
command.WithFlag("--max-count=1"), command.WithFlag("--max-count=1"),
command.WithArg(sha.String()),
) )
output := &bytes.Buffer{} output := &bytes.Buffer{}
err := cmd.Run(ctx, command.WithDir(repoPath), command.WithStdout(output)) err := cmd.Run(ctx, command.WithDir(repoPath), command.WithStdout(output))
@ -419,7 +419,7 @@ func getChangeInfoTypes(
c.Path = lineParts[1] c.Path = lineParts[1]
} }
c.ChangeType = convertChangeType(ctx, line) c.Status = convertFileDiffStatus(ctx, line)
changeInfoTypes[c.Path] = c changeInfoTypes[c.Path] = c
} }
@ -478,7 +478,7 @@ func getChangeInfoChanges(
} }
type changeInfoType struct { type changeInfoType struct {
ChangeType enum.FileDiffStatus Status enum.FileDiffStatus
OldPath string // populated only in case of renames OldPath string // populated only in case of renames
Path string Path string
} }
@ -487,7 +487,7 @@ type changeInfoChange struct {
Deletions int64 Deletions int64
} }
func convertChangeType(ctx context.Context, c string) enum.FileDiffStatus { func convertFileDiffStatus(ctx context.Context, c string) enum.FileDiffStatus {
switch { switch {
case strings.HasPrefix(c, "A"): case strings.HasPrefix(c, "A"):
return enum.FileDiffStatusAdded return enum.FileDiffStatusAdded

View File

@ -124,7 +124,7 @@ type ListCommitsOutput struct {
} }
type CommitFileStats struct { type CommitFileStats struct {
ChangeType enum.FileDiffStatus Status enum.FileDiffStatus
Path string Path string
OldPath string // populated only in case of renames OldPath string // populated only in case of renames
Insertions int64 Insertions int64

View File

@ -73,7 +73,7 @@ func mapFileStats(typeStats []api.CommitFileStats) []CommitFileStats {
for i, tStat := range typeStats { for i, tStat := range typeStats {
stats[i] = CommitFileStats{ stats[i] = CommitFileStats{
ChangeType: tStat.ChangeType, Status: tStat.ChangeType,
Path: tStat.Path, Path: tStat.Path,
OldPath: tStat.OldPath, OldPath: tStat.OldPath,
Insertions: tStat.Insertions, Insertions: tStat.Insertions,

View File

@ -121,8 +121,10 @@ func Identifier(identifier string) error {
return nil return nil
} }
// RepoIdentifier performs the default Identifier check and also blocks illegal repo identifiers. type RepoIdentifier func(identifier string) error
func RepoIdentifier(identifier string) error {
// RepoIdentifierDefault performs the default Identifier check and also blocks illegal repo identifiers.
func RepoIdentifierDefault(identifier string) error {
if err := Identifier(identifier); err != nil { if err := Identifier(identifier); err != nil {
return err return err
} }

View File

@ -22,6 +22,7 @@ import (
var WireSet = wire.NewSet( var WireSet = wire.NewSet(
ProvidePrincipalUIDCheck, ProvidePrincipalUIDCheck,
ProvideSpaceIdentifierCheck, ProvideSpaceIdentifierCheck,
ProvideRepoIdentifierCheck,
) )
func ProvideSpaceIdentifierCheck() SpaceIdentifier { func ProvideSpaceIdentifierCheck() SpaceIdentifier {
@ -31,3 +32,7 @@ func ProvideSpaceIdentifierCheck() SpaceIdentifier {
func ProvidePrincipalUIDCheck() PrincipalUID { func ProvidePrincipalUIDCheck() PrincipalUID {
return PrincipalUIDDefault return PrincipalUIDDefault
} }
func ProvideRepoIdentifierCheck() RepoIdentifier {
return RepoIdentifierDefault
}

View File

@ -39,7 +39,6 @@ const Editor = forwardRef<MonacoCodeEditorRef, AdvancedSourceCodeEditorProps>((p
const { getString } = useStrings() const { getString } = useStrings()
const { onChange, onEntityAddUpdate, onEntityFieldAddUpdate } = props const { onChange, onEntityAddUpdate, onEntityFieldAddUpdate } = props
const editorRef = useRef<MonacoCodeEditorRef | null>(null) const editorRef = useRef<MonacoCodeEditorRef | null>(null)
const [latestYAML, setLatestYAML] = useState<string>('')
const [entityYAMLData, setEntityYAMLData] = useState<EntityAddUpdateInterface>() const [entityYAMLData, setEntityYAMLData] = useState<EntityAddUpdateInterface>()
const [entityFieldData, setEntityFieldYAMLData] = useState<Partial<EntityAddUpdateInterface>>() const [entityFieldData, setEntityFieldYAMLData] = useState<Partial<EntityAddUpdateInterface>>()
const entityYAMLDataRef = useRef<EntityAddUpdateInterface>() const entityYAMLDataRef = useRef<EntityAddUpdateInterface>()
@ -50,10 +49,6 @@ const Editor = forwardRef<MonacoCodeEditorRef, AdvancedSourceCodeEditorProps>((p
setForwardedRef(ref, editor) setForwardedRef(ref, editor)
} }
useEffect(() => {
onChange?.(latestYAML)
}, [latestYAML]) // eslint-disable-line react-hooks/exhaustive-deps
useEffect(() => { useEffect(() => {
if (!isEmpty(entityYAMLData)) { if (!isEmpty(entityYAMLData)) {
onEntityAddUpdate(entityYAMLData) onEntityAddUpdate(entityYAMLData)
@ -179,7 +174,7 @@ const Editor = forwardRef<MonacoCodeEditorRef, AdvancedSourceCodeEditorProps>((p
const debouncedHandleYAMLUpdate = useMemo( const debouncedHandleYAMLUpdate = useMemo(
() => () =>
debounce((updatedYAML: string) => { debounce((updatedYAML: string) => {
setLatestYAML(updatedYAML) onChange?.(updatedYAML)
prepareEntityFieldUpdate() prepareEntityFieldUpdate()
}, 300), }, 300),
[prepareEntityFieldUpdate] [prepareEntityFieldUpdate]

View File

@ -15,7 +15,7 @@
*/ */
import React, { useMemo } from 'react' import React, { useMemo } from 'react'
import { Container, Layout, Button, FlexExpander, ButtonVariation, Text } from '@harnessio/uicore' import { Container, Layout, Button, FlexExpander, ButtonVariation, Text, ButtonSize } from '@harnessio/uicore'
import cx from 'classnames' import cx from 'classnames'
import { Icon } from '@harnessio/icons' import { Icon } from '@harnessio/icons'
import { Color } from '@harnessio/design-system' import { Color } from '@harnessio/design-system'
@ -33,6 +33,7 @@ import { useGetSpaceParam } from 'hooks/useGetSpaceParam'
import { permissionProps } from 'utils/Utils' import { permissionProps } from 'utils/Utils'
import CodeSearch from 'components/CodeSearch/CodeSearch' import CodeSearch from 'components/CodeSearch/CodeSearch'
import { useDocumentTitle } from 'hooks/useDocumentTitle' import { useDocumentTitle } from 'hooks/useDocumentTitle'
import { CopyButton } from 'components/CopyButton/CopyButton'
import css from './ContentHeader.module.scss' import css from './ContentHeader.module.scss'
export function ContentHeader({ export function ContentHeader({
@ -122,6 +123,7 @@ export function ContentHeader({
) )
}} }}
/> />
{resourcePath && <CopyButton content={resourcePath} icon={CodeIcon.Copy} size={ButtonSize.MEDIUM} />}
</Layout.Horizontal> </Layout.Horizontal>
</Container> </Container>
<FlexExpander /> <FlexExpander />