mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-01-04 04:07:16 +02:00
180 lines
5.2 KiB
Go
180 lines
5.2 KiB
Go
package aakaas
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/url"
|
|
"strconv"
|
|
"strings"
|
|
|
|
abapbuild "github.com/SAP/jenkins-library/pkg/abap/build"
|
|
"github.com/SAP/jenkins-library/pkg/log"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
const wildCard string = "NEXT"
|
|
const statusFilterCV string = "DeliveryStatus eq 'R'"
|
|
const statusFilterPV string = "DeliveryStatus eq 'T' or DeliveryStatus eq 'P'"
|
|
|
|
type versionable struct {
|
|
Name string
|
|
Version string
|
|
TechRelease string
|
|
TechSpLevel string
|
|
TechPatchLevel string
|
|
|
|
connector abapbuild.Connector
|
|
queryUrl string
|
|
}
|
|
|
|
type versionables struct {
|
|
Wrapper struct {
|
|
Vs []versionable `json:"results"`
|
|
} `json:"d"`
|
|
}
|
|
|
|
func (v *versionable) constructVersionable(name string, dottedVersionString string, connector abapbuild.Connector, queryURL string) error {
|
|
if name == "" {
|
|
return errors.New("No Component/Product Name provided")
|
|
}
|
|
subStrings := strings.Split(dottedVersionString, ".")
|
|
if len(subStrings) != 3 {
|
|
return errors.New("Provide a dotted-version-string with 2 '.' [Release.SP.Patch]")
|
|
}
|
|
v.Name = name
|
|
v.TechRelease = subStrings[0]
|
|
v.TechSpLevel = fmt.Sprintf("%04s", subStrings[1])
|
|
v.TechPatchLevel = fmt.Sprintf("%04s", subStrings[2])
|
|
v.connector = connector
|
|
v.queryUrl = queryURL
|
|
v.Version = dottedVersionString
|
|
return nil
|
|
}
|
|
|
|
func (v *versionable) resolveNext(statusFilter string) error {
|
|
|
|
switch strings.Count(v.Version, wildCard) {
|
|
case 0:
|
|
return nil
|
|
case 1:
|
|
log.Entry().Info("Wildcard detected in dotted-version-string. Looking up highest existing package in AAKaaS...")
|
|
var err error
|
|
switch wildCard {
|
|
case v.TechRelease:
|
|
err = v.resolveRelease(statusFilter)
|
|
case v.TechSpLevel:
|
|
err = v.resolveSpLevel(statusFilter)
|
|
case v.TechPatchLevel:
|
|
err = v.resolvePatchLevel(statusFilter)
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if v.Version, err = v.getDottedVersionString(); err != nil {
|
|
return err
|
|
}
|
|
default:
|
|
return errors.New("The dotted-version-string must contain only one wildcard " + wildCard)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (v *versionable) resolveRelease(statusFilter string) error {
|
|
filter := "Name eq '" + v.Name + "' and TechSpLevel eq '0000' and TechPatchLevel eq '0000' and ( " + statusFilter + " )"
|
|
orderBy := "TechRelease desc"
|
|
|
|
if queryResuult, err := v.queryVersion(filter, orderBy); err != nil {
|
|
return err
|
|
} else {
|
|
if newRelease, err := strconv.Atoi(queryResuult.TechRelease); err != nil {
|
|
return err
|
|
} else {
|
|
v.TechRelease = strconv.Itoa(newRelease + 1)
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
|
|
func (v *versionable) resolveSpLevel(statusFilter string) error {
|
|
filter := "Name eq '" + v.Name + "' and TechRelease eq '" + v.TechRelease + "' and TechPatchLevel eq '0000' and ( " + statusFilter + " )"
|
|
orderBy := "TechSpLevel desc"
|
|
|
|
if queryResuult, err := v.queryVersion(filter, orderBy); err != nil {
|
|
return err
|
|
} else {
|
|
if newSpLevel, err := strconv.Atoi(queryResuult.TechSpLevel); err != nil {
|
|
return err
|
|
} else {
|
|
v.TechSpLevel = fmt.Sprintf("%04d", newSpLevel+1)
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
|
|
func (v *versionable) resolvePatchLevel(statusFilter string) error {
|
|
filter := "Name eq '" + v.Name + "' and TechRelease eq '" + v.TechRelease + "' and TechSpLevel eq '" + v.TechSpLevel + "' and ( " + statusFilter + " )"
|
|
orderBy := "TechPatchLevel desc"
|
|
|
|
if queryResuult, err := v.queryVersion(filter, orderBy); err != nil {
|
|
return err
|
|
} else {
|
|
if newPatchLevel, err := strconv.Atoi(queryResuult.TechPatchLevel); err != nil {
|
|
return err
|
|
} else {
|
|
v.TechPatchLevel = fmt.Sprintf("%04d", newPatchLevel+1)
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
|
|
func (v *versionable) queryVersion(filter string, orderBy string) (*versionable, error) {
|
|
result := versionable{}
|
|
|
|
values := url.Values{}
|
|
values.Set("$filter", filter)
|
|
values.Set("$orderby", orderBy)
|
|
values.Set("$select", "Name,Version,TechRelease,TechSpLevel,TechPatchLevel,Namespace") //Namespace needed otherwise empty result - will be fixed by OCS shortly
|
|
values.Set("$format", "json")
|
|
values.Set("$top", "1")
|
|
|
|
requestUrl := v.queryUrl + "?" + values.Encode()
|
|
|
|
if body, err := v.connector.Get(requestUrl); err != nil {
|
|
return &result, err
|
|
} else {
|
|
Versions := versionables{}
|
|
if err := json.Unmarshal(body, &Versions); err != nil {
|
|
return &result, errors.Wrap(err, "Unexpected AAKaaS response for Component Version Query: "+string(body))
|
|
}
|
|
switch len(Versions.Wrapper.Vs) {
|
|
case 0:
|
|
result = versionable{
|
|
TechRelease: "0",
|
|
TechSpLevel: "0000",
|
|
TechPatchLevel: "0000",
|
|
}
|
|
case 1:
|
|
result = Versions.Wrapper.Vs[0]
|
|
default:
|
|
return &result, errors.New("Unexpected Number of CVs in result: " + fmt.Sprint(len(Versions.Wrapper.Vs)))
|
|
}
|
|
}
|
|
log.Entry().Infof("... looked up highest existing package in AAKaaS of the codeline: %s.%s.%s", result.TechRelease, result.TechSpLevel, result.TechPatchLevel)
|
|
return &result, nil
|
|
}
|
|
|
|
func (v *versionable) getDottedVersionString() (string, error) {
|
|
var spLevelAsnumber int
|
|
var patchLevelAsNumber int
|
|
var err error
|
|
if spLevelAsnumber, err = strconv.Atoi(v.TechSpLevel); err != nil {
|
|
return "", err
|
|
}
|
|
if patchLevelAsNumber, err = strconv.Atoi(v.TechPatchLevel); err != nil {
|
|
return "", err
|
|
}
|
|
dottedVersionString := strings.Join([]string{v.TechRelease, strconv.Itoa(spLevelAsnumber), strconv.Itoa(patchLevelAsNumber)}, ".")
|
|
return dottedVersionString, nil
|
|
}
|