Skip to content

feat(docs) Add docs generation #5

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

Merged
merged 1 commit into from
Jun 16, 2022
Merged
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
18 changes: 16 additions & 2 deletions .github/workflows/releases.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Code checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Go
Expand All @@ -26,4 +26,18 @@ jobs:
version: v0.184.0
args: release
env:
GITHUB_TOKEN: ${{ secrets.GORELEASER_GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GORELEASER_GITHUB_TOKEN }}
- name: Docs checkout
uses: actions/checkout@v3
with:
repository: algolia/cli-docs
path: docs
fetch-depth: 0
token: ${{secrets.GORELEASER_GITHUB_TOKEN}}
- name: Update docs
env:
GIT_COMMITTER_NAME: algolia-ci
GIT_AUTHOR_NAME: algolia-ci
GIT_COMMITTER_EMAIL: [email protected]
GIT_AUTHOR_EMAIL: [email protected]
run: make docs-bump
17 changes: 16 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
.PHONY: test
test:
go test ./...
go test ./...

## Documentation related tasks

docs:
git clone https://github.com/algolia/cli-docs.git "$@"

.PHONY: docs-bump
docs-bump: docs
git -C docs pull
git -C docs rm 'algolia_*.md' 2>/dev/null || true
go run ./cmd/docs --doc-path docs
rm -f docs/*.bak
git -C docs add 'algolia*.md'
git -C docs commit -m 'update docs' || true
git -C docs push
64 changes: 64 additions & 0 deletions cmd/docs/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package main

import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/spf13/pflag"

"github.com/algolia/cli/internal/docs"
"github.com/algolia/cli/pkg/cmd/root"
"github.com/algolia/cli/pkg/cmdutil"
"github.com/algolia/cli/pkg/config"
"github.com/algolia/cli/pkg/iostreams"
)

func main() {
if err := run(os.Args); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}

func run(args []string) error {
flags := pflag.NewFlagSet("", pflag.ContinueOnError)
dir := flags.StringP("doc-path", "", "", "Path directory where you want generate doc files")
help := flags.BoolP("help", "h", false, "Help about any command")

if err := flags.Parse(args); err != nil {
return err
}

if *help {
fmt.Fprintf(os.Stderr, "Usage of %s:\n\n%s", filepath.Base(args[0]), flags.FlagUsages())
return nil
}

if *dir == "" {
return fmt.Errorf("error: --doc-path not set")
}

ios, _, _, _ := iostreams.Test()
rootCmd := root.NewRootCmd(&cmdutil.Factory{
IOStreams: ios,
Config: &config.Config{},
})
rootCmd.InitDefaultHelpCmd()

if err := os.MkdirAll(*dir, 0755); err != nil {
return err
}

if err := docs.GenMarkdownTree(rootCmd, *dir, linkHandler); err != nil {
return err
}

return nil

}

func linkHandler(name string) string {
return fmt.Sprintf("./%s", strings.TrimSuffix(name, ".md"))
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ require (
github.com/muesli/termenv v0.9.0
github.com/sirupsen/logrus v1.8.1
github.com/spf13/cobra v1.2.1
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.9.0
github.com/stretchr/testify v1.7.0
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
Expand Down
197 changes: 197 additions & 0 deletions internal/docs/markdown.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
package docs

import (
"fmt"
"html/template"
"io"
"os"
"path/filepath"
"strings"

"github.com/spf13/cobra"
"github.com/spf13/pflag"
)

func printOptions(w io.Writer, cmd *cobra.Command) error {
flags := cmd.NonInheritedFlags()
flags.SetOutput(w)
if flags.HasAvailableFlags() {
fmt.Fprint(w, "### Options\n\n")
if err := printFlagsHTML(w, flags); err != nil {
return err
}
fmt.Fprint(w, "\n\n")
}

parentFlags := cmd.InheritedFlags()
parentFlags.SetOutput(w)
if hasNonHelpFlags(parentFlags) {
fmt.Fprint(w, "### Options inherited from parent commands\n\n")
if err := printFlagsHTML(w, parentFlags); err != nil {
return err
}
fmt.Fprint(w, "\n\n")
}
return nil
}

func hasNonHelpFlags(fs *pflag.FlagSet) (found bool) {
fs.VisitAll(func(f *pflag.Flag) {
if !f.Hidden && f.Name != "help" {
found = true
}
})
return
}

type flagView struct {
Name string
Varname string
Shorthand string
Usage string
}

var flagsTemplate = `
<dl class="flags">{{ range . }}
<dt>{{ if .Shorthand }}<code>-{{.Shorthand}}</code>, {{ end -}}
<code>--{{.Name}}{{ if .Varname }} &lt;{{.Varname}}&gt;{{ end }}</code></dt>
<dd>{{.Usage}}</dd>
{{ end }}</dl>
`

var tpl = template.Must(template.New("flags").Parse(flagsTemplate))

func printFlagsHTML(w io.Writer, fs *pflag.FlagSet) error {
var flags []flagView
fs.VisitAll(func(f *pflag.Flag) {
if f.Hidden || f.Name == "help" {
return
}
varname, usage := pflag.UnquoteUsage(f)
flags = append(flags, flagView{
Name: f.Name,
Varname: varname,
Shorthand: f.Shorthand,
Usage: usage,
})
})
return tpl.Execute(w, flags)
}

type CmdView struct {
Title string
Parent string
HasChildren bool
}

var headerTemplate = `---
layout: default
title: {{.Title}}{{if .HasChildren}}
has_children: true
{{end}}
{{if .Parent}}parent: {{.Parent}}{{end}}
---
`

var headerTpl = template.Must(template.New("header").Parse(headerTemplate))

func printHeaderMarkdown(w io.Writer, cmd *cobra.Command) error {
// Do no put everything under the "algolia" command
if cmd.Name() == "algolia" {
return headerTpl.Execute(w, &CmdView{
Title: cmd.CommandPath(),
Parent: "",
HasChildren: false,
})
}

var parent string
if cmd.HasParent() {
parent = cmd.Parent().CommandPath()
if parent == "algolia" {
parent = ""
}
}

return headerTpl.Execute(w, &CmdView{
Title: cmd.CommandPath(),
Parent: parent,
HasChildren: cmd.HasSubCommands(),
})
}

func GenMarkdown(cmd *cobra.Command, w io.Writer, linkHandler func(string) string) error {
// Markdown header (with parent page if applicable)
if err := printHeaderMarkdown(w, cmd); err != nil {
return err
}

fmt.Fprintf(w, "## %s\n\n", cmd.CommandPath())

hasLong := cmd.Long != ""
if !hasLong {
fmt.Fprintf(w, "%s\n\n", cmd.Short)
}
if cmd.Runnable() {
fmt.Fprintf(w, "```\n%s\n```\n\n", cmd.UseLine())
}
if hasLong {
fmt.Fprintf(w, "%s\n\n", cmd.Long)
}

if cmd.Commands() != nil && len(cmd.Commands()) > 0 {
fmt.Fprint(w, "### Commands\n\n")
for _, subcmd := range cmd.Commands() {
if !subcmd.IsAvailableCommand() {
continue
}
fmt.Fprintf(w, "* [%s](%s)\n", subcmd.CommandPath(), linkHandler(cmdDocsPath(subcmd)))
}
}

if err := printOptions(w, cmd); err != nil {
return err
}

if len(cmd.Example) > 0 {
fmt.Fprint(w, "### Examples\n\n{% highlight bash %}{% raw %}\n")
fmt.Fprint(w, cmd.Example)
fmt.Fprint(w, "{% endraw %}{% endhighlight %}\n\n")
}

if cmd.HasParent() {
p := cmd.Parent()
fmt.Fprint(w, "### See also\n\n")
fmt.Fprintf(w, "* [%s](%s)\n", p.CommandPath(), linkHandler(cmdDocsPath(p)))
}

return nil
}

func GenMarkdownTree(cmd *cobra.Command, dir string, linkHandler func(string) string) error {
for _, c := range cmd.Commands() {
if c.Hidden {
continue
}

if err := GenMarkdownTree(c, dir, linkHandler); err != nil {
return err
}
}

filename := filepath.Join(dir, cmdDocsPath(cmd))
f, err := os.Create(filename)
if err != nil {
return err
}
defer f.Close()

if err := GenMarkdown(cmd, f, linkHandler); err != nil {
return err
}
return nil
}

func cmdDocsPath(c *cobra.Command) string {
return strings.ReplaceAll(c.CommandPath(), " ", "_") + ".md"
}
12 changes: 6 additions & 6 deletions pkg/cmd/open/open.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,16 +84,16 @@ func NewOpenCmd(f *cmdutil.Factory) *cobra.Command {
Long: `The open command provices shortcuts to quickly let you open pages to Algolia within your browser. 'algolia open --list' for a list of supported shortcuts.`,
Example: heredoc.Doc(`
# Display the list of supported shortcuts
algolia open --list
$ algolia open --list

# Open the dashboard for the current application
algolia open dashboard

$ algolia open dashboard
# Open the API reference
algolia open api

$ algolia open api
# Open the documentation
algolia open docs
$ algolia open docs
`),
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) > 0 {
Expand Down