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
2 changes: 1 addition & 1 deletion pkg/cli/add_interactive_engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func (c *AddInteractiveConfig) selectAIEngineAndKey() error {

// If engine is already overridden, skip selection
if c.EngineOverride != "" {
fmt.Fprintf(os.Stderr, "Using coding agent: %s\n", c.EngineOverride)
fmt.Fprintln(os.Stderr, console.FormatInfoMessage(fmt.Sprintf("Using coding agent: %s", c.EngineOverride)))
return c.configureEngineAPISecret(c.EngineOverride)
}

Expand Down
35 changes: 35 additions & 0 deletions pkg/cli/add_interactive_secrets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
package cli

import (
"bytes"
"context"
"io"
"os"
"testing"

"github.com/github/gh-aw/pkg/console"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -169,6 +173,37 @@ func TestAddInteractiveConfig_configureEngineAPISecret_skipSecret(t *testing.T)
}
}

func TestAddInteractiveConfig_selectAIEngineAndKey_engineOverrideFormatsInfoMessage(t *testing.T) {
config := &AddInteractiveConfig{
Ctx: context.Background(),
EngineOverride: "copilot",
SkipSecret: true,
RepoOverride: "owner/repo",
}

oldStderr := os.Stderr
r, w, err := os.Pipe()
require.NoError(t, err, "Failed to create stderr pipe")
os.Stderr = w
t.Cleanup(func() { os.Stderr = oldStderr })

err = config.selectAIEngineAndKey()

w.Close()

var buf bytes.Buffer
_, copyErr := io.Copy(&buf, r)
require.NoError(t, copyErr, "Failed to read stderr output")
Comment on lines +184 to +196
require.NoError(t, err, "selectAIEngineAndKey should succeed with an explicit engine override")

assert.Contains(
t,
buf.String(),
console.FormatInfoMessage("Using coding agent: copilot"),
"Expected engine override path to use formatted info output",
)
}

func TestParseSecretNames(t *testing.T) {
tests := []struct {
name string
Expand Down
72 changes: 72 additions & 0 deletions pkg/cli/commands_file_watching_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
package cli

import (
"bytes"
"context"
"fmt"
"io"
"os"
"path/filepath"
"strings"
"testing"
"time"

"github.com/github/gh-aw/pkg/console"
"github.com/github/gh-aw/pkg/stringutil"

"github.com/github/gh-aw/pkg/testutil"
Expand Down Expand Up @@ -439,6 +442,40 @@ func TestCompileSingleFile(t *testing.T) {
}
})

t.Run("compile single file formats errors for stderr", func(t *testing.T) {
tempDir := testutil.TempDir(t, "test-*")
workflowsDir := filepath.Join(tempDir, ".github/workflows")
os.MkdirAll(workflowsDir, 0755)

filePath := filepath.Join(workflowsDir, "invalid.md")
content := "---\nmalformed: yaml: content:\n - missing\n proper: structure\n---\n# Invalid\n"
os.WriteFile(filePath, []byte(content), 0644)

compiler := workflow.NewCompiler()
stats := &CompilationStats{}

oldStderr := os.Stderr
r, w, err := os.Pipe()
require.NoError(t, err, "Failed to create stderr pipe")
os.Stderr = w
t.Cleanup(func() { os.Stderr = oldStderr })

result := compileSingleFile(compiler, filePath, stats, false, false)

w.Close()

var buf bytes.Buffer
_, err = io.Copy(&buf, r)
require.NoError(t, err, "Failed to read stderr output")
Comment on lines +457 to +469

strippedOutput := stringutil.StripANSI(buf.String())

assert.True(t, result, "Expected compilation to be attempted")
assert.Contains(t, strippedOutput, "✗", "Expected compile errors to include the formatted error marker")
assert.Contains(t, strippedOutput, "invalid.md", "Expected stderr output to identify the failing workflow")
assert.Contains(t, strippedOutput, "unexpected ':'", "Expected stderr output to include the compiler error details")
})

t.Run("compile single file with checkExists true and file exists", func(t *testing.T) {
tempDir := testutil.TempDir(t, "test-*")
workflowsDir := filepath.Join(tempDir, ".github/workflows")
Expand Down Expand Up @@ -516,3 +553,38 @@ func TestCompileSingleFile(t *testing.T) {
}
})
}

func TestCompileModifiedFilesWithDependencies_FormatsWatchMessage(t *testing.T) {
tempDir := testutil.TempDir(t, "test-*")
workflowsDir := filepath.Join(tempDir, ".github/workflows")
require.NoError(t, os.MkdirAll(workflowsDir, 0755), "Failed to create workflows directory")

filePath := filepath.Join(workflowsDir, "test.md")
content := "---\non: push\nengine: claude\n---\n# Test\n\nTest workflow content"
require.NoError(t, os.WriteFile(filePath, []byte(content), 0644), "Failed to write workflow file")

compiler := workflow.NewCompiler()
depGraph := NewDependencyGraph(workflowsDir)
require.NoError(t, depGraph.BuildGraph(compiler), "Failed to build dependency graph")

oldStderr := os.Stderr
r, w, err := os.Pipe()
require.NoError(t, err, "Failed to create stderr pipe")
os.Stderr = w
t.Cleanup(func() { os.Stderr = oldStderr })

compileModifiedFilesWithDependencies(compiler, depGraph, []string{filePath}, false)

w.Close()

var buf bytes.Buffer
_, err = io.Copy(&buf, r)
require.NoError(t, err, "Failed to read stderr output")

assert.Contains(
t,
buf.String(),
console.FormatProgressMessage("Watching for file changes"),
"Expected watch mode to use formatted progress output",
)
}
7 changes: 3 additions & 4 deletions pkg/cli/compile_file_operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,8 @@ func compileSingleFile(compiler *workflow.Compiler, file string, stats *Compilat
}

if err := CompileWorkflowWithValidation(compiler, file, verbose, false, false, false, false, false); err != nil {
// Always show compilation errors on new line
// Note: Don't wrap in FormatErrorMessage as the error is already formatted by console.FormatError
fmt.Fprintln(os.Stderr, err.Error())
// Always show compilation errors on a new line using standard CLI error styling.
fmt.Fprintln(os.Stderr, console.FormatErrorMessage(err.Error()))
Comment on lines +72 to +73
stats.Errors++
stats.FailedWorkflows = append(stats.FailedWorkflows, filepath.Base(file))
} else {
Expand Down Expand Up @@ -171,7 +170,7 @@ func compileModifiedFilesWithDependencies(compiler *workflow.Compiler, depGraph
}
}

fmt.Fprintln(os.Stderr, "Watching for file changes")
fmt.Fprintln(os.Stderr, console.FormatProgressMessage("Watching for file changes"))
if verbose {
fmt.Fprintln(os.Stderr, console.FormatProgressMessage(fmt.Sprintf("Recompiling %d workflow(s) affected by %d change(s)...", len(workflowsToCompile), len(files))))
}
Expand Down
Loading