Skip to content
Open
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ require (
github.com/pterm/pterm v0.12.81
github.com/segmentio/ksuid v1.0.4
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
github.com/zitadel/oidc/v2 v2.12.2
golang.org/x/mod v0.25.0
golang.org/x/oauth2 v0.30.0
Expand Down Expand Up @@ -61,7 +62,6 @@ require (
github.com/rivo/uniseg v0.4.7 // indirect
github.com/sergi/go-diff v1.3.1 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/testify v1.9.0 // indirect
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect
github.com/uptrace/bun v1.2.3 // indirect
Expand Down
131 changes: 131 additions & 0 deletions tools/commandusage/export.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package main

import (
"encoding/json"
"fmt"
"os"
"strings"

"github.com/formancehq/fctl/cmd"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)

var (
file = "inventory.json"
)

type Flag struct {
Name string `json:"name"`
Description string `json:"description"`
Deprecated string `json:"deprecated,omitempty"`
Usage string `json:"usage"`
DefaultValue string `json:"default_value,omitempty"`
Type string `json:"type,omitempty"`
}

type DocCommand struct {
Name string `json:"name"`
Usage string `json:"usage"`
Description string `json:"description"`
Deprecated string `json:"deprecated,omitempty"`
Aliases []string `json:"aliases,omitempty"`

Flags []Flag `json:"flags,omitempty"`
GlobalFlags []Flag `json:"global_flags,omitempty"`

SubCommands []DocCommand `json:"subcommands,omitempty"`
}

func flagSetToFlags(flagSet *pflag.FlagSet) []Flag {
flags := make([]Flag, 0)

flagSet.VisitAll(func(f *pflag.Flag) {
if f.Hidden {
return
}

userHomeDir, err := os.UserHomeDir()
if err != nil {
panic(err)
}
if strings.Contains(f.DefValue, userHomeDir) {
f.DefValue = strings.ReplaceAll(f.DefValue, userHomeDir, "~")
}

flags = append(flags, Flag{
Name: f.Name,
Description: f.Usage,
Deprecated: f.Deprecated,
DefaultValue: f.DefValue,
Usage: f.Usage,
Type: f.Value.Type(),
})
})

return flags
}

func cobraCommandAsDocCommand(parentCommandName string, command *cobra.Command) DocCommand {
return DocCommand{
Name: func() string {
if parentCommandName != "" {
return fmt.Sprintf("%s %s", parentCommandName, command.Name())
}
return command.Name()
}(),
Usage: command.Use,
Description: command.Short,
Deprecated: command.Deprecated,
Aliases: command.Aliases,
Flags: flagSetToFlags(command.Flags()),
GlobalFlags: flagSetToFlags(command.Root().PersistentFlags()),
}

}

func getFullCommandPath(cmd *cobra.Command) string {
if cmd == nil || cmd == cmd.Root() {
return ""
}
parent := getFullCommandPath(cmd.Parent())
if parent == "" {
return cmd.Name()
}
return parent + " " + cmd.Name()
}

func visitSubCommands(command *cobra.Command) []DocCommand {
parentName := getFullCommandPath(command.Parent())
docs := []DocCommand{cobraCommandAsDocCommand(parentName, command)}
for _, subCommand := range command.Commands() {
docs = append(docs, visitSubCommands(subCommand)...)
}
return docs
}

//go:generate rm -rf docs
//go:generate go run ./
Copy link
Contributor

Choose a reason for hiding this comment

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

why run the binary on generate?

func main() {
_, err := os.Stat(file)
if err == nil {
if err := os.Remove(file); err != nil {
panic(err)
}
}

commands := visitSubCommands(cmd.NewRootCommand())
file, err := os.OpenFile(file, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of remove the file with os.Remove then opening a new fil with os.OpenFile, you can use os.Create which truncates the file if it already exists.

if err != nil {
panic(err)
}
defer file.Close()

b, err := json.Marshal(commands)
if err != nil {
panic(err)
}
if _, err := file.Write(b); err != nil {
panic(err)
}
}
1 change: 1 addition & 0 deletions tools/commandusage/inventory.json

Large diffs are not rendered by default.