From dad1c87afe3950c61dc64b63331ea504fe899d44 Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Tue, 26 Sep 2017 13:07:13 +0200 Subject: [PATCH] Rework generation of manpages and completion files This commit removes the `manpages` and `autocomplet` commands and replaces them with the more generic `generate` command. Also, zsh completion file support was added. --- cmd/restic/cmd_autocomplete.go | 37 ------------- cmd/restic/cmd_generate.go | 94 ++++++++++++++++++++++++++++++++++ cmd/restic/cmd_manpage.go | 70 ------------------------- 3 files changed, 94 insertions(+), 107 deletions(-) delete mode 100644 cmd/restic/cmd_autocomplete.go create mode 100644 cmd/restic/cmd_generate.go delete mode 100644 cmd/restic/cmd_manpage.go diff --git a/cmd/restic/cmd_autocomplete.go b/cmd/restic/cmd_autocomplete.go deleted file mode 100644 index 643bd96bf..000000000 --- a/cmd/restic/cmd_autocomplete.go +++ /dev/null @@ -1,37 +0,0 @@ -package main - -import ( - "github.com/spf13/cobra" -) - -var cmdAutocomplete = &cobra.Command{ - Use: "autocomplete", - Short: "Generate shell autocompletion script", - Long: `The "autocomplete" command generates a shell autocompletion script. - -NOTE: The current version supports Bash only. - This should work for *nix systems with Bash installed. - -By default, the file is written directly to /etc/bash_completion.d -for convenience, and the command may need superuser rights, e.g.: - -$ sudo restic autocomplete`, - - DisableAutoGenTag: true, - RunE: func(cmd *cobra.Command, args []string) error { - if err := cmdRoot.GenBashCompletionFile(autocompleteTarget); err != nil { - return err - } - return nil - }, -} - -var autocompleteTarget string - -func init() { - cmdRoot.AddCommand(cmdAutocomplete) - - cmdAutocomplete.Flags().StringVarP(&autocompleteTarget, "completionfile", "", "/usr/share/bash-completion/completions/restic", "autocompletion file") - // For bash-completion - cmdAutocomplete.Flags().SetAnnotation("completionfile", cobra.BashCompFilenameExt, []string{}) -} diff --git a/cmd/restic/cmd_generate.go b/cmd/restic/cmd_generate.go new file mode 100644 index 000000000..5c42537dc --- /dev/null +++ b/cmd/restic/cmd_generate.go @@ -0,0 +1,94 @@ +package main + +import ( + "time" + + "github.com/restic/restic/internal/errors" + "github.com/spf13/cobra" + "github.com/spf13/cobra/doc" +) + +var cmdGenerate = &cobra.Command{ + Use: "generate [command]", + Short: "Generate manual pages and auto-completion files (bash, zsh)", + Long: ` +The "generate" command writes automatically generated files like the man pages +and the auto-completion files for bash and zsh). +`, + DisableAutoGenTag: true, + RunE: runGenerate, +} + +type generateOptions struct { + ManDir string + BashCompletionFile string + ZSHCompletionFile string +} + +var genOpts generateOptions + +func init() { + cmdRoot.AddCommand(cmdGenerate) + fs := cmdGenerate.Flags() + fs.StringVar(&genOpts.ManDir, "man", "", "write man pages to `directory`") + fs.StringVar(&genOpts.BashCompletionFile, "bash-completion", "", "write bash completion `file`") + fs.StringVar(&genOpts.ZSHCompletionFile, "zsh-completion", "", "write zsh completion `file`") +} + +func writeManpages(dir string) error { + // use a fixed date for the man pages so that generating them is deterministic + date, err := time.Parse("Jan 2006", "Jan 2017") + if err != nil { + return err + } + + header := &doc.GenManHeader{ + Title: "restic backup", + Section: "1", + Source: "generated by `restic generate`", + Date: &date, + } + + Verbosef("writing man pages to directory %v\n", dir) + return doc.GenManTree(cmdRoot, header, dir) +} + +func writeBashCompletion(file string) error { + Verbosef("writing bash completion file to %v\n", file) + return cmdRoot.GenBashCompletionFile(file) +} + +func writeZSHCompletion(file string) error { + Verbosef("writing zsh completion file to %v\n", file) + return cmdRoot.GenZshCompletionFile(file) +} + +func runGenerate(cmd *cobra.Command, args []string) error { + if genOpts.ManDir != "" { + err := writeManpages(genOpts.ManDir) + if err != nil { + return err + } + } + + if genOpts.BashCompletionFile != "" { + err := writeBashCompletion(genOpts.BashCompletionFile) + if err != nil { + return err + } + } + + if genOpts.ZSHCompletionFile != "" { + err := writeZSHCompletion(genOpts.ZSHCompletionFile) + if err != nil { + return err + } + } + + var empty generateOptions + if genOpts == empty { + return errors.Fatal("nothing to do, please specify at least one output file/dir") + } + + return nil +} diff --git a/cmd/restic/cmd_manpage.go b/cmd/restic/cmd_manpage.go deleted file mode 100644 index 1d39f4242..000000000 --- a/cmd/restic/cmd_manpage.go +++ /dev/null @@ -1,70 +0,0 @@ -package main - -import ( - "os" - "time" - - "github.com/restic/restic/internal/errors" - "github.com/spf13/cobra" - "github.com/spf13/cobra/doc" -) - -var cmdManpage = &cobra.Command{ - Use: "manpage [command]", - Short: "Generate manual pages", - Long: ` -The "manpage" command generates a manual page for a single command. It can also -be used to write all manual pages to a directory. If the output directory is -set and no command is specified, all manpages are written to the directory. -`, - DisableAutoGenTag: true, - RunE: runManpage, -} - -var manpageOpts = struct { - OutputDir string -}{} - -func init() { - cmdRoot.AddCommand(cmdManpage) - fs := cmdManpage.Flags() - fs.StringVar(&manpageOpts.OutputDir, "output-dir", "", "write man pages to this `directory`") -} - -func runManpage(cmd *cobra.Command, args []string) error { - // use a fixed date for the man pages so that generating them is deterministic - date, err := time.Parse("Jan 2006", "Jan 2017") - if err != nil { - return err - } - - header := &doc.GenManHeader{ - Title: "restic backup", - Section: "1", - Source: "generated by `restic manpage`", - Date: &date, - } - - dir := manpageOpts.OutputDir - if dir != "" { - Verbosef("writing man pages to directory %v\n", dir) - return doc.GenManTree(cmdRoot, header, dir) - } - - switch { - case len(args) == 0: - return errors.Fatalf("no command given") - case len(args) > 1: - return errors.Fatalf("more than one command given: %v", args) - } - - name := args[0] - - for _, cmd := range cmdRoot.Commands() { - if cmd.Name() == name { - return doc.GenMan(cmd, header, os.Stdout) - } - } - - return errors.Fatalf("command %q is not known", args) -}