mirror of https://github.com/harness/drone.git
fix: [CDE-555]: allow mixed data types in lifecycle command object fo… (#3604)
(#3169)
<img width="1569" alt="Screenshot 2024-12-17 at 2 29 36 PM"
src="https://github.com/user-attachments/assets/e635fc69-3264-4b65-8b4e-6b9df016a21c"
/>
* fix: [CDE-555]: allow mixed data types in lifecycle command object
form.
(cherry picked from commit 9c792e53fd
)
[CDE-555]:
https://harness.atlassian.net/browse/CDE-555?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
pull/3610/head
v3.1.0
parent
cf8b8b2215
commit
231536844c
|
@ -16,7 +16,7 @@ package types
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
@ -33,24 +33,21 @@ type DevcontainerConfig struct {
|
|||
RemoteUser string `json:"remoteUser,omitempty"`
|
||||
}
|
||||
|
||||
//nolint:tagliatelle
|
||||
type LifecycleCommand struct {
|
||||
CommandString string `json:"commandString,omitempty"`
|
||||
CommandArray []string `json:"commandArray,omitempty"`
|
||||
// Map to store commands by tags
|
||||
CommandMap map[string]string `json:"commandMap,omitempty"`
|
||||
CommandMapArray map[string][]string `json:"commandMapArray,omitempty"`
|
||||
Discriminator string `json:"-"` // Tracks the original type for proper re-marshaling
|
||||
}
|
||||
|
||||
// Constants for discriminator values.
|
||||
const (
|
||||
TypeString = "string"
|
||||
TypeArray = "array"
|
||||
TypeCommandMapString = "commandMap"
|
||||
TypeCommandMapArray = "commandMapArray"
|
||||
TypeString = "string"
|
||||
TypeArray = "array"
|
||||
TypeCommandMap = "commandMap"
|
||||
)
|
||||
|
||||
//nolint:tagliatelle
|
||||
type LifecycleCommand struct {
|
||||
CommandString string `json:"commandString,omitempty"`
|
||||
CommandArray []string `json:"commandArray,omitempty"`
|
||||
CommandMap map[string]any `json:"commandMap,omitempty"`
|
||||
Discriminator string `json:"-"` // Tracks the original type for proper re-marshaling
|
||||
}
|
||||
|
||||
func (lc *LifecycleCommand) UnmarshalJSON(data []byte) error {
|
||||
// Try to unmarshal as a single string
|
||||
var commandStr string
|
||||
|
@ -59,6 +56,7 @@ func (lc *LifecycleCommand) UnmarshalJSON(data []byte) error {
|
|||
lc.Discriminator = TypeString
|
||||
return nil
|
||||
}
|
||||
|
||||
// Try to unmarshal as an array of strings
|
||||
var commandArr []string
|
||||
if err := json.Unmarshal(data, &commandArr); err == nil {
|
||||
|
@ -66,21 +64,35 @@ func (lc *LifecycleCommand) UnmarshalJSON(data []byte) error {
|
|||
lc.Discriminator = TypeArray
|
||||
return nil
|
||||
}
|
||||
// Try to unmarshal as a map of commands (tags to commands)
|
||||
var commandMap map[string]string
|
||||
if err := json.Unmarshal(data, &commandMap); err == nil {
|
||||
lc.CommandMap = commandMap
|
||||
lc.Discriminator = TypeCommandMapString
|
||||
|
||||
// Try to unmarshal as a map with mixed types
|
||||
var rawMap map[string]any
|
||||
if err := json.Unmarshal(data, &rawMap); err == nil {
|
||||
for key, value := range rawMap {
|
||||
switch v := value.(type) {
|
||||
case string:
|
||||
// Valid string value
|
||||
case []interface{}:
|
||||
// Convert []interface{} to []string
|
||||
var strArray []string
|
||||
for _, item := range v {
|
||||
if str, ok := item.(string); ok {
|
||||
strArray = append(strArray, str)
|
||||
} else {
|
||||
return fmt.Errorf("invalid format: array contains non-string value")
|
||||
}
|
||||
}
|
||||
rawMap[key] = strArray
|
||||
default:
|
||||
return fmt.Errorf("invalid format: map contains unsupported type")
|
||||
}
|
||||
}
|
||||
lc.CommandMap = rawMap
|
||||
lc.Discriminator = TypeCommandMap
|
||||
return nil
|
||||
}
|
||||
// Try to unmarshal as a CommandMapArray
|
||||
var commandMapArray map[string][]string
|
||||
if err := json.Unmarshal(data, &commandMapArray); err == nil {
|
||||
lc.CommandMapArray = commandMapArray
|
||||
lc.Discriminator = TypeCommandMapArray
|
||||
return nil
|
||||
}
|
||||
return errors.New("invalid format: must be string, []string, map[string]string, or map[string][]string")
|
||||
|
||||
return fmt.Errorf("invalid format: must be string, []string, or map[string]any")
|
||||
}
|
||||
|
||||
func (lc *LifecycleCommand) MarshalJSON() ([]byte, error) {
|
||||
|
@ -89,32 +101,29 @@ func (lc *LifecycleCommand) MarshalJSON() ([]byte, error) {
|
|||
return json.Marshal(lc.CommandString)
|
||||
case TypeArray:
|
||||
return json.Marshal(lc.CommandArray)
|
||||
case TypeCommandMapString:
|
||||
case TypeCommandMap:
|
||||
return json.Marshal(lc.CommandMap)
|
||||
case TypeCommandMapArray:
|
||||
return json.Marshal(lc.CommandMapArray)
|
||||
default:
|
||||
return nil, errors.New("unknown type for LifecycleCommand")
|
||||
return nil, fmt.Errorf("unknown type for LifecycleCommand")
|
||||
}
|
||||
}
|
||||
|
||||
// ToCommandArray converts the LifecycleCommand into a slice of full commands.
|
||||
func (lc *LifecycleCommand) ToCommandArray() []string {
|
||||
switch {
|
||||
case lc.CommandString != "":
|
||||
switch lc.Discriminator {
|
||||
case TypeString:
|
||||
return []string{lc.CommandString}
|
||||
case lc.CommandArray != nil:
|
||||
case TypeArray:
|
||||
return []string{strings.Join(lc.CommandArray, " ")}
|
||||
case lc.CommandMap != nil:
|
||||
case TypeCommandMap:
|
||||
var commands []string
|
||||
for _, command := range lc.CommandMap {
|
||||
commands = append(commands, command)
|
||||
}
|
||||
return commands
|
||||
case lc.CommandMapArray != nil:
|
||||
var commands []string
|
||||
for _, commandArray := range lc.CommandMapArray {
|
||||
commands = append(commands, strings.Join(commandArray, " "))
|
||||
for _, value := range lc.CommandMap {
|
||||
switch v := value.(type) {
|
||||
case string:
|
||||
commands = append(commands, v)
|
||||
case []string:
|
||||
commands = append(commands, strings.Join(v, " "))
|
||||
}
|
||||
}
|
||||
return commands
|
||||
default:
|
||||
|
|
Loading…
Reference in New Issue