diff options
| author | Paul Buetow <paul@buetow.org> | 2025-10-02 08:38:03 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-10-02 08:38:03 +0300 |
| commit | 0c1b108ff5fccf39ae5bc6dc06802ce565bda633 (patch) | |
| tree | 914e65e04bae26d3eae565f9d6a64d08ade361d0 /cmd | |
| parent | 36be499ed342d92969ccaaff083c557a0951def9 (diff) | |
new version major refactorv0.2.0
Diffstat (limited to 'cmd')
| -rw-r--r-- | cmd/yoga/main.go | 50 | ||||
| -rw-r--r-- | cmd/yoga/main_test.go | 85 |
2 files changed, 135 insertions, 0 deletions
diff --git a/cmd/yoga/main.go b/cmd/yoga/main.go new file mode 100644 index 0000000..fbf11bd --- /dev/null +++ b/cmd/yoga/main.go @@ -0,0 +1,50 @@ +package main + +import ( + "flag" + "fmt" + "io" + "os" + "strings" + + "yoga/internal/app" + "yoga/internal/fsutil" + "yoga/internal/meta" +) + +const defaultRoot = "~/Yoga" + +var ( + runApp = app.Run + exit = os.Exit +) + +func main() { + exit(run(os.Args[1:], os.Stdout, os.Stderr)) +} + +func run(args []string, stdout, stderr io.Writer) int { + fs := flag.NewFlagSet("yoga", flag.ContinueOnError) + fs.SetOutput(stderr) + rootFlag := fs.String("root", "", "Directory containing yoga videos (default ~/Yoga)") + cropFlag := fs.String("crop", "", "Optional crop aspect for VLC (e.g. 5:4)") + versionFlag := fs.Bool("version", false, "Print version and exit") + if err := fs.Parse(args); err != nil { + return 2 + } + if *versionFlag { + fmt.Fprintf(stdout, "Yoga version %s\n", meta.Version) + return 0 + } + root, err := fsutil.ResolveRootPath(*rootFlag, defaultRoot) + if err != nil { + fmt.Fprintf(stderr, "%v\n", err) + return 1 + } + opts := app.Options{Root: root, Crop: strings.TrimSpace(*cropFlag)} + if err := runApp(opts); err != nil { + fmt.Fprintf(stderr, "error: %v\n", err) + return 1 + } + return 0 +} diff --git a/cmd/yoga/main_test.go b/cmd/yoga/main_test.go new file mode 100644 index 0000000..d06ff33 --- /dev/null +++ b/cmd/yoga/main_test.go @@ -0,0 +1,85 @@ +package main + +import ( + "bytes" + "errors" + "os" + "path/filepath" + "testing" + + "yoga/internal/app" +) + +func TestRunPrintsVersion(t *testing.T) { + var stdout, stderr bytes.Buffer + code := run([]string{"--version"}, &stdout, &stderr) + if code != 0 { + t.Fatalf("expected exit code 0, got %d", code) + } + if !bytes.Contains(stdout.Bytes(), []byte("Yoga version")) { + t.Fatalf("expected version output, got %s", stdout.String()) + } +} + +func TestRunSuccess(t *testing.T) { + var stdout, stderr bytes.Buffer + root := t.TempDir() + orig := runApp + runApp = func(opts app.Options) error { return nil } + defer func() { runApp = orig }() + code := run([]string{"--root", root}, &stdout, &stderr) + if code != 0 { + t.Fatalf("expected exit code 0, got %d", code) + } +} + +func TestRunAppError(t *testing.T) { + var stdout, stderr bytes.Buffer + root := t.TempDir() + orig := runApp + runApp = func(app.Options) error { return errors.New("boom") } + defer func() { runApp = orig }() + code := run([]string{"--root", root}, &stdout, &stderr) + if code != 1 { + t.Fatalf("expected exit code 1, got %d", code) + } + if !bytes.Contains(stderr.Bytes(), []byte("error:")) { + t.Fatalf("expected error output, got %s", stderr.String()) + } +} + +func TestRunDefaultRootCreated(t *testing.T) { + var stdout, stderr bytes.Buffer + home := t.TempDir() + t.Setenv("HOME", home) + orig := runApp + runApp = func(opts app.Options) error { + if _, err := os.Stat(filepath.Join(home, "Yoga")); err != nil { + t.Fatalf("expected default directory: %v", err) + } + return nil + } + defer func() { runApp = orig }() + code := run(nil, &stdout, &stderr) + if code != 0 { + t.Fatalf("expected exit code 0, got %d", code) + } +} + +func TestMainUsesExit(t *testing.T) { + root := t.TempDir() + origRun := runApp + origExit := exit + runApp = func(opts app.Options) error { return nil } + var code int + exit = func(c int) { code = c } + defer func() { + runApp = origRun + exit = origExit + }() + os.Args = []string{"yoga", "--root", root} + main() + if code != 0 { + t.Fatalf("expected exit code 0, got %d", code) + } +} |
