Skip to content

Commit 53fd508

Browse files
authored
Refactor duplicated helper utilities and centralize pointer helpers via typeutil.Ptr (#35349)
1 parent 9b3594e commit 53fd508

8 files changed

Lines changed: 46 additions & 35 deletions

pkg/cli/codemod_engine_env_secrets.go

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"strings"
55

66
"github.com/github/gh-aw/pkg/logger"
7+
"github.com/github/gh-aw/pkg/sliceutil"
78
"github.com/github/gh-aw/pkg/workflow"
89
)
910

@@ -54,7 +55,7 @@ func getEngineEnvSecretsCodemod() Codemod {
5455
return cleaned, true
5556
})
5657
if applied {
57-
engineEnvSecretsCodemodLog.Printf("Removed unsafe engine.env secret keys: %v", mapKeys(unsafeKeys))
58+
engineEnvSecretsCodemodLog.Printf("Removed unsafe engine.env secret keys: %v", sliceutil.MapKeys(unsafeKeys))
5859
}
5960
return newContent, applied, err
6061
},
@@ -238,11 +239,3 @@ func removeEmptyEngineEnvBlock(lines []string) []string {
238239
}
239240
return result
240241
}
241-
242-
func mapKeys(m map[string]bool) []string {
243-
keys := make([]string, 0, len(m))
244-
for k := range m {
245-
keys = append(keys, k)
246-
}
247-
return keys
248-
}

pkg/cli/gateway_logs_timeline.go

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import (
2323
"sort"
2424
"strings"
2525
"time"
26+
27+
"github.com/github/gh-aw/pkg/fileutil"
2628
)
2729

2830
// TimelineEventSource identifies which system produced a timeline event.
@@ -285,23 +287,17 @@ func auditEntryToTimelineEvent(entry AuditLogEntry) (UnifiedTimelineEvent, bool)
285287
// Returns an empty string when no file is found.
286288
func findGatewayJSONLPath(logDir string) string {
287289
// Root-level gateway.jsonl (pre-mcp-logs-subdirectory artifact layout)
288-
if p := filepath.Join(logDir, "gateway.jsonl"); fileExists(p) {
290+
if p := filepath.Join(logDir, "gateway.jsonl"); fileutil.FileExists(p) {
289291
return p
290292
}
291293
// mcp-logs/ subdirectory (standard layout after artifact download)
292-
if p := filepath.Join(logDir, "mcp-logs", "gateway.jsonl"); fileExists(p) {
294+
if p := filepath.Join(logDir, "mcp-logs", "gateway.jsonl"); fileutil.FileExists(p) {
293295
return p
294296
}
295297
// Fallback: rpc-messages.jsonl
296298
return findRPCMessagesPath(logDir)
297299
}
298300

299-
// fileExists is a small helper that reports whether path exists and is a regular file.
300-
func fileExists(path string) bool {
301-
info, err := os.Stat(path)
302-
return err == nil && !info.IsDir()
303-
}
304-
305301
// collectGatewayTimelineEvents reads the gateway JSONL file in logDir and returns a slice
306302
// of timeline events, one per parseable, recognised log entry. The file may be
307303
// gateway.jsonl or rpc-messages.jsonl (the latter is used as a fallback).

pkg/cli/mcp_helpers.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"path/filepath"
1111

1212
"github.com/github/gh-aw/pkg/logger"
13+
"github.com/github/gh-aw/pkg/typeutil"
1314
)
1415

1516
var mcpHelpersLog = logger.New("cli:mcp_helpers")
@@ -40,7 +41,7 @@ func GetBinaryPath() (string, error) {
4041
}
4142

4243
// boolPtr returns a pointer to the given bool value, used for optional *bool fields.
43-
func boolPtr(b bool) *bool { return new(b) }
44+
func boolPtr(b bool) *bool { return typeutil.Ptr(b) }
4445

4546
// logAndValidateBinaryPath determines the binary path, logs it, and validates it exists.
4647
// Returns the detected binary path and an error if the path cannot be determined or if the file doesn't exist.

pkg/typeutil/convert_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,18 @@ import (
88
"testing"
99
)
1010

11+
func TestPtr(t *testing.T) {
12+
b := Ptr(true)
13+
if b == nil || !*b {
14+
t.Fatalf("Ptr(true) = %v, want pointer to true", b)
15+
}
16+
17+
s := Ptr("hello")
18+
if s == nil || *s != "hello" {
19+
t.Fatalf("Ptr(\"hello\") = %v, want pointer to hello", s)
20+
}
21+
}
22+
1123
func TestParseIntValue(t *testing.T) {
1224
tests := []struct {
1325
name string

pkg/typeutil/ptr.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package typeutil
2+
3+
// Ptr returns a pointer to the provided value.
4+
func Ptr[T any](v T) *T { return &v }

pkg/workflow/compiler_safe_outputs_config_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"strings"
99
"testing"
1010

11+
"github.com/github/gh-aw/pkg/typeutil"
1112
"github.com/stretchr/testify/assert"
1213
"github.com/stretchr/testify/require"
1314
)
@@ -1666,10 +1667,10 @@ func TestHandlerConfigPushToPullRequestBranchPatchSizeOverridesGlobal(t *testing
16661667
}
16671668

16681669
// testBoolPtr is a helper function for bool pointers in config tests
1669-
func testBoolPtr(b bool) *bool { return new(b) }
1670+
func testBoolPtr(b bool) *bool { return typeutil.Ptr(b) }
16701671

16711672
// testStringPtr is a helper function for string pointers in config tests
1672-
func testStringPtr(s string) *string { return new(s) }
1673+
func testStringPtr(s string) *string { return typeutil.Ptr(s) }
16731674

16741675
// TestAutoEnabledHandlers tests that missing_tool and missing_data
16751676
// are automatically enabled even when not explicitly configured.

pkg/workflow/role_checks.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -633,29 +633,31 @@ func (c *Compiler) extractAllowBotAuthoredTriggerComment(frontmatter map[string]
633633
return false
634634
}
635635

636-
// mergeStringSlicesDedup merges two string slices with deduplication (preserving order of first occurrence).
637-
// Logs the merged result under the given logLabel when the result is non-empty.
638-
func mergeStringSlicesDedup(top, imported []string, logLabel string) []string {
639-
result := sliceutil.Deduplicate(append(top, imported...))
636+
// mergeSkipRoles merges top-level skip-roles with imported skip-roles (union)
637+
func (c *Compiler) mergeSkipRoles(topSkipRoles []string, importedSkipRoles []string) []string {
638+
result := sliceutil.MergeUnique(topSkipRoles, importedSkipRoles...)
640639
if len(result) > 0 {
641-
roleLog.Printf("Merged %s: %v (top=%d, imported=%d, total=%d)", logLabel, result, len(top), len(imported), len(result))
640+
roleLog.Printf("Merged %s: %v (top=%d, imported=%d, total=%d)", "skip-roles", result, len(topSkipRoles), len(importedSkipRoles), len(result))
642641
}
643642
return result
644643
}
645644

646-
// mergeSkipRoles merges top-level skip-roles with imported skip-roles (union)
647-
func (c *Compiler) mergeSkipRoles(topSkipRoles []string, importedSkipRoles []string) []string {
648-
return mergeStringSlicesDedup(topSkipRoles, importedSkipRoles, "skip-roles")
649-
}
650-
651645
// mergeSkipBots merges top-level skip-bots with imported skip-bots (union)
652646
func (c *Compiler) mergeSkipBots(topSkipBots []string, importedSkipBots []string) []string {
653-
return mergeStringSlicesDedup(topSkipBots, importedSkipBots, "skip-bots")
647+
result := sliceutil.MergeUnique(topSkipBots, importedSkipBots...)
648+
if len(result) > 0 {
649+
roleLog.Printf("Merged %s: %v (top=%d, imported=%d, total=%d)", "skip-bots", result, len(topSkipBots), len(importedSkipBots), len(result))
650+
}
651+
return result
654652
}
655653

656654
// mergeBots merges top-level bots with imported bots (union)
657655
func (c *Compiler) mergeBots(topBots []string, importedBots []string) []string {
658-
return mergeStringSlicesDedup(topBots, importedBots, "bots")
656+
result := sliceutil.MergeUnique(topBots, importedBots...)
657+
if len(result) > 0 {
658+
roleLog.Printf("Merged %s: %v (top=%d, imported=%d, total=%d)", "bots", result, len(topBots), len(importedBots), len(result))
659+
}
660+
return result
659661
}
660662

661663
// extractActivationGitHubToken extracts the 'github-token' field from the 'on:' section of frontmatter.

pkg/workflow/test_helpers_shared_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
package workflow
22

3+
import "github.com/github/gh-aw/pkg/typeutil"
4+
35
// boolPtr returns a pointer to a bool value.
46
// This is a shared helper used by both unit and integration tests.
57
func boolPtr(b bool) *bool {
6-
return new(b)
8+
return typeutil.Ptr(b)
79
}
810

911
// ptrBool returns a pointer to a bool value.
1012
func ptrBool(b bool) *bool {
11-
return new(b)
13+
return typeutil.Ptr(b)
1214
}
1315

1416
// strPtr returns a pointer to a string value.
1517
// This is a shared helper used by tests to create *string values for templatable fields.
1618
func strPtr(s string) *string {
17-
return new(s)
19+
return typeutil.Ptr(s)
1820
}
1921

2022
// mockValidationError helps create validation errors for testing.

0 commit comments

Comments
 (0)