From: Matt Joiner <anacrolix@gmail.com>
Date: Mon, 20 Jun 2022 08:40:53 +0000 (+1000)
Subject: Track latest bargle
X-Git-Tag: v1.47.0~2^2~7
X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=5c2f1ed307281ef3103cfeebb024b77a68d7345f;p=btrtrc.git

Track latest bargle
---

diff --git a/cmd/torrent/main.go b/cmd/torrent/main.go
index 34219b51..f21bc87e 100644
--- a/cmd/torrent/main.go
+++ b/cmd/torrent/main.go
@@ -2,132 +2,111 @@
 package main
 
 import (
-	"encoding/json"
-	"errors"
-	"fmt"
-	"io"
 	stdLog "log"
 	"net/http"
-	"os"
 
-	"github.com/anacrolix/args"
+	"github.com/anacrolix/bargle"
 	"github.com/anacrolix/envpprof"
-	"github.com/anacrolix/log"
 	xprometheus "github.com/anacrolix/missinggo/v2/prometheus"
-	"github.com/anacrolix/torrent/bencode"
-	"github.com/anacrolix/torrent/version"
-	"github.com/davecgh/go-spew/spew"
 	"github.com/prometheus/client_golang/prometheus"
 	"github.com/prometheus/client_golang/prometheus/promhttp"
 )
 
-func main() {
-	if err := mainErr(); err != nil {
-		log.Printf("error in main: %v", err)
-		os.Exit(1)
-	}
-}
-
 func init() {
 	prometheus.MustRegister(xprometheus.NewExpvarCollector())
 	http.Handle("/metrics", promhttp.Handler())
 }
 
