github.com/docker/docker-ce@v17.12.1-ce-rc2+incompatible/components/cli/man/generate.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"log"
     7  	"os"
     8  	"path/filepath"
     9  
    10  	"github.com/docker/cli/cli/command"
    11  	"github.com/docker/cli/cli/command/commands"
    12  	"github.com/docker/docker/pkg/term"
    13  	"github.com/spf13/cobra"
    14  	"github.com/spf13/cobra/doc"
    15  	"github.com/spf13/pflag"
    16  )
    17  
    18  const descriptionSourcePath = "man/src/"
    19  
    20  func generateManPages(opts *options) error {
    21  	header := &doc.GenManHeader{
    22  		Title:   "DOCKER",
    23  		Section: "1",
    24  		Source:  "Docker Community",
    25  	}
    26  
    27  	stdin, stdout, stderr := term.StdStreams()
    28  	dockerCli := command.NewDockerCli(stdin, stdout, stderr)
    29  	cmd := &cobra.Command{Use: "docker"}
    30  	commands.AddCommands(cmd, dockerCli)
    31  	source := filepath.Join(opts.source, descriptionSourcePath)
    32  	if err := loadLongDescription(cmd, source); err != nil {
    33  		return err
    34  	}
    35  
    36  	cmd.DisableAutoGenTag = true
    37  	cmd.DisableFlagsInUseLine = true
    38  	return doc.GenManTreeFromOpts(cmd, doc.GenManTreeOptions{
    39  		Header:           header,
    40  		Path:             opts.target,
    41  		CommandSeparator: "-",
    42  	})
    43  }
    44  
    45  func loadLongDescription(cmd *cobra.Command, path string) error {
    46  	for _, cmd := range cmd.Commands() {
    47  		cmd.DisableFlagsInUseLine = true
    48  		if cmd.Name() == "" {
    49  			continue
    50  		}
    51  		fullpath := filepath.Join(path, cmd.Name()+".md")
    52  
    53  		if cmd.HasSubCommands() {
    54  			loadLongDescription(cmd, filepath.Join(path, cmd.Name()))
    55  		}
    56  
    57  		if _, err := os.Stat(fullpath); err != nil {
    58  			log.Printf("WARN: %s does not exist, skipping\n", fullpath)
    59  			continue
    60  		}
    61  
    62  		content, err := ioutil.ReadFile(fullpath)
    63  		if err != nil {
    64  			return err
    65  		}
    66  		cmd.Long = string(content)
    67  
    68  		fullpath = filepath.Join(path, cmd.Name()+"-example.md")
    69  		if _, err := os.Stat(fullpath); err != nil {
    70  			continue
    71  		}
    72  
    73  		content, err = ioutil.ReadFile(fullpath)
    74  		if err != nil {
    75  			return err
    76  		}
    77  		cmd.Example = string(content)
    78  
    79  	}
    80  	return nil
    81  }
    82  
    83  type options struct {
    84  	source string
    85  	target string
    86  }
    87  
    88  func parseArgs() (*options, error) {
    89  	opts := &options{}
    90  	cwd, _ := os.Getwd()
    91  	flags := pflag.NewFlagSet(os.Args[0], pflag.ContinueOnError)
    92  	flags.StringVar(&opts.source, "root", cwd, "Path to project root")
    93  	flags.StringVar(&opts.target, "target", "/tmp", "Target path for generated man pages")
    94  	err := flags.Parse(os.Args[1:])
    95  	return opts, err
    96  }
    97  
    98  func main() {
    99  	opts, err := parseArgs()
   100  	if err != nil {
   101  		fmt.Fprintln(os.Stderr, err.Error())
   102  	}
   103  	fmt.Printf("Project root: %s\n", opts.source)
   104  	fmt.Printf("Generating man pages into %s\n", opts.target)
   105  	if err := generateManPages(opts); err != nil {
   106  		fmt.Fprintf(os.Stderr, "Failed to generate man pages: %s\n", err.Error())
   107  	}
   108  }