Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix docgen for subcommands #13518

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 84 additions & 4 deletions go/cmd/internal/docgen/docgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import (
"fmt"
"io/fs"
"os"
"os/exec"
"path/filepath"
"strings"

Expand Down Expand Up @@ -79,9 +80,85 @@ func GenerateMarkdownTree(cmd *cobra.Command, dir string) error {
return fmt.Errorf("failed to index doc (generated at %s) into proper position (%s): %w", rootDocPath, indexDocPath, err)
}

if err := restructure(dir, dir, cmd.Name(), cmd.Commands()); err != nil {
return err
}

return nil
}

/*
_index.md (aka vtctldclient.md)
vtctldclient_AddCellInfo.md
vtctldclient_movetables.md
vtctldclient_movetables_show.md

becomes

_index.md
vtctldclient_AddCellInfo.md
vtctldclient_movetables/
_index.md
vtctldclient_movetables_show.md
*/

func restructure(rootDir string, dir string, name string, commands []*cobra.Command) error {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weeeeeeeeeeeeee 🙃

for _, cmd := range commands {
fullCmdFilename := strings.Join([]string{name, cmd.Name()}, "_")

children := cmd.Commands()

switch {
case len(children) > 0:
// Command (top-level or not) with children.
// 1. Set up a directory for its children.
// 2. Move its doc into that dir as "_index.md"
// 3. Restructure its children.
cmdDir := filepath.Join(dir, fullCmdFilename)
if err := os.MkdirAll(cmdDir, 0755); err != nil {
return fmt.Errorf("failed to create subdir for %s: %w", fullCmdFilename, err)
}

if err := os.Rename(filepath.Join(rootDir, fullCmdFilename+".md"), filepath.Join(cmdDir, "_index.md")); err != nil {
return fmt.Errorf("failed to move index doc for command %s with children: %w", fullCmdFilename, err)
}

if err := restructure(rootDir, cmdDir, fullCmdFilename, children); err != nil {
return fmt.Errorf("failed to restructure child commands for %s: %w", fullCmdFilename, err)
}
case rootDir != dir:
// Sub-command without children.
// 1. Move its doc into the directory for its parent, name unchanged.
if cmd.Name() == "help" {
// all commands with children have their own "help" subcommand,
// which we do not generate docs for
continue
}

oldName := filepath.Join(rootDir, fullCmdFilename+".md")
newName := filepath.Join(dir, fullCmdFilename+".md")

if err := os.Rename(oldName, newName); err != nil {
return fmt.Errorf("failed to move child command %s to its parent's dir: %w", fullCmdFilename, err)
}

sed := newParentLinkSedCommand(name, newName)
if out, err := sed.CombinedOutput(); err != nil {
return fmt.Errorf("failed to rewrite links to parent command in child %s: %w (extra: %s)", newName, err, out)
}
default:
// Top-level command without children. Nothing to restructure.
continue
}
}

return nil
}

func newParentLinkSedCommand(parent string, file string) *exec.Cmd {
return exec.Command("sed", "-i ''", "-e", fmt.Sprintf("s:(./%s/):(../):", parent), file)
}

func recursivelyDisableAutoGenTags(root *cobra.Command) {
commands := []*cobra.Command{root}
for cmd := commands[0]; len(commands) > 0; cmd, commands = commands[0], commands[1:] {
Expand All @@ -106,16 +183,19 @@ func frontmatterFilePrepender(filename string) string {
cmdName = root
}

cmdName = strings.ReplaceAll(cmdName, "_", " ")

return fmt.Sprintf(frontmatter, cmdName, root)
}

func linkHandler(filename string) string {
name := filepath.Base(filename)
base := strings.TrimSuffix(name, filepath.Ext(name))
base := filepath.Base(filename)
name := strings.TrimSuffix(base, filepath.Ext(base))
Comment on lines +192 to +193
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these names ended up being more clear to me ("why is the thing we get from .Base not called base?")


if _, _, ok := strings.Cut(base, "_"); !ok {
_, _, ok := strings.Cut(name, "_")
if !ok {
return "../"
}

return fmt.Sprintf("./%s/", strings.ToLower(base))
return fmt.Sprintf("./%s/", strings.ToLower(name))
}
Loading