Skip to content

Commit

Permalink
Migrate distribution V1 commands to cli-artifactory (#1342)
Browse files Browse the repository at this point in the history
* Moved cli utils to plugins common for migrating ds commands from cli to artifactory
  • Loading branch information
bhanurp authored Feb 12, 2025
1 parent 284c79c commit e5223ab
Show file tree
Hide file tree
Showing 4 changed files with 259 additions and 0 deletions.
81 changes: 81 additions & 0 deletions common/cliutils/spec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package cliutils

import (
speccore "github.com/jfrog/jfrog-cli-core/v2/common/spec"
"github.com/jfrog/jfrog-cli-core/v2/plugins/components"
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
"strings"
)

func GetSpec(c *components.Context, isDownload, overrideFieldsIfSet bool) (specFiles *speccore.SpecFiles, err error) {
specFiles, err = speccore.CreateSpecFromFile(c.GetStringFlagValue("spec"), coreutils.SpecVarsStringToMap(c.GetStringFlagValue("spec-vars")))
if err != nil {
return nil, err
}
if isDownload {
trimPatternPrefix(specFiles)
}
if overrideFieldsIfSet {
overrideSpecFields(c, specFiles)
}
return
}

func overrideSpecFields(c *components.Context, specFiles *speccore.SpecFiles) {
for i := 0; i < len(specFiles.Files); i++ {
OverrideFieldsIfSet(specFiles.Get(i), c)
}
}

func trimPatternPrefix(specFiles *speccore.SpecFiles) {
for i := 0; i < len(specFiles.Files); i++ {
specFiles.Get(i).Pattern = strings.TrimPrefix(specFiles.Get(i).Pattern, "/")
}
}

func OverrideFieldsIfSet(spec *speccore.File, c *components.Context) {
overrideArrayIfSet(&spec.Exclusions, c, "exclusions")
overrideArrayIfSet(&spec.SortBy, c, "sort-by")
overrideIntIfSet(&spec.Offset, c, "offset")
overrideIntIfSet(&spec.Limit, c, "limit")
overrideStringIfSet(&spec.SortOrder, c, "sort-order")
overrideStringIfSet(&spec.Props, c, "props")
overrideStringIfSet(&spec.TargetProps, c, "target-props")
overrideStringIfSet(&spec.ExcludeProps, c, "exclude-props")
overrideStringIfSet(&spec.Build, c, "build")
overrideStringIfSet(&spec.Project, c, "project")
overrideStringIfSet(&spec.ExcludeArtifacts, c, "exclude-artifacts")
overrideStringIfSet(&spec.IncludeDeps, c, "include-deps")
overrideStringIfSet(&spec.Bundle, c, "bundle")
overrideStringIfSet(&spec.Recursive, c, "recursive")
overrideStringIfSet(&spec.Flat, c, "flat")
overrideStringIfSet(&spec.Explode, c, "explode")
overrideStringIfSet(&spec.BypassArchiveInspection, c, "bypass-archive-inspection")
overrideStringIfSet(&spec.Regexp, c, "regexp")
overrideStringIfSet(&spec.IncludeDirs, c, "include-dirs")
overrideStringIfSet(&spec.ValidateSymlinks, c, "validate-symlinks")
overrideStringIfSet(&spec.Symlinks, c, "symlinks")
overrideStringIfSet(&spec.Transitive, c, "transitive")
overrideStringIfSet(&spec.PublicGpgKey, c, "gpg-key")
}

// If `fieldName` exist in the cli args, read it to `field` as a string.
func overrideStringIfSet(field *string, c *components.Context, fieldName string) {
if c.IsFlagSet(fieldName) {
*field = c.GetStringFlagValue(fieldName)
}
}

// If `fieldName` exist in the cli args, read it to `field` as an array split by `;`.
func overrideArrayIfSet(field *[]string, c *components.Context, fieldName string) {
if c.IsFlagSet(fieldName) {
*field = append([]string{}, strings.Split(c.GetStringFlagValue(fieldName), ";")...)
}
}

// If `fieldName` exist in the cli args, read it to `field` as a int.
func overrideIntIfSet(field *int, c *components.Context, fieldName string) {
if c.IsFlagSet(fieldName) {
*field, _ = c.GetIntFlagValue(fieldName)
}
}
128 changes: 128 additions & 0 deletions common/cliutils/summary/summary.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package summary

import (
"encoding/json"
clientutils "github.com/jfrog/jfrog-client-go/utils"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
"github.com/jfrog/jfrog-client-go/utils/log"
"strings"
)

type StatusType int

const (
Success StatusType = iota
Failure
)

var StatusTypes = []string{
"success",
"failure",
}

func (statusType StatusType) MarshalJSON() ([]byte, error) {
return json.Marshal(StatusTypes[statusType])
}

func (statusType *StatusType) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
switch strings.ToLower(s) {
default:
*statusType = Failure
case "success":
*statusType = Success

}
return nil
}

func NewBuildInfoSummary(success, failed int, sha256 string, err error) *BuildInfoSummary {
summaryReport := GetSummaryReport(success, failed, false, err)
buildInfoSummary := BuildInfoSummary{Summary: *summaryReport, Sha256Array: []Sha256{}}
if success == 1 {
buildInfoSummary.AddSha256(sha256)
}
return &buildInfoSummary
}

func (summary *Summary) Marshal() ([]byte, error) {
return json.Marshal(summary)
}

func (bis *BuildInfoSummary) Marshal() ([]byte, error) {
return json.Marshal(bis)
}

type Summary struct {
Status StatusType `json:"status"`
Totals *Totals `json:"totals"`
}

type Totals struct {
Success int `json:"success"`
Failure int `json:"failure"`
}

type BuildInfoSummary struct {
Summary
Sha256Array []Sha256 `json:"files"`
}

type Sha256 struct {
Sha256Str string `json:"sha256"`
}

func (bis *BuildInfoSummary) AddSha256(sha256Str string) {
sha256 := Sha256{Sha256Str: sha256Str}
bis.Sha256Array = append(bis.Sha256Array, sha256)
}

func GetSummaryReport(success, failed int, failNoOp bool, err error) *Summary {
summary := &Summary{Totals: &Totals{}}
if err != nil || failed > 0 || (success == 0 && failNoOp) {
summary.Status = Failure
} else {
summary.Status = Success
}
summary.Totals.Success = success
summary.Totals.Failure = failed
return summary
}

func PrintBuildInfoSummaryReport(succeeded bool, sha256 string, originalErr error) error {
success, failed := 1, 0
if !succeeded {
success, failed = 0, 1
}
buildInfoSummary, mErr := CreateBuildInfoSummaryReportString(success, failed, sha256, originalErr)
if mErr != nil {
return summaryPrintError(mErr, originalErr)
}
log.Output(buildInfoSummary)
return summaryPrintError(mErr, originalErr)
}

func CreateBuildInfoSummaryReportString(success, failed int, sha256 string, err error) (string, error) {
buildInfoSummary := NewBuildInfoSummary(success, failed, sha256, err)
buildInfoSummaryContent, mErr := buildInfoSummary.Marshal()
if errorutils.CheckError(mErr) != nil {
return "", mErr
}
return clientutils.IndentJson(buildInfoSummaryContent), mErr
}

// Print summary report.
// a given non-nil error will pass through and be returned as is if no other errors are raised.
// In case of a nil error, the current function error will be returned.
func summaryPrintError(summaryError, originalError error) error {
if originalError != nil {
if summaryError != nil {
log.Error(summaryError)
}
return originalError
}
return summaryError
}
24 changes: 24 additions & 0 deletions plugins/common/utils.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package common

import (
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
clientutils "github.com/jfrog/jfrog-client-go/utils"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -100,3 +102,25 @@ func buildAndSortFlags(keys []string, flagsMap map[string]components.Flag) (flag
sort.Slice(flags, func(i, j int) bool { return flags[i].GetName() < flags[j].GetName() })
return
}

// This function indicates whether the command should be executed without
// confirmation warning or not.
// If the --quiet option was sent, it is used to determine whether to prompt the confirmation or not.
// If not, the command will prompt the confirmation, unless the CI environment variable was set to true.
func GetQuietValue(c *components.Context) bool {
if c.IsFlagSet("quiet") {
return c.GetBoolFlagValue("quiet")
}

return getCiValue()
}

// Return true if the CI environment variable was set to true.
func getCiValue() bool {
var ci bool
var err error
if ci, err = clientutils.GetBoolEnvValue(coreutils.CI, false); err != nil {
return false
}
return ci
}
26 changes: 26 additions & 0 deletions plugins/components/commandcomp.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,18 @@ func SetHiddenStrFlag() StringFlagOption {
}
}

func SetMandatoryFalse() StringFlagOption {
return func(f *StringFlag) {
f.Mandatory = false
}
}

func WithBoolDefaultValueFalse() BoolFlagOption {
return func(f *BoolFlag) {
f.DefaultValue = false
}
}

type BoolFlag struct {
BaseFlag
DefaultValue bool
Expand Down Expand Up @@ -201,3 +213,17 @@ func SetHiddenBoolFlag() BoolFlagOption {
f.Hidden = true
}
}

func (c *Context) WithDefaultIntFlagValue(flagName string, defValue int) (value int, err error) {
value = defValue
if c.IsFlagSet(flagName) {
var parsed int64
parsed, err = strconv.ParseInt(c.GetStringFlagValue(flagName), 0, 64)
if err != nil {
err = fmt.Errorf("can't parse int flag '%s': %w", flagName, err)
return
}
value = int(parsed)
}
return
}

0 comments on commit e5223ab

Please sign in to comment.