github.com/kristofferahl/go-centry@v1.5.0/cmd/centry/commands.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"sort"
     6  	"strings"
     7  
     8  	"github.com/kristofferahl/go-centry/internal/pkg/cmd"
     9  	"github.com/kristofferahl/go-centry/internal/pkg/config"
    10  	"github.com/kristofferahl/go-centry/internal/pkg/shell"
    11  	"github.com/sirupsen/logrus"
    12  	"github.com/urfave/cli/v2"
    13  )
    14  
    15  func withCommandDefaults(c *cli.Command) *cli.Command {
    16  	if c.CustomHelpTemplate == "" {
    17  		c.CustomHelpTemplate = commandHelpTemplate
    18  	}
    19  	c.HideHelpCommand = true
    20  	return c
    21  }
    22  
    23  func registerInternalCommands(runtime *Runtime) {
    24  	context := runtime.context
    25  
    26  	if context.executor == CLI {
    27  		serveCmd := &ServeCommand{
    28  			Manifest: context.manifest,
    29  			Log: context.log.GetLogger().WithFields(logrus.Fields{
    30  				"command": "serve",
    31  			}),
    32  		}
    33  		generateMarkdownCmd := &GenerateMarkdownCommand{
    34  			CLI:      runtime.cli,
    35  			Manifest: context.manifest,
    36  			Log: context.log.GetLogger().WithFields(logrus.Fields{
    37  				"command": "generate-markdown",
    38  			}),
    39  		}
    40  		internalCmd := withCommandDefaults(&cli.Command{
    41  			Name:      "internal",
    42  			Usage:     "Internal centry commands",
    43  			UsageText: "",
    44  			Hidden:    context.manifest.Config.HideInternalCommands,
    45  			Subcommands: []*cli.Command{
    46  				serveCmd.ToCLICommand(),
    47  				generateMarkdownCmd.ToCLICommand(),
    48  			},
    49  		})
    50  		runtime.cli.Commands = append(runtime.cli.Commands, internalCmd)
    51  	}
    52  }
    53  
    54  func registerManifestCommands(runtime *Runtime, options *cmd.OptionsSet) {
    55  	context := runtime.context
    56  
    57  	for _, cmd := range context.manifest.Commands {
    58  		cmd := cmd
    59  
    60  		if context.commandEnabledFunc != nil && context.commandEnabledFunc(cmd) == false {
    61  			continue
    62  		}
    63  
    64  		script := createScript(cmd, context)
    65  
    66  		funcs, err := script.Functions()
    67  		if err != nil {
    68  			context.log.GetLogger().WithFields(logrus.Fields{
    69  				"command": cmd.Name,
    70  			}).Errorf("failed to parse script functions. %v", err)
    71  		} else {
    72  			for _, fn := range funcs {
    73  				fn := fn
    74  				cmd := cmd
    75  				namespace := script.FunctionNamespace(cmd.Name)
    76  
    77  				if fn.Name != cmd.Name && strings.HasPrefix(fn.Name, namespace) == false {
    78  					continue
    79  				}
    80  
    81  				cmdDescription := cmd.Description
    82  				if fn.Description != "" {
    83  					cmd.Description = fn.Description
    84  				}
    85  
    86  				cmdHelp := cmd.Help
    87  				if fn.Help != "" {
    88  					cmd.Help = fn.Help
    89  				}
    90  
    91  				scriptCmd := &ScriptCommand{
    92  					Context:       context,
    93  					Log:           context.log.GetLogger().WithFields(logrus.Fields{}),
    94  					GlobalOptions: options,
    95  					Command:       cmd,
    96  					Script:        script,
    97  					Function:      *fn,
    98  				}
    99  				cliCmd := scriptCmd.ToCLICommand()
   100  
   101  				cmdKeyParts := scriptCmd.GetCommandInvocationPath()
   102  
   103  				var root *cli.Command
   104  				for depth, cmdKeyPart := range cmdKeyParts {
   105  					if depth == 0 {
   106  						if getCommand(runtime.cli.Commands, cmdKeyPart) == nil {
   107  							if depth == len(cmdKeyParts)-1 {
   108  								// add destination command
   109  								runtime.cli.Commands = append(runtime.cli.Commands, cliCmd)
   110  							} else {
   111  								// add placeholder
   112  								runtime.cli.Commands = append(runtime.cli.Commands, withCommandDefaults(&cli.Command{
   113  									Name:      cmdKeyPart,
   114  									Usage:     cmdDescription,
   115  									UsageText: cmdHelp,
   116  									Action:    nil,
   117  								}))
   118  							}
   119  						}
   120  						root = getCommand(runtime.cli.Commands, cmdKeyPart)
   121  					} else {
   122  						if getCommand(root.Subcommands, cmdKeyPart) == nil {
   123  							if depth == len(cmdKeyParts)-1 {
   124  								// add destination command
   125  								root.Subcommands = append(root.Subcommands, cliCmd)
   126  							} else {
   127  								// add placeholder
   128  								root.Subcommands = append(root.Subcommands, withCommandDefaults(&cli.Command{
   129  									Name:      cmdKeyPart,
   130  									Usage:     "...",
   131  									UsageText: "",
   132  									Action:    nil,
   133  								}))
   134  							}
   135  						}
   136  						root = getCommand(root.Subcommands, cmdKeyPart)
   137  					}
   138  				}
   139  
   140  				runtime.events = append(runtime.events, fmt.Sprintf("registered command \"%s\"", scriptCmd.GetCommandInvocation()))
   141  			}
   142  		}
   143  	}
   144  }
   145  
   146  func getCommand(commands []*cli.Command, name string) *cli.Command {
   147  	for _, c := range commands {
   148  		if c.HasName(name) {
   149  			return c
   150  		}
   151  	}
   152  
   153  	return nil
   154  }
   155  
   156  func sortCommands(commands []*cli.Command) {
   157  	sort.Slice(commands, func(i, j int) bool {
   158  		return commands[i].Name < commands[j].Name
   159  	})
   160  }
   161  
   162  func createScript(cmd config.Command, context *Context) shell.Script {
   163  	return &shell.BashScript{
   164  		BasePath: context.manifest.BasePath,
   165  		Path:     cmd.Path,
   166  		Log: context.log.GetLogger().WithFields(logrus.Fields{
   167  			"script": cmd.Path,
   168  		}),
   169  	}
   170  }