go-pkg/lsm2/cli/main.go
2024-11-02 09:00:17 -06:00

86 lines
1.5 KiB
Go

package main
import (
"errors"
"fmt"
"io"
"iter"
"os"
"path/filepath"
"github.com/docopt/docopt-go"
"go.sour.is/pkg/lsm2"
)
var usage = `
Usage: lsm2 create <archive> <files>...`
type args struct {
Create bool
Archive string `docopt:"<archive>"`
Files []string `docopt:"<files>"`
}
func main() {
opts, err := docopt.ParseDoc(usage)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println(opts, must(opts.Bool("create")))
console := console{os.Stdin, os.Stdout, os.Stderr}
args := args{}
err = opts.Bind(&args)
fmt.Println(err)
run(console, args)
}
type console struct {
Stdin io.Reader
Stdout io.Writer
Stderr io.Writer
}
func (c console) Write(b []byte) (int, error) {
return c.Stdout.Write(b)
}
func run(console console, args args) error {
switch {
case args.Create:
fmt.Fprintf(console, "creating %s from %v\n", filepath.Base(args.Archive), args.Files)
out, err := os.OpenFile(args.Archive, os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return err
}
defer out.Close()
filesWritten := 0
defer func() { fmt.Fprintln(console, "wrote", filesWritten, "files") }()
return lsm2.WriteIter(out, iter.Seq[io.Reader](func(yield func(io.Reader) bool) {
for _, name := range args.Files {
f, err := os.Open(name)
if err != nil {
continue
}
filesWritten++
if !yield(f) {
f.Close()
return
}
f.Close()
}
}))
default:
return errors.New("unknown command")
}
}
func must[T any](v T, err error) T {
if err != nil {
panic(err)
}
return v
}