1
0
Fork 0
woodpecker-sonatype-nexus/upload.go

127 lines
2.8 KiB
Go

// SPDX-License-Identifier: Apache-2.0
// (c) 2024, Konstantin Demin
package main
import (
"encoding/json"
"fmt"
"path/filepath"
"reflect"
"strings"
"github.com/rs/zerolog/log"
)
type UploadRuleBase struct {
Repository string `json:"repository"`
Paths []string `json:"paths"`
}
type UploadRule struct {
UploadRuleBase
Properties map[string]any
}
func (p *Plugin) processRawUploads() error {
var err error
b := []byte(p.Settings.RawUploads)
var base []UploadRuleBase
err = json.Unmarshal(b, &base)
if err != nil {
log.Error().Msg("unable to parse upload rules")
return err
}
if len(base) == 0 {
return nil
}
var raw []any
err = json.Unmarshal(b, &raw)
if err != nil {
log.Error().Msg("unable to parse upload rules")
return err
}
if len(raw) == 0 {
return nil
}
// just in case
b = nil
if len(raw) != len(base) {
// just in case
log.Error().Msgf("upload[] deserialization error: array length mismatch: %d != %d", len(base), len(raw))
return &ErrMalformed{}
}
result := make([]UploadRule, 0, len(raw))
for i := range raw {
if base[i].Repository == "" {
return reportEmptySetting(fmt.Sprintf("upload[%d].repository", i))
}
if len(base[i].Paths) == 0 {
return reportEmptySetting(fmt.Sprintf("upload[%d].paths", i))
}
for k, patt := range base[i].Paths {
_, err = filepath.Glob(patt)
if err != nil {
return reportMalformedSetting(fmt.Sprintf("upload[%d].paths[%d]", i, k), fmt.Sprintf("bad pattern %q: %v", patt, err))
}
}
rtype := reflect.TypeOf(raw[i])
if rtype.Kind() != reflect.Map {
return reportMalformedSetting(fmt.Sprintf("upload[%d]", i), fmt.Sprintf("not a map[string]any but %v", rtype.Kind()))
}
if rtype.Key().Kind() != reflect.String {
return reportMalformedSetting(fmt.Sprintf("upload[%d]", i), fmt.Sprintf("not a map[string]any but map[%v]any", rtype.Key().Kind()))
}
m := raw[i].(map[string]any)
ur := UploadRule{}
ur.Repository = base[i].Repository
ur.Paths = make([]string, len(base[i].Paths))
copy(ur.Paths, base[i].Paths)
for k := range m {
switch strings.ToLower(k) {
case "repository", "paths":
log.Info().Msgf("upload[%d]: %q is handled by type %q", i, k, "UploadRuleBase")
continue
case "asset", "filename":
log.Info().Msgf("upload[%d]: %q is handled internally on per-artifact basis", i, k)
continue
}
rtype = reflect.TypeOf(m[k])
switch rtype.Kind() {
case reflect.Invalid,
reflect.Array,
reflect.Chan,
reflect.Func,
reflect.Interface,
reflect.Map,
reflect.Pointer,
reflect.Slice,
reflect.Struct,
reflect.UnsafePointer:
//
return reportMalformedSetting(fmt.Sprintf("upload[%d]", i), fmt.Sprintf("%q is type of %q", k, rtype.String()))
}
ur.Properties[k] = m[k]
}
result = append(result, ur)
}
p.Uploads = result
return nil
}