diff options
| author | Paul Buetow <paul@buetow.org> | 2025-09-06 15:04:37 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-09-06 15:04:37 +0300 |
| commit | 7c0266e94378f6121719939c6d53915eb72eed3e (patch) | |
| tree | 64017871e9516fbe3cf2dfbd63729e790ed1e0ef /cmd | |
| parent | e2418d22e0ff8d5d8bb883cf38b47dc94a6c308e (diff) | |
feat(hexai-action): add --infile/--outfile flags; docs and tests\n\n- Add flags to read from file and write to file\n- Refactor IO open into helper for testability\n- Add CLI integration-style test for IO\n- Update README and docs/usage.md with examples\n- Update docs/testing.md with instructions
Diffstat (limited to 'cmd')
| -rw-r--r-- | cmd/internal/hexai-action/main.go | 42 | ||||
| -rw-r--r-- | cmd/internal/hexai-action/main_test.go | 44 |
2 files changed, 85 insertions, 1 deletions
diff --git a/cmd/internal/hexai-action/main.go b/cmd/internal/hexai-action/main.go index 50e6774..8bcc3cd 100644 --- a/cmd/internal/hexai-action/main.go +++ b/cmd/internal/hexai-action/main.go @@ -2,15 +2,55 @@ package main import ( "context" + "flag" "fmt" + "io" "os" "codeberg.org/snonux/hexai/internal/hexaiaction" ) func main() { - if err := hexaiaction.Run(context.Background(), os.Stdin, os.Stdout, os.Stderr); err != nil { + infile := flag.String("infile", "", "Read input from this file instead of stdin") + outfile := flag.String("outfile", "", "Write output to this file instead of stdout") + flag.Parse() + + in, out, closeIn, closeOut, err := openIO(*infile, *outfile) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + defer closeIn() + defer closeOut() + + if err := hexaiaction.Run(context.Background(), in, out, os.Stderr); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } } + +// openIO returns readers/writers for infile/outfile flags with deferred closers. +func openIO(infile, outfile string) (io.Reader, io.Writer, func(), func(), error) { + in := io.Reader(os.Stdin) + out := io.Writer(os.Stdout) + closeIn := func() {} + closeOut := func() {} + + if path := infile; path != "" { + f, err := os.Open(path) + if err != nil { + return nil, nil, func() {}, func() {}, fmt.Errorf("hexai-action: cannot open infile: %w", err) + } + in = f + closeIn = func() { _ = f.Close() } + } + if path := outfile; path != "" { + f, err := os.Create(path) + if err != nil { + return nil, nil, func() {}, func() {}, fmt.Errorf("hexai-action: cannot open outfile: %w", err) + } + out = f + closeOut = func() { _ = f.Close() } + } + return in, out, closeIn, closeOut, nil +} diff --git a/cmd/internal/hexai-action/main_test.go b/cmd/internal/hexai-action/main_test.go new file mode 100644 index 0000000..9603826 --- /dev/null +++ b/cmd/internal/hexai-action/main_test.go @@ -0,0 +1,44 @@ +package main + +import ( + "io" + "os" + "path/filepath" + "testing" +) + +// TestOpenIO_InOutFiles verifies that openIO opens the specified files +// and that writing via the returned writer persists to disk. +func TestOpenIO_InOutFiles(t *testing.T) { + dir := t.TempDir() + inPath := filepath.Join(dir, "in.txt") + outPath := filepath.Join(dir, "out.txt") + + // Prepare input file + want := "hello world" + if err := os.WriteFile(inPath, []byte(want), 0o600); err != nil { + t.Fatalf("write infile: %v", err) + } + + in, out, cin, cout, err := openIO(inPath, outPath) + if err != nil { + t.Fatalf("openIO: %v", err) + } + defer cin() + defer cout() + + // Copy through to simulate main's behavior + if _, err := io.Copy(out.(io.Writer), in); err != nil { + t.Fatalf("copy: %v", err) + } + + // Verify outfile content + got, err := os.ReadFile(outPath) + if err != nil { + t.Fatalf("read outfile: %v", err) + } + if string(got) != want { + t.Fatalf("mismatch: got %q want %q", string(got), want) + } +} + |
