From aab474aecdaef9dfbf6268c18e9befdcb6b8a416 Mon Sep 17 00:00:00 2001 From: Sergey Rubanov Date: Wed, 10 Jul 2024 15:49:45 +0200 Subject: [PATCH 1/5] Create CLI docs --- .gitignore | 2 ++ Makefile | 4 +++ cli/generate_docs.go | 49 ++++++++++++++++++++++++++++++++++++ cli/generate_docs_default.go | 11 ++++++++ cli/main.go | 18 ++++++++++++- cli/run.go | 10 +++++++- go.mod | 2 ++ go.sum | 2 ++ 8 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 cli/generate_docs.go create mode 100644 cli/generate_docs_default.go diff --git a/.gitignore b/.gitignore index 2703e13..eed529f 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,5 @@ goreleaser/ .netrc .dispatch + +docs/ diff --git a/Makefile b/Makefile index 0364577..d8b7d9e 100644 --- a/Makefile +++ b/Makefile @@ -39,3 +39,7 @@ push: image update: for ref in $$(yq -r '.deps[] | .remote + "/gen/go/" + .owner + "/" + .repository + "/protocolbuffers/go@" + .commit' proto/buf.lock); do go get $$ref; done go mod tidy + +dispatch-docs: + ${GO} build -tags docs -o ${DISPATCH} . + ${DISPATCH} diff --git a/cli/generate_docs.go b/cli/generate_docs.go new file mode 100644 index 0000000..04c7430 --- /dev/null +++ b/cli/generate_docs.go @@ -0,0 +1,49 @@ +//go:build docs + +package cli + +import ( + "os" + "path" + "strings" + + "github.com/spf13/cobra" + "github.com/spf13/cobra/doc" +) + +var isDocsBuild = true + +func generateDocs(cmd *cobra.Command, filename string, title string) { + cmd.DisableAutoGenTag = true + + // create docs directory + _ = os.Mkdir("./docs", 0755) + + err := doc.GenMarkdownTreeCustom(cmd, "./docs", + func(_ string) string { + return `--- +title: ` + title + ` +--- + +` + }, + func(name string) string { + // err := doc.GenMarkdownCustom(cmd, out, func(name string) string { + base := strings.TrimSuffix(name, path.Ext(name)) + return "/cli/" + strings.ToLower(base) + "/" + }) + if err != nil { + panic(err) + } + + // if command has subcommands, generate markdown for each subcommand + if cmd.HasSubCommands() { + for _, c := range cmd.Commands() { + // if c.Use starts with "help", skip it + if strings.HasPrefix(c.Use, "help") { + continue + } + generateDocs(c, filename, title+" "+c.Use) + } + } +} diff --git a/cli/generate_docs_default.go b/cli/generate_docs_default.go new file mode 100644 index 0000000..851f719 --- /dev/null +++ b/cli/generate_docs_default.go @@ -0,0 +1,11 @@ +//go:build !docs + +package cli + +import "github.com/spf13/cobra" + +var isDocsBuild = false + +func generateDocs(_ *cobra.Command, _ string, _ string) { + // do nothing if the build tag "docs" is not set +} diff --git a/cli/main.go b/cli/main.go index 0d807d0..ccb4d66 100644 --- a/cli/main.go +++ b/cli/main.go @@ -17,11 +17,19 @@ Support: support@dispatch.run ` ) +var mainCommandText string + func createMainCommand() *cobra.Command { + if isDocsBuild { + mainCommandText = "This is the main command for Dispatch CLI. Add a subcommand to make it useful." + } else { + mainCommandText = DispatchCmdLong + } cmd := &cobra.Command{ Version: version(), Use: "dispatch", - Long: DispatchCmdLong, + Long: mainCommandText, + Short: "Main command for Dispatch CLI", PersistentPreRunE: func(cmd *cobra.Command, args []string) error { return loadEnvFromFile(DotEnvFilePath) }, @@ -50,6 +58,14 @@ func createMainCommand() *cobra.Command { cmd.AddCommand(runCommand()) cmd.AddCommand(versionCommand()) + // Generate markdown documentation + generateDocs(loginCommand(), "dispatch_login.md", "dispatch login") + generateDocs(initCommand(), "dispatch_init.md", "dispatch init") + generateDocs(switchCommand(DispatchConfigPath), "dispatch_switch.md", "dispatch switch") + generateDocs(verificationCommand(), "dispatch_verification.md", "dispatch verification") + generateDocs(runCommand(), "dispatch_run.md", "dispatch run") + generateDocs(versionCommand(), "dispatch_version.md", "dispatch version") + return cmd } diff --git a/cli/run.go b/cli/run.go index 7a809bd..9ae1eb9 100644 --- a/cli/run.go +++ b/cli/run.go @@ -56,7 +56,15 @@ var ( logPrefixSeparatorStyle = lipgloss.NewStyle().Foreground(grayColor) ) +var runExampleText string + func runCommand() *cobra.Command { + if isDocsBuild { + runExampleText = "```\ndispatch run [options] -- \n```" + } else { + runExampleText = " dispatch run [options] -- " + } + cmd := &cobra.Command{ Use: "run", Short: "Run a Dispatch application", @@ -65,7 +73,7 @@ func runCommand() *cobra.Command { The command to start the local application endpoint should be specified after the run command and its options: - dispatch run [options] -- +`+runExampleText+` Dispatch spawns the local application endpoint and then dispatches function calls to it continuously. diff --git a/go.mod b/go.mod index 0c93a43..c23ccbd 100644 --- a/go.mod +++ b/go.mod @@ -22,6 +22,7 @@ require ( github.com/atotto/clipboard v0.1.4 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect @@ -33,6 +34,7 @@ require ( github.com/muesli/termenv v0.15.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rivo/uniseg v0.4.6 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.19.0 // indirect diff --git a/go.sum b/go.sum index 82b63e9..72b86de 100644 --- a/go.sum +++ b/go.sum @@ -14,6 +14,7 @@ github.com/charmbracelet/lipgloss v0.9.1 h1:PNyd3jvaJbg4jRHKWXnCj1akQm4rh8dbEzN1 github.com/charmbracelet/lipgloss v0.9.1/go.mod h1:1mPmG4cxScwUQALAAnacHaigiiHB9Pmr+v1VEawJl6I= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= +github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -51,6 +52,7 @@ github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.6 h1:Sovz9sDSwbOz9tgUy8JpT+KgCkPYJEN/oYzlJiYTNLg= github.com/rivo/uniseg v0.4.6/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= From e47c0f67c91e57ec0647788f046d05269447db0f Mon Sep 17 00:00:00 2001 From: Sergey Rubanov Date: Thu, 11 Jul 2024 11:35:51 +0200 Subject: [PATCH 2/5] fix command names --- cli/generate_docs.go | 51 +++++++++++++++++++++++++----------- cli/generate_docs_default.go | 2 +- cli/main.go | 7 +---- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/cli/generate_docs.go b/cli/generate_docs.go index 04c7430..4450247 100644 --- a/cli/generate_docs.go +++ b/cli/generate_docs.go @@ -3,6 +3,7 @@ package cli import ( + "bytes" "os" "path" "strings" @@ -13,37 +14,55 @@ import ( var isDocsBuild = true -func generateDocs(cmd *cobra.Command, filename string, title string) { +func generateDocs(cmd *cobra.Command, title string) { cmd.DisableAutoGenTag = true // create docs directory _ = os.Mkdir("./docs", 0755) - err := doc.GenMarkdownTreeCustom(cmd, "./docs", - func(_ string) string { - return `--- -title: ` + title + ` ---- - -` - }, - func(name string) string { - // err := doc.GenMarkdownCustom(cmd, out, func(name string) string { - base := strings.TrimSuffix(name, path.Ext(name)) - return "/cli/" + strings.ToLower(base) + "/" - }) + out := new(bytes.Buffer) + + err := doc.GenMarkdownCustom(cmd, out, func(name string) string { + // err := doc.GenMarkdownCustom(cmd, out, func(name string) string { + base := strings.TrimSuffix(name, path.Ext(name)) + return "/cli/" + strings.ToLower(base) + "/" + }) if err != nil { panic(err) } + // Define the text to be replaced and the replacement text + oldText := []byte("## " + title) + newText := []byte("---\ntitle: " + title + "\n---") + + // Perform the replacement on the buffer's content + updatedContent := bytes.Replace(out.Bytes(), oldText, newText, 1) + + // Reset the buffer and write the updated content back to it + out.Reset() + out.Write(updatedContent) + + // write markdown to file + file, err := os.Create("./docs/" + strings.ReplaceAll(title, " ", "_") + ".md") + if err != nil { + panic(err) + } + + _, err = file.Write(out.Bytes()) + if err != nil { + panic(err) + } + + defer file.Close() + // if command has subcommands, generate markdown for each subcommand if cmd.HasSubCommands() { for _, c := range cmd.Commands() { // if c.Use starts with "help", skip it - if strings.HasPrefix(c.Use, "help") { + if c.Name() == "help" { continue } - generateDocs(c, filename, title+" "+c.Use) + generateDocs(c, title+" "+c.Name()) } } } diff --git a/cli/generate_docs_default.go b/cli/generate_docs_default.go index 851f719..d8b0722 100644 --- a/cli/generate_docs_default.go +++ b/cli/generate_docs_default.go @@ -6,6 +6,6 @@ import "github.com/spf13/cobra" var isDocsBuild = false -func generateDocs(_ *cobra.Command, _ string, _ string) { +func generateDocs(_ *cobra.Command, _ string) { // do nothing if the build tag "docs" is not set } diff --git a/cli/main.go b/cli/main.go index ccb4d66..2d1e7ef 100644 --- a/cli/main.go +++ b/cli/main.go @@ -59,12 +59,7 @@ func createMainCommand() *cobra.Command { cmd.AddCommand(versionCommand()) // Generate markdown documentation - generateDocs(loginCommand(), "dispatch_login.md", "dispatch login") - generateDocs(initCommand(), "dispatch_init.md", "dispatch init") - generateDocs(switchCommand(DispatchConfigPath), "dispatch_switch.md", "dispatch switch") - generateDocs(verificationCommand(), "dispatch_verification.md", "dispatch verification") - generateDocs(runCommand(), "dispatch_run.md", "dispatch run") - generateDocs(versionCommand(), "dispatch_version.md", "dispatch version") + generateDocs(cmd, "dispatch") return cmd } From 4945a26ac4da14779150d2217f3a7917690b6afd Mon Sep 17 00:00:00 2001 From: Sergey Rubanov Date: Mon, 15 Jul 2024 18:25:58 +0200 Subject: [PATCH 3/5] Release CLI build with docs support --- .goreleaser.yml | 25 ++++++++++++++++++++++++- go.mod | 2 +- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 7842170..ddad54a 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,5 +1,6 @@ project_name: dispatch dist: ./goreleaser/dist +version: 2 before: hooks: @@ -9,7 +10,8 @@ gomod: proxy: true builds: - - main: . + - id: dispatch + main: . binary: dispatch mod_timestamp: "{{ .CommitTimestamp }}" @@ -22,6 +24,25 @@ builds: - linux - windows + - id: dispatch-docs + main: . + binary: dispatch-docs + mod_timestamp: "{{ .CommitTimestamp }}" + tags: docs + + goarch: + - amd64 + + goos: + - linux + +archives: + - id: dispatch + builds: [dispatch] + - id: dispatch-docs + builds: [dispatch-docs] + name_template: "{{ .ProjectName }}_docs_{{ .Version }}_{{ .Os }}_{{ .Arch }}" + release: github: owner: dispatchrun @@ -34,6 +55,8 @@ changelog: brews: - name: dispatch + ids: + - dispatch url_template: "https://github.com/dispatchrun/dispatch/releases/download/{{ .Tag }}/{{ .ArtifactName }}" commit_author: diff --git a/go.mod b/go.mod index c23ccbd..c334c0c 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/charmbracelet/lipgloss v0.9.1 github.com/joho/godotenv v1.5.1 github.com/muesli/reflow v0.3.0 + github.com/muesli/termenv v0.15.2 github.com/nlpodyssey/gopickle v0.3.0 github.com/pelletier/go-toml/v2 v2.2.0 github.com/spf13/cobra v1.8.0 @@ -31,7 +32,6 @@ require ( github.com/mattn/go-runewidth v0.0.15 // indirect github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b // indirect github.com/muesli/cancelreader v0.2.2 // indirect - github.com/muesli/termenv v0.15.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rivo/uniseg v0.4.6 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect From bc398aeea56c91eae164c7e588850991f16a2159 Mon Sep 17 00:00:00 2001 From: Sergey Rubanov Date: Mon, 15 Jul 2024 23:35:58 +0200 Subject: [PATCH 4/5] cleanup --- cli/generate_docs.go | 4 +++- cli/generate_docs_default.go | 11 ++++++++++- cli/main.go | 20 +------------------- cli/run.go | 10 +--------- 4 files changed, 15 insertions(+), 30 deletions(-) diff --git a/cli/generate_docs.go b/cli/generate_docs.go index 4450247..ca4a672 100644 --- a/cli/generate_docs.go +++ b/cli/generate_docs.go @@ -12,7 +12,9 @@ import ( "github.com/spf13/cobra/doc" ) -var isDocsBuild = true +const DispatchCmdLong = "This is the main command for Dispatch CLI. Add a subcommand to make it useful." + +const RunExampleText = "```\ndispatch run [options] -- \n```" func generateDocs(cmd *cobra.Command, title string) { cmd.DisableAutoGenTag = true diff --git a/cli/generate_docs_default.go b/cli/generate_docs_default.go index d8b0722..3fe6860 100644 --- a/cli/generate_docs_default.go +++ b/cli/generate_docs_default.go @@ -4,7 +4,16 @@ package cli import "github.com/spf13/cobra" -var isDocsBuild = false +const DispatchCmdLong = `Welcome to Dispatch! + +To get started, use the login command to authenticate with Dispatch or create an account. + +Documentation: https://docs.dispatch.run +Discord: https://dispatch.run/discord +Support: support@dispatch.run +` + +const RunExampleText = " dispatch run [options] -- " func generateDocs(_ *cobra.Command, _ string) { // do nothing if the build tag "docs" is not set diff --git a/cli/main.go b/cli/main.go index 2d1e7ef..5bcdfbe 100644 --- a/cli/main.go +++ b/cli/main.go @@ -6,29 +6,11 @@ import ( "github.com/spf13/cobra" ) -var ( - DispatchCmdLong = `Welcome to Dispatch! - -To get started, use the login command to authenticate with Dispatch or create an account. - -Documentation: https://docs.dispatch.run -Discord: https://dispatch.run/discord -Support: support@dispatch.run -` -) - -var mainCommandText string - func createMainCommand() *cobra.Command { - if isDocsBuild { - mainCommandText = "This is the main command for Dispatch CLI. Add a subcommand to make it useful." - } else { - mainCommandText = DispatchCmdLong - } cmd := &cobra.Command{ Version: version(), Use: "dispatch", - Long: mainCommandText, + Long: DispatchCmdLong, Short: "Main command for Dispatch CLI", PersistentPreRunE: func(cmd *cobra.Command, args []string) error { return loadEnvFromFile(DotEnvFilePath) diff --git a/cli/run.go b/cli/run.go index 9ae1eb9..0fc8544 100644 --- a/cli/run.go +++ b/cli/run.go @@ -56,15 +56,7 @@ var ( logPrefixSeparatorStyle = lipgloss.NewStyle().Foreground(grayColor) ) -var runExampleText string - func runCommand() *cobra.Command { - if isDocsBuild { - runExampleText = "```\ndispatch run [options] -- \n```" - } else { - runExampleText = " dispatch run [options] -- " - } - cmd := &cobra.Command{ Use: "run", Short: "Run a Dispatch application", @@ -73,7 +65,7 @@ func runCommand() *cobra.Command { The command to start the local application endpoint should be specified after the run command and its options: -`+runExampleText+` +`+RunExampleText+` Dispatch spawns the local application endpoint and then dispatches function calls to it continuously. From 1cb35782549649a4b7c4986f65c530d4ca6e716e Mon Sep 17 00:00:00 2001 From: Sergey Rubanov Date: Tue, 16 Jul 2024 17:52:45 +0200 Subject: [PATCH 5/5] publish as zip for windows --- .goreleaser.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.goreleaser.yml b/.goreleaser.yml index ddad54a..40a0f87 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -39,6 +39,10 @@ builds: archives: - id: dispatch builds: [dispatch] + format_overrides: + - goos: windows + format: zip + - id: dispatch-docs builds: [dispatch-docs] name_template: "{{ .ProjectName }}_docs_{{ .Version }}_{{ .Os }}_{{ .Arch }}"