127 lines
2.8 KiB
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
|
||
|
}
|