Merge pull request #1282 from restic/rework-autogeneration

Rework generation of manpages and completion files
This commit is contained in:
Alexander Neumann 2017-09-26 14:16:41 +02:00
commit 7fe657ec71
29 changed files with 1274 additions and 231 deletions

View File

@ -129,13 +129,7 @@ down to the following steps:
next stable release. While writing, ask yourself: If I were the user, what
would I need to be aware of with this change.
8. When your contribution adds and/or changes command-line parameters or help
texts, the manual pages need to be regenerated and commited to the
repository. In order to do this, compile restic and save the generated
updated man pages in the subdir `doc/man` with the following command:
`./restic manpage --output-dir doc/man`
9. Once your code looks good and passes all the tests, we'll merge it. Thanks
8. Once your code looks good and passes all the tests, we'll merge it. Thanks
a lot for your contribution!
Please provide the patches for each bug or feature in a separate branch and

View File

@ -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{})
}

View File

@ -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
}

View File

@ -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)
}

1121
doc/bash-completion.sh Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,78 +0,0 @@
.TH "restic backup" "1" "Jan 2017" "generated by `restic manpage`" ""
.nh
.ad l
.SH NAME
.PP
restic\-autocomplete \- Generate shell autocompletion script
.SH SYNOPSIS
.PP
\fBrestic autocomplete [flags]\fP
.SH DESCRIPTION
.PP
The "autocomplete" command generates a shell autocompletion script.
.PP
NOTE: The current version supports Bash only.
This should work for *nix systems with Bash installed.
.PP
By default, the file is written directly to /etc/bash\_completion.d
for convenience, and the command may need superuser rights, e.g.:
.PP
$ sudo restic autocomplete
.SH OPTIONS
.PP
\fB\-\-completionfile\fP="/usr/share/bash\-completion/completions/restic"
autocompletion file
.PP
\fB\-h\fP, \fB\-\-help\fP[=false]
help for autocomplete
.SH OPTIONS INHERITED FROM PARENT COMMANDS
.PP
\fB\-\-cache\-dir\fP=""
set the cache directory
.PP
\fB\-\-json\fP[=false]
set output mode to JSON for commands that support it
.PP
\fB\-\-no\-cache\fP[=false]
do not use a local cache
.PP
\fB\-\-no\-lock\fP[=false]
do not lock the repo, this allows some operations on read\-only repos
.PP
\fB\-o\fP, \fB\-\-option\fP=[]
set extended option (\fB\fCkey=value\fR, can be specified multiple times)
.PP
\fB\-p\fP, \fB\-\-password\-file\fP=""
read the repository password from a file (default: $RESTIC\_PASSWORD\_FILE)
.PP
\fB\-q\fP, \fB\-\-quiet\fP[=false]
do not output comprehensive progress report
.PP
\fB\-r\fP, \fB\-\-repo\fP=""
repository to backup to or restore from (default: $RESTIC\_REPOSITORY)
.SH SEE ALSO
.PP
\fBrestic(1)\fP

View File

@ -1,4 +1,4 @@
.TH "restic backup" "1" "Jan 2017" "generated by `restic manpage`" ""
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
.nh
.ad l

View File

@ -1,4 +1,4 @@
.TH "restic backup" "1" "Jan 2017" "generated by `restic manpage`" ""
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
.nh
.ad l

View File

@ -1,4 +1,4 @@
.TH "restic backup" "1" "Jan 2017" "generated by `restic manpage`" ""
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
.nh
.ad l

View File

@ -1,4 +1,4 @@
.TH "restic backup" "1" "Jan 2017" "generated by `restic manpage`" ""
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
.nh
.ad l

View File

@ -1,4 +1,4 @@
.TH "restic backup" "1" "Jan 2017" "generated by `restic manpage`" ""
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
.nh
.ad l

View File

@ -1,4 +1,4 @@
.TH "restic backup" "1" "Jan 2017" "generated by `restic manpage`" ""
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
.nh
.ad l

View File

@ -1,33 +1,40 @@
.TH "restic backup" "1" "Jan 2017" "generated by `restic manpage`" ""
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
.nh
.ad l
.SH NAME
.PP
restic\-manpage \- Generate manual pages
restic\-generate \- Generate manual pages and auto\-completion files (bash, zsh)
.SH SYNOPSIS
.PP
\fBrestic manpage [command] [flags]\fP
\fBrestic generate [command] [flags]\fP
.SH DESCRIPTION
.PP
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.
The "generate" command writes automatically generated files like the man pages
and the auto\-completion files for bash and zsh).
.SH OPTIONS
.PP
\fB\-h\fP, \fB\-\-help\fP[=false]
help for manpage
\fB\-\-bash\-completion\fP=""
write bash completion \fB\fCfile\fR
.PP
\fB\-\-output\-dir\fP=""
write man pages to this \fB\fCdirectory\fR
\fB\-h\fP, \fB\-\-help\fP[=false]
help for generate
.PP
\fB\-\-man\fP=""
write man pages to \fB\fCdirectory\fR
.PP
\fB\-\-zsh\-completion\fP=""
write zsh completion \fB\fCfile\fR
.SH OPTIONS INHERITED FROM PARENT COMMANDS

View File

@ -1,4 +1,4 @@
.TH "restic backup" "1" "Jan 2017" "generated by `restic manpage`" ""
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
.nh
.ad l

View File

@ -1,4 +1,4 @@
.TH "restic backup" "1" "Jan 2017" "generated by `restic manpage`" ""
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
.nh
.ad l

View File

@ -1,4 +1,4 @@
.TH "restic backup" "1" "Jan 2017" "generated by `restic manpage`" ""
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
.nh
.ad l

View File

@ -1,4 +1,4 @@
.TH "restic backup" "1" "Jan 2017" "generated by `restic manpage`" ""
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
.nh
.ad l

View File

@ -1,4 +1,4 @@
.TH "restic backup" "1" "Jan 2017" "generated by `restic manpage`" ""
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
.nh
.ad l

View File

@ -1,4 +1,4 @@
.TH "restic backup" "1" "Jan 2017" "generated by `restic manpage`" ""
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
.nh
.ad l

View File

@ -1,4 +1,4 @@
.TH "restic backup" "1" "Jan 2017" "generated by `restic manpage`" ""
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
.nh
.ad l

View File

@ -1,4 +1,4 @@
.TH "restic backup" "1" "Jan 2017" "generated by `restic manpage`" ""
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
.nh
.ad l

View File

@ -1,4 +1,4 @@
.TH "restic backup" "1" "Jan 2017" "generated by `restic manpage`" ""
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
.nh
.ad l

View File

@ -1,4 +1,4 @@
.TH "restic backup" "1" "Jan 2017" "generated by `restic manpage`" ""
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
.nh
.ad l

View File

@ -1,4 +1,4 @@
.TH "restic backup" "1" "Jan 2017" "generated by `restic manpage`" ""
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
.nh
.ad l

View File

@ -1,4 +1,4 @@
.TH "restic backup" "1" "Jan 2017" "generated by `restic manpage`" ""
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
.nh
.ad l

View File

@ -1,4 +1,4 @@
.TH "restic backup" "1" "Jan 2017" "generated by `restic manpage`" ""
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
.nh
.ad l

View File

@ -1,4 +1,4 @@
.TH "restic backup" "1" "Jan 2017" "generated by `restic manpage`" ""
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
.nh
.ad l
@ -59,4 +59,4 @@ directories in an encrypted repository stored on different backends.
.SH SEE ALSO
.PP
\fBrestic\-autocomplete(1)\fP, \fBrestic\-backup(1)\fP, \fBrestic\-cat(1)\fP, \fBrestic\-check(1)\fP, \fBrestic\-dump(1)\fP, \fBrestic\-find(1)\fP, \fBrestic\-forget(1)\fP, \fBrestic\-init(1)\fP, \fBrestic\-key(1)\fP, \fBrestic\-list(1)\fP, \fBrestic\-ls(1)\fP, \fBrestic\-manpage(1)\fP, \fBrestic\-migrate(1)\fP, \fBrestic\-mount(1)\fP, \fBrestic\-prune(1)\fP, \fBrestic\-rebuild\-index(1)\fP, \fBrestic\-restore(1)\fP, \fBrestic\-snapshots(1)\fP, \fBrestic\-tag(1)\fP, \fBrestic\-unlock(1)\fP, \fBrestic\-version(1)\fP
\fBrestic\-backup(1)\fP, \fBrestic\-cat(1)\fP, \fBrestic\-check(1)\fP, \fBrestic\-dump(1)\fP, \fBrestic\-find(1)\fP, \fBrestic\-forget(1)\fP, \fBrestic\-generate(1)\fP, \fBrestic\-init(1)\fP, \fBrestic\-key(1)\fP, \fBrestic\-list(1)\fP, \fBrestic\-ls(1)\fP, \fBrestic\-migrate(1)\fP, \fBrestic\-mount(1)\fP, \fBrestic\-prune(1)\fP, \fBrestic\-rebuild\-index(1)\fP, \fBrestic\-restore(1)\fP, \fBrestic\-snapshots(1)\fP, \fBrestic\-tag(1)\fP, \fBrestic\-unlock(1)\fP, \fBrestic\-version(1)\fP

20
doc/zsh-completion.zsh Normal file
View File

@ -0,0 +1,20 @@
#compdef restic
_arguments \
'1: :->level1' \
'2: :_files'
case $state in
level1)
case $words[1] in
restic)
_arguments '1: :(backup cat check dump find forget generate help init key list ls migrate mount options prune rebuild-index restore snapshots tag unlock version)'
;;
*)
_arguments '*: :_files'
;;
esac
;;
*)
_arguments '*: :_files'
;;
esac

View File

@ -280,14 +280,6 @@ func (env *TravisEnvironment) RunTests() error {
return err
}
if err := run("./restic", "manpage", "--output-dir", manpath); err != nil {
return err
}
if err := run("diff", "-aur", filepath.Join("doc/man"), manpath); err != nil {
return fmt.Errorf("========== man pages are not up to date\nplease run `restic manpage --output-dir doc/man`\n%v", err)
}
return nil
}