Files
Duc-Tam Nguyen e126968c65 Check the deferred Close calls so the linter is happy
errcheck flagged six naked defer Close() calls in the pack code and its
tests. Wrap them in the same defer func() { _ = x.Close() }() form the rest
of the tree already uses.
2026-06-15 00:02:48 +07:00

67 lines
1.9 KiB
Go

package cli
import (
"context"
"fmt"
"net"
"net/http"
"os"
"github.com/spf13/cobra"
"github.com/tamnd/kage/pack"
"github.com/tamnd/kage/viewer"
"github.com/tamnd/kage/zim"
)
func newOpenCmd() *cobra.Command {
var addr string
var openBrowser bool
cmd := &cobra.Command{
Use: "open <file.zim>",
Short: "Serve a ZIM archive in your browser for offline reading",
Long: "open serves a packed ZIM file over a local HTTP server so you can browse the\n" +
"site exactly as it was cloned. It is the read side of kage pack --format zim.",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return runOpen(cmd.Context(), args[0], addr, openBrowser)
},
}
cmd.Flags().StringVarP(&addr, "addr", "a", "127.0.0.1:8800", "address to listen on")
cmd.Flags().BoolVar(&openBrowser, "open", true, "open the default browser")
return cmd
}
func runOpen(ctx context.Context, path, addr string, openBrowser bool) error {
r, err := zim.Open(path)
if err != nil {
return fmt.Errorf("cannot open %q: %w", path, err)
}
defer func() { _ = r.Close() }()
ln, err := net.Listen("tcp", addr)
if err != nil {
return fmt.Errorf("cannot listen on %s: %w", addr, err)
}
url := "http://" + ln.Addr().String()
fmt.Fprintln(os.Stderr, styleTitle.Render("kage open")+" "+styleDim.Render(path))
fmt.Fprintln(os.Stderr, " open "+styleAccent.Render(url))
if viewer.Native {
fmt.Fprintln(os.Stderr, styleDim.Render(" close the window to stop"))
} else {
fmt.Fprintln(os.Stderr, styleDim.Render(" press Ctrl-C to stop"))
}
srv := &http.Server{Handler: pack.Handler(r)}
srvErr := make(chan error, 1)
go func() { srvErr <- srv.Serve(ln) }()
_ = viewer.Show(ctx, viewer.Options{Title: archiveTitle(r), URL: url, Browser: openBrowser})
_ = srv.Close()
if err := <-srvErr; err != nil && err != http.ErrServerClosed {
return err
}
return nil
}