github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/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/piperutils" 11 12 "github.com/SAP/jenkins-library/pkg/maven" 13 ) 14 15 // Coordinates to address the artifact coordinates like groupId, artifactId, version and packaging 16 type Coordinates struct { 17 GroupID string 18 ArtifactID string 19 Version string 20 Packaging string 21 } 22 23 // Artifact defines the versioning operations for various build tools 24 type Artifact interface { 25 VersioningScheme() string 26 GetVersion() (string, error) 27 SetVersion(string) error 28 GetCoordinates() (Coordinates, error) 29 } 30 31 // Options define build tool specific settings in order to properly retrieve e.g. the version / coordinates of an artifact 32 type Options struct { 33 ProjectSettingsFile string 34 DockerImage string 35 GlobalSettingsFile string 36 M2Path string 37 Defines []string 38 VersionSource string 39 VersionSection string 40 VersionField string 41 VersioningScheme string 42 HelmUpdateAppVersion bool 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 switch buildTool { 79 case "custom": 80 var err error 81 artifact, err = customArtifact(buildDescriptorFilePath, opts.VersionField, opts.VersionSection, opts.VersioningScheme) 82 if err != nil { 83 return artifact, err 84 } 85 case "docker": 86 artifact = &Docker{ 87 utils: utils, 88 options: opts, 89 path: buildDescriptorFilePath, 90 versionSource: opts.VersionSource, 91 versioningScheme: opts.VersioningScheme, 92 } 93 case "dub": 94 if len(buildDescriptorFilePath) == 0 { 95 buildDescriptorFilePath = "dub.json" 96 } 97 artifact = &JSONfile{ 98 path: buildDescriptorFilePath, 99 versionField: "version", 100 } 101 case "gradle": 102 if len(buildDescriptorFilePath) == 0 { 103 buildDescriptorFilePath = "gradle.properties" 104 } 105 artifact = &Gradle{ 106 path: buildDescriptorFilePath, 107 versionField: opts.VersionField, 108 utils: utils, 109 } 110 case "golang": 111 if len(buildDescriptorFilePath) == 0 { 112 var err error 113 buildDescriptorFilePath, err = searchDescriptor([]string{"go.mod", "VERSION", "version.txt"}, fileExists) 114 if err != nil { 115 return artifact, err 116 } 117 } 118 119 switch buildDescriptorFilePath { 120 case "go.mod": 121 artifact = &GoMod{path: buildDescriptorFilePath, fileExists: fileExists} 122 break 123 default: 124 artifact = &Versionfile{path: buildDescriptorFilePath} 125 } 126 case "helm": 127 artifact = &HelmChart{ 128 path: buildDescriptorFilePath, 129 utils: utils, 130 updateAppVersion: opts.HelmUpdateAppVersion, 131 } 132 case "maven": 133 if len(buildDescriptorFilePath) == 0 { 134 buildDescriptorFilePath = "pom.xml" 135 } 136 artifact = &Maven{ 137 runner: &mvnRunner{}, 138 utils: utils, 139 options: maven.EvaluateOptions{ 140 PomPath: buildDescriptorFilePath, 141 ProjectSettingsFile: opts.ProjectSettingsFile, 142 GlobalSettingsFile: opts.GlobalSettingsFile, 143 M2Path: opts.M2Path, 144 Defines: opts.Defines, 145 }, 146 } 147 case "mta": 148 if len(buildDescriptorFilePath) == 0 { 149 buildDescriptorFilePath = "mta.yaml" 150 } 151 artifact = &YAMLfile{ 152 path: buildDescriptorFilePath, 153 versionField: "version", 154 artifactIDField: "ID", 155 } 156 case "npm", "yarn": 157 if len(buildDescriptorFilePath) == 0 { 158 buildDescriptorFilePath = "package.json" 159 } 160 artifact = &JSONfile{ 161 path: buildDescriptorFilePath, 162 versionField: "version", 163 } 164 case "pip": 165 if len(buildDescriptorFilePath) == 0 { 166 var err error 167 buildDescriptorFilePath, err = searchDescriptor([]string{"setup.py", "version.txt", "VERSION"}, fileExists) 168 if err != nil { 169 return artifact, err 170 } 171 } 172 artifact = &Pip{ 173 path: buildDescriptorFilePath, 174 fileExists: fileExists, 175 } 176 case "sbt": 177 if len(buildDescriptorFilePath) == 0 { 178 var err error 179 buildDescriptorFilePath, err = searchDescriptor([]string{"sbtDescriptor.json", "build.sbt"}, fileExists) 180 if err != nil { 181 return artifact, err 182 } 183 } 184 artifact = &JSONfile{ 185 path: buildDescriptorFilePath, 186 versionField: "version", 187 } 188 default: 189 return artifact, fmt.Errorf("build tool '%v' not supported", buildTool) 190 } 191 192 return artifact, nil 193 } 194 195 func searchDescriptor(supported []string, existsFunc func(string) (bool, error)) (string, error) { 196 var descriptor string 197 for _, f := range supported { 198 exists, _ := existsFunc(f) 199 if exists { 200 descriptor = f 201 break 202 } 203 } 204 if len(descriptor) == 0 { 205 return "", fmt.Errorf("no build descriptor available, supported: %v", supported) 206 } 207 return descriptor, nil 208 } 209 210 func customArtifact(buildDescriptorFilePath, field, section, scheme string) (Artifact, error) { 211 switch filepath.Ext(buildDescriptorFilePath) { 212 case ".cfg", ".ini": 213 return &INIfile{ 214 path: buildDescriptorFilePath, 215 versionField: field, 216 versionSection: section, 217 versioningScheme: scheme, 218 }, nil 219 case ".json": 220 return &JSONfile{ 221 path: buildDescriptorFilePath, 222 versionField: field, 223 }, nil 224 case ".yaml", ".yml": 225 return &YAMLfile{ 226 path: buildDescriptorFilePath, 227 versionField: field, 228 }, nil 229 case ".txt", "": 230 return &Versionfile{ 231 path: buildDescriptorFilePath, 232 versioningScheme: scheme, 233 }, nil 234 default: 235 return nil, fmt.Errorf("file type not supported: '%v'", buildDescriptorFilePath) 236 } 237 }