Skip to content

Commit

Permalink
Add summary and description provider to improve documentation
Browse files Browse the repository at this point in the history
- Added descriptionProvider which can be used to override command
  summaries and descriptions in order to improve the documentation
- Extended command structs with summary and description fields
- Updated to latest OpenAPI definitions with improved summaries
  • Loading branch information
thschmitt committed Oct 1, 2024
1 parent 3959adf commit e308086
Show file tree
Hide file tree
Showing 20 changed files with 1,887 additions and 1,412 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ func (c CreateCommand) Execute(context plugin.ExecutionContext, writer output.Ou
```go
func (c CreateCommand) Command() plugin.Command {
return *plugin.NewCommand("myservice").
WithOperation("create-product", "Creates a product").
WithOperation("create-product", "Create product", "Creates a new product in the store").
WithParameter("id", plugin.ParameterTypeInteger, "The product id", true).
WithParameter("name", plugin.ParameterTypeString, "The product name", true).
WithParameter("description", plugin.ParameterTypeString, "The product description", false)
Expand Down
25 changes: 13 additions & 12 deletions commandline/command_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,7 @@ func (b CommandBuilder) execute(executionContext executor.ExecutionContext, outp
func (b CommandBuilder) createCategoryCommand(operation parser.Operation) *cli.Command {
return &cli.Command{
Name: operation.Category.Name,
Usage: operation.Category.Summary,
Description: operation.Category.Description,
Flags: []cli.Flag{
b.HelpFlag(),
Expand Down Expand Up @@ -541,6 +542,7 @@ func (b CommandBuilder) createServiceCommand(definition parser.Definition) *cli.

return &cli.Command{
Name: definition.Name,
Usage: definition.Summary,
Description: definition.Description,
Flags: []cli.Flag{
b.HelpFlag(),
Expand All @@ -559,6 +561,7 @@ func (b CommandBuilder) createAutoCompleteEnableCommand() *cli.Command {

return &cli.Command{
Name: "enable",
Usage: "Enable auto complete",
Description: "Enables auto complete in your shell",
Flags: []cli.Flag{
&cli.StringFlag{
Expand Down Expand Up @@ -590,6 +593,7 @@ func (b CommandBuilder) createAutoCompleteEnableCommand() *cli.Command {
func (b CommandBuilder) createAutoCompleteCompleteCommand(version string) *cli.Command {
return &cli.Command{
Name: "complete",
Usage: "Autocomplete suggestions",
Description: "Returns the autocomplete suggestions",
Flags: []cli.Flag{
&cli.StringFlag{
Expand Down Expand Up @@ -625,6 +629,7 @@ func (b CommandBuilder) createAutoCompleteCompleteCommand(version string) *cli.C
func (b CommandBuilder) createAutoCompleteCommand(version string) *cli.Command {
return &cli.Command{
Name: "autocomplete",
Usage: "Autocompletion",
Description: "Commands for autocompletion",
Flags: []cli.Flag{
b.HelpFlag(),
Expand Down Expand Up @@ -655,6 +660,7 @@ func (b CommandBuilder) createConfigCommand() *cli.Command {

return &cli.Command{
Name: "config",
Usage: "Interactive Configuration",
Description: "Interactive command to configure the CLI",
Flags: flags,
Subcommands: []*cli.Command{
Expand All @@ -663,11 +669,7 @@ func (b CommandBuilder) createConfigCommand() *cli.Command {
Action: func(context *cli.Context) error {
auth := context.String(authFlagName)
profileName := context.String(profileFlagName)
handler := ConfigCommandHandler{
StdIn: b.StdIn,
StdOut: b.StdOut,
ConfigProvider: b.ConfigProvider,
}
handler := newConfigCommandHandler(b.StdIn, b.StdOut, b.ConfigProvider)
return handler.Configure(auth, profileName)
},
HideHelp: true,
Expand Down Expand Up @@ -698,17 +700,14 @@ func (b CommandBuilder) createConfigSetCommand() *cli.Command {
}
return &cli.Command{
Name: "set",
Usage: "Set config parameters",
Description: "Set config parameters",
Flags: flags,
Action: func(context *cli.Context) error {
profileName := context.String(profileFlagName)
key := context.String(keyFlagName)
value := context.String(valueFlagName)
handler := ConfigCommandHandler{
StdIn: b.StdIn,
StdOut: b.StdOut,
ConfigProvider: b.ConfigProvider,
}
handler := newConfigCommandHandler(b.StdIn, b.StdOut, b.ConfigProvider)
return handler.Set(key, value, profileName)
},
HideHelp: true,
Expand Down Expand Up @@ -754,16 +753,18 @@ func (b CommandBuilder) loadAutocompleteDefinitions(args []string, version strin
return b.loadDefinitions(args, version)
}

func (b CommandBuilder) createShowCommand(definitions []parser.Definition, commands []*cli.Command) *cli.Command {
func (b CommandBuilder) createShowCommand(definitions []parser.Definition) *cli.Command {
return &cli.Command{
Name: "commands",
Usage: "Inspect available CLI operations",
Description: "Command to inspect available uipath CLI operations",
Flags: []cli.Flag{
b.HelpFlag(),
},
Subcommands: []*cli.Command{
{
Name: "show",
Usage: "Print CLI commands",
Description: "Print available uipath CLI commands",
Flags: []cli.Flag{
b.HelpFlag(),
Expand Down Expand Up @@ -832,7 +833,7 @@ func (b CommandBuilder) Create(args []string) ([]*cli.Command, error) {
servicesCommands := b.createServiceCommands(definitions)
autocompleteCommand := b.createAutoCompleteCommand(version)
configCommand := b.createConfigCommand()
showCommand := b.createShowCommand(definitions, servicesCommands)
showCommand := b.createShowCommand(definitions)
commands := append(servicesCommands, autocompleteCommand, configCommand, showCommand)
return commands, nil
}
Expand Down
56 changes: 32 additions & 24 deletions commandline/config_command_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import (
"github.com/UiPath/uipathcli/config"
)

// The ConfigCommandHandler implements commands for configuring the CLI.
// configCommandHandler implements commands for configuring the CLI.
// The CLI can be configured interactively or by setting config values
// programmatically.
//
// Example:
// uipath config ==> interactive configuration of the CLI
// uipath config set ==> stores a value in the configuration file
type ConfigCommandHandler struct {
type configCommandHandler struct {
StdIn io.Reader
StdOut io.Writer
ConfigProvider config.ConfigProvider
Expand All @@ -31,7 +31,7 @@ const CredentialsAuth = "credentials"
const LoginAuth = "login"
const PatAuth = "pat"

func (h ConfigCommandHandler) Set(key string, value string, profileName string) error {
func (h configCommandHandler) Set(key string, value string, profileName string) error {
config := h.getOrCreateProfile(profileName)
err := h.setConfigValue(&config, key, value)
if err != nil {
Expand All @@ -45,7 +45,7 @@ func (h ConfigCommandHandler) Set(key string, value string, profileName string)
return nil
}

func (h ConfigCommandHandler) setConfigValue(config *config.Config, key string, value string) error {
func (h configCommandHandler) setConfigValue(config *config.Config, key string, value string) error {
keyParts := strings.Split(key, ".")
if key == "version" {
config.SetVersion(value)
Expand Down Expand Up @@ -91,19 +91,19 @@ func (h ConfigCommandHandler) setConfigValue(config *config.Config, key string,
return fmt.Errorf("Unknown config key '%s'", key)
}

func (h ConfigCommandHandler) isHeaderKey(keyParts []string) bool {
func (h configCommandHandler) isHeaderKey(keyParts []string) bool {
return len(keyParts) == 2 && keyParts[0] == "header"
}

func (h ConfigCommandHandler) isParameterKey(keyParts []string) bool {
func (h configCommandHandler) isParameterKey(keyParts []string) bool {
return len(keyParts) == 2 && keyParts[0] == "parameter"
}

func (h ConfigCommandHandler) isAuthPropertyKey(keyParts []string) bool {
func (h configCommandHandler) isAuthPropertyKey(keyParts []string) bool {
return len(keyParts) == 3 && keyParts[0] == "auth" && keyParts[1] == "properties"
}

func (h ConfigCommandHandler) convertToBool(value string) (bool, error) {
func (h configCommandHandler) convertToBool(value string) (bool, error) {
if strings.EqualFold(value, "true") {
return true, nil
}
Expand All @@ -113,7 +113,7 @@ func (h ConfigCommandHandler) convertToBool(value string) (bool, error) {
return false, fmt.Errorf("Invalid boolean value: %s", value)
}

func (h ConfigCommandHandler) Configure(auth string, profileName string) error {
func (h configCommandHandler) Configure(auth string, profileName string) error {
switch auth {
case CredentialsAuth:
return h.configureCredentials(profileName)
Expand All @@ -127,7 +127,7 @@ func (h ConfigCommandHandler) Configure(auth string, profileName string) error {
return fmt.Errorf("Invalid auth, supported values: %s, %s, %s", CredentialsAuth, LoginAuth, PatAuth)
}

func (h ConfigCommandHandler) configure(profileName string) error {
func (h configCommandHandler) configure(profileName string) error {
config := h.getOrCreateProfile(profileName)
reader := bufio.NewReader(h.StdIn)

Expand All @@ -149,7 +149,7 @@ func (h ConfigCommandHandler) configure(profileName string) error {
return nil
}

func (h ConfigCommandHandler) readAuthInput(config config.Config, reader *bufio.Reader) bool {
func (h configCommandHandler) readAuthInput(config config.Config, reader *bufio.Reader) bool {
authType := h.readAuthTypeInput(config, reader)
switch authType {
case CredentialsAuth:
Expand All @@ -175,7 +175,7 @@ func (h ConfigCommandHandler) readAuthInput(config config.Config, reader *bufio.
}
}

func (h ConfigCommandHandler) configureCredentials(profileName string) error {
func (h configCommandHandler) configureCredentials(profileName string) error {
config := h.getOrCreateProfile(profileName)
reader := bufio.NewReader(h.StdIn)

Expand All @@ -201,7 +201,7 @@ func (h ConfigCommandHandler) configureCredentials(profileName string) error {
return nil
}

func (h ConfigCommandHandler) configureLogin(profileName string) error {
func (h configCommandHandler) configureLogin(profileName string) error {
config := h.getOrCreateProfile(profileName)
reader := bufio.NewReader(h.StdIn)

Expand All @@ -227,7 +227,7 @@ func (h ConfigCommandHandler) configureLogin(profileName string) error {
return nil
}

func (h ConfigCommandHandler) configurePat(profileName string) error {
func (h configCommandHandler) configurePat(profileName string) error {
config := h.getOrCreateProfile(profileName)
reader := bufio.NewReader(h.StdIn)

Expand All @@ -253,7 +253,7 @@ func (h ConfigCommandHandler) configurePat(profileName string) error {
return nil
}

func (h ConfigCommandHandler) getAuthType(config config.Config) string {
func (h configCommandHandler) getAuthType(config config.Config) string {
if config.Pat() != "" {
return PatAuth
}
Expand All @@ -266,15 +266,15 @@ func (h ConfigCommandHandler) getAuthType(config config.Config) string {
return ""
}

func (h ConfigCommandHandler) getOrCreateProfile(profileName string) config.Config {
func (h configCommandHandler) getOrCreateProfile(profileName string) config.Config {
config := h.ConfigProvider.Config(profileName)
if config == nil {
return h.ConfigProvider.New()
}
return *config
}

func (h ConfigCommandHandler) getDisplayValue(value string, masked bool) string {
func (h configCommandHandler) getDisplayValue(value string, masked bool) string {
if value == "" {
return notSetMessage
}
Expand All @@ -284,14 +284,14 @@ func (h ConfigCommandHandler) getDisplayValue(value string, masked bool) string
return value
}

func (h ConfigCommandHandler) maskValue(value string) string {
func (h configCommandHandler) maskValue(value string) string {
if len(value) < 10 {
return maskMessage
}
return maskMessage + value[len(value)-4:]
}

func (h ConfigCommandHandler) readUserInput(message string, reader *bufio.Reader) (string, error) {
func (h configCommandHandler) readUserInput(message string, reader *bufio.Reader) (string, error) {
fmt.Fprint(h.StdOut, message+" ")
value, err := reader.ReadString('\n')
if err != nil {
Expand All @@ -300,7 +300,7 @@ func (h ConfigCommandHandler) readUserInput(message string, reader *bufio.Reader
return strings.Trim(value, " \r\n\t"), nil
}

func (h ConfigCommandHandler) readOrgTenantInput(config config.Config, reader *bufio.Reader) (string, string, error) {
func (h configCommandHandler) readOrgTenantInput(config config.Config, reader *bufio.Reader) (string, string, error) {
message := fmt.Sprintf("Enter organization [%s]:", h.getDisplayValue(config.Organization, false))
organization, err := h.readUserInput(message, reader)
if err != nil {
Expand All @@ -316,7 +316,7 @@ func (h ConfigCommandHandler) readOrgTenantInput(config config.Config, reader *b
return organization, tenant, nil
}

func (h ConfigCommandHandler) readCredentialsInput(config config.Config, reader *bufio.Reader) (string, string, error) {
func (h configCommandHandler) readCredentialsInput(config config.Config, reader *bufio.Reader) (string, string, error) {
message := fmt.Sprintf("Enter client id [%s]:", h.getDisplayValue(config.ClientId(), true))
clientId, err := h.readUserInput(message, reader)
if err != nil {
Expand All @@ -332,7 +332,7 @@ func (h ConfigCommandHandler) readCredentialsInput(config config.Config, reader
return clientId, clientSecret, nil
}

func (h ConfigCommandHandler) readLoginInput(config config.Config, reader *bufio.Reader) (string, string, string, error) {
func (h configCommandHandler) readLoginInput(config config.Config, reader *bufio.Reader) (string, string, string, error) {
message := fmt.Sprintf("Enter client id [%s]:", h.getDisplayValue(config.ClientId(), true))
clientId, err := h.readUserInput(message, reader)
if err != nil {
Expand All @@ -352,12 +352,12 @@ func (h ConfigCommandHandler) readLoginInput(config config.Config, reader *bufio
return clientId, redirectUri, scopes, nil
}

func (h ConfigCommandHandler) readPatInput(config config.Config, reader *bufio.Reader) (string, error) {
func (h configCommandHandler) readPatInput(config config.Config, reader *bufio.Reader) (string, error) {
message := fmt.Sprintf("Enter personal access token [%s]:", h.getDisplayValue(config.Pat(), true))
return h.readUserInput(message, reader)
}

func (h ConfigCommandHandler) readAuthTypeInput(config config.Config, reader *bufio.Reader) string {
func (h configCommandHandler) readAuthTypeInput(config config.Config, reader *bufio.Reader) string {
authType := h.getAuthType(config)
for {
message := fmt.Sprintf(`Authentication type [%s]:
Expand All @@ -381,3 +381,11 @@ Select:`, h.getDisplayValue(authType, false))
}
}
}

func newConfigCommandHandler(stdIn io.Reader, stdOut io.Writer, configProvider config.ConfigProvider) *configCommandHandler {
return &configCommandHandler{
StdIn: stdIn,
StdOut: stdOut,
ConfigProvider: configProvider,
}
}
2 changes: 1 addition & 1 deletion commandline/definition_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func (p DefinitionProvider) applyPluginCommand(plugin plugin.CommandPlugin, comm
parameters := p.convertToParameters(command.Parameters)
var category *parser.OperationCategory
if command.Category != nil {
category = parser.NewOperationCategory(command.Category.Name, command.Category.Description)
category = parser.NewOperationCategory(command.Category.Name, command.Category.Summary, command.Category.Description)
}
baseUri, _ := url.Parse(parser.DefaultServerBaseUrl)
operation := parser.NewOperation(command.Name, command.Description, "", "", *baseUri, "", "application/json", parameters, plugin, command.Hidden, category)
Expand Down
10 changes: 5 additions & 5 deletions commandline/multi_definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func (d multiDefinition) Merge(name string, definitions []*parser.Definition) *p
operations := []parser.Operation{}
for _, definition := range definitions {
for _, operation := range definition.Operations {
category := d.getCategory(operation, definition)
category := d.getCategory(operation)
operations = append(operations, *parser.NewOperation(operation.Name,
operation.Summary,
operation.Description,
Expand All @@ -30,14 +30,14 @@ func (d multiDefinition) Merge(name string, definitions []*parser.Definition) *p
category))
}
}
return parser.NewDefinition(name, definitions[0].Description, operations)
return parser.NewDefinition(name, definitions[0].Summary, definitions[0].Description, operations)
}

func (d multiDefinition) getCategory(operation parser.Operation, definition *parser.Definition) *parser.OperationCategory {
if operation.Category == nil || operation.Category.Description != "" {
func (d multiDefinition) getCategory(operation parser.Operation) *parser.OperationCategory {
if operation.Category == nil || operation.Category.Summary != "" || operation.Category.Description != "" {
return operation.Category
}
return parser.NewOperationCategory(operation.Category.Name, definition.Description)
return parser.NewOperationCategory(operation.Category.Name, operation.Category.Summary, operation.Category.Description)
}

func newMultiDefinition() *multiDefinition {
Expand Down
Loading

0 comments on commit e308086

Please sign in to comment.