-
Notifications
You must be signed in to change notification settings - Fork 391
Expand file tree
/
Copy pathupdate_entity_helpers.go
More file actions
176 lines (153 loc) · 6.01 KB
/
update_entity_helpers.go
File metadata and controls
176 lines (153 loc) · 6.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
package workflow
import (
"github.com/githubnext/gh-aw/pkg/logger"
)
// UpdateEntityType represents the type of entity being updated
type UpdateEntityType string
const (
UpdateEntityIssue UpdateEntityType = "issue"
UpdateEntityPullRequest UpdateEntityType = "pull_request"
UpdateEntityDiscussion UpdateEntityType = "discussion"
UpdateEntityRelease UpdateEntityType = "release"
)
// UpdateEntityConfig holds the configuration for an update entity operation
type UpdateEntityConfig struct {
BaseSafeOutputConfig `yaml:",inline"`
SafeOutputTargetConfig `yaml:",inline"`
// Type-specific fields are stored in the concrete config structs
}
// UpdateEntityJobParams holds the parameters needed to build an update entity job
type UpdateEntityJobParams struct {
EntityType UpdateEntityType
ConfigKey string // e.g., "update-issue", "update-pull-request"
JobName string // e.g., "update_issue", "update_pull_request"
StepName string // e.g., "Update Issue", "Update Pull Request"
ScriptGetter func() string
PermissionsFunc func() *Permissions
CustomEnvVars []string // Type-specific environment variables
Outputs map[string]string // Type-specific outputs
Condition ConditionNode // Job condition expression
}
// UpdateEntityJobBuilder encapsulates entity-specific configuration for building update jobs
type UpdateEntityJobBuilder struct {
EntityType UpdateEntityType
ConfigKey string
JobName string
StepName string
ScriptGetter func() string
PermissionsFunc func() *Permissions
BuildCustomEnvVars func(*UpdateEntityConfig) []string
BuildOutputs func() map[string]string
BuildEventCondition func(string) ConditionNode // Optional: builds event condition if target is empty
}
// parseUpdateEntityConfig is a generic function to parse update entity configurations
func (c *Compiler) parseUpdateEntityConfig(outputMap map[string]any, params UpdateEntityJobParams, logger *logger.Logger, parseSpecificFields func(map[string]any, *UpdateEntityConfig)) *UpdateEntityConfig {
if configData, exists := outputMap[params.ConfigKey]; exists {
logger.Printf("Parsing %s configuration", params.ConfigKey)
config := &UpdateEntityConfig{}
if configMap, ok := configData.(map[string]any); ok {
// Parse target config (target, target-repo) with validation
targetConfig, isInvalid := ParseTargetConfig(configMap)
if isInvalid {
logger.Print("Invalid target-repo configuration")
return nil
}
config.SafeOutputTargetConfig = targetConfig
// Parse type-specific fields if provided
if parseSpecificFields != nil {
parseSpecificFields(configMap, config)
}
// Parse common base fields with default max of 1
c.parseBaseSafeOutputConfig(configMap, &config.BaseSafeOutputConfig, 1)
} else {
// If configData is nil or not a map, still set the default max
config.Max = 1
}
return config
}
return nil
}
// parseUpdateEntityBase is a helper that reduces scaffolding duplication across update entity parsers.
// It handles the common pattern of:
// 1. Building UpdateEntityJobParams
// 2. Calling parseUpdateEntityConfig
// 3. Checking for nil result
// 4. Returning the base config and config map for entity-specific field parsing
//
// Returns:
// - baseConfig: The parsed base configuration (nil if parsing failed)
// - configMap: The entity-specific config map for additional field parsing (nil if not present)
//
// Callers should check if baseConfig is nil before proceeding with entity-specific parsing.
func (c *Compiler) parseUpdateEntityBase(
outputMap map[string]any,
entityType UpdateEntityType,
configKey string,
logger *logger.Logger,
) (*UpdateEntityConfig, map[string]any) {
// Build params for base config parsing
params := UpdateEntityJobParams{
EntityType: entityType,
ConfigKey: configKey,
}
// Parse the base config (common fields like max, target, target-repo)
baseConfig := c.parseUpdateEntityConfig(outputMap, params, logger, nil)
if baseConfig == nil {
return nil, nil
}
// Extract the config map for entity-specific field parsing
var configMap map[string]any
if configData, exists := outputMap[configKey]; exists {
if cm, ok := configData.(map[string]any); ok {
configMap = cm
}
}
return baseConfig, configMap
}
// FieldParsingMode determines how boolean fields are parsed from the config
type FieldParsingMode int
const (
// FieldParsingKeyExistence mode: Field presence (even if nil) indicates it can be updated
// Used by update-issue and update-discussion
FieldParsingKeyExistence FieldParsingMode = iota
// FieldParsingBoolValue mode: Field's boolean value determines if it can be updated
// Used by update-pull-request (defaults to true if nil)
FieldParsingBoolValue
)
// parseUpdateEntityBoolField is a generic helper that parses boolean fields from config maps
// based on the specified parsing mode.
//
// Parameters:
// - configMap: The entity-specific configuration map
// - fieldName: The name of the field to parse (e.g., "title", "body", "status")
// - mode: The parsing mode (FieldParsingKeyExistence or FieldParsingBoolValue)
//
// Returns:
// - *bool: A pointer to bool if the field should be enabled, nil if disabled
//
// Behavior by mode:
// - FieldParsingKeyExistence: Returns new(bool) if key exists, nil otherwise
// - FieldParsingBoolValue: Returns &boolValue if key exists and is bool, nil otherwise
func parseUpdateEntityBoolField(configMap map[string]any, fieldName string, mode FieldParsingMode) *bool {
if configMap == nil {
return nil
}
val, exists := configMap[fieldName]
if !exists {
return nil
}
switch mode {
case FieldParsingKeyExistence:
// Key presence (even if nil) indicates field can be updated
return new(bool) // Allocate a new bool pointer (defaults to false)
case FieldParsingBoolValue:
// Parse actual boolean value from config
if boolVal, ok := val.(bool); ok {
return &boolVal
}
// If present but not a bool (e.g., null), return nil (no explicit setting)
return nil
default:
return nil
}
}