summaryrefslogtreecommitdiff
path: root/cmd/hexai-tmux-action
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-16 03:10:55 +0200
committerPaul Buetow <paul@buetow.org>2026-03-16 03:10:55 +0200
commit1fc1611fa99993cab5dc8bf0844183285296e3b2 (patch)
treec5c9b8b5abac5b5d4c0d56ed90b0580184cc4383 /cmd/hexai-tmux-action
parent12090f25a3677291863dbb80277bdad3eaec0324 (diff)
Release v0.24.0v0.24.0
Bring unit test coverage from ~75% to 85.1% project-wide. All internal packages now exceed 80% coverage. Refactored cmd entrypoints to extract testable run() functions with injectable seams. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'cmd/hexai-tmux-action')
-rw-r--r--cmd/hexai-tmux-action/main.go43
-rw-r--r--cmd/hexai-tmux-action/main_test.go63
2 files changed, 98 insertions, 8 deletions
diff --git a/cmd/hexai-tmux-action/main.go b/cmd/hexai-tmux-action/main.go
index 6249de3..715c41f 100644
--- a/cmd/hexai-tmux-action/main.go
+++ b/cmd/hexai-tmux-action/main.go
@@ -4,6 +4,7 @@ import (
"context"
"flag"
"fmt"
+ "io"
"os"
"strings"
@@ -11,6 +12,10 @@ import (
"codeberg.org/snonux/hexai/internal/hexaiaction"
)
+// runCommand is the seam for testing: override in tests to avoid launching
+// the real tmux action.
+var runCommand = hexaiaction.RunCommand
+
func main() {
infile := flag.String("infile", "", "Read input from this file instead of stdin")
outfile := flag.String("outfile", "", "Write output to this file instead of stdout")
@@ -22,16 +27,38 @@ func main() {
tmuxPercent := flag.Int("tmux-percent", 33, "tmux split size percentage (1-100)")
flag.Parse()
- opts := hexaiaction.Options{
- Infile: *infile, Outfile: *outfile,
- UIChild: *uiChild, TmuxTarget: *tmuxTarget, TmuxSplit: *tmuxSplit, TmuxPercent: *tmuxPercent,
- }
- ctx := context.Background()
- if path := strings.TrimSpace(*configPath); path != "" {
- ctx = hexaiaction.WithConfigPath(ctx, path)
+ opts := actionOptions{
+ infile: *infile, outfile: *outfile,
+ uiChild: *uiChild, configPath: *configPath,
+ tmuxTarget: *tmuxTarget, tmuxSplit: *tmuxSplit, tmuxPercent: *tmuxPercent,
}
- if err := hexaiaction.RunCommand(ctx, opts, os.Stdin, os.Stdout, os.Stderr); err != nil {
+ if err := run(opts, os.Stdin, os.Stdout, os.Stderr); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+
+// actionOptions holds the parsed command-line flags for hexai-tmux-action.
+type actionOptions struct {
+ infile string
+ outfile string
+ uiChild bool
+ configPath string
+ tmuxTarget string
+ tmuxSplit string
+ tmuxPercent int
+}
+
+// run builds the hexaiaction.Options and context, then delegates to runCommand.
+func run(opts actionOptions, stdin io.Reader, stdout, stderr io.Writer) error {
+ haOpts := hexaiaction.Options{
+ Infile: opts.infile, Outfile: opts.outfile,
+ UIChild: opts.uiChild, TmuxTarget: opts.tmuxTarget,
+ TmuxSplit: opts.tmuxSplit, TmuxPercent: opts.tmuxPercent,
+ }
+ ctx := context.Background()
+ if path := strings.TrimSpace(opts.configPath); path != "" {
+ ctx = hexaiaction.WithConfigPath(ctx, path)
+ }
+ return runCommand(ctx, haOpts, stdin, stdout, stderr)
+}
diff --git a/cmd/hexai-tmux-action/main_test.go b/cmd/hexai-tmux-action/main_test.go
new file mode 100644
index 0000000..8abd420
--- /dev/null
+++ b/cmd/hexai-tmux-action/main_test.go
@@ -0,0 +1,63 @@
+package main
+
+import (
+ "context"
+ "errors"
+ "io"
+ "testing"
+
+ "codeberg.org/snonux/hexai/internal/hexaiaction"
+)
+
+func TestRun_DelegatesToRunCommand(t *testing.T) {
+ old := runCommand
+ t.Cleanup(func() { runCommand = old })
+
+ var gotOpts hexaiaction.Options
+ runCommand = func(_ context.Context, opts hexaiaction.Options, _ io.Reader, _, _ io.Writer) error {
+ gotOpts = opts
+ return nil
+ }
+
+ opts := actionOptions{
+ infile: "in.txt", outfile: "out.txt",
+ tmuxSplit: "h", tmuxPercent: 50,
+ }
+ if err := run(opts, nil, nil, nil); err != nil {
+ t.Fatalf("run: %v", err)
+ }
+ if gotOpts.Infile != "in.txt" || gotOpts.Outfile != "out.txt" {
+ t.Fatalf("unexpected opts: %+v", gotOpts)
+ }
+ if gotOpts.TmuxSplit != "h" || gotOpts.TmuxPercent != 50 {
+ t.Fatalf("unexpected tmux opts: %+v", gotOpts)
+ }
+}
+
+func TestRun_WithConfigPath(t *testing.T) {
+ old := runCommand
+ t.Cleanup(func() { runCommand = old })
+
+ runCommand = func(_ context.Context, _ hexaiaction.Options, _ io.Reader, _, _ io.Writer) error {
+ return nil
+ }
+
+ opts := actionOptions{configPath: " /tmp/test.toml ", tmuxSplit: "v", tmuxPercent: 33}
+ if err := run(opts, nil, nil, nil); err != nil {
+ t.Fatalf("run: %v", err)
+ }
+}
+
+func TestRun_Error(t *testing.T) {
+ old := runCommand
+ t.Cleanup(func() { runCommand = old })
+
+ wantErr := errors.New("action failed")
+ runCommand = func(_ context.Context, _ hexaiaction.Options, _ io.Reader, _, _ io.Writer) error {
+ return wantErr
+ }
+
+ if err := run(actionOptions{}, nil, nil, nil); !errors.Is(err, wantErr) {
+ t.Fatalf("expected error, got: %v", err)
+ }
+}