diff options
| author | Přemysl Eric Janouch <p@janouch.name> | 2023-12-26 05:58:19 +0100 | 
|---|---|---|
| committer | Přemysl Eric Janouch <p@janouch.name> | 2023-12-26 06:39:28 +0100 | 
| commit | 74a6dd0233bd0c983e191b9708e0ed257e78b0ff (patch) | |
| tree | 2a09d73f247d8f72c06fb88d0f190badf9f25ee9 | |
| parent | 615860362a39b769f75cf45a8d0e58d3e218e72a (diff) | |
| download | gallery-74a6dd0233bd0c983e191b9708e0ed257e78b0ff.tar.gz gallery-74a6dd0233bd0c983e191b9708e0ed257e78b0ff.tar.xz gallery-74a6dd0233bd0c983e191b9708e0ed257e78b0ff.zip  | |
WIP: Command arguments
| -rw-r--r-- | main.go | 81 | 
1 files changed, 53 insertions, 28 deletions
@@ -9,6 +9,7 @@ import (  	"encoding/hex"  	"encoding/json"  	"errors" +	"flag"  	"fmt"  	"html/template"  	"image" @@ -260,9 +261,9 @@ func parallelize(strings []string, callback parallelFunc) error {  // cmdInit initializes a "gallery directory" that contains gallery.sqlite,  // images, thumbs. -func cmdInit(args []string) error { +func cmdInit(fs *flag.FlagSet, args []string) error {  	if len(args) != 1 { -		return errors.New("usage: GD") +		return errWrongUsage  	}  	if err := openDB(args[0]); err != nil { @@ -1074,9 +1075,9 @@ func handleAPISearch(w http.ResponseWriter, r *http.Request) {  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  // cmdWeb runs a web UI against GD on ADDRESS. -func cmdWeb(args []string) error { +func cmdWeb(fs *flag.FlagSet, args []string) error {  	if len(args) != 2 { -		return errors.New("usage: GD ADDRESS") +		return errWrongUsage  	}  	if err := openDB(args[0]); err != nil {  		return err @@ -1681,11 +1682,17 @@ func syncRun(ctx context.Context, tx *sql.Tx, roots []string) error {  // cmdSync ensures the given (sub)roots are accurately reflected  // in the database. -func cmdSync(args []string) error { -	if len(args) < 2 { -		return errors.New("usage: GD ROOT...") +func cmdSync(fs *flag.FlagSet, args []string) error { +	// TODO: Convert the other commands as well. +	fullpaths := fs.Bool("fullpaths", false, "don't basename the arguments") +	if err := fs.Parse(args); err != nil { +		return err  	} -	if err := openDB(args[0]); err != nil { +	if fs.NArg() < 2 { +		return errWrongUsage +	} + +	if err := openDB(fs.Arg(0)); err != nil {  		return err  	} @@ -1709,9 +1716,12 @@ func cmdSync(args []string) error {  		return err  	} +	// TODO: Handle sensibly. +	_ = fullpaths +  	// Normalize arguments.  	// At least for now, turn all roots into absolute paths. -	roots := args[1:] +	roots := fs.Args()[1:]  	for i := range roots {  		roots[i], err = filepath.Abs(filepath.Clean(roots[i]))  		if err != nil { @@ -1739,9 +1749,9 @@ func cmdSync(args []string) error {  // cmdRemove is for manual removal of subtrees from the database.  // Beware that inputs are database, not filesystem paths. -func cmdRemove(args []string) error { +func cmdRemove(fs *flag.FlagSet, args []string) error {  	if len(args) < 2 { -		return errors.New("usage: GD PATH...") +		return errWrongUsage  	}  	if err := openDB(args[0]); err != nil {  		return err @@ -1784,7 +1794,7 @@ func cmdRemove(args []string) error {  // cmdTag mass imports tags from data passed on stdin as a TSV  // of SHA1 TAG WEIGHT entries. -func cmdTag(args []string) error { +func cmdTag(fs *flag.FlagSet, args []string) error {  	if len(args) < 2 || len(args) > 3 {  		return errors.New("usage: GD SPACE [DESCRIPTION]")  	} @@ -1935,7 +1945,7 @@ func checkFiles(root, suffix string, hashes []string) (bool, []string, error) {  }  // cmdCheck carries out various database consistency checks. -func cmdCheck(args []string) error { +func cmdCheck(fs *flag.FlagSet, args []string) error {  	if len(args) != 1 {  		return errors.New("usage: GD")  	} @@ -2052,9 +2062,9 @@ func makeThumbnailFor(sha1 string) (message string, err error) {  }  // cmdThumbnail generates missing thumbnails, in parallel. -func cmdThumbnail(args []string) error { +func cmdThumbnail(fs *flag.FlagSet, args []string) error {  	if len(args) < 1 { -		return errors.New("usage: GD [SHA1...]") +		return errWrongUsage  	}  	if err := openDB(args[0]); err != nil {  		return err @@ -2207,9 +2217,9 @@ func makeDhashFor(sha1 string) (message string, err error) {  }  // cmdDhash generates perceptual hash from thumbnails. -func cmdDhash(args []string) error { +func cmdDhash(fs *flag.FlagSet, args []string) error {  	if len(args) < 1 { -		return errors.New("usage: GD [SHA1...]") +		return errWrongUsage  	}  	if err := openDB(args[0]); err != nil {  		return err @@ -2229,20 +2239,25 @@ func cmdDhash(args []string) error {  // --- Main -------------------------------------------------------------------- +var errWrongUsage = errors.New("wrong usage") +  var commands = map[string]struct { -	handler func(args []string) error +	handler func(*flag.FlagSet, []string) error +	usage   string  }{ -	"init":      {cmdInit}, -	"web":       {cmdWeb}, -	"tag":       {cmdTag}, -	"sync":      {cmdSync}, -	"remove":    {cmdRemove}, -	"check":     {cmdCheck}, -	"thumbnail": {cmdThumbnail}, -	"dhash":     {cmdDhash}, +	"init":      {cmdInit, "GD"}, +	"web":       {cmdWeb, "GD ADDRESS"}, +	"tag":       {cmdTag, "GD SPACE [DESCRIPTION]"}, +	"sync":      {cmdSync, "GD ROOT..."}, +	"remove":    {cmdRemove, "GD PATH..."}, +	"check":     {cmdCheck, "GD"}, +	"thumbnail": {cmdThumbnail, "GD [SHA1...]"}, +	"dhash":     {cmdDhash, "GD [SHA1...]"},  }  func main() { +	// TODO: Implement a global -h command. +	// The flag package doesn't reorder, unlike GNU, so it's fine.  	if len(os.Args) <= 2 {  		log.Fatalln("Missing arguments")  	} @@ -2252,8 +2267,15 @@ func main() {  		log.Fatalln("Unknown command: " + os.Args[1])  	} +	fs := flag.NewFlagSet(os.Args[1], flag.ExitOnError) +	fs.Usage = func() { +		fmt.Fprintf(fs.Output(), +			"Usage: %s [OPTION...] %s...\n", fs.Name(), cmd.usage) +		fs.PrintDefaults() +	} +  	taskSemaphore = newSemaphore(runtime.NumCPU()) -	err := cmd.handler(os.Args[2:]) +	err := cmd.handler(fs, os.Args[2:])  	// Note that the database object has a closing finalizer,  	// we just additionally print any errors coming from there. @@ -2263,7 +2285,10 @@ func main() {  		}  	} -	if err != nil { +	if errors.Is(err, errWrongUsage) { +		fs.Usage() +		os.Exit(2) +	} else if err != nil {  		log.Fatalln(err)  	}  }  | 
