...

Source file src/github.com/ory/x/clidoc/generate.go

Documentation: github.com/ory/x/clidoc

     1  package clidoc
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"fmt"
     7  	"html"
     8  	"io"
     9  	"io/ioutil"
    10  	"os"
    11  	"path"
    12  	"path/filepath"
    13  	"sort"
    14  	"strings"
    15  
    16  	"github.com/spf13/cobra"
    17  	"github.com/spf13/cobra/doc"
    18  	"github.com/tidwall/gjson"
    19  	"github.com/tidwall/sjson"
    20  )
    21  
    22  const sideBarLabel = "Command Line Interface (CLI)"
    23  
    24  // Generate generates markdown documentation for a cobra command and its children.
    25  func Generate(cmd *cobra.Command, args []string) error {
    26  	if len(args) != 1 {
    27  		return errors.New("command expects one argument which is the project's root folder")
    28  	}
    29  
    30  	navItems := make([]string, 0)
    31  	if err := generate(cmd, args[0], &navItems); err != nil {
    32  		return err
    33  	}
    34  	sort.Strings(navItems)
    35  
    36  	spath := filepath.Join(args[0], "docs", "sidebar.json")
    37  	sidebar, err := ioutil.ReadFile(spath)
    38  	if err != nil {
    39  		return err
    40  	}
    41  
    42  	if !gjson.ValidBytes(sidebar) {
    43  		return errors.New("sidebar file is not valid JSON")
    44  	}
    45  
    46  	var index int
    47  	gjson.GetBytes(sidebar, `Reference`).ForEach(func(key, value gjson.Result) bool {
    48  		if strings.Contains(value.Raw, sideBarLabel) {
    49  			return false
    50  		}
    51  		index++
    52  		return true
    53  	})
    54  
    55  	sidebar, err = sjson.SetBytes(sidebar, fmt.Sprintf(`Reference.%d.%s`, index, sideBarLabel), navItems)
    56  	if err != nil {
    57  		return err
    58  	}
    59  
    60  	/* #nosec G306 - TODO evaluate why */
    61  	if err := ioutil.WriteFile(spath, []byte(gjson.GetBytes(sidebar, "@pretty").Raw), 0644); err != nil {
    62  		return err
    63  	}
    64  
    65  	return nil
    66  }
    67  
    68  func trimExt(s string) string {
    69  	return strings.ReplaceAll(strings.TrimSuffix(s, filepath.Ext(s)), "_", "-")
    70  }
    71  
    72  func generate(cmd *cobra.Command, dir string, navItems *[]string) error {
    73  	cmd.DisableAutoGenTag = true
    74  	for _, c := range cmd.Commands() {
    75  		if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
    76  			continue
    77  		}
    78  		if err := generate(c, dir, navItems); err != nil {
    79  			return err
    80  		}
    81  	}
    82  
    83  	basename := strings.Replace(cmd.CommandPath(), " ", "-", -1)
    84  	if err := os.MkdirAll(filepath.Join(dir, "docs", "docs", "cli"), 0755); err != nil {
    85  		return err
    86  	}
    87  
    88  	filename := filepath.Join(dir, "docs", "docs", "cli", basename) + ".md"
    89  	f, err := os.Create(filename)
    90  	if err != nil {
    91  		return err
    92  	}
    93  	defer f.Close()
    94  
    95  	if _, err := io.WriteString(f, fmt.Sprintf(`---
    96  id: %s
    97  title: %s
    98  description: %s %s
    99  ---
   100  
   101  <!--
   102  This file is auto-generated.
   103  
   104  To improve this file please make your change against the appropriate "./cmd/*.go" file.
   105  -->
   106  `,
   107  		basename,
   108  		cmd.CommandPath(),
   109  		cmd.CommandPath(),
   110  		cmd.Short,
   111  	)); err != nil {
   112  		return err
   113  	}
   114  
   115  	*navItems = append(*navItems, path.Join("cli", basename))
   116  
   117  	var b bytes.Buffer
   118  	if err := doc.GenMarkdownCustom(cmd, &b, trimExt); err != nil {
   119  		return err
   120  	}
   121  
   122  	_, err = f.WriteString(html.EscapeString(b.String()))
   123  	return err
   124  }
   125  

View as plain text