Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion pkg/cli/deps_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,22 @@ import (
"os"
"path/filepath"
"strings"

"github.com/github/gh-aw/pkg/logger"
)

var depsHelpersLog = logger.New("cli:deps_helpers")

// findGoMod locates the go.mod file in the repository.
// It first checks the current directory, then falls back to the git root.
func findGoMod() (string, error) {
// Try current directory first
if _, err := os.Stat("go.mod"); err == nil {
return filepath.Abs("go.mod")
absPath, err := filepath.Abs("go.mod")
if err == nil {
depsHelpersLog.Printf("Found go.mod in current directory: %s", absPath)
}
return absPath, err
}

// Try git root
Expand All @@ -26,12 +34,14 @@ func findGoMod() (string, error) {
return "", errors.New("not in a Go module (no go.mod found)")
}

depsHelpersLog.Printf("Found go.mod at git root: %s", goModPath)
return goModPath, nil
}

// parseGoModFile parses a go.mod file and returns all dependencies (direct and indirect).
// Callers can filter on the Indirect field as needed.
func parseGoModFile(path string) ([]DependencyInfoWithIndirect, error) {
depsHelpersLog.Printf("Parsing go.mod file: %s", path)
content, err := os.ReadFile(path)
if err != nil {
return nil, err
Expand Down Expand Up @@ -75,5 +85,6 @@ func parseGoModFile(path string) ([]DependencyInfoWithIndirect, error) {
}
}

depsHelpersLog.Printf("Parsed %d dependencies from go.mod", len(deps))
return deps, nil
}
5 changes: 5 additions & 0 deletions pkg/parser/virtual_fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ import (
"os"
"strings"
"sync"

"github.com/github/gh-aw/pkg/logger"
)

var virtualFsLog = logger.New("parser:virtual_fs")

// builtinVirtualFiles holds embedded built-in files registered at startup.
// Keys use the "@builtin:" path prefix (e.g. "@builtin:engines/copilot.md").
// The map is populated once and then read-only; concurrent reads are safe.
Expand Down Expand Up @@ -35,6 +39,7 @@ func RegisterBuiltinVirtualFile(path string, content []byte) {
}
return // idempotent: same content, no-op
}
virtualFsLog.Printf("Registering builtin virtual file: %s (%d bytes)", path, len(content))
builtinVirtualFiles[path] = content
}

Expand Down
9 changes: 9 additions & 0 deletions pkg/workflow/engine_definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@ import (
"strings"

"github.com/github/gh-aw/pkg/constants"
"github.com/github/gh-aw/pkg/logger"
"github.com/github/gh-aw/pkg/parser"
)

var engineCatalogLog = logger.New("workflow:engine_definition")

// AuthStrategy identifies how an engine authenticates with its provider.
type AuthStrategy string

Expand Down Expand Up @@ -190,6 +193,7 @@ func NewEngineCatalog(registry *EngineRegistry) *EngineCatalog {
catalog.Register(def)
}

engineCatalogLog.Printf("Engine catalog initialized with %d built-in definitions", len(catalog.definitions))
return catalog
}

Expand Down Expand Up @@ -229,8 +233,11 @@ func (c *EngineCatalog) All() []*EngineDefinition {
// 2. Prefix match in the underlying EngineRegistry (backward compat, e.g. "codex-experimental")
// 3. Returns a formatted validation error when no match is found
func (c *EngineCatalog) Resolve(id string, config *EngineConfig) (*ResolvedEngineTarget, error) {
engineCatalogLog.Printf("Resolving engine: %s", id)

// Exact catalog lookup
if def, ok := c.definitions[id]; ok {
engineCatalogLog.Printf("Exact catalog match found for engine: %s (runtimeID=%s)", id, def.RuntimeID)
runtime, err := c.registry.GetEngine(def.RuntimeID)
if err != nil {
return nil, fmt.Errorf("engine %q definition references unknown runtime %q: %w", id, def.RuntimeID, err)
Expand All @@ -241,6 +248,7 @@ func (c *EngineCatalog) Resolve(id string, config *EngineConfig) (*ResolvedEngin
// Fall back to runtime-ID prefix lookup for backward compat (e.g. "codex-experimental")
runtime, err := c.registry.GetEngineByPrefix(id)
if err == nil {
engineCatalogLog.Printf("Engine %q resolved via runtime-ID prefix fallback to %q", id, runtime.GetID())
def := &EngineDefinition{
ID: id,
DisplayName: runtime.GetDisplayName(),
Expand All @@ -251,6 +259,7 @@ func (c *EngineCatalog) Resolve(id string, config *EngineConfig) (*ResolvedEngin
}

// Engine not found — produce a helpful validation error matching the existing format
engineCatalogLog.Printf("Engine not found: %s", id)
validEngines := c.registry.GetSupportedEngines()
suggestions := parser.FindClosestMatches(id, validEngines, 1)
enginesStr := strings.Join(validEngines, ", ")
Expand Down
6 changes: 6 additions & 0 deletions pkg/workflow/repo_memory_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,16 @@ import (
"strings"
)

var repoMemValidationLog = newValidationLogger("repo_memory")

// validateBranchPrefix validates that the branch prefix meets requirements
func validateBranchPrefix(prefix string) error {
if prefix == "" {
return nil // Empty means use default
}

repoMemValidationLog.Printf("Validating branch prefix: %q", prefix)

// Check length (4-32 characters)
if len(prefix) < 4 {
return fmt.Errorf("branch-prefix must be at least 4 characters long, got %d", len(prefix))
Expand All @@ -49,12 +53,14 @@ func validateBranchPrefix(prefix string) error {
return errors.New("branch-prefix cannot be 'copilot' (reserved)")
}

repoMemValidationLog.Printf("Branch prefix %q passed validation", prefix)
return nil
}

// validateNoDuplicateMemoryIDs checks for duplicate memory IDs and returns an error if found.
// Uses the generic validateNoDuplicateIDs helper for consistent duplicate detection.
func validateNoDuplicateMemoryIDs(memories []RepoMemoryEntry) error {
repoMemValidationLog.Printf("Validating %d memory entries for duplicate IDs", len(memories))
return validateNoDuplicateIDs(memories, func(m RepoMemoryEntry) string { return m.ID }, func(id string) error {
return fmt.Errorf("duplicate memory ID found: '%s'. Each memory must have a unique ID", id)
})
Expand Down
14 changes: 12 additions & 2 deletions pkg/workflow/safe_outputs_runtime.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package workflow

import "github.com/github/gh-aw/pkg/constants"
import (
"github.com/github/gh-aw/pkg/constants"
"github.com/github/gh-aw/pkg/logger"
)

var safeOutputsRuntimeLog = logger.New("workflow:safe_outputs_runtime")

// ========================================
// Safe Output Runtime Configuration
Expand All @@ -14,9 +19,11 @@ import "github.com/github/gh-aw/pkg/constants"
// Falls back to the default activation job runner image when not explicitly set.
func (c *Compiler) formatSafeOutputsRunsOn(safeOutputs *SafeOutputsConfig) string {
if safeOutputs == nil || safeOutputs.RunsOn == "" {
safeOutputsRuntimeLog.Printf("Safe outputs runs-on not set, using default: %s", constants.DefaultActivationJobRunnerImage)
return "runs-on: " + constants.DefaultActivationJobRunnerImage
}

safeOutputsRuntimeLog.Printf("Safe outputs runs-on: %s", safeOutputs.RunsOn)
return "runs-on: " + safeOutputs.RunsOn
}

Expand All @@ -26,5 +33,8 @@ func usesPatchesAndCheckouts(safeOutputs *SafeOutputsConfig) bool {
if safeOutputs == nil {
return false
}
return safeOutputs.CreatePullRequests != nil || safeOutputs.PushToPullRequestBranch != nil
result := safeOutputs.CreatePullRequests != nil || safeOutputs.PushToPullRequestBranch != nil
safeOutputsRuntimeLog.Printf("usesPatchesAndCheckouts: createPR=%v, pushToPRBranch=%v, result=%v",
safeOutputs.CreatePullRequests != nil, safeOutputs.PushToPullRequestBranch != nil, result)
return result
}