-func mainErr() error {
-	defer envpprof.Stop()
-	stdLog.SetFlags(stdLog.Flags() | stdLog.Lshortfile)
-	debug := args.Flag(args.FlagOpt{Long: "debug"})
-	return args.ParseMain(
-		debug,
-		args.Subcommand("metainfo", metainfoCmd),
-		args.Subcommand("announce", func(p args.SubCmdCtx) error {
-			var cmd AnnounceCmd
-			err := p.NewParser().AddParams(
-				args.Pos("tracker", &cmd.Tracker),
-				args.Pos("infohash", &cmd.InfoHash)).Parse()
-			if err != nil {
-				return err
-			}
-			return announceErr(cmd)
-		}),
-		args.Subcommand("scrape", func(p args.SubCmdCtx) error {
-			var cmd ScrapeCmd
-			err := p.NewParser().AddParams(
-				args.Pos("tracker", &cmd.Tracker),
-				args.Pos("infohash", &cmd.InfoHashes, args.Arity('+'))).Parse()
-			if err != nil {
-				return err
-			}
-			return scrape(cmd)
-		}),
-		args.Subcommand("download", func(p args.SubCmdCtx) error {
+func main() {
+	defer stdLog.SetFlags(stdLog.Flags() | stdLog.Lshortfile)
+	main := bargle.Main{}
+	main.Defer(envpprof.Stop)
+	debug := false
+	main.Options = append(main.Options, bargle.Flag{Longs: []string{"debug"}, Value: &debug})
+	main.Positionals = append(main.Positionals,
+		bargle.Subcommand{Name: "metainfo", Command: metainfoCmd()},
+		//bargle.Subcommand{Name: "announce", Command: func() bargle.Command {
+		//	var cmd AnnounceCmd
+		//	err := p.NewParser().AddParams(
+		//		args.Pos("tracker", &cmd.Tracker),
+		//		args.Pos("infohash", &cmd.InfoHash)).Parse()
+		//	if err != nil {
+		//		return err
+		//	}
+		//	return announceErr(cmd)
+		//}()},
+		//bargle.Subcommand{Name: "scrape", Command: func() bargle.Command {
+		//	var cmd ScrapeCmd
+		//	err := p.NewParser().AddParams(
+		//		args.Pos("tracker", &cmd.Tracker),
+		//		args.Pos("infohash", &cmd.InfoHashes, args.Arity('+'))).Parse()
+		//	if err != nil {
+		//		return err
+		//	}
+		//	return scrape(cmd)
+		//}()},
+		bargle.Subcommand{Name: "download", Command: func() bargle.Command {
 			var dlc DownloadCmd
-			err := p.NewParser().AddParams(
-				append(args.FromStruct(&dlc), debug)...,
-			).Parse()
-			if err != nil {
-				return err
-			}
-			dlf := downloadFlags{
-				Debug:       debug.Bool(),
-				DownloadCmd: dlc,
-			}
-			p.Defer(func() error {
-				return downloadErr(dlf)
-			})
-			return nil
-		}),
-		args.Subcommand(
-			"bencode",
-			func(p args.SubCmdCtx) error {
-				var print func(interface{}) error
-				if !p.Parse(
-					args.Subcommand("json", func(ctx args.SubCmdCtx) (err error) {
-						ctx.Parse()
-						je := json.NewEncoder(os.Stdout)
-						je.SetIndent("", "  ")
-						print = je.Encode
-						return nil
-					}),
-					args.Subcommand("spew", func(ctx args.SubCmdCtx) (err error) {
-						ctx.Parse()
-						config := spew.NewDefaultConfig()
-						config.DisableCapacities = true
-						config.Indent = "  "
-						print = func(v interface{}) error {
-							config.Dump(v)
-							return nil
-						}
-						return nil
-					}),
-				).RanSubCmd {
-					return errors.New("an output type is required")
-				}
-				d := bencode.NewDecoder(os.Stdin)
-				p.Defer(func() error {
-					for i := 0; ; i++ {
-						var v interface{}
-						err := d.Decode(&v)
-						if err == io.EOF {
-							break
-						}
-						if err != nil {
-							return fmt.Errorf("decoding message index %d: %w", i, err)
-						}
-						print(v)
-					}
-					return nil
+			cmd := bargle.FromStruct(&dlc)
+			cmd.DefaultAction = func() error {
+				return downloadErr(downloadFlags{
+					Debug:       debug,
+					DownloadCmd: dlc,
 				})
-				return nil
-			},
-			args.Help("reads bencoding from stdin into Go native types and spews the result"),
-		),
-		args.Subcommand("version", func(p args.SubCmdCtx) error {
-			fmt.Printf("HTTP User-Agent: %q\n", version.DefaultHttpUserAgent)
-			fmt.Printf("Torrent client version: %q\n", version.DefaultExtendedHandshakeClientVersion)
-			fmt.Printf("Torrent version prefix: %q\n", version.DefaultBep20Prefix)
-			return nil
-		}),
-		args.Subcommand("serve", serve, args.Help("creates and seeds a torrent from a filepath")),
+			}
+			return cmd
+		}()},
+		//bargle.Subcommand{Name:
+		//	"bencode", Command: func() bargle.Command {
+		//		var print func(interface{}) error
+		//		if !p.Parse(
+		//			args.Subcommand("json", func(ctx args.SubCmdCtx) (err error) {
+		//				ctx.Parse()
+		//				je := json.NewEncoder(os.Stdout)
+		//				je.SetIndent("", "  ")
+		//				print = je.Encode
+		//				return nil
+		//			}),
+		//			args.Subcommand("spew", func(ctx args.SubCmdCtx) (err error) {
+		//				ctx.Parse()
+		//				config := spew.NewDefaultConfig()
+		//				config.DisableCapacities = true
+		//				config.Indent = "  "
+		//				print = func(v interface{}) error {
+		//					config.Dump(v)
+		//					return nil
+		//				}
+		//				return nil
+		//			}),
+		//		).RanSubCmd {
+		//			return errors.New("an output type is required")
+		//		}
+		//		d := bencode.NewDecoder(os.Stdin)
+		//		p.Defer(func() error {
+		//			for i := 0; ; i++ {
+		//				var v interface{}
+		//				err := d.Decode(&v)
+		//				if err == io.EOF {
+		//					break
+		//				}
+		//				if err != nil {
+		//					return fmt.Errorf("decoding message index %d: %w", i, err)
+		//				}
+		//				print(v)
+		//			}
+		//			return nil
+		//		})
+		//		return nil
+		//	}(),
+		//	Desc: "reads bencoding from stdin into Go native types and spews the result",
+		//},
+		//bargle.Subcommand{Name: "version", Command: func() bargle.Command {
+		//	fmt.Printf("HTTP User-Agent: %q\n", version.DefaultHttpUserAgent)
+		//	fmt.Printf("Torrent client version: %q\n", version.DefaultExtendedHandshakeClientVersion)
+		//	fmt.Printf("Torrent version prefix: %q\n", version.DefaultBep20Prefix)
+		//	return nil
+		//}()},
+		bargle.Subcommand{Name: "serve", Command: serve(), Desc: "creates and seeds a torrent from a filepath"},
 	)
+	main.Run()
 }
diff --git a/cmd/torrent/metainfo.go b/cmd/torrent/metainfo.go
index f8f558ff..4cca7954 100644
--- a/cmd/torrent/metainfo.go
+++ b/cmd/torrent/metainfo.go
@@ -6,7 +6,7 @@ import (
 	"fmt"
 	"os"
 
-	"github.com/anacrolix/args"
+	"github.com/anacrolix/bargle"
 	"github.com/anacrolix/torrent/metainfo"
 	"github.com/bradfitz/iter"
 )
@@ -17,53 +17,64 @@ type pprintMetainfoFlags struct {
 	Files       bool
 }
 
-func metainfoCmd(ctx args.SubCmdCtx) (err error) {
+func metainfoCmd() (cmd bargle.Command) {
 	var metainfoPath string
 	var mi *metainfo.MetaInfo
-	// TODO: Treat no subcommand as a failure.
-	return ctx.NewParser().AddParams(
-		args.Pos("torrent file", &metainfoPath, args.AfterParse(func() (err error) {
-			mi, err = metainfo.LoadFromFile(metainfoPath)
-			return
-		})),
-		args.Subcommand("magnet", func(ctx args.SubCmdCtx) (err error) {
-			info, err := mi.UnmarshalInfo()
-			if err != nil {
-				return
-			}
-			fmt.Fprintf(os.Stdout, "%s\n", mi.Magnet(nil, &info).String())
-			return nil
-		}),
-		args.Subcommand("pprint", func(ctx args.SubCmdCtx) (err error) {
-			var flags pprintMetainfoFlags
-			err = ctx.NewParser().AddParams(args.FromStruct(&flags)...).Parse()
-			if err != nil {
-				return
-			}
-			err = pprintMetainfo(mi, flags)
-			if err != nil {
-				return
-			}
-			if !flags.JustName {
-				os.Stdout.WriteString("\n")
+	// TODO: Test if bargle treats no subcommand as a failure.
+	cmd.Positionals = append(cmd.Positionals,
+		&bargle.Positional[*string]{
+			Name:  "torrent file",
+			Value: &metainfoPath,
+			AfterParseFunc: func(ctx bargle.Context) error {
+				ctx.AfterParse(func() (err error) {
+					mi, err = metainfo.LoadFromFile(metainfoPath)
+					return
+				})
+				return nil
+			},
+		},
+		bargle.Subcommand{Name: "magnet", Command: func() (cmd bargle.Command) {
+			cmd.DefaultAction = func() (err error) {
+				info, err := mi.UnmarshalInfo()
+				if err != nil {
+					return
+				}
+				fmt.Fprintf(os.Stdout, "%s\n", mi.Magnet(nil, &info).String())
+				return nil
 			}
 			return
-		}),
-		args.Subcommand("infohash", func(ctx args.SubCmdCtx) (err error) {
-			fmt.Printf("%s: %s\n", mi.HashInfoBytes().HexString(), metainfoPath)
-			return nil
-		}),
-		args.Subcommand("list-files", func(ctx args.SubCmdCtx) (err error) {
-			info, err := mi.UnmarshalInfo()
-			if err != nil {
-				return fmt.Errorf("unmarshalling info from metainfo at %q: %v", metainfoPath, err)
-			}
-			for _, f := range info.UpvertedFiles() {
-				fmt.Println(f.DisplayPath(&info))
-			}
-			return nil
-		}),
-	).Parse()
+		}()},
+		//bargle.Subcommand{Name: "pprint", Command: func(ctx args.SubCmdCtx) (err error) {
+		//	var flags pprintMetainfoFlags
+		//	err = ctx.NewParser().AddParams(args.FromStruct(&flags)...).Parse()
+		//	if err != nil {
+		//		return
+		//	}
+		//	err = pprintMetainfo(mi, flags)
+		//	if err != nil {
+		//		return
+		//	}
+		//	if !flags.JustName {
+		//		os.Stdout.WriteString("\n")
+		//	}
+		//	return
+		//}},
+		//bargle.Subcommand{Name: "infohash", Command: func(ctx args.SubCmdCtx) (err error) {
+		//	fmt.Printf("%s: %s\n", mi.HashInfoBytes().HexString(), metainfoPath)
+		//	return nil
+		//}},
+		//bargle.Subcommand{Name: "list-files", Command: func(ctx args.SubCmdCtx) (err error) {
+		//	info, err := mi.UnmarshalInfo()
+		//	if err != nil {
+		//		return fmt.Errorf("unmarshalling info from metainfo at %q: %v", metainfoPath, err)
+		//	}
+		//	for _, f := range info.UpvertedFiles() {
+		//		fmt.Println(f.DisplayPath(&info))
+		//	}
+		//	return nil
+		//}},
+	)
+	return
 }
 
 func pprintMetainfo(metainfo *metainfo.MetaInfo, flags pprintMetainfoFlags) error {
diff --git a/cmd/torrent/serve.go b/cmd/torrent/serve.go
index b32f245b..5b88a529 100644
--- a/cmd/torrent/serve.go
+++ b/cmd/torrent/serve.go
@@ -5,7 +5,7 @@ import (
 	"net/http"
 	"path/filepath"
 
-	"github.com/anacrolix/args"
+	"github.com/anacrolix/bargle"
 	"github.com/anacrolix/log"
 	"github.com/anacrolix/torrent"
 	"github.com/anacrolix/torrent/bencode"
@@ -13,10 +13,10 @@ import (
 	"github.com/anacrolix/torrent/storage"
 )
 
-func serve(ctx args.SubCmdCtx) error {
-	var filePath string
-	ctx.Parse(args.Pos("filePath", &filePath))
-	ctx.Defer(func() error {
+func serve() (cmd bargle.Command) {
+	filePath := &bargle.Positional[string]{}
+	cmd.Positionals = append(cmd.Positionals, filePath)
+	cmd.DefaultAction = func() error {
 		cfg := torrent.NewDefaultClientConfig()
 		cfg.Seed = true
 		cl, err := torrent.NewClient(cfg)
@@ -35,9 +35,9 @@ func serve(ctx args.SubCmdCtx) error {
 		info := metainfo.Info{
 			PieceLength: pieceLength,
 		}
-		err = info.BuildFromFilePath(filePath)
+		err = info.BuildFromFilePath(filePath.Value)
 		if err != nil {
-			return fmt.Errorf("building info from path %q: %w", filePath, err)
+			return fmt.Errorf("building info from path %q: %w", filePath.Value, err)
 		}
 		for _, fi := range info.Files {
 			log.Printf("added %q", fi.Path)
@@ -54,7 +54,7 @@ func serve(ctx args.SubCmdCtx) error {
 		to, _ := cl.AddTorrentOpt(torrent.AddTorrentOpts{
 			InfoHash: ih,
 			Storage: storage.NewFileOpts(storage.NewFileClientOpts{
-				ClientBaseDir: filePath,
+				ClientBaseDir: filePath.Value,
 				FilePathMaker: func(opts storage.FilePathMakerOpts) string {
 					return filepath.Join(opts.File.Path...)
 				},
@@ -78,6 +78,6 @@ func serve(ctx args.SubCmdCtx) error {
 		}
 		fmt.Printf("%v: %v\n", to, to.Metainfo().Magnet(&ih, &info))
 		select {}
-	})
-	return nil
+	}
+	return
 }
diff --git a/go.mod b/go.mod
index a3313d6b..c49bcf4e 100644
--- a/go.mod
+++ b/go.mod
@@ -51,6 +51,7 @@ require (
 require (
 	github.com/alecthomas/atomic v0.1.0-alpha2 // indirect
 	github.com/alexflint/go-scalar v1.1.0 // indirect
+	github.com/anacrolix/bargle v0.0.0-20220620083758-c3885e1796d1 // indirect
 	github.com/anacrolix/mmsg v1.0.0 // indirect
 	github.com/anacrolix/stm v0.4.0 // indirect
 	github.com/benbjohnson/immutable v0.3.0 // indirect
diff --git a/go.sum b/go.sum
index 97592e17..8923906d 100644
--- a/go.sum
+++ b/go.sum
@@ -64,6 +64,8 @@ github.com/alexflint/go-scalar v1.1.0 h1:aaAouLLzI9TChcPXotr6gUhq+Scr8rl0P9P4Pnl
 github.com/alexflint/go-scalar v1.1.0/go.mod h1:LoFvNMqS1CPrMVltza4LvnGKhaSpc3oyLEBUZVhhS2o=
 github.com/anacrolix/args v0.5.1-0.20220509024600-c3b77d0b61ac h1:XWoepbk3zgOQ8jMO3vpOnohd6MfENPbFZPivB2L7myc=
 github.com/anacrolix/args v0.5.1-0.20220509024600-c3b77d0b61ac/go.mod h1:Fj/N2PehEwTBE5t/V/9xgTcxDkuYQ+5IBoFw/8gkldI=
+github.com/anacrolix/bargle v0.0.0-20220620083758-c3885e1796d1 h1:RijTNFCxug0EBODz/AmqJDA3Ow700v5jJZQL1j+RLvI=
+github.com/anacrolix/bargle v0.0.0-20220620083758-c3885e1796d1/go.mod h1:cC/kX8wL4i1n+63lOrXhPQQlsoxCo0EqV88fGExQwcY=
 github.com/anacrolix/chansync v0.3.0 h1:lRu9tbeuw3wl+PhMu/r+JJCRu5ArFXIluOgdF0ao6/U=
 github.com/anacrolix/chansync v0.3.0/go.mod h1:DZsatdsdXxD0WiwcGl0nJVwyjCKMDv+knl1q2iBjA2k=
 github.com/anacrolix/dht/v2 v2.18.0 h1:btjVjzjKqO5nKGbJHJ2UmuwiRx+EgX3e+OCHC9+WRz8=