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