Skip to content
30 changes: 1 addition & 29 deletions pkg/jira/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"encoding/json"
"net/http"
"strconv"
"strings"

"github.com/ankitpokhrel/jira-cli/pkg/adf"
Expand Down Expand Up @@ -240,34 +239,7 @@ func constructCustomFields(fields map[string]string, configuredFields []IssueTyp
if identifier != strings.ToLower(key) {
continue
}

switch configured.Schema.DataType {
case customFieldFormatOption:
data.Fields.M.customFields[configured.Key] = customFieldTypeOption{Value: val}
case customFieldFormatProject:
data.Fields.M.customFields[configured.Key] = customFieldTypeProject{Value: val}
case customFieldFormatArray:
pieces := strings.Split(strings.TrimSpace(val), ",")
if configured.Schema.Items == customFieldFormatOption {
items := make([]customFieldTypeOption, 0)
for _, p := range pieces {
items = append(items, customFieldTypeOption{Value: p})
}
data.Fields.M.customFields[configured.Key] = items
} else {
data.Fields.M.customFields[configured.Key] = pieces
}
case customFieldFormatNumber:
num, err := strconv.ParseFloat(val, 64) //nolint:gomnd
if err != nil {
// Let Jira API handle data type error for now.
data.Fields.M.customFields[configured.Key] = val
} else {
data.Fields.M.customFields[configured.Key] = customFieldTypeNumber(num)
}
default:
data.Fields.M.customFields[configured.Key] = val
}
data.Fields.M.customFields[configured.Key] = constructCustomField(configured.Schema.DataType, configured.Schema.Items, val)
}
}
}
Expand Down
77 changes: 62 additions & 15 deletions pkg/jira/customfield.go
Original file line number Diff line number Diff line change
@@ -1,41 +1,88 @@
package jira

import (
"encoding/json"
"strconv"
"strings"
)

const (
customFieldFormatAny = "any"
customFieldFormatOption = "option"
customFieldFormatArray = "array"
customFieldFormatNumber = "number"
customFieldFormatString = "string"
customFieldFormatProject = "project"
customFieldFormatJson = "json"
)

type customField map[string]interface{}

type customFieldTypeNumber float64

type customFieldTypeNumberSet struct {
Set customFieldTypeNumber `json:"set"`
type customFieldTypeString string

type customFieldTypeOption struct {
Value string `json:"value"`
}

type customFieldTypeStringSet struct {
Set string `json:"set"`
type customFieldTypeProject struct {
Value string `json:"key"`
}

type customFieldTypeOption struct {
Value string `json:"value"`
type customFieldTypeJson struct {
Json string
}

type customFieldTypeOptionSet struct {
Set customFieldTypeOption `json:"set"`
func (field customFieldTypeJson) MarshalJSON() ([]byte, error) {
return []byte(field.Json), nil
}

type customFieldTypeOptionAddRemove struct {
Add *customFieldTypeOption `json:"add,omitempty"`
Remove *customFieldTypeOption `json:"remove,omitempty"`
type customFieldEditTypeSet struct {
Set any `json:"set"`
}

type customFieldTypeProject struct {
Value string `json:"key"`
type customFieldEditTypeAddRemove struct {
Add *any `json:"add,omitempty"`
Remove *any `json:"remove,omitempty"`
}

type customFieldTypeProjectSet struct {
Set customFieldTypeProject `json:"set"`
func constructCustomField(dataType string, itemType string, value string) any {
switch dataType {
case customFieldFormatOption:
return customFieldTypeOption{Value: value}
case customFieldFormatProject:
return customFieldTypeProject{Value: value}
case customFieldFormatArray:
pieces := strings.Split(strings.TrimSpace(value), ",")
items := make([]any, len(pieces))
for idx, piece := range pieces {
items[idx] = constructCustomField(itemType, "", piece)
}
return items
case customFieldFormatNumber:
num, err := strconv.ParseFloat(value, 64) //nolint:gomnd
if err != nil {
// Let Jira API handle data type error for now.
return value
} else {
return customFieldTypeNumber(num)
}
case customFieldFormatAny:
fallthrough
case customFieldFormatString:
return customFieldTypeString(value)
case customFieldFormatJson:
return customFieldTypeJson{Json: value}
default:
// An unknown type like "version" or "user". Try parsing as JSON,
// and if that doesn't work, just send as a string
var unused any
err := json.Unmarshal([]byte(value), &unused)
if err == nil {
return customFieldTypeJson{Json: value}
} else {
return value
}
}
}
41 changes: 12 additions & 29 deletions pkg/jira/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"encoding/json"
"net/http"
"strconv"
"strings"
)

Expand Down Expand Up @@ -366,37 +365,21 @@ func constructCustomFieldsForEdit(fields map[string]string, configuredFields []I
if identifier != strings.ToLower(key) {
continue
}

switch configured.Schema.DataType {
case customFieldFormatOption:
data.Update.M.customFields[configured.Key] = []customFieldTypeOptionSet{{Set: customFieldTypeOption{Value: val}}}
case customFieldFormatProject:
data.Update.M.customFields[configured.Key] = []customFieldTypeProjectSet{{Set: customFieldTypeProject{Value: val}}}
case customFieldFormatArray:
if configured.Schema.DataType == customFieldFormatArray {
pieces := strings.Split(strings.TrimSpace(val), ",")
if configured.Schema.Items == customFieldFormatOption {
items := make([]customFieldTypeOptionAddRemove, 0)
for _, p := range pieces {
if strings.HasPrefix(p, separatorMinus) {
items = append(items, customFieldTypeOptionAddRemove{Remove: &customFieldTypeOption{Value: strings.TrimPrefix(p, separatorMinus)}})
} else {
items = append(items, customFieldTypeOptionAddRemove{Add: &customFieldTypeOption{Value: p}})
}
items := make([]customFieldEditTypeAddRemove, len(pieces))
for idx, piece := range pieces {
field := constructCustomField(configured.Schema.Items, "", strings.TrimPrefix(piece, separatorMinus))
if strings.HasPrefix(piece, separatorMinus) {
items[idx] = customFieldEditTypeAddRemove{Remove: &field}
} else {
items[idx] = customFieldEditTypeAddRemove{Add: &field}
}
data.Update.M.customFields[configured.Key] = items
} else {
data.Update.M.customFields[configured.Key] = pieces
}
case customFieldFormatNumber:
num, err := strconv.ParseFloat(val, 64) //nolint:gomnd
if err != nil {
// Let Jira API handle data type error for now.
data.Update.M.customFields[configured.Key] = []customFieldTypeStringSet{{Set: val}}
} else {
data.Update.M.customFields[configured.Key] = []customFieldTypeNumberSet{{Set: customFieldTypeNumber(num)}}
}
default:
data.Update.M.customFields[configured.Key] = []customFieldTypeStringSet{{Set: val}}
data.Update.M.customFields[configured.Key] = items
} else {
field := constructCustomField(configured.Schema.DataType, "", val)
data.Update.M.customFields[configured.Key] = []customFieldEditTypeSet{{Set: field}}
}
}
}
Expand Down