From 3a826881854c503d823f4d9c66b5f459cbfcde19 Mon Sep 17 00:00:00 2001 From: Dawid Ciepiela <71898979+sarumaj@users.noreply.github.com> Date: Fri, 26 Jan 2024 14:23:47 +0100 Subject: [PATCH] doc (#83) * add documentation parts * add badge for go reference --------- Co-authored-by: Dawid Ciepiela <71898979-sarumaj@users.noreply.github.com> --- README.md | 55 +++++++++++++------------ cmd/gh-gr/main.go | 33 +++++++++++++++ pkg/commands/command_cleanup.go | 1 + pkg/commands/command_export.go | 14 ++++--- pkg/commands/command_import.go | 14 ++++--- pkg/commands/command_init.go | 1 + pkg/commands/command_pull.go | 1 + pkg/commands/command_push.go | 1 + pkg/commands/command_remove.go | 14 ++++--- pkg/commands/command_root.go | 16 ++++--- pkg/commands/command_status.go | 1 + pkg/commands/command_update.go | 1 + pkg/commands/command_version.go | 23 ++++++----- pkg/commands/command_view.go | 16 ++++--- pkg/commands/package_doc.go | 20 +++++++++ pkg/configfile/config_encoders.go | 8 +++- pkg/configfile/package_doc.go | 7 ++++ pkg/restclient/package_doc.go | 5 +++ pkg/restclient/resources/package_doc.go | 6 +++ pkg/util/colored_yaml_encoder.go | 12 +++--- pkg/util/package_doc.go | 5 +++ 21 files changed, 182 insertions(+), 72 deletions(-) create mode 100644 pkg/commands/package_doc.go create mode 100644 pkg/configfile/package_doc.go create mode 100644 pkg/restclient/package_doc.go create mode 100644 pkg/restclient/resources/package_doc.go create mode 100644 pkg/util/package_doc.go diff --git a/README.md b/README.md index 1918806..0398842 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![Go Report Card](https://goreportcard.com/badge/github.com/sarumaj/gh-gr)](https://goreportcard.com/report/github.com/sarumaj/gh-gr) [![Maintainability](https://img.shields.io/codeclimate/maintainability-percentage/sarumaj/gh-gr.svg)](https://codeclimate.com/github/sarumaj/gh-gr/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/0c9cdd86241d58f97085/test_coverage)](https://codeclimate.com/github/sarumaj/gh-gr/test_coverage) +[![Go Reference](https://pkg.go.dev/badge/github.com/sarumaj/gh-gr.svg)](https://pkg.go.dev/github.com/sarumaj/gh-gr) --- @@ -29,33 +30,33 @@ $ gh extension install https://github.com/sarumaj/gh-gr ```console $ gh gr --help ->> gr is a gh cli extension allowing management of multiple repositories at once ->> ->> Usage: ->> gr [flags] ->> gr [command] ->> ->> Available Commands: ->> cleanup Clean up untracked local repositories ->> completion Generate the autocompletion script for the specified shell ->> export Export current configuration to stdout ->> help Help about any command ->> import Import configuration from stdin or a file ->> init Initialize repository mirror ->> pull Pull all repositories ->> push Push all repositories ->> remove Remove current configuration ->> status Show status for all repositories ->> update Update configuration ->> version Display version information ->> view Display current configuration ->> ->> Flags: ->> -c, --concurrency uint Concurrency for concurrent jobs (default 12) ->> -h, --help help for gr ->> -t, --timeout duration Set timeout for long running jobs (default 10m0s) ->> ->> Use "gr [command] --help" for more information about a command. +> gr is a gh cli extension allowing management of multiple repositories at once +> +> Usage: +> gr [flags] +> gr [command] +> +> Available Commands: +> cleanup Clean up untracked local repositories +> completion Generate the autocompletion script for the specified shell +> export Export current configuration to stdout +> help Help about any command +> import Import configuration from stdin or a file +> init Initialize repository mirror +> pull Pull all repositories +> push Push all repositories +> remove Remove current configuration +> status Show status for all repositories +> update Update configuration +> version Display version information +> view Display current configuration +> +> Flags: +> -c, --concurrency uint Concurrency for concurrent jobs (default 12) +> -h, --help help for gr +> -t, --timeout duration Set timeout for long running jobs (default 10m0s) +> +> Use "gr [command] --help" for more information about a command. ``` First, create the configuration: diff --git a/cmd/gh-gr/main.go b/cmd/gh-gr/main.go index b4e7dd3..9154d1c 100644 --- a/cmd/gh-gr/main.go +++ b/cmd/gh-gr/main.go @@ -1,3 +1,36 @@ +/* + gh-gr is a CLI tool to manage GitHub repositories. + The tool is designed to work with multiple GitHub accounts and organizations. + It utilizes the GitHub API to retrieve the list of repositories and their metadata. + Futhermore, it plugs into the GitHub CLI to provide a seamless experience. + + Usage: + gr [flags] + gr [command] + + Available Commands: + cleanup Clean up untracked local repositories + completion Generate the autocompletion script for the specified shell + export Export current configuration to stdout + help Help about any command + import Import configuration from stdin or a file + init Initialize repository mirror + pull Pull all repositories + push Push all repositories + remove Remove current configuration + status Show status for all repositories + update Update configuration + version Display version information + view Display current configuration + + Flags: + -c, --concurrency uint Concurrency for concurrent jobs (default 12) + -h, --help help for gr + -t, --timeout duration Set timeout for long running jobs (default 10m0s) + + Use "gr [command] --help" for more information about a command. +*/ + package main import ( diff --git a/pkg/commands/command_cleanup.go b/pkg/commands/command_cleanup.go index 6051488..bc91cd4 100644 --- a/pkg/commands/command_cleanup.go +++ b/pkg/commands/command_cleanup.go @@ -7,6 +7,7 @@ import ( cobra "github.com/spf13/cobra" ) +// cleanupCmd represents the cleanup command var cleanupCmd = &cobra.Command{ Use: "cleanup", Aliases: []string{"clean", "cl"}, diff --git a/pkg/commands/command_export.go b/pkg/commands/command_export.go index 030a207..7425e70 100644 --- a/pkg/commands/command_export.go +++ b/pkg/commands/command_export.go @@ -10,9 +10,13 @@ import ( cobra "github.com/spf13/cobra" ) -var exportCmd = func() *cobra.Command { - var formatOption string +// exportFlags contains flags for import command +var exportFlags struct { + formatOption string +} +// exportCmd represents the export command +var exportCmd = func() *cobra.Command { exportCmd := &cobra.Command{ Use: "export", Short: "Export current configuration to stdout", @@ -28,14 +32,14 @@ var exportCmd = func() *cobra.Command { logger := loggerEntry.WithField("command", "export") conf := configfile.Load() - logger.Debugf("Export format: %s", formatOption) - conf.Display(formatOption, true) + logger.Debugf("Export format: %s", exportFlags.formatOption) + conf.Display(exportFlags.formatOption, true) }, } flags := exportCmd.Flags() supportedFormats := strings.Join(configfile.GetListOfSupportedFormats(true), ", ") - flags.StringVarP(&formatOption, "format", "f", "yaml", fmt.Sprintf("Change output format, supported formats: [%s]", supportedFormats)) + flags.StringVarP(&exportFlags.formatOption, "format", "f", "yaml", fmt.Sprintf("Change output format, supported formats: [%s]", supportedFormats)) return exportCmd }() diff --git a/pkg/commands/command_import.go b/pkg/commands/command_import.go index 5c4251f..548d86d 100644 --- a/pkg/commands/command_import.go +++ b/pkg/commands/command_import.go @@ -8,9 +8,13 @@ import ( cobra "github.com/spf13/cobra" ) -var importCmd = func() *cobra.Command { - var formatOption string +// importFlags contains flags for import command +var importFlags struct { + formatOption string +} +// importCmd represents the import command +var importCmd = func() *cobra.Command { importCmd := &cobra.Command{ Use: "import", Short: "Import configuration from stdin or a file", @@ -21,9 +25,9 @@ var importCmd = func() *cobra.Command { Example: "cat export.yaml | gh gr import --format yaml", Run: func(*cobra.Command, []string) { logger := loggerEntry.WithField("command", "import") - logger.Debugf("Import format: %s", formatOption) + logger.Debugf("Import format: %s", importFlags.formatOption) - configfile.Import(formatOption) + configfile.Import(importFlags.formatOption) }, PostRun: func(*cobra.Command, []string) { updateConfigFlags() @@ -32,7 +36,7 @@ var importCmd = func() *cobra.Command { flags := importCmd.Flags() supportedFormats := strings.Join(configfile.GetListOfSupportedFormats(true), ", ") - flags.StringVarP(&formatOption, "format", "f", "yaml", fmt.Sprintf("Change input format, supported formats: [%s]", supportedFormats)) + flags.StringVarP(&importFlags.formatOption, "format", "f", "yaml", fmt.Sprintf("Change input format, supported formats: [%s]", supportedFormats)) return importCmd }() diff --git a/pkg/commands/command_init.go b/pkg/commands/command_init.go index 97db2d8..168f825 100644 --- a/pkg/commands/command_init.go +++ b/pkg/commands/command_init.go @@ -4,6 +4,7 @@ import ( cobra "github.com/spf13/cobra" ) +// initCmd represents the init command var initCmd = func() *cobra.Command { initCmd := &cobra.Command{ Use: "init", diff --git a/pkg/commands/command_pull.go b/pkg/commands/command_pull.go index a95b0c9..974b49f 100644 --- a/pkg/commands/command_pull.go +++ b/pkg/commands/command_pull.go @@ -12,6 +12,7 @@ import ( pool "gopkg.in/go-playground/pool.v3" ) +// pullCmd represents the pull command var pullCmd = &cobra.Command{ Use: "pull", Short: "Pull all repositories", diff --git a/pkg/commands/command_push.go b/pkg/commands/command_push.go index 80cbd6d..a1e6f4f 100644 --- a/pkg/commands/command_push.go +++ b/pkg/commands/command_push.go @@ -12,6 +12,7 @@ import ( pool "gopkg.in/go-playground/pool.v3" ) +// pullCmd represents the pull command var pushCmd = &cobra.Command{ Use: "push", Short: "Push all repositories", diff --git a/pkg/commands/command_remove.go b/pkg/commands/command_remove.go index 15194c3..f40f9e7 100644 --- a/pkg/commands/command_remove.go +++ b/pkg/commands/command_remove.go @@ -7,9 +7,13 @@ import ( cobra "github.com/spf13/cobra" ) -var removeCmd = func() *cobra.Command { - var purge bool +// removeFlags represents the flags for remove command +var removeFlags struct { + purge bool +} +// removeCmd represents the remove command +var removeCmd = func() *cobra.Command { removeCmd := &cobra.Command{ Use: "remove", Aliases: []string{"reset", "rm", "delete", "del"}, @@ -26,13 +30,13 @@ var removeCmd = func() *cobra.Command { logger := loggerEntry.WithField("command", "remove") conf := configfile.Load() - logger.Debugf("Removing config, purge: %t", purge) - conf.Remove(purge) + logger.Debugf("Removing config, purge: %t", removeFlags.purge) + conf.Remove(removeFlags.purge) }, } flags := removeCmd.Flags() - flags.BoolVar(&purge, "purge", false, "DANGER!!! Purge directory with local repositories") + flags.BoolVar(&removeFlags.purge, "purge", false, "DANGER!!! Purge directory with local repositories") return removeCmd }() diff --git a/pkg/commands/command_root.go b/pkg/commands/command_root.go index 4ab0661..685a52c 100644 --- a/pkg/commands/command_root.go +++ b/pkg/commands/command_root.go @@ -10,9 +10,13 @@ import ( cobra "github.com/spf13/cobra" ) +// configFlags is a global variable holding configuration flags var configFlags = &configfile.Configuration{} + +// loggerEntry is a global variable holding logger entry at package level var loggerEntry = util.Logger.WithFields(logrus.Fields{"mod": "commands"}) +// rootCmd represents the base command when called without any subcommands var rootCmd = func() *cobra.Command { cmd := &cobra.Command{ Use: "gr", @@ -26,13 +30,15 @@ var rootCmd = func() *cobra.Command { configFlags = configfile.Load() } + logger := util.Logger if util.GetenvBool(util.Verbose) { - util.Logger.SetLevel(logrus.DebugLevel) + logger.SetLevel(logrus.DebugLevel) } - util.Logger.Debug("Running in verbose mode") + logger.Debugf("Version: %s, build date: %s, executable path: %s", versionFlags.internalVersion, versionFlags.internalBuildDate, util.GetExecutablePath()) + logger.Debug("Running in verbose mode") }, - Version: internalVersion, + Version: versionFlags.internalVersion, } flags := cmd.PersistentFlags() @@ -46,10 +52,8 @@ var rootCmd = func() *cobra.Command { // Execute executes the root command. func Execute(version, buildDate string) { - internalVersion, internalBuildDate = version, buildDate - + versionFlags.internalVersion, versionFlags.internalBuildDate = version, buildDate logger := util.Logger - logger.Debugf("Version: %s, build date: %s, executable path: %s", internalVersion, internalBuildDate, util.GetExecutablePath()) defer util.AcquireProcessIDLock().Unlock() diff --git a/pkg/commands/command_status.go b/pkg/commands/command_status.go index cc6bd37..8a8e3a4 100644 --- a/pkg/commands/command_status.go +++ b/pkg/commands/command_status.go @@ -10,6 +10,7 @@ import ( pool "gopkg.in/go-playground/pool.v3" ) +// statusCmd represents the status command var statusCmd = &cobra.Command{ Use: "status", Short: "Show status for all repositories", diff --git a/pkg/commands/command_update.go b/pkg/commands/command_update.go index 77d9527..9a9cd5c 100644 --- a/pkg/commands/command_update.go +++ b/pkg/commands/command_update.go @@ -4,6 +4,7 @@ import ( cobra "github.com/spf13/cobra" ) +// updateCmd represents the update command var updateCmd = &cobra.Command{ Use: "update", Short: "Update configuration", diff --git a/pkg/commands/command_version.go b/pkg/commands/command_version.go index cd0b902..3a0491d 100644 --- a/pkg/commands/command_version.go +++ b/pkg/commands/command_version.go @@ -15,13 +15,16 @@ import ( // Address of remote repository where the newest version of gh-gr is released. const remoteRepository = "sarumaj/gh-gr" -// Version holds the application version. -// It gets filled automatically at build time. -var internalVersion string - -// BuildDate holds the date and time at which the application was build. -// It gets filled automatically at build time. -var internalBuildDate string +// versionFlags holds the application version and build date. +var versionFlags struct { + // Version holds the application version. + // It gets filled automatically at build time. + internalVersion string + + // BuildDate holds the date and time at which the application was build. + // It gets filled automatically at build time. + internalBuildDate string +} var versionCmd = &cobra.Command{ Use: "version", @@ -30,7 +33,7 @@ var versionCmd = &cobra.Command{ Run: func(*cobra.Command, []string) { c := util.Console() - current := supererrors.ExceptFn(supererrors.W(semver.ParseTolerant(internalVersion))) + current := supererrors.ExceptFn(supererrors.W(semver.ParseTolerant(versionFlags.internalVersion))) latest, found, err := selfupdate.DetectLatest(context.Background(), selfupdate.ParseSlug(remoteRepository)) var vSuffix string @@ -43,8 +46,8 @@ var versionCmd = &cobra.Command{ } - _ = supererrors.ExceptFn(supererrors.W(fmt.Fprintln(c.Stdout(), c.CheckColors(color.BlueString, "Version: %s", internalVersion+vSuffix)))) - _ = supererrors.ExceptFn(supererrors.W(fmt.Fprintln(c.Stdout(), c.CheckColors(color.BlueString, "Built at: %s", internalBuildDate)))) + _ = supererrors.ExceptFn(supererrors.W(fmt.Fprintln(c.Stdout(), c.CheckColors(color.BlueString, "Version: %s", versionFlags.internalVersion+vSuffix)))) + _ = supererrors.ExceptFn(supererrors.W(fmt.Fprintln(c.Stdout(), c.CheckColors(color.BlueString, "Built at: %s", versionFlags.internalBuildDate)))) _ = supererrors.ExceptFn(supererrors.W(fmt.Fprintln(c.Stdout(), c.CheckColors(color.BlueString, "Executable path: %s", util.GetExecutablePath())))) }, } diff --git a/pkg/commands/command_view.go b/pkg/commands/command_view.go index 819c138..a242ae5 100644 --- a/pkg/commands/command_view.go +++ b/pkg/commands/command_view.go @@ -10,10 +10,14 @@ import ( cobra "github.com/spf13/cobra" ) -var viewCmd = func() *cobra.Command { - var formatOption string - var filters []string +// viewFlags represents the flags for view command +var viewFlags struct { + formatOption string + filters []string +} +// viewCmd represents the view command +var viewCmd = func() *cobra.Command { viewCmd := &cobra.Command{ Aliases: []string{"show", "list", "ls"}, Use: "view", @@ -31,14 +35,14 @@ var viewCmd = func() *cobra.Command { conf := configfile.Load() logger.Debug("Streaming") - conf.Display(formatOption, false, filters...) + conf.Display(viewFlags.formatOption, false, viewFlags.filters...) }, } flags := viewCmd.Flags() supportedFormats := strings.Join(configfile.GetListOfSupportedFormats(true), ", ") - flags.StringVarP(&formatOption, "format", "f", "yaml", fmt.Sprintf("Change output format, supported formats: [%s]", supportedFormats)) - flags.StringArrayVarP(&filters, "match", "m", []string{}, "Glob pattern(s) to filter repositories") + flags.StringVarP(&viewFlags.formatOption, "format", "f", "yaml", fmt.Sprintf("Change output format, supported formats: [%s]", supportedFormats)) + flags.StringArrayVarP(&viewFlags.filters, "match", "m", []string{}, "Glob pattern(s) to filter repositories") return viewCmd }() diff --git a/pkg/commands/package_doc.go b/pkg/commands/package_doc.go new file mode 100644 index 0000000..3448cc6 --- /dev/null +++ b/pkg/commands/package_doc.go @@ -0,0 +1,20 @@ +/* + Package commands provides the command line interface for the application. + Available commands are: + - cleanup + - export + - init + - import + - pull + - push + - remove + - status + - update + - version + - view + + Each command is implemented as a separate file in this package. + The commands make use of multiprocessor and multithreaded execution. +*/ + +package commands diff --git a/pkg/configfile/config_encoders.go b/pkg/configfile/config_encoders.go index fda786d..59da3f0 100644 --- a/pkg/configfile/config_encoders.go +++ b/pkg/configfile/config_encoders.go @@ -11,6 +11,7 @@ import ( util "github.com/sarumaj/gh-gr/pkg/util" ) +// supportedEncoders contains supported encoder pairs for both encoding and decoding. var supportedEncoders = func() map[string]encoderPair { return map[string]encoderPair{ "json": { @@ -54,8 +55,11 @@ var supportedEncoders = func() map[string]encoderPair { }() type ( - decoder interface{ Decode(any) error } - encoder interface{ Encode(any) error } + // decoder is minimal interface for decoding. + decoder interface{ Decode(any) error } + // encoder is minimal interface for encoding. + encoder interface{ Encode(any) error } + // encoderPair is pair of encoder and decoder. encoderPair struct { Encoder func(io.Writer, bool) encoder Decoder func(io.Reader) decoder diff --git a/pkg/configfile/package_doc.go b/pkg/configfile/package_doc.go new file mode 100644 index 0000000..67d4dc6 --- /dev/null +++ b/pkg/configfile/package_doc.go @@ -0,0 +1,7 @@ +/* + Package configfile provides a simple interface for reading and writing configuration file. + The configuration file is stored in the user's GitHub CLI configuration under a dedicated section. + The configuration file is encoded in YAML format. +*/ + +package configfile diff --git a/pkg/restclient/package_doc.go b/pkg/restclient/package_doc.go new file mode 100644 index 0000000..af19b6f --- /dev/null +++ b/pkg/restclient/package_doc.go @@ -0,0 +1,5 @@ +/* + Package restclient provides a REST client for the GitHub API. +*/ + +package restclient diff --git a/pkg/restclient/resources/package_doc.go b/pkg/restclient/resources/package_doc.go new file mode 100644 index 0000000..1b2d717 --- /dev/null +++ b/pkg/restclient/resources/package_doc.go @@ -0,0 +1,6 @@ +/* + Package resources provides the resources for the restclient. + Types have been autogenerated using https://mholt.github.io/json-to-go/. +*/ + +package resources diff --git a/pkg/util/colored_yaml_encoder.go b/pkg/util/colored_yaml_encoder.go index c588bd4..d72678d 100644 --- a/pkg/util/colored_yaml_encoder.go +++ b/pkg/util/colored_yaml_encoder.go @@ -12,17 +12,17 @@ import ( printer "github.com/goccy/go-yaml/printer" ) -// Regular expression for matching ANSI code sequences for color codes. +// colorSequenceRegex is a regular expression for matching ANSI code sequences for color codes. var colorSequenceRegex = regexp.MustCompile(regexp.QuoteMeta(CSI) + fmt.Sprintf("[^%[1]s]+%[1]s", CCT)) -// Custom encoder to produce colored YAML output. +// coloredYAMLEncoder is a custom encoder to produce colored YAML output. type coloredYAMLEncoder struct { b *bytes.Buffer w io.Writer *yaml.Encoder } -// Encode YAML and colorize output. +// Encode encodes YAML and colorizes output. func (enc *coloredYAMLEncoder) Encode(v any) error { if err := enc.Encoder.Encode(v); err != nil { return err @@ -50,7 +50,7 @@ func (enc *coloredYAMLEncoder) Encode(v any) error { return err } -// Helper to produce color config for YAML property. +// makeColoredProperty is a helper to produce color config for YAML property. func makeColoredProperty(c color.Attribute) func() *printer.Property { return func() *printer.Property { return &printer.Property{ @@ -60,7 +60,7 @@ func makeColoredProperty(c color.Attribute) func() *printer.Property { } } -// Create new colorful YAML encoder for given writer. +// NewColoredYAMLEncoder creates new colorful YAML encoder for given writer. func NewColoredYAMLEncoder(w io.Writer, opts ...yaml.EncodeOption) *coloredYAMLEncoder { buffer := bytes.NewBuffer(nil) return &coloredYAMLEncoder{ @@ -70,7 +70,7 @@ func NewColoredYAMLEncoder(w io.Writer, opts ...yaml.EncodeOption) *coloredYAMLE } } -// For future use to uncolorize content of a reader. +// UncolorizeReader is reserved for future use to uncolorize content of a reader. func UncolorizeReader(r io.Reader) (io.Reader, error) { raw, err := io.ReadAll(r) if err != nil { diff --git a/pkg/util/package_doc.go b/pkg/util/package_doc.go new file mode 100644 index 0000000..d15eb9d --- /dev/null +++ b/pkg/util/package_doc.go @@ -0,0 +1,5 @@ +/* + Package util provides utility functions for the application. +*/ + +package util