github.com/osievert/jfrog-cli-core@v1.2.7/artifactory/spec/specfiles.go (about) 1 package spec 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "github.com/jfrog/jfrog-cli-core/utils/coreutils" 8 "github.com/jfrog/jfrog-client-go/artifactory/services/utils" 9 clientutils "github.com/jfrog/jfrog-client-go/utils" 10 "github.com/jfrog/jfrog-client-go/utils/errorutils" 11 "github.com/jfrog/jfrog-client-go/utils/io/fileutils" 12 "github.com/jfrog/jfrog-client-go/utils/log" 13 ) 14 15 type SpecFiles struct { 16 Files []File 17 } 18 19 func (spec *SpecFiles) Get(index int) *File { 20 if index < len(spec.Files) { 21 return &spec.Files[index] 22 } 23 return new(File) 24 } 25 26 func CreateSpecFromFile(specFilePath string, specVars map[string]string) (spec *SpecFiles, err error) { 27 spec = new(SpecFiles) 28 content, err := fileutils.ReadFile(specFilePath) 29 if errorutils.CheckError(err) != nil { 30 return 31 } 32 33 if len(specVars) > 0 { 34 content = coreutils.ReplaceVars(content, specVars) 35 } 36 37 err = json.Unmarshal(content, spec) 38 if errorutils.CheckError(err) != nil { 39 return 40 } 41 return 42 } 43 44 type File struct { 45 Aql utils.Aql 46 Pattern string 47 // Deprecated, use Exclusions instead 48 ExcludePatterns []string 49 Exclusions []string 50 Target string 51 Explode string 52 Props string 53 ExcludeProps string 54 SortOrder string 55 SortBy []string 56 Offset int 57 Limit int 58 Build string 59 ExcludeArtifacts string 60 IncludeDeps string 61 Bundle string 62 Recursive string 63 Flat string 64 Regexp string 65 IncludeDirs string 66 ArchiveEntries string 67 ValidateSymlinks string 68 } 69 70 func (f File) IsFlat(defaultValue bool) (bool, error) { 71 return clientutils.StringToBool(f.Flat, defaultValue) 72 } 73 74 func (f File) IsExplode(defaultValue bool) (bool, error) { 75 return clientutils.StringToBool(f.Explode, defaultValue) 76 } 77 78 func (f File) IsRegexp(defaultValue bool) (bool, error) { 79 return clientutils.StringToBool(f.Regexp, defaultValue) 80 } 81 82 func (f File) IsRecursive(defaultValue bool) (bool, error) { 83 return clientutils.StringToBool(f.Recursive, defaultValue) 84 } 85 86 func (f File) IsIncludeDirs(defaultValue bool) (bool, error) { 87 return clientutils.StringToBool(f.IncludeDirs, defaultValue) 88 } 89 90 func (f File) IsVlidateSymlinks(defaultValue bool) (bool, error) { 91 return clientutils.StringToBool(f.ValidateSymlinks, defaultValue) 92 } 93 94 func (f File) IsExcludeArtifacts(defaultValue bool) (bool, error) { 95 return clientutils.StringToBool(f.ExcludeArtifacts, defaultValue) 96 } 97 98 func (f File) IsIncludeDeps(defaultValue bool) (bool, error) { 99 return clientutils.StringToBool(f.IncludeDeps, defaultValue) 100 } 101 102 func (f *File) ToArtifactoryCommonParams() *utils.ArtifactoryCommonParams { 103 params := new(utils.ArtifactoryCommonParams) 104 params.Aql = f.Aql 105 params.Pattern = f.Pattern 106 params.ExcludePatterns = f.ExcludePatterns 107 params.Exclusions = f.Exclusions 108 params.Target = f.Target 109 params.Props = f.Props 110 params.ExcludeProps = f.ExcludeProps 111 params.Build = f.Build 112 params.Bundle = f.Bundle 113 params.SortOrder = f.SortOrder 114 params.SortBy = f.SortBy 115 params.Offset = f.Offset 116 params.Limit = f.Limit 117 params.ArchiveEntries = f.ArchiveEntries 118 return params 119 } 120 121 func ValidateSpec(files []File, isTargetMandatory, isSearchBasedSpec bool) error { 122 if len(files) == 0 { 123 return errors.New("Spec must include at least one file group") 124 } 125 excludePatternsUsed := false 126 for _, file := range files { 127 isAql := len(file.Aql.ItemsFind) > 0 128 isPattern := len(file.Pattern) > 0 129 isExcludePatterns := len(file.ExcludePatterns) > 0 && len(file.ExcludePatterns[0]) > 0 130 excludePatternsUsed = excludePatternsUsed || isExcludePatterns 131 isExclusions := len(file.Exclusions) > 0 && len(file.Exclusions[0]) > 0 132 isTarget := len(file.Target) > 0 133 isSortOrder := len(file.SortOrder) > 0 134 isSortBy := len(file.SortBy) > 0 135 isBuild := len(file.Build) > 0 136 isExcludeArtifacts, _ := file.IsExcludeArtifacts(false) 137 isIncludeDeps, _ := file.IsIncludeDeps(false) 138 isBundle := len(file.Bundle) > 0 139 isOffset := file.Offset > 0 140 isLimit := file.Limit > 0 141 isValidSortOrder := file.SortOrder == "asc" || file.SortOrder == "desc" 142 143 if isTargetMandatory && !isTarget { 144 return errors.New("Spec must include target.") 145 } 146 if !isSearchBasedSpec && !isPattern { 147 return errors.New("Spec must include a pattern.") 148 } 149 if isBuild && isBundle { 150 return fileSpecValidationError("build", "bundle") 151 } 152 if isSearchBasedSpec { 153 if !isAql && !isPattern && !isBuild && !isBundle { 154 return errors.New("Spec must include either aql, pattern, build or bundle.") 155 } 156 if isOffset { 157 if isBuild { 158 return fileSpecValidationError("build", "offset") 159 } 160 if isBundle { 161 return fileSpecValidationError("bundle", "offset") 162 } 163 } 164 if isLimit { 165 if isBuild { 166 return fileSpecValidationError("build", "limit") 167 } 168 if isBundle { 169 return fileSpecValidationError("bundle", "limit") 170 } 171 } 172 } 173 if isAql && isPattern { 174 return fileSpecValidationError("aql", "pattern") 175 } 176 if isAql && isExcludePatterns { 177 return fileSpecValidationError("aql", "exclude-patterns") 178 } 179 if isAql && isExclusions { 180 return fileSpecValidationError("aql", "exclusions") 181 } 182 if isExclusions && isExcludePatterns { 183 return fileSpecValidationError("exclusions", "exclude-patterns") 184 } 185 if !isSortBy && isSortOrder { 186 return errors.New("Spec cannot include 'sort-order' if 'sort-by' is not included") 187 } 188 if isSortOrder && !isValidSortOrder { 189 return errors.New("The value of 'sort-order' can only be 'asc' or 'desc'.") 190 } 191 if !isBuild && (isExcludeArtifacts || isIncludeDeps) { 192 return errors.New("Spec cannot include 'exclude-artifacts' or 'include-deps' if 'build' is not included.") 193 } 194 } 195 if excludePatternsUsed { 196 showDeprecationOnExcludePatterns() 197 } 198 return nil 199 } 200 201 func fileSpecValidationError(fieldA, fieldB string) error { 202 return errors.New(fmt.Sprintf("Spec cannot include both '%s' and '%s.'", fieldA, fieldB)) 203 } 204 205 func showDeprecationOnExcludePatterns() { 206 log.Warn(`The --exclude-patterns command option and the 'excludePatterns' File Spec property are deprecated. 207 Please use the --exclusions command option or the 'exclusions' File Spec property instead. 208 Unlike exclude-patterns, exclusions take into account the repository as part of the pattern. 209 For example: 210 "excludePatterns": ["a.zip"] 211 can be translated to 212 "exclusions": ["repo-name/a.zip"] 213 or 214 "exclusions": ["*/a.zip"]`) 215 }