diff --git a/lifecycle/common.go b/lifecycle/common.go deleted file mode 100644 index 5ec4b4131..000000000 --- a/lifecycle/common.go +++ /dev/null @@ -1,83 +0,0 @@ -package lifecycle - -import ( - "github.com/jfrog/jfrog-cli-core/v2/artifactory/utils" - "github.com/jfrog/jfrog-cli-core/v2/common/spec" - "github.com/jfrog/jfrog-cli-core/v2/utils/config" - "github.com/jfrog/jfrog-client-go/lifecycle" - "github.com/jfrog/jfrog-client-go/lifecycle/services" - clientUtils "github.com/jfrog/jfrog-client-go/utils" - "github.com/jfrog/jfrog-client-go/utils/distribution" -) - -const minimalLifecycleArtifactoryVersion = "7.63.2" - -type releaseBundleCmd struct { - serverDetails *config.ServerDetails - releaseBundleName string - releaseBundleVersion string - sync bool - rbProjectKey string -} - -func (rbc *releaseBundleCmd) getPrerequisites() (servicesManager *lifecycle.LifecycleServicesManager, - rbDetails services.ReleaseBundleDetails, queryParams services.CommonOptionalQueryParams, err error) { - return rbc.initPrerequisites() -} - -func (rbp *ReleaseBundlePromoteCommand) getPromotionPrerequisites() (servicesManager *lifecycle.LifecycleServicesManager, - rbDetails services.ReleaseBundleDetails, queryParams services.CommonOptionalQueryParams, err error) { - servicesManager, rbDetails, queryParams, err = rbp.initPrerequisites() - queryParams.PromotionType = rbp.promotionType - return servicesManager, rbDetails, queryParams, err -} - -func (rbc *releaseBundleCmd) initPrerequisites() (servicesManager *lifecycle.LifecycleServicesManager, - rbDetails services.ReleaseBundleDetails, queryParams services.CommonOptionalQueryParams, err error) { - servicesManager, err = utils.CreateLifecycleServiceManager(rbc.serverDetails, false) - if err != nil { - return - } - rbDetails = services.ReleaseBundleDetails{ - ReleaseBundleName: rbc.releaseBundleName, - ReleaseBundleVersion: rbc.releaseBundleVersion, - } - queryParams = services.CommonOptionalQueryParams{ - ProjectKey: rbc.rbProjectKey, - Async: !rbc.sync, - } - - return -} - -func validateArtifactoryVersionSupported(serverDetails *config.ServerDetails) error { - rtServiceManager, err := utils.CreateServiceManager(serverDetails, 3, 0, false) - if err != nil { - return err - } - - versionStr, err := rtServiceManager.GetVersion() - if err != nil { - return err - } - - return clientUtils.ValidateMinimumVersion(clientUtils.Artifactory, versionStr, minimalLifecycleArtifactoryVersion) -} - -// If distribution rules are empty, distribute to all edges. -func getAggregatedDistRules(distributionRules *spec.DistributionRules) (aggregatedRules []*distribution.DistributionCommonParams) { - if isDistributionRulesEmpty(distributionRules) { - aggregatedRules = append(aggregatedRules, &distribution.DistributionCommonParams{SiteName: "*"}) - } else { - for _, rules := range distributionRules.DistributionRules { - aggregatedRules = append(aggregatedRules, rules.ToDistributionCommonParams()) - } - } - return -} - -func isDistributionRulesEmpty(distributionRules *spec.DistributionRules) bool { - return distributionRules == nil || - len(distributionRules.DistributionRules) == 0 || - len(distributionRules.DistributionRules) == 1 && distributionRules.DistributionRules[0].IsEmpty() -} diff --git a/lifecycle/common_test.go b/lifecycle/common_test.go deleted file mode 100644 index 8eb58b95c..000000000 --- a/lifecycle/common_test.go +++ /dev/null @@ -1,69 +0,0 @@ -package lifecycle - -import ( - "github.com/jfrog/jfrog-cli-core/v2/utils/config" - "github.com/jfrog/jfrog-client-go/lifecycle/services" - "github.com/stretchr/testify/assert" - "testing" -) - -func TestGetPrerequisites_Success(t *testing.T) { - serverDetails := &config.ServerDetails{} - rbCmd := &releaseBundleCmd{ - serverDetails: serverDetails, - releaseBundleName: "testRelease", - releaseBundleVersion: "1.0.0", - sync: true, - rbProjectKey: "project1", - } - - expectedQueryParams := services.CommonOptionalQueryParams{ - ProjectKey: rbCmd.rbProjectKey, - Async: false, - } - - expectedRbDetails := services.ReleaseBundleDetails{ - ReleaseBundleName: rbCmd.releaseBundleName, - ReleaseBundleVersion: rbCmd.releaseBundleVersion, - } - - servicesManager, rbDetails, queryParams, err := rbCmd.getPrerequisites() - - assert.NoError(t, err) - assert.NotNil(t, servicesManager, "Expected servicesManager to be initialized") - assert.Equal(t, expectedRbDetails, rbDetails, "ReleaseBundleDetails does not match expected values") - assert.Equal(t, expectedQueryParams, queryParams, "QueryParams do not match expected values") - -} - -func TestGetPromotionPrerequisites_Success(t *testing.T) { - serverDetails := &config.ServerDetails{} - rbp := &ReleaseBundlePromoteCommand{ - promotionType: "move", - releaseBundleCmd: releaseBundleCmd{ - serverDetails: serverDetails, - releaseBundleName: "testRelease", - releaseBundleVersion: "1.0.0", - sync: true, - rbProjectKey: "project1", - }, - } - - expectedQueryParams := services.CommonOptionalQueryParams{ - ProjectKey: rbp.rbProjectKey, - Async: false, - PromotionType: rbp.promotionType, - } - - expectedRbDetails := services.ReleaseBundleDetails{ - ReleaseBundleName: rbp.releaseBundleName, - ReleaseBundleVersion: rbp.releaseBundleVersion, - } - - servicesManager, rbDetails, queryParams, err := rbp.getPromotionPrerequisites() - - assert.NoError(t, err) - assert.NotNil(t, servicesManager, "Expected servicesManager to be initialized") - assert.Equal(t, expectedRbDetails, rbDetails, "ReleaseBundleDetails do not match expected values") // Replace _ with appropriate variable. - assert.Equal(t, expectedQueryParams, queryParams, "QueryParams do not match expected values") -} diff --git a/lifecycle/createcommon.go b/lifecycle/createcommon.go deleted file mode 100644 index 6b0e7f35c..000000000 --- a/lifecycle/createcommon.go +++ /dev/null @@ -1,253 +0,0 @@ -package lifecycle - -import ( - "github.com/jfrog/jfrog-cli-core/v2/common/spec" - "github.com/jfrog/jfrog-cli-core/v2/utils/config" - "github.com/jfrog/jfrog-cli-core/v2/utils/coreutils" - "github.com/jfrog/jfrog-client-go/lifecycle/services" - "github.com/jfrog/jfrog-client-go/utils/errorutils" -) - -const ( - missingCreationSourcesErrMsg = "unexpected err while validating spec - could not detect any creation sources" - multipleCreationSourcesErrMsg = "multiple creation sources were detected in separate spec files. Only a single creation source should be provided. Detected:" - singleAqlErrMsg = "only a single aql query can be provided" -) - -type ReleaseBundleCreateCommand struct { - releaseBundleCmd - signingKeyName string - spec *spec.SpecFiles - // Backward compatibility: - buildsSpecPath string - releaseBundlesSpecPath string -} - -func NewReleaseBundleCreateCommand() *ReleaseBundleCreateCommand { - return &ReleaseBundleCreateCommand{} -} - -func (rbc *ReleaseBundleCreateCommand) SetServerDetails(serverDetails *config.ServerDetails) *ReleaseBundleCreateCommand { - rbc.serverDetails = serverDetails - return rbc -} - -func (rbc *ReleaseBundleCreateCommand) SetReleaseBundleName(releaseBundleName string) *ReleaseBundleCreateCommand { - rbc.releaseBundleName = releaseBundleName - return rbc -} - -func (rbc *ReleaseBundleCreateCommand) SetReleaseBundleVersion(releaseBundleVersion string) *ReleaseBundleCreateCommand { - rbc.releaseBundleVersion = releaseBundleVersion - return rbc -} - -func (rbc *ReleaseBundleCreateCommand) SetSigningKeyName(signingKeyName string) *ReleaseBundleCreateCommand { - rbc.signingKeyName = signingKeyName - return rbc -} - -func (rbc *ReleaseBundleCreateCommand) SetSync(sync bool) *ReleaseBundleCreateCommand { - rbc.sync = sync - return rbc -} - -func (rbc *ReleaseBundleCreateCommand) SetReleaseBundleProject(rbProjectKey string) *ReleaseBundleCreateCommand { - rbc.rbProjectKey = rbProjectKey - return rbc -} - -func (rbc *ReleaseBundleCreateCommand) SetSpec(spec *spec.SpecFiles) *ReleaseBundleCreateCommand { - rbc.spec = spec - return rbc -} - -// Deprecated -func (rbc *ReleaseBundleCreateCommand) SetBuildsSpecPath(buildsSpecPath string) *ReleaseBundleCreateCommand { - rbc.buildsSpecPath = buildsSpecPath - return rbc -} - -// Deprecated -func (rbc *ReleaseBundleCreateCommand) SetReleaseBundlesSpecPath(releaseBundlesSpecPath string) *ReleaseBundleCreateCommand { - rbc.releaseBundlesSpecPath = releaseBundlesSpecPath - return rbc -} - -func (rbc *ReleaseBundleCreateCommand) CommandName() string { - return "rb_create" -} - -func (rbc *ReleaseBundleCreateCommand) ServerDetails() (*config.ServerDetails, error) { - return rbc.serverDetails, nil -} - -func (rbc *ReleaseBundleCreateCommand) Run() error { - if err := validateArtifactoryVersionSupported(rbc.serverDetails); err != nil { - return err - } - - servicesManager, rbDetails, queryParams, err := rbc.getPrerequisites() - if err != nil { - return err - } - - sourceType, err := rbc.identifySourceType() - if err != nil { - return err - } - - switch sourceType { - case services.Aql: - return rbc.createFromAql(servicesManager, rbDetails, queryParams) - case services.Artifacts: - return rbc.createFromArtifacts(servicesManager, rbDetails, queryParams) - case services.Builds: - return rbc.createFromBuilds(servicesManager, rbDetails, queryParams) - case services.ReleaseBundles: - return rbc.createFromReleaseBundles(servicesManager, rbDetails, queryParams) - default: - return errorutils.CheckErrorf("unknown source for release bundle creation was provided") - } -} - -func (rbc *ReleaseBundleCreateCommand) identifySourceType() (services.SourceType, error) { - switch { - case rbc.buildsSpecPath != "": - return services.Builds, nil - case rbc.releaseBundlesSpecPath != "": - return services.ReleaseBundles, nil - case rbc.spec != nil: - return validateAndIdentifyRbCreationSpec(rbc.spec.Files) - default: - return "", errorutils.CheckErrorf("a spec file input is mandatory") - } -} - -func validateAndIdentifyRbCreationSpec(files []spec.File) (services.SourceType, error) { - if len(files) == 0 { - return "", errorutils.CheckErrorf("spec must include at least one file group") - } - - var detectedCreationSources []services.SourceType - for _, file := range files { - sourceType, err := validateFile(file) - if err != nil { - return "", err - } - detectedCreationSources = append(detectedCreationSources, sourceType) - } - - if err := validateCreationSources(detectedCreationSources); err != nil { - return "", err - } - return detectedCreationSources[0], nil -} - -func validateCreationSources(detectedCreationSources []services.SourceType) error { - if len(detectedCreationSources) == 0 { - return errorutils.CheckErrorf(missingCreationSourcesErrMsg) - } - - // Assert single creation source. - for i := 1; i < len(detectedCreationSources); i++ { - if detectedCreationSources[i] != detectedCreationSources[0] { - return generateSingleCreationSourceErr(detectedCreationSources) - } - } - - // If aql, assert single file. - if detectedCreationSources[0] == services.Aql && len(detectedCreationSources) > 1 { - return errorutils.CheckErrorf(singleAqlErrMsg) - } - return nil -} - -func generateSingleCreationSourceErr(detectedCreationSources []services.SourceType) error { - var detectedStr []string - for _, source := range detectedCreationSources { - detectedStr = append(detectedStr, string(source)) - } - return errorutils.CheckErrorf( - "%s '%s'", multipleCreationSourcesErrMsg, coreutils.ListToText(detectedStr)) -} - -func validateFile(file spec.File) (services.SourceType, error) { - // Aql creation source: - isAql := len(file.Aql.ItemsFind) > 0 - - // Build creation source: - isBuild := len(file.Build) > 0 - isIncludeDeps, _ := file.IsIncludeDeps(false) - - // Bundle creation source: - isBundle := len(file.Bundle) > 0 - - // Build & bundle: - isProject := len(file.Project) > 0 - - // Artifacts creation source: - isPattern := len(file.Pattern) > 0 - isExclusions := len(file.Exclusions) > 0 && len(file.Exclusions[0]) > 0 - isProps := len(file.Props) > 0 - isExcludeProps := len(file.ExcludeProps) > 0 - isRecursive, err := file.IsRecursive(true) - if err != nil { - return "", errorutils.CheckErrorf("invalid value provided to the 'recursive' field. error: %s", err.Error()) - } - - // Unsupported: - isPathMapping := len(file.PathMapping.Input) > 0 || len(file.PathMapping.Output) > 0 - isTarget := len(file.Target) > 0 - isSortOrder := len(file.SortOrder) > 0 - isSortBy := len(file.SortBy) > 0 - isExcludeArtifacts, _ := file.IsExcludeArtifacts(false) - isGPGKey := len(file.PublicGpgKey) > 0 - isOffset := file.Offset > 0 - isLimit := file.Limit > 0 - isArchive := len(file.Archive) > 0 - isSymlinks, _ := file.IsSymlinks(false) - isRegexp := file.Regexp == "true" - isAnt := file.Ant == "true" - isExplode, _ := file.IsExplode(false) - isBypassArchiveInspection, _ := file.IsBypassArchiveInspection(false) - isTransitive, _ := file.IsTransitive(false) - - if isPathMapping || isTarget || isSortOrder || isSortBy || isExcludeArtifacts || isGPGKey || isOffset || isLimit || - isSymlinks || isArchive || isAnt || isRegexp || isExplode || isBypassArchiveInspection || isTransitive { - return "", errorutils.CheckErrorf("unsupported fields were provided in file spec. " + - "release bundle creation file spec only supports the following fields: " + - "'aql', 'build', 'includeDeps', 'bundle', 'project', 'pattern', 'exclusions', 'props', 'excludeProps' and 'recursive'") - } - if coreutils.SumTrueValues([]bool{isAql, isBuild, isBundle, isPattern}) != 1 { - return "", errorutils.CheckErrorf("exactly one creation source is supported (aql, builds, release bundles or pattern (artifacts))") - } - - switch { - case isAql: - return services.Aql, - validateCreationSource([]bool{isIncludeDeps, isProject, isExclusions, isProps, isExcludeProps, !isRecursive}, - "aql creation source supports no other fields") - case isBuild: - return services.Builds, - validateCreationSource([]bool{isExclusions, isProps, isExcludeProps, !isRecursive}, - "builds creation source only supports the 'includeDeps' and 'project' fields") - case isBundle: - return services.ReleaseBundles, - validateCreationSource([]bool{isIncludeDeps, isExclusions, isProps, isExcludeProps, !isRecursive}, - "release bundles creation source only supports the 'project' field") - case isPattern: - return services.Artifacts, - validateCreationSource([]bool{isIncludeDeps, isProject}, - "release bundles creation source only supports the 'exclusions', 'props', 'excludeProps' and 'recursive' fields") - default: - return "", errorutils.CheckErrorf("unexpected err in spec validation") - } -} - -func validateCreationSource(unsupportedFields []bool, errMsg string) error { - if coreutils.SumTrueValues(unsupportedFields) > 0 { - return errorutils.CheckErrorf(errMsg) - } - return nil -} diff --git a/lifecycle/createcommon_test.go b/lifecycle/createcommon_test.go deleted file mode 100644 index a0c3b598f..000000000 --- a/lifecycle/createcommon_test.go +++ /dev/null @@ -1,76 +0,0 @@ -package lifecycle - -import ( - "github.com/jfrog/jfrog-cli-core/v2/common/spec" - "github.com/jfrog/jfrog-client-go/artifactory/services/utils" - "github.com/jfrog/jfrog-client-go/lifecycle/services" - "github.com/stretchr/testify/assert" - "testing" -) - -func TestValidateCreationSources(t *testing.T) { - testCases := []struct { - testName string - detectedCreationSources []services.SourceType - errExpected bool - errMsg string - }{ - {"missing creation sources", []services.SourceType{}, true, missingCreationSourcesErrMsg}, - {"single creation source", []services.SourceType{services.Aql, services.Artifacts, services.Builds}, - true, multipleCreationSourcesErrMsg + " 'aql, artifacts and builds'"}, - {"single aql err", []services.SourceType{services.Aql, services.Aql}, true, singleAqlErrMsg}, - {"valid aql", []services.SourceType{services.Aql}, false, ""}, - {"valid artifacts", []services.SourceType{services.Artifacts, services.Artifacts}, false, ""}, - {"valid builds", []services.SourceType{services.Builds, services.Builds}, false, ""}, - {"valid release bundles", []services.SourceType{services.ReleaseBundles, services.ReleaseBundles}, false, ""}, - } - for _, testCase := range testCases { - t.Run(testCase.testName, func(t *testing.T) { - err := validateCreationSources(testCase.detectedCreationSources) - if testCase.errExpected { - assert.EqualError(t, err, testCase.errMsg) - } else { - assert.NoError(t, err) - } - }) - } -} - -func TestValidateFile(t *testing.T) { - testCases := []struct { - testName string - file spec.File - errExpected bool - expectedSourceType services.SourceType - }{ - {"valid aql", spec.File{Aql: utils.Aql{ItemsFind: "abc"}}, false, services.Aql}, - {"valid build", spec.File{Build: "name/number", IncludeDeps: "true", Project: "project"}, false, services.Builds}, - {"valid bundle", spec.File{Bundle: "name/number", Project: "project"}, false, services.ReleaseBundles}, - {"valid artifacts", - spec.File{ - Pattern: "repo/path/file", - Exclusions: []string{"exclude"}, - Props: "prop", - ExcludeProps: "exclude prop", - Recursive: "false"}, false, services.Artifacts}, - {"invalid fields", spec.File{PathMapping: utils.PathMapping{Input: "input"}, Target: "target"}, true, ""}, - {"multiple creation sources", - spec.File{Aql: utils.Aql{ItemsFind: "abc"}, Build: "name/number", Bundle: "name/number", Pattern: "repo/path/file"}, - true, ""}, - {"invalid aql", spec.File{Aql: utils.Aql{ItemsFind: "abc"}, Props: "prop"}, true, ""}, - {"invalid builds", spec.File{Build: "name/number", Recursive: "false"}, true, ""}, - {"invalid bundles", spec.File{Bundle: "name/number", IncludeDeps: "true"}, true, ""}, - {"invalid artifacts", spec.File{Pattern: "repo/path/file", Project: "proj"}, true, ""}, - } - for _, testCase := range testCases { - t.Run(testCase.testName, func(t *testing.T) { - sourceType, err := validateFile(testCase.file) - if testCase.errExpected { - assert.Error(t, err) - } else { - assert.NoError(t, err) - assert.Equal(t, testCase.expectedSourceType, sourceType) - } - }) - } -} diff --git a/lifecycle/createfromaql.go b/lifecycle/createfromaql.go deleted file mode 100644 index 12918bd75..000000000 --- a/lifecycle/createfromaql.go +++ /dev/null @@ -1,13 +0,0 @@ -package lifecycle - -import ( - "fmt" - "github.com/jfrog/jfrog-client-go/lifecycle" - "github.com/jfrog/jfrog-client-go/lifecycle/services" -) - -func (rbc *ReleaseBundleCreateCommand) createFromAql(servicesManager *lifecycle.LifecycleServicesManager, - rbDetails services.ReleaseBundleDetails, queryParams services.CommonOptionalQueryParams) error { - aqlQuery := fmt.Sprintf(`items.find(%s)`, rbc.spec.Get(0).Aql.ItemsFind) - return servicesManager.CreateReleaseBundleFromAql(rbDetails, queryParams, rbc.signingKeyName, aqlQuery) -} diff --git a/lifecycle/createfromartifacts.go b/lifecycle/createfromartifacts.go deleted file mode 100644 index 8a2633451..000000000 --- a/lifecycle/createfromartifacts.go +++ /dev/null @@ -1,55 +0,0 @@ -package lifecycle - -import ( - "errors" - "github.com/jfrog/jfrog-cli-core/v2/artifactory/utils" - rtServicesUtils "github.com/jfrog/jfrog-client-go/artifactory/services/utils" - "github.com/jfrog/jfrog-client-go/lifecycle" - "github.com/jfrog/jfrog-client-go/lifecycle/services" - "github.com/jfrog/jfrog-client-go/utils/io/content" - "github.com/jfrog/jfrog-client-go/utils/log" - "path" -) - -func (rbc *ReleaseBundleCreateCommand) createFromArtifacts(lcServicesManager *lifecycle.LifecycleServicesManager, - rbDetails services.ReleaseBundleDetails, queryParams services.CommonOptionalQueryParams) (err error) { - - rtServicesManager, err := utils.CreateServiceManager(rbc.serverDetails, 3, 0, false) - if err != nil { - return err - } - - log.Info("Searching artifacts...") - searchResults, callbackFunc, err := utils.SearchFiles(rtServicesManager, rbc.spec) - defer func() { - err = errors.Join(err, callbackFunc()) - }() - if err != nil { - return err - } - artifactsSource, err := aqlResultToArtifactsSource(searchResults) - if err != nil { - return err - } - - return lcServicesManager.CreateReleaseBundleFromArtifacts(rbDetails, queryParams, rbc.signingKeyName, artifactsSource) -} - -func aqlResultToArtifactsSource(readers []*content.ContentReader) (artifactsSource services.CreateFromArtifacts, err error) { - for _, reader := range readers { - for searchResult := new(rtServicesUtils.ResultItem); reader.NextRecord(searchResult) == nil; searchResult = new(rtServicesUtils.ResultItem) { - if err != nil { - return - } - artifactsSource.Artifacts = append(artifactsSource.Artifacts, services.ArtifactSource{ - Path: path.Join(searchResult.Repo, searchResult.Path, searchResult.Name), - Sha256: searchResult.Sha256, - }) - } - if err = reader.GetError(); err != nil { - return - } - reader.Reset() - } - return -} diff --git a/lifecycle/createfrombuilds.go b/lifecycle/createfrombuilds.go deleted file mode 100644 index 02e54e644..000000000 --- a/lifecycle/createfrombuilds.go +++ /dev/null @@ -1,140 +0,0 @@ -package lifecycle - -import ( - "encoding/json" - rtUtils "github.com/jfrog/jfrog-cli-core/v2/artifactory/utils" - "github.com/jfrog/jfrog-cli-core/v2/common/spec" - rtServices "github.com/jfrog/jfrog-client-go/artifactory/services" - "github.com/jfrog/jfrog-client-go/artifactory/services/utils" - "github.com/jfrog/jfrog-client-go/lifecycle" - "github.com/jfrog/jfrog-client-go/lifecycle/services" - "github.com/jfrog/jfrog-client-go/utils/errorutils" - "github.com/jfrog/jfrog-client-go/utils/io/fileutils" -) - -func (rbc *ReleaseBundleCreateCommand) createFromBuilds(servicesManager *lifecycle.LifecycleServicesManager, - rbDetails services.ReleaseBundleDetails, queryParams services.CommonOptionalQueryParams) error { - - var buildsSource services.CreateFromBuildsSource - var err error - if rbc.buildsSpecPath != "" { - buildsSource, err = rbc.getBuildSourceFromBuildsSpec() - } else { - buildsSource, err = rbc.convertSpecToBuildsSource(rbc.spec.Files) - } - if err != nil { - return err - } - - if len(buildsSource.Builds) == 0 { - return errorutils.CheckErrorf("at least one build is expected in order to create a release bundle from builds") - } - - return servicesManager.CreateReleaseBundleFromBuilds(rbDetails, queryParams, rbc.signingKeyName, buildsSource) -} - -func (rbc *ReleaseBundleCreateCommand) getBuildSourceFromBuildsSpec() (buildsSource services.CreateFromBuildsSource, err error) { - builds := CreateFromBuildsSpec{} - content, err := fileutils.ReadFile(rbc.buildsSpecPath) - if err != nil { - return - } - if err = json.Unmarshal(content, &builds); errorutils.CheckError(err) != nil { - return - } - - return rbc.convertBuildsSpecToBuildsSource(builds) -} - -func (rbc *ReleaseBundleCreateCommand) convertBuildsSpecToBuildsSource(builds CreateFromBuildsSpec) (services.CreateFromBuildsSource, error) { - buildsSource := services.CreateFromBuildsSource{} - for _, build := range builds.Builds { - buildSource := services.BuildSource{BuildName: build.Name, IncludeDependencies: build.IncludeDependencies} - buildNumber, err := rbc.getLatestBuildNumberIfEmpty(build.Name, build.Number, build.Project) - if err != nil { - return services.CreateFromBuildsSource{}, err - } - buildSource.BuildNumber = buildNumber - buildSource.BuildRepository = utils.GetBuildInfoRepositoryByProject(build.Project) - buildsSource.Builds = append(buildsSource.Builds, buildSource) - } - return buildsSource, nil -} - -func (rbc *ReleaseBundleCreateCommand) convertSpecToBuildsSource(files []spec.File) (services.CreateFromBuildsSource, error) { - buildsSource := services.CreateFromBuildsSource{} - for _, file := range files { - buildName, buildNumber, err := rbc.getBuildDetailsFromIdentifier(file.Build, file.Project) - if err != nil { - return services.CreateFromBuildsSource{}, err - } - isIncludeDeps, err := file.IsIncludeDeps(false) - if err != nil { - return services.CreateFromBuildsSource{}, err - } - - buildSource := services.BuildSource{ - BuildName: buildName, - BuildNumber: buildNumber, - BuildRepository: utils.GetBuildInfoRepositoryByProject(file.Project), - IncludeDependencies: isIncludeDeps, - } - buildsSource.Builds = append(buildsSource.Builds, buildSource) - } - return buildsSource, nil -} - -func (rbc *ReleaseBundleCreateCommand) getLatestBuildNumberIfEmpty(buildName, buildNumber, project string) (string, error) { - if buildNumber != "" { - return buildNumber, nil - } - - aqlService, err := rbc.getAqlService() - if err != nil { - return "", err - } - - buildNumber, err = utils.GetLatestBuildNumberFromArtifactory(buildName, project, aqlService) - if err != nil { - return "", err - } - if buildNumber == "" { - return "", errorutils.CheckErrorf("could not find a build info with name '%s' in artifactory", buildName) - } - return buildNumber, nil -} - -func (rbc *ReleaseBundleCreateCommand) getBuildDetailsFromIdentifier(buildIdentifier, project string) (string, string, error) { - aqlService, err := rbc.getAqlService() - if err != nil { - return "", "", err - } - - buildName, buildNumber, err := utils.GetBuildNameAndNumberFromBuildIdentifier(buildIdentifier, project, aqlService) - if err != nil { - return "", "", err - } - if buildName == "" || buildNumber == "" { - return "", "", errorutils.CheckErrorf("could not identify a build info by the '%s' identifier in artifactory", buildIdentifier) - } - return buildName, buildNumber, nil -} - -func (rbc *ReleaseBundleCreateCommand) getAqlService() (*rtServices.AqlService, error) { - rtServiceManager, err := rtUtils.CreateServiceManager(rbc.serverDetails, 3, 0, false) - if err != nil { - return nil, err - } - return rtServices.NewAqlService(rtServiceManager.GetConfig().GetServiceDetails(), rtServiceManager.Client()), nil -} - -type CreateFromBuildsSpec struct { - Builds []SourceBuildSpec `json:"builds,omitempty"` -} - -type SourceBuildSpec struct { - Name string `json:"name,omitempty"` - Number string `json:"number,omitempty"` - Project string `json:"project,omitempty"` - IncludeDependencies bool `json:"includeDependencies,omitempty"` -} diff --git a/lifecycle/createfrombundles.go b/lifecycle/createfrombundles.go deleted file mode 100644 index 7c18141de..000000000 --- a/lifecycle/createfrombundles.go +++ /dev/null @@ -1,89 +0,0 @@ -package lifecycle - -import ( - "encoding/json" - "github.com/jfrog/jfrog-cli-core/v2/common/spec" - "github.com/jfrog/jfrog-client-go/artifactory/services/utils" - "github.com/jfrog/jfrog-client-go/lifecycle" - "github.com/jfrog/jfrog-client-go/lifecycle/services" - "github.com/jfrog/jfrog-client-go/utils/errorutils" - "github.com/jfrog/jfrog-client-go/utils/io/fileutils" -) - -func (rbc *ReleaseBundleCreateCommand) createFromReleaseBundles(servicesManager *lifecycle.LifecycleServicesManager, - rbDetails services.ReleaseBundleDetails, queryParams services.CommonOptionalQueryParams) error { - - var releaseBundlesSource services.CreateFromReleaseBundlesSource - var err error - if rbc.releaseBundlesSpecPath != "" { - releaseBundlesSource, err = rbc.getReleaseBundlesSourceFromBundlesSpec() - } else { - releaseBundlesSource, err = rbc.convertSpecToReleaseBundlesSource(rbc.spec.Files) - } - if err != nil { - return err - } - - if len(releaseBundlesSource.ReleaseBundles) == 0 { - return errorutils.CheckErrorf("at least one release bundle is expected in order to create a release bundle from release bundles") - } - - return servicesManager.CreateReleaseBundleFromBundles(rbDetails, queryParams, rbc.signingKeyName, releaseBundlesSource) -} - -func (rbc *ReleaseBundleCreateCommand) convertToReleaseBundlesSource(bundles CreateFromReleaseBundlesSpec) services.CreateFromReleaseBundlesSource { - releaseBundlesSource := services.CreateFromReleaseBundlesSource{} - for _, rb := range bundles.ReleaseBundles { - rbSource := services.ReleaseBundleSource{ - ReleaseBundleName: rb.Name, - ReleaseBundleVersion: rb.Version, - ProjectKey: rb.Project, - } - releaseBundlesSource.ReleaseBundles = append(releaseBundlesSource.ReleaseBundles, rbSource) - } - return releaseBundlesSource -} - -func (rbc *ReleaseBundleCreateCommand) convertSpecToReleaseBundlesSource(files []spec.File) (services.CreateFromReleaseBundlesSource, error) { - releaseBundlesSource := services.CreateFromReleaseBundlesSource{} - for _, file := range files { - name, version, err := utils.ParseNameAndVersion(file.Bundle, false) - if err != nil { - return releaseBundlesSource, err - } - if name == "" || version == "" { - return releaseBundlesSource, errorutils.CheckErrorf( - "invalid release bundle source was provided. Both name and version are mandatory. Provided name: '%s', version: '%s'", name, version) - } - rbSource := services.ReleaseBundleSource{ - ReleaseBundleName: name, - ReleaseBundleVersion: version, - ProjectKey: file.Project, - } - releaseBundlesSource.ReleaseBundles = append(releaseBundlesSource.ReleaseBundles, rbSource) - } - return releaseBundlesSource, nil -} - -func (rbc *ReleaseBundleCreateCommand) getReleaseBundlesSourceFromBundlesSpec() (releaseBundlesSource services.CreateFromReleaseBundlesSource, err error) { - releaseBundles := CreateFromReleaseBundlesSpec{} - content, err := fileutils.ReadFile(rbc.releaseBundlesSpecPath) - if err != nil { - return - } - if err = json.Unmarshal(content, &releaseBundles); errorutils.CheckError(err) != nil { - return - } - - return rbc.convertToReleaseBundlesSource(releaseBundles), nil -} - -type CreateFromReleaseBundlesSpec struct { - ReleaseBundles []SourceReleaseBundleSpec `json:"releaseBundles,omitempty"` -} - -type SourceReleaseBundleSpec struct { - Name string `json:"name,omitempty"` - Version string `json:"version,omitempty"` - Project string `json:"project,omitempty"` -} diff --git a/lifecycle/deletelocal.go b/lifecycle/deletelocal.go deleted file mode 100644 index d1e434aa8..000000000 --- a/lifecycle/deletelocal.go +++ /dev/null @@ -1,132 +0,0 @@ -package lifecycle - -import ( - "errors" - "fmt" - "github.com/jfrog/jfrog-cli-core/v2/utils/config" - "github.com/jfrog/jfrog-cli-core/v2/utils/coreutils" - "github.com/jfrog/jfrog-client-go/lifecycle" - "github.com/jfrog/jfrog-client-go/lifecycle/services" - "github.com/jfrog/jfrog-client-go/utils/log" - "strings" -) - -type ReleaseBundleDeleteCommand struct { - releaseBundleCmd - environment string - quiet bool -} - -func NewReleaseBundleDeleteCommand() *ReleaseBundleDeleteCommand { - return &ReleaseBundleDeleteCommand{} -} - -func (rbd *ReleaseBundleDeleteCommand) SetServerDetails(serverDetails *config.ServerDetails) *ReleaseBundleDeleteCommand { - rbd.serverDetails = serverDetails - return rbd -} - -func (rbd *ReleaseBundleDeleteCommand) SetReleaseBundleName(releaseBundleName string) *ReleaseBundleDeleteCommand { - rbd.releaseBundleName = releaseBundleName - return rbd -} - -func (rbd *ReleaseBundleDeleteCommand) SetReleaseBundleVersion(releaseBundleVersion string) *ReleaseBundleDeleteCommand { - rbd.releaseBundleVersion = releaseBundleVersion - return rbd -} - -func (rbd *ReleaseBundleDeleteCommand) SetSync(sync bool) *ReleaseBundleDeleteCommand { - rbd.sync = sync - return rbd -} - -func (rbd *ReleaseBundleDeleteCommand) SetReleaseBundleProject(rbProjectKey string) *ReleaseBundleDeleteCommand { - rbd.rbProjectKey = rbProjectKey - return rbd -} - -func (rbd *ReleaseBundleDeleteCommand) SetEnvironment(environment string) *ReleaseBundleDeleteCommand { - rbd.environment = environment - return rbd -} - -func (rbd *ReleaseBundleDeleteCommand) SetQuiet(quiet bool) *ReleaseBundleDeleteCommand { - rbd.quiet = quiet - return rbd -} - -func (rbd *ReleaseBundleDeleteCommand) CommandName() string { - return "rb_delete" -} - -func (rbd *ReleaseBundleDeleteCommand) ServerDetails() (*config.ServerDetails, error) { - return rbd.serverDetails, nil -} - -func (rbd *ReleaseBundleDeleteCommand) Run() error { - if err := validateArtifactoryVersionSupported(rbd.serverDetails); err != nil { - return err - } - - servicesManager, rbDetails, queryParams, err := rbd.getPrerequisites() - if err != nil { - return err - } - - if rbd.environment != "" { - return rbd.deletePromotionsOnly(servicesManager, rbDetails, queryParams) - } - return rbd.deleteLocalReleaseBundle(servicesManager, rbDetails, queryParams) -} - -func (rbd *ReleaseBundleDeleteCommand) deletePromotionsOnly(servicesManager *lifecycle.LifecycleServicesManager, - rbDetails services.ReleaseBundleDetails, commonQueryParams services.CommonOptionalQueryParams) error { - - deletionSubject := fmt.Sprintf("all promotions to environment '%s' of release bundle '%s/%s'", rbd.environment, rbd.releaseBundleName, rbd.releaseBundleVersion) - if !rbd.confirmDelete(deletionSubject) { - return nil - } - - optionalQueryParams := services.GetPromotionsOptionalQueryParams{ProjectKey: commonQueryParams.ProjectKey} - response, err := servicesManager.GetReleaseBundleVersionPromotions(rbDetails, optionalQueryParams) - if err != nil { - return err - } - success := 0 - fail := 0 - for _, promotion := range response.Promotions { - if strings.EqualFold(promotion.Environment, rbd.environment) { - if curErr := servicesManager.DeleteReleaseBundleVersionPromotion(rbDetails, commonQueryParams, promotion.CreatedMillis.String()); curErr != nil { - err = errors.Join(err, curErr) - fail++ - } else { - success++ - } - } - } - if success == 0 && fail == 0 { - log.Info(fmt.Sprintf("No promotions were found for environment '%s'", rbd.environment)) - } else { - log.Info(fmt.Sprintf("Promotions deleted successfully: %d, failed: %d", success, fail)) - } - - return err -} - -func (rbd *ReleaseBundleDeleteCommand) deleteLocalReleaseBundle(servicesManager *lifecycle.LifecycleServicesManager, - rbDetails services.ReleaseBundleDetails, queryParams services.CommonOptionalQueryParams) error { - deletionSubject := fmt.Sprintf("release bundle '%s/%s' locally with all its promotions", rbd.releaseBundleName, rbd.releaseBundleVersion) - if !rbd.confirmDelete(deletionSubject) { - return nil - } - return servicesManager.DeleteReleaseBundleVersion(rbDetails, queryParams) -} - -func (rbd *ReleaseBundleDeleteCommand) confirmDelete(deletionSubject string) bool { - if rbd.quiet { - return true - } - return coreutils.AskYesNo( - fmt.Sprintf("Are you sure you want to delete %s?\n"+avoidConfirmationMsg, deletionSubject), false) -} diff --git a/lifecycle/deleteremote.go b/lifecycle/deleteremote.go deleted file mode 100644 index 6b1665131..000000000 --- a/lifecycle/deleteremote.go +++ /dev/null @@ -1,159 +0,0 @@ -package lifecycle - -import ( - "encoding/json" - "fmt" - "github.com/jfrog/jfrog-cli-core/v2/common/spec" - "github.com/jfrog/jfrog-cli-core/v2/utils/config" - "github.com/jfrog/jfrog-cli-core/v2/utils/coreutils" - "github.com/jfrog/jfrog-client-go/lifecycle" - "github.com/jfrog/jfrog-client-go/lifecycle/services" - clientutils "github.com/jfrog/jfrog-client-go/utils" - "github.com/jfrog/jfrog-client-go/utils/distribution" - "github.com/jfrog/jfrog-client-go/utils/errorutils" - "github.com/jfrog/jfrog-client-go/utils/log" -) - -const avoidConfirmationMsg = "You can avoid this confirmation message by adding --quiet to the command." - -type ReleaseBundleRemoteDeleteCommand struct { - releaseBundleCmd - distributionRules *spec.DistributionRules - dryRun bool - quiet bool - maxWaitMinutes int -} - -func NewReleaseBundleRemoteDeleteCommand() *ReleaseBundleRemoteDeleteCommand { - return &ReleaseBundleRemoteDeleteCommand{} -} - -func (rbd *ReleaseBundleRemoteDeleteCommand) SetServerDetails(serverDetails *config.ServerDetails) *ReleaseBundleRemoteDeleteCommand { - rbd.serverDetails = serverDetails - return rbd -} - -func (rbd *ReleaseBundleRemoteDeleteCommand) SetReleaseBundleName(releaseBundleName string) *ReleaseBundleRemoteDeleteCommand { - rbd.releaseBundleName = releaseBundleName - return rbd -} - -func (rbd *ReleaseBundleRemoteDeleteCommand) SetReleaseBundleVersion(releaseBundleVersion string) *ReleaseBundleRemoteDeleteCommand { - rbd.releaseBundleVersion = releaseBundleVersion - return rbd -} - -func (rbd *ReleaseBundleRemoteDeleteCommand) SetSync(sync bool) *ReleaseBundleRemoteDeleteCommand { - rbd.sync = sync - return rbd -} - -func (rbd *ReleaseBundleRemoteDeleteCommand) SetReleaseBundleProject(rbProjectKey string) *ReleaseBundleRemoteDeleteCommand { - rbd.rbProjectKey = rbProjectKey - return rbd -} - -func (rbd *ReleaseBundleRemoteDeleteCommand) SetDistributionRules(distributionRules *spec.DistributionRules) *ReleaseBundleRemoteDeleteCommand { - rbd.distributionRules = distributionRules - return rbd -} - -func (rbd *ReleaseBundleRemoteDeleteCommand) SetDryRun(dryRun bool) *ReleaseBundleRemoteDeleteCommand { - rbd.dryRun = dryRun - return rbd -} - -func (rbd *ReleaseBundleRemoteDeleteCommand) SetQuiet(quiet bool) *ReleaseBundleRemoteDeleteCommand { - rbd.quiet = quiet - return rbd -} - -func (rbd *ReleaseBundleRemoteDeleteCommand) SetMaxWaitMinutes(maxWaitMinutes int) *ReleaseBundleRemoteDeleteCommand { - rbd.maxWaitMinutes = maxWaitMinutes - return rbd -} - -func (rbd *ReleaseBundleRemoteDeleteCommand) CommandName() string { - return "rb_remote_delete" -} - -func (rbd *ReleaseBundleRemoteDeleteCommand) ServerDetails() (*config.ServerDetails, error) { - return rbd.serverDetails, nil -} - -func (rbd *ReleaseBundleRemoteDeleteCommand) Run() error { - if err := validateArtifactoryVersionSupported(rbd.serverDetails); err != nil { - return err - } - - servicesManager, rbDetails, queryParams, err := rbd.getPrerequisites() - if err != nil { - return err - } - - return rbd.deleteRemote(servicesManager, rbDetails, queryParams) -} - -func (rbd *ReleaseBundleRemoteDeleteCommand) deleteRemote(servicesManager *lifecycle.LifecycleServicesManager, - rbDetails services.ReleaseBundleDetails, queryParams services.CommonOptionalQueryParams) error { - - confirm, err := rbd.confirmDelete() - if err != nil || !confirm { - return err - } - - aggregatedRules := rbd.getAggregatedDistRules() - - return servicesManager.RemoteDeleteReleaseBundle(rbDetails, services.ReleaseBundleRemoteDeleteParams{ - DistributionRules: aggregatedRules, - DryRun: rbd.dryRun, - MaxWaitMinutes: rbd.maxWaitMinutes, - CommonOptionalQueryParams: queryParams, - }) -} - -func (rbd *ReleaseBundleRemoteDeleteCommand) distributionRulesEmpty() bool { - return rbd.distributionRules == nil || - len(rbd.distributionRules.DistributionRules) == 0 || - len(rbd.distributionRules.DistributionRules) == 1 && rbd.distributionRules.DistributionRules[0].IsEmpty() -} - -func (rbd *ReleaseBundleRemoteDeleteCommand) confirmDelete() (bool, error) { - if rbd.quiet { - return true, nil - } - - message := fmt.Sprintf("Are you sure you want to delete the release bundle '%s/%s' remotely ", rbd.releaseBundleName, rbd.releaseBundleVersion) - if rbd.distributionRulesEmpty() { - message += "from all edges?" - } else { - var distributionRulesBodies []distribution.DistributionRulesBody - for _, rule := range rbd.distributionRules.DistributionRules { - distributionRulesBodies = append(distributionRulesBodies, distribution.DistributionRulesBody{ - SiteName: rule.SiteName, - CityName: rule.CityName, - CountryCodes: rule.CountryCodes, - }) - } - bytes, err := json.Marshal(distributionRulesBodies) - if err != nil { - return false, errorutils.CheckError(err) - } - - log.Output(clientutils.IndentJson(bytes)) - message += "from all edges with the above distribution rules?" - } - - return coreutils.AskYesNo(message+"\n"+avoidConfirmationMsg, false), nil -} - -func (rbd *ReleaseBundleRemoteDeleteCommand) getAggregatedDistRules() (aggregatedRules []*distribution.DistributionCommonParams) { - if rbd.distributionRulesEmpty() { - aggregatedRules = append(aggregatedRules, &distribution.DistributionCommonParams{SiteName: "*"}) - } else { - for _, rules := range rbd.distributionRules.DistributionRules { - aggregatedRules = append(aggregatedRules, rules.ToDistributionCommonParams()) - } - } - return -} diff --git a/lifecycle/distribute.go b/lifecycle/distribute.go deleted file mode 100644 index 76165ef56..000000000 --- a/lifecycle/distribute.go +++ /dev/null @@ -1,111 +0,0 @@ -package lifecycle - -import ( - "github.com/jfrog/jfrog-cli-core/v2/common/spec" - "github.com/jfrog/jfrog-cli-core/v2/utils/config" - "github.com/jfrog/jfrog-client-go/lifecycle/services" -) - -type ReleaseBundleDistributeCommand struct { - releaseBundleCmd - distributionRules *spec.DistributionRules - dryRun bool - autoCreateRepo bool - pathMappingPattern string - pathMappingTarget string - maxWaitMinutes int -} - -func NewReleaseBundleDistributeCommand() *ReleaseBundleDistributeCommand { - return &ReleaseBundleDistributeCommand{} -} - -func (rbd *ReleaseBundleDistributeCommand) SetServerDetails(serverDetails *config.ServerDetails) *ReleaseBundleDistributeCommand { - rbd.serverDetails = serverDetails - return rbd -} - -func (rbd *ReleaseBundleDistributeCommand) SetReleaseBundleName(releaseBundleName string) *ReleaseBundleDistributeCommand { - rbd.releaseBundleName = releaseBundleName - return rbd -} - -func (rbd *ReleaseBundleDistributeCommand) SetReleaseBundleVersion(releaseBundleVersion string) *ReleaseBundleDistributeCommand { - rbd.releaseBundleVersion = releaseBundleVersion - return rbd -} - -func (rbd *ReleaseBundleDistributeCommand) SetReleaseBundleProject(rbProjectKey string) *ReleaseBundleDistributeCommand { - rbd.rbProjectKey = rbProjectKey - return rbd -} - -func (rbd *ReleaseBundleDistributeCommand) SetDistributionRules(distributionRules *spec.DistributionRules) *ReleaseBundleDistributeCommand { - rbd.distributionRules = distributionRules - return rbd -} - -func (rbd *ReleaseBundleDistributeCommand) SetDryRun(dryRun bool) *ReleaseBundleDistributeCommand { - rbd.dryRun = dryRun - return rbd -} - -func (rbd *ReleaseBundleDistributeCommand) SetAutoCreateRepo(autoCreateRepo bool) *ReleaseBundleDistributeCommand { - rbd.autoCreateRepo = autoCreateRepo - return rbd -} - -func (rbd *ReleaseBundleDistributeCommand) SetPathMappingPattern(pathMappingPattern string) *ReleaseBundleDistributeCommand { - rbd.pathMappingPattern = pathMappingPattern - return rbd -} - -func (rbd *ReleaseBundleDistributeCommand) SetPathMappingTarget(pathMappingTarget string) *ReleaseBundleDistributeCommand { - rbd.pathMappingTarget = pathMappingTarget - return rbd -} - -func (rbd *ReleaseBundleDistributeCommand) SetSync(sync bool) *ReleaseBundleDistributeCommand { - rbd.sync = sync - return rbd -} - -func (rbd *ReleaseBundleDistributeCommand) SetMaxWaitMinutes(maxWaitMinutes int) *ReleaseBundleDistributeCommand { - rbd.maxWaitMinutes = maxWaitMinutes - return rbd -} - -func (rbd *ReleaseBundleDistributeCommand) Run() error { - if err := validateArtifactoryVersionSupported(rbd.serverDetails); err != nil { - return err - } - - servicesManager, rbDetails, _, err := rbd.getPrerequisites() - if err != nil { - return err - } - - pathMapping := services.PathMapping{ - Pattern: rbd.pathMappingPattern, - Target: rbd.pathMappingTarget, - } - - distributeParams := services.DistributeReleaseBundleParams{ - Sync: rbd.sync, - AutoCreateRepo: rbd.autoCreateRepo, - MaxWaitMinutes: rbd.maxWaitMinutes, - DistributionRules: getAggregatedDistRules(rbd.distributionRules), - PathMappings: []services.PathMapping{pathMapping}, - ProjectKey: rbd.rbProjectKey, - } - - return servicesManager.DistributeReleaseBundle(rbDetails, distributeParams) -} - -func (rbd *ReleaseBundleDistributeCommand) ServerDetails() (*config.ServerDetails, error) { - return rbd.serverDetails, nil -} - -func (rbd *ReleaseBundleDistributeCommand) CommandName() string { - return "rb_distribute" -} diff --git a/lifecycle/export.go b/lifecycle/export.go deleted file mode 100644 index 41001e27f..000000000 --- a/lifecycle/export.go +++ /dev/null @@ -1,133 +0,0 @@ -package lifecycle - -import ( - artUtils "github.com/jfrog/jfrog-cli-core/v2/artifactory/utils" - "github.com/jfrog/jfrog-cli-core/v2/utils/config" - "github.com/jfrog/jfrog-cli-core/v2/utils/coreutils" - "github.com/jfrog/jfrog-client-go/artifactory" - artServices "github.com/jfrog/jfrog-client-go/artifactory/services" - "github.com/jfrog/jfrog-client-go/artifactory/services/utils" - clientConfig "github.com/jfrog/jfrog-client-go/config" - "github.com/jfrog/jfrog-client-go/lifecycle/services" - "github.com/jfrog/jfrog-client-go/utils/errorutils" - "github.com/jfrog/jfrog-client-go/utils/log" - "strings" -) - -type ReleaseBundleExportCommand struct { - releaseBundleCmd - modifications services.Modifications - downloadConfigurations artUtils.DownloadConfiguration - targetPath string -} - -func (rbe *ReleaseBundleExportCommand) Run() (err error) { - if err = validateArtifactoryVersionSupported(rbe.serverDetails); err != nil { - return - } - servicesManager, rbDetails, queryParams, err := rbe.getPrerequisites() - if err != nil { - return errorutils.CheckErrorf("Failed getting prerequisites for exporting command, error: '%s'", err.Error()) - } - // Start the Export process and wait for completion - log.Info("Exporting Release Bundle archive...") - exportResponse, err := servicesManager.ExportReleaseBundle(rbDetails, rbe.modifications, queryParams) - if err != nil { - return errorutils.CheckErrorf("Failed exporting release bundle, error: '%s'", err.Error()) - } - // Download the exported bundle - log.Debug("Downloading the exported bundle...") - downloaded, failed, err := rbe.downloadReleaseBundle(exportResponse, rbe.downloadConfigurations) - if err != nil || failed > 0 || downloaded < 1 { - return - } - log.Info("Successfully Downloaded Release Bundle archive") - return -} - -// Download the exported release bundle using artifactory service manager -func (rbe *ReleaseBundleExportCommand) downloadReleaseBundle(exportResponse services.ReleaseBundleExportedStatusResponse, downloadConfiguration artUtils.DownloadConfiguration) (downloaded int, failed int, err error) { - downloadParams := artServices.DownloadParams{ - CommonParams: &utils.CommonParams{ - Pattern: strings.TrimPrefix(exportResponse.RelativeUrl, "/"), - Target: rbe.targetPath, - }, - MinSplitSize: downloadConfiguration.MinSplitSize, - SplitCount: downloadConfiguration.SplitCount, - } - artifactoryServiceManager, err := createArtifactoryServiceManager(rbe.serverDetails) - if err != nil { - return - } - return artifactoryServiceManager.DownloadFiles(downloadParams) - -} -func (rbe *ReleaseBundleExportCommand) ServerDetails() (*config.ServerDetails, error) { - return rbe.serverDetails, nil -} - -func (rbe *ReleaseBundleExportCommand) CommandName() string { - return "rb_export" -} - -func NewReleaseBundleExportCommand() *ReleaseBundleExportCommand { - return &ReleaseBundleExportCommand{} -} -func (rbe *ReleaseBundleExportCommand) SetServerDetails(serverDetails *config.ServerDetails) *ReleaseBundleExportCommand { - rbe.serverDetails = serverDetails - return rbe -} - -func (rbe *ReleaseBundleExportCommand) SetReleaseBundleExportModifications(modifications services.Modifications) *ReleaseBundleExportCommand { - rbe.modifications = modifications - return rbe -} -func (rbe *ReleaseBundleExportCommand) SetReleaseBundleName(releaseBundleName string) *ReleaseBundleExportCommand { - rbe.releaseBundleName = releaseBundleName - return rbe -} - -func (rbe *ReleaseBundleExportCommand) SetReleaseBundleVersion(releaseBundleVersion string) *ReleaseBundleExportCommand { - rbe.releaseBundleVersion = releaseBundleVersion - return rbe -} - -func (rbe *ReleaseBundleExportCommand) SetProject(project string) *ReleaseBundleExportCommand { - rbe.rbProjectKey = project - return rbe -} - -func (rbe *ReleaseBundleExportCommand) SetDownloadConfiguration(downloadConfig artUtils.DownloadConfiguration) *ReleaseBundleExportCommand { - rbe.downloadConfigurations = downloadConfig - return rbe -} - -func (rbe *ReleaseBundleExportCommand) SetTargetPath(target string) *ReleaseBundleExportCommand { - if target == "" { - // Default value as current dir - target += "./" - } - rbe.targetPath = target - return rbe -} - -func createArtifactoryServiceManager(artDetails *config.ServerDetails) (artifactory.ArtifactoryServicesManager, error) { - certsPath, err := coreutils.GetJfrogCertsDir() - if err != nil { - return nil, err - } - artAuth, err := artDetails.CreateArtAuthConfig() - if err != nil { - return nil, err - } - serviceConfig, err := clientConfig.NewConfigBuilder(). - SetServiceDetails(artAuth). - SetCertificatesPath(certsPath). - SetInsecureTls(artDetails.InsecureTls). - SetDryRun(false). - Build() - if err != nil { - return nil, err - } - return artifactory.New(serviceConfig) -} diff --git a/lifecycle/import.go b/lifecycle/import.go deleted file mode 100644 index 084ca6205..000000000 --- a/lifecycle/import.go +++ /dev/null @@ -1,60 +0,0 @@ -package lifecycle - -import ( - "fmt" - "github.com/jfrog/jfrog-cli-core/v2/artifactory/utils" - "github.com/jfrog/jfrog-cli-core/v2/utils/config" - "github.com/jfrog/jfrog-client-go/utils/io/fileutils" - "github.com/jfrog/jfrog-client-go/utils/log" -) - -type ReleaseBundleImportCommand struct { - releaseBundleCmd - filePath string -} - -func (rbi *ReleaseBundleImportCommand) ServerDetails() (*config.ServerDetails, error) { - return rbi.serverDetails, nil -} - -func (rbi *ReleaseBundleImportCommand) CommandName() string { - return "rb_import" -} - -func NewReleaseBundleImportCommand() *ReleaseBundleImportCommand { - return &ReleaseBundleImportCommand{} -} -func (rbi *ReleaseBundleImportCommand) SetServerDetails(serverDetails *config.ServerDetails) *ReleaseBundleImportCommand { - rbi.serverDetails = serverDetails - return rbi -} - -func (rbi *ReleaseBundleImportCommand) SetFilepath(filePath string) *ReleaseBundleImportCommand { - rbi.filePath = filePath - return rbi -} - -func (rbi *ReleaseBundleImportCommand) Run() (err error) { - if err = validateArtifactoryVersionSupported(rbi.serverDetails); err != nil { - return - } - artService, err := utils.CreateServiceManager(rbi.serverDetails, 3, 0, false) - if err != nil { - return - } - - exists, err := fileutils.IsFileExists(rbi.filePath, false) - if err != nil { - return - } - if !exists { - return fmt.Errorf("file not found: %s", rbi.filePath) - } - - log.Info("Importing the release bundle archive...") - if err = artService.ImportReleaseBundle(rbi.filePath); err != nil { - return - } - log.Info("Successfully imported the release bundle archive") - return -} diff --git a/lifecycle/promote.go b/lifecycle/promote.go deleted file mode 100644 index 285104d98..000000000 --- a/lifecycle/promote.go +++ /dev/null @@ -1,109 +0,0 @@ -package lifecycle - -import ( - "encoding/json" - "github.com/jfrog/jfrog-cli-core/v2/utils/config" - "github.com/jfrog/jfrog-client-go/lifecycle/services" - "github.com/jfrog/jfrog-client-go/utils" - "github.com/jfrog/jfrog-client-go/utils/log" -) - -type ReleaseBundlePromoteCommand struct { - releaseBundleCmd - signingKeyName string - environment string - includeReposPatterns []string - excludeReposPatterns []string - promotionType string -} - -func NewReleaseBundlePromoteCommand() *ReleaseBundlePromoteCommand { - return &ReleaseBundlePromoteCommand{} -} - -func (rbp *ReleaseBundlePromoteCommand) SetServerDetails(serverDetails *config.ServerDetails) *ReleaseBundlePromoteCommand { - rbp.serverDetails = serverDetails - return rbp -} - -func (rbp *ReleaseBundlePromoteCommand) SetReleaseBundleName(releaseBundleName string) *ReleaseBundlePromoteCommand { - rbp.releaseBundleName = releaseBundleName - return rbp -} - -func (rbp *ReleaseBundlePromoteCommand) SetReleaseBundleVersion(releaseBundleVersion string) *ReleaseBundlePromoteCommand { - rbp.releaseBundleVersion = releaseBundleVersion - return rbp -} - -func (rbp *ReleaseBundlePromoteCommand) SetSigningKeyName(signingKeyName string) *ReleaseBundlePromoteCommand { - rbp.signingKeyName = signingKeyName - return rbp -} - -func (rbp *ReleaseBundlePromoteCommand) SetSync(sync bool) *ReleaseBundlePromoteCommand { - rbp.sync = sync - return rbp -} - -func (rbp *ReleaseBundlePromoteCommand) SetReleaseBundleProject(rbProjectKey string) *ReleaseBundlePromoteCommand { - rbp.rbProjectKey = rbProjectKey - return rbp -} - -func (rbp *ReleaseBundlePromoteCommand) SetEnvironment(environment string) *ReleaseBundlePromoteCommand { - rbp.environment = environment - return rbp -} - -func (rbp *ReleaseBundlePromoteCommand) SetIncludeReposPatterns(includeReposPatterns []string) *ReleaseBundlePromoteCommand { - rbp.includeReposPatterns = includeReposPatterns - return rbp -} - -func (rbp *ReleaseBundlePromoteCommand) SetExcludeReposPatterns(excludeReposPatterns []string) *ReleaseBundlePromoteCommand { - rbp.excludeReposPatterns = excludeReposPatterns - return rbp -} - -func (rbp *ReleaseBundlePromoteCommand) SetPromotionType(promotionType string) *ReleaseBundlePromoteCommand { - rbp.promotionType = promotionType - return rbp -} - -func (rbp *ReleaseBundlePromoteCommand) CommandName() string { - return "rb_promote" -} - -func (rbp *ReleaseBundlePromoteCommand) ServerDetails() (*config.ServerDetails, error) { - return rbp.serverDetails, nil -} - -func (rbp *ReleaseBundlePromoteCommand) Run() error { - if err := validateArtifactoryVersionSupported(rbp.serverDetails); err != nil { - return err - } - - servicesManager, rbDetails, queryParams, err := rbp.getPromotionPrerequisites() - - if err != nil { - return err - } - - promotionParams := services.RbPromotionParams{ - Environment: rbp.environment, - IncludedRepositoryKeys: rbp.includeReposPatterns, - ExcludedRepositoryKeys: rbp.excludeReposPatterns, - } - - promotionResp, err := servicesManager.PromoteReleaseBundle(rbDetails, queryParams, rbp.signingKeyName, promotionParams) - if err != nil { - return err - } - content, err := json.Marshal(promotionResp) - if err != nil { - return err - } - log.Output(utils.IndentJson(content)) - return nil -} diff --git a/plugins/common/utils.go b/plugins/common/utils.go index 1f7655c9b..f404fba68 100644 --- a/plugins/common/utils.go +++ b/plugins/common/utils.go @@ -3,6 +3,7 @@ package common import ( "github.com/jfrog/jfrog-cli-core/v2/utils/coreutils" clientutils "github.com/jfrog/jfrog-client-go/utils" + "os" "sort" "strconv" "strings" @@ -56,10 +57,6 @@ func RunCmdWithDeprecationWarning(cmdName, oldSubcommand string, c *components.C return cmd(c) } -func GetThreadsCount(c *components.Context) (threads int, err error) { - return cliutils.GetThreadsCount(c.GetStringFlagValue("threads")) -} - func GetPrintCurrentCmdHelp(c *components.Context) func() error { return func() error { return c.PrintCommandHelp(c.CommandName) @@ -124,3 +121,21 @@ func getCiValue() bool { } return ci } + +// Get project key from flag or environment variable +func GetProject(c *components.Context) string { + projectKey := c.GetStringFlagValue("project") + return getOrDefaultEnv(projectKey, coreutils.Project) +} + +// Return argument if not empty or retrieve from environment variable +func getOrDefaultEnv(arg, envKey string) string { + if arg != "" { + return arg + } + return os.Getenv(envKey) +} + +func GetThreadsCount(c *components.Context) (threads int, err error) { + return cliutils.GetThreadsCount(c.GetStringFlagValue("threads")) +} diff --git a/plugins/components/commandcomp.go b/plugins/components/commandcomp.go index ca1efb766..91e9168a0 100644 --- a/plugins/components/commandcomp.go +++ b/plugins/components/commandcomp.go @@ -61,9 +61,19 @@ func (c *Context) GetStringFlagValue(flagName string) string { } func (c *Context) AddStringFlag(key, value string) { + if c.stringFlags == nil { + c.stringFlags = make(map[string]string) + } c.stringFlags[key] = value } +func (c *Context) AddBoolFlag(key string, value bool) { + if c.boolFlags == nil { + c.boolFlags = make(map[string]bool) + } + c.boolFlags[key] = value +} + func (c *Context) GetIntFlagValue(flagName string) (value int, err error) { parsed, err := strconv.ParseInt(c.GetStringFlagValue(flagName), 0, 64) if err != nil { @@ -74,6 +84,19 @@ func (c *Context) GetIntFlagValue(flagName string) (value int, err error) { return } +func (c *Context) GetDefaultIntFlagValueIfNotSet(flagName string, defaultValue int) (value int, err error) { + if c.IsFlagSet(flagName) { + 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, err + } + value = int(parsed) + return value, err + } + return defaultValue, nil +} + func (c *Context) GetBoolFlagValue(flagName string) bool { return c.boolFlags[flagName] } @@ -183,6 +206,12 @@ func WithBoolDefaultValueFalse() BoolFlagOption { } } +func WithBoolDefaultValueTrue() BoolFlagOption { + return func(f *BoolFlag) { + f.DefaultValue = true + } +} + type BoolFlag struct { BaseFlag DefaultValue bool