github.com/xhghs/rclone@v1.51.1-0.20200430155106-e186a28cced8/cmd/gendocs/gendocs.go (about)

     1  package gendocs
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"os"
     8  	"path"
     9  	"path/filepath"
    10  	"strings"
    11  	"time"
    12  
    13  	"github.com/rclone/rclone/cmd"
    14  	"github.com/spf13/cobra"
    15  	"github.com/spf13/cobra/doc"
    16  	"github.com/spf13/pflag"
    17  )
    18  
    19  func init() {
    20  	cmd.Root.AddCommand(commandDefinition)
    21  }
    22  
    23  const gendocFrontmatterTemplate = `---
    24  date: %s
    25  title: "%s"
    26  slug: %s
    27  url: %s
    28  ---
    29  `
    30  
    31  var commandDefinition = &cobra.Command{
    32  	Use:   "gendocs output_directory",
    33  	Short: `Output markdown docs for rclone to the directory supplied.`,
    34  	Long: `
    35  This produces markdown docs for the rclone commands to the directory
    36  supplied.  These are in a format suitable for hugo to render into the
    37  rclone.org website.`,
    38  	RunE: func(command *cobra.Command, args []string) error {
    39  		cmd.CheckArgs(1, 1, command, args)
    40  		now := time.Now().Format(time.RFC3339)
    41  
    42  		// Create the directory structure
    43  		root := args[0]
    44  		out := filepath.Join(root, "commands")
    45  		err := os.MkdirAll(out, 0777)
    46  		if err != nil {
    47  			return err
    48  		}
    49  
    50  		// Write the flags page
    51  		var buf bytes.Buffer
    52  		cmd.Root.SetOutput(&buf)
    53  		cmd.Root.SetArgs([]string{"help", "flags"})
    54  		cmd.GeneratingDocs = true
    55  		err = cmd.Root.Execute()
    56  		if err != nil {
    57  			return err
    58  		}
    59  		flagsHelp := strings.Replace(buf.String(), "YYYY-MM-DD", now, -1)
    60  		err = ioutil.WriteFile(filepath.Join(root, "flags.md"), []byte(flagsHelp), 0777)
    61  		if err != nil {
    62  			return err
    63  		}
    64  
    65  		// markup for the docs files
    66  		prepender := func(filename string) string {
    67  			name := filepath.Base(filename)
    68  			base := strings.TrimSuffix(name, path.Ext(name))
    69  			url := "/commands/" + strings.ToLower(base) + "/"
    70  			return fmt.Sprintf(gendocFrontmatterTemplate, now, strings.Replace(base, "_", " ", -1), base, url)
    71  		}
    72  		linkHandler := func(name string) string {
    73  			base := strings.TrimSuffix(name, path.Ext(name))
    74  			return "/commands/" + strings.ToLower(base) + "/"
    75  		}
    76  
    77  		// Hide all of the root entries flags
    78  		cmd.Root.Flags().VisitAll(func(flag *pflag.Flag) {
    79  			flag.Hidden = true
    80  		})
    81  		err = doc.GenMarkdownTreeCustom(cmd.Root, out, prepender, linkHandler)
    82  		if err != nil {
    83  			return err
    84  		}
    85  
    86  		// Munge the files to add a link to the global flags page
    87  		err = filepath.Walk(out, func(path string, info os.FileInfo, err error) error {
    88  			if err != nil {
    89  				return err
    90  			}
    91  			if !info.IsDir() {
    92  				b, err := ioutil.ReadFile(path)
    93  				if err != nil {
    94  					return err
    95  				}
    96  				doc := string(b)
    97  				doc = strings.Replace(doc, "\n### SEE ALSO", `
    98  See the [global flags page](/flags/) for global options not listed here.
    99  
   100  ### SEE ALSO`, 1)
   101  				err = ioutil.WriteFile(path, []byte(doc), 0777)
   102  				if err != nil {
   103  					return err
   104  				}
   105  			}
   106  			return nil
   107  		})
   108  		if err != nil {
   109  			return err
   110  		}
   111  
   112  		return nil
   113  	},
   114  }