github.com/SAP/jenkins-library@v1.362.0/pkg/versioning/versioning.go (about) 1 package versioning 2 3 import ( 4 "fmt" 5 "io" 6 "net/http" 7 "os" 8 "path/filepath" 9 10 "github.com/SAP/jenkins-library/pkg/maven" 11 "github.com/SAP/jenkins-library/pkg/piperutils" 12 ) 13 14 // Coordinates to address the artifact coordinates like groupId, artifactId, version and packaging 15 type Coordinates struct { 16 GroupID string 17 ArtifactID string 18 Version string 19 Packaging string 20 } 21 22 // Artifact defines the versioning operations for various build tools 23 type Artifact interface { 24 VersioningScheme() string 25 GetVersion() (string, error) 26 SetVersion(string) error 27 GetCoordinates() (Coordinates, error) 28 } 29 30 // Options define build tool specific settings in order to properly retrieve e.g. the version / coordinates of an artifact 31 type Options struct { 32 ProjectSettingsFile string 33 DockerImage string 34 GlobalSettingsFile string 35 M2Path string 36 Defines []string 37 VersionSource string 38 VersionSection string 39 VersionField string 40 VersioningScheme string 41 HelmUpdateAppVersion bool 42 CAPVersioningPreference string 43 } 44 45 // Utils defines the versioning operations for various build tools 46 type Utils interface { 47 Stdout(out io.Writer) 48 Stderr(err io.Writer) 49 RunExecutable(e string, p ...string) error 50 51 DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error 52 Glob(pattern string) (matches []string, err error) 53 FileExists(filename string) (bool, error) 54 Copy(src, dest string) (int64, error) 55 MkdirAll(path string, perm os.FileMode) error 56 FileWrite(path string, content []byte, perm os.FileMode) error 57 FileRead(path string) ([]byte, error) 58 FileRemove(path string) error 59 } 60 61 type mvnRunner struct{} 62 63 func (m *mvnRunner) Execute(options *maven.ExecuteOptions, utils maven.Utils) (string, error) { 64 return maven.Execute(options, utils) 65 } 66 func (m *mvnRunner) Evaluate(options *maven.EvaluateOptions, expression string, utils maven.Utils) (string, error) { 67 return maven.Evaluate(options, expression, utils) 68 } 69 70 var fileExists func(string) (bool, error) 71 72 // GetArtifact returns the build tool specific implementation for retrieving version, etc. of an artifact 73 func GetArtifact(buildTool, buildDescriptorFilePath string, opts *Options, utils Utils) (Artifact, error) { 74 var artifact Artifact 75 if fileExists == nil { 76 fileExists = piperutils.FileExists 77 } 78 79 // CAPVersioningPreference can only be 'maven' or 'npm'. Verification done on artifactPrepareVersion.yaml level 80 if buildTool == "CAP" { 81 buildTool = opts.CAPVersioningPreference 82 } 83 84 switch buildTool { 85 case "custom": 86 var err error 87 artifact, err = customArtifact(buildDescriptorFilePath, opts.VersionField, opts.VersionSection, opts.VersioningScheme) 88 if err != nil { 89 return artifact, err 90 } 91 case "docker": 92 artifact = &Docker{ 93 utils: utils, 94 options: opts, 95 path: buildDescriptorFilePath, 96 versionSource: opts.VersionSource, 97 versioningScheme: opts.VersioningScheme, 98 } 99 case "dub": 100 if len(buildDescriptorFilePath) == 0 { 101 buildDescriptorFilePath = "dub.json" 102 } 103 artifact = &JSONfile{ 104 path: buildDescriptorFilePath, 105 versionField: "version", 106 } 107 case "gradle": 108 if len(buildDescriptorFilePath) == 0 { 109 buildDescriptorFilePath = "gradle.properties" 110 } 111 artifact = &Gradle{ 112 path: buildDescriptorFilePath, 113 versionField: opts.VersionField, 114 utils: utils, 115 } 116 case "golang": 117 if len(buildDescriptorFilePath) == 0 { 118 var err error 119 buildDescriptorFilePath, err = searchDescriptor([]string{"go.mod", "VERSION", "version.txt"}, fileExists) 120 if err != nil { 121 return artifact, err 122 } 123 } 124 125 switch buildDescriptorFilePath { 126 case "go.mod": 127 artifact = &GoMod{path: buildDescriptorFilePath, fileExists: fileExists} 128 break 129 default: 130 artifact = &Versionfile{path: buildDescriptorFilePath} 131 } 132 case "helm": 133 artifact = &HelmChart{ 134 path: buildDescriptorFilePath, 135 utils: utils, 136 updateAppVersion: opts.HelmUpdateAppVersion, 137 } 138 case "maven": 139 if len(buildDescriptorFilePath) == 0 { 140 buildDescriptorFilePath = "pom.xml" 141 } 142 artifact = &Maven{ 143 runner: &mvnRunner{}, 144 utils: utils, 145 options: maven.EvaluateOptions{ 146 PomPath: buildDescriptorFilePath, 147 ProjectSettingsFile: opts.ProjectSettingsFile, 148 GlobalSettingsFile: opts.GlobalSettingsFile, 149 M2Path: opts.M2Path, 150 Defines: opts.Defines, 151 }, 152 } 153 case "mta": 154 if len(buildDescriptorFilePath) == 0 { 155 buildDescriptorFilePath = "mta.yaml" 156 } 157 artifact = &YAMLfile{ 158 path: buildDescriptorFilePath, 159 versionField: "version", 160 artifactIDField: "ID", 161 } 162 case "npm", "yarn": 163 if len(buildDescriptorFilePath) == 0 { 164 buildDescriptorFilePath = "package.json" 165 } 166 artifact = &JSONfile{ 167 path: buildDescriptorFilePath, 168 versionField: "version", 169 } 170 case "pip": 171 if len(buildDescriptorFilePath) == 0 { 172 var err error 173 buildDescriptorFilePath, err = searchDescriptor([]string{"setup.py", "version.txt", "VERSION"}, fileExists) 174 if err != nil { 175 return artifact, err 176 } 177 } 178 artifact = &Pip{ 179 path: buildDescriptorFilePath, 180 fileExists: fileExists, 181 } 182 case "sbt": 183 if len(buildDescriptorFilePath) == 0 { 184 var err error 185 buildDescriptorFilePath, err = searchDescriptor([]string{"sbtDescriptor.json", "build.sbt"}, fileExists) 186 if err != nil { 187 return artifact, err 188 } 189 } 190 artifact = &JSONfile{ 191 path: buildDescriptorFilePath, 192 versionField: "version", 193 } 194 default: 195 return artifact, fmt.Errorf("build tool '%v' not supported", buildTool) 196 } 197 198 return artifact, nil 199 } 200 201 func searchDescriptor(supported []string, existsFunc func(string) (bool, error)) (string, error) { 202 var descriptor string 203 for _, f := range supported { 204 exists, _ := existsFunc(f) 205 if exists { 206 descriptor = f 207 break 208 } 209 } 210 if len(descriptor) == 0 { 211 return "", fmt.Errorf("no build descriptor available, supported: %v", supported) 212 } 213 return descriptor, nil 214 } 215 216 func customArtifact(buildDescriptorFilePath, field, section, scheme string) (Artifact, error) { 217 switch filepath.Ext(buildDescriptorFilePath) { 218 case ".cfg", ".ini": 219 return &INIfile{ 220 path: buildDescriptorFilePath, 221 versionField: field, 222 versionSection: section, 223 versioningScheme: scheme, 224 }, nil 225 case ".json": 226 return &JSONfile{ 227 path: buildDescriptorFilePath, 228 versionField: field, 229 }, nil 230 case ".yaml", ".yml": 231 return &YAMLfile{ 232 path: buildDescriptorFilePath, 233 versionField: field, 234 }, nil 235 case ".txt", "": 236 return &Versionfile{ 237 path: buildDescriptorFilePath, 238 versioningScheme: scheme, 239 }, nil 240 default: 241 return nil, fmt.Errorf("file type not supported: '%v'", buildDescriptorFilePath) 242 } 243 }