mukan-ignite/ignite/internal/tools/gen-cli-docs/main.go
Mukan Erkin Törük 26b204bd04
Some checks are pending
Docs Deploy / build_and_deploy (push) Waiting to run
Generate Docs / cli (push) Waiting to run
Generate Config Doc / cli (push) Waiting to run
Go formatting / go-formatting (push) Waiting to run
Check links / markdown-link-check (push) Waiting to run
Integration / pre-test (push) Waiting to run
Integration / test on (push) Blocked by required conditions
Integration / status (push) Blocked by required conditions
Lint / Lint Go code (push) Waiting to run
Test / test (ubuntu-latest) (push) Waiting to run
feat: fork Ignite CLI v29 as Mukan Ignite — remove cosmos-sdk restrictions
2026-05-11 03:31:37 +03:00

210 lines
4.4 KiB
Go

// this tool generates Ignite CLI docs to be placed in the docs/cli dir and deployed
// on docs.ignite.com
package main
import (
"bufio"
"bytes"
"context"
"fmt"
"io"
"log"
"os"
"path/filepath"
"sort"
"strings"
"github.com/spf13/cobra"
"github.com/spf13/cobra/doc"
ignitecmd "github.com/ignite/cli/v29/ignite/cmd"
pluginsconfig "github.com/ignite/cli/v29/ignite/config/plugins"
"github.com/ignite/cli/v29/ignite/pkg/env"
"github.com/ignite/cli/v29/ignite/services/plugin"
"github.com/ignite/cli/v29/ignite/templates/field/datatype"
)
const (
scaffoldTypeFooter = `
Field Usage:
- fieldName
- fieldName:fieldType
If no :fieldType, default (string) is used
`
scaffoldTypeHead = `# Scaffold Type
Ignites provides a set of scaffold types that can be used to generate code for your application.
These types are used in the ` + "`ignite scaffold`" + ` command.
## Available Scaffold Types
`
head = `---
description: Ignite CLI docs.
---
# CLI commands
Documentation for Ignite CLI.
`
outFlag = "out"
)
func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}
func run() error {
// We want to have documentation for commands that are implemented in plugins.
// To do that, we need to add the related plugins in the config.
// To avoid conflicts with user config, set an alternate config dir in tmp.
dir, err := os.MkdirTemp("", ".ignite")
if err != nil {
return err
}
defer os.RemoveAll(dir)
env.SetConfigDir(dir)
pluginDir, err := plugin.PluginsPath()
if err != nil {
return err
}
cfg, err := pluginsconfig.ParseDir(pluginDir)
if err != nil {
return err
}
if err := cfg.Save(); err != nil {
return err
}
cmd, cleanUp, err := ignitecmd.New(context.Background())
if err != nil {
return err
}
defer cleanUp()
cmd.Flags().String(outFlag, "output.md", ".md file path to place Ignite CLI docs inside")
if err := cmd.Flags().MarkHidden(outFlag); err != nil {
return err
}
// Run ExecuteC so cobra adds the completion command.
cmd, err = cmd.ExecuteC()
if err != nil {
return err
}
outPath, err := cmd.Flags().GetString(outFlag)
if err != nil {
return nil
}
return generateUsage(cmd, outPath)
}
func generateUsage(cmd *cobra.Command, outPath string) error {
if err := os.MkdirAll(filepath.Dir(outPath), 0o755); err != nil {
return err
}
f, err := os.OpenFile(outPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o644)
if err != nil {
return err
}
defer f.Close()
if _, err := fmt.Fprint(f, head); err != nil {
return err
}
if err := generateCmd(cmd, f); err != nil {
return err
}
return generateScaffoldTypes(f)
}
func generateScaffoldTypes(w io.Writer) error {
if _, err := fmt.Fprint(w, scaffoldTypeHead); err != nil {
return err
}
supported := datatype.SupportedTypes()
entries := make([][]string, 0, len(supported))
for name, usage := range supported {
entries = append(entries, []string{name, usage})
}
sort.Slice(entries, func(i, j int) bool {
return entries[i][0] < entries[j][0]
})
// Write table header
if _, err := fmt.Fprintf(w, "| Type | Usage |\n"); err != nil {
return err
}
if _, err := fmt.Fprintf(w, "| --- | --- |\n"); err != nil {
return err
}
// Write table rows
for _, entry := range entries {
if _, err := fmt.Fprintf(w, "| %s | %s |\n", entry[0], entry[1]); err != nil {
return err
}
}
if _, err := fmt.Fprint(w, scaffoldTypeFooter); err != nil {
return err
}
return nil
}
func generateCmd(cmd *cobra.Command, w io.Writer) error {
cmd.DisableAutoGenTag = true
b := &bytes.Buffer{}
if err := doc.GenMarkdownCustom(cmd, b, linkHandler); err != nil {
return err
}
// here we change sub titles to bold styling. Otherwise, these titles will get
// printed in the right menu of docs.ignite.com which is unpleasant because
// we only want to see a list of all available commands without the extra noise.
sc := bufio.NewScanner(b)
for sc.Scan() {
t := sc.Text()
if strings.HasPrefix(t, "###") {
t = strings.TrimPrefix(t, "### ")
t = fmt.Sprintf("**%s**", t)
}
if _, err := fmt.Fprintln(w, t); err != nil {
return err
}
}
for _, cmd := range cmd.Commands() {
if !cmd.IsAvailableCommand() || cmd.IsAdditionalHelpTopicCommand() {
continue
}
_, _ = io.WriteString(w, "\n")
if err := generateCmd(cmd, w); err != nil {
return err
}
}
return nil
}
func linkHandler(link string) string {
link = strings.ReplaceAll(link, "_", "-")
link = strings.TrimSuffix(link, ".md")
link = "#" + link
return link
}