Skip to content

Commit

Permalink
Move command creation into functions
Browse files Browse the repository at this point in the history
  • Loading branch information
marcomorain committed Jul 4, 2018
1 parent 820cd83 commit a5a853a
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 67 deletions.
24 changes: 14 additions & 10 deletions cmd/collapse.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,35 @@ package cmd

import (
"github.com/CircleCI-Public/circleci-cli/filetree"
"github.com/pkg/errors"
"github.com/spf13/cobra"
yaml "gopkg.in/yaml.v2"
)

var collapseCommand = &cobra.Command{
Use: "collapse",
Short: "Collapse your CircleCI configuration to a single file",
Run: collapse,
}

var root string

func init() {
func newCollapseCommand() *cobra.Command {

collapseCommand := &cobra.Command{
Use: "collapse",
Short: "Collapse your CircleCI configuration to a single file",
RunE: collapse,
}
collapseCommand.Flags().StringVarP(&root, "root", "r", ".circleci", "path to your configuration (default is .circleci)")

return collapseCommand
}

func collapse(cmd *cobra.Command, args []string) {
func collapse(cmd *cobra.Command, args []string) error {
tree, err := filetree.NewTree(root)
if err != nil {
Logger.FatalOnError("An error occurred trying to build the tree", err)
return errors.Wrap(err, "An error occurred trying to build the tree")
}

y, err := yaml.Marshal(&tree)
if err != nil {
Logger.FatalOnError("Failed trying to marshal the tree to YAML ", err)
return errors.Wrap(err, "Failed trying to marshal the tree to YAML ")
}
Logger.Infof("%s\n", string(y))
return nil
}
34 changes: 18 additions & 16 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,30 @@ import (
// Path to the config.yml file to operate on.
var configPath string

var configCmd = &cobra.Command{
Use: "config",
Short: "Operate on build config files",
}
func newConfigCommand() *cobra.Command {
configCmd := &cobra.Command{
Use: "config",
Short: "Operate on build config files",
}

var validateCommand = &cobra.Command{
Use: "validate",
Aliases: []string{"check"},
Short: "Check that the config file is well formed.",
RunE: validateConfig,
}
validateCommand := &cobra.Command{
Use: "validate",
Aliases: []string{"check"},
Short: "Check that the config file is well formed.",
RunE: validateConfig,
}

var expandCommand = &cobra.Command{
Use: "expand",
Short: "Expand the config.",
RunE: expandConfig,
}
expandCommand := &cobra.Command{
Use: "expand",
Short: "Expand the config.",
RunE: expandConfig,
}

func init() {
configCmd.PersistentFlags().StringVarP(&configPath, "path", "p", ".circleci/config.yml", "path to build config")
configCmd.AddCommand(validateCommand)
configCmd.AddCommand(expandCommand)

return configCmd
}

func validateConfig(cmd *cobra.Command, args []string) error {
Expand Down
24 changes: 15 additions & 9 deletions cmd/configure.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,29 @@ import (
"fmt"
"strings"

"github.com/pkg/errors"
"github.com/spf13/viper"

"github.com/manifoldco/promptui"
"github.com/spf13/cobra"
)

var configureCommand = &cobra.Command{
Use: "configure",
Short: "Configure the tool with your credentials",
Run: configure,
}

var testing = false

func init() {
func newConfigureCommand() *cobra.Command {

configureCommand := &cobra.Command{
Use: "configure",
Short: "Configure the tool with your credentials",
RunE: configure,
}

configureCommand.Flags().BoolVar(&testing, "testing", false, "Enable test mode to bypass interactive UI.")
if err := configureCommand.Flags().MarkHidden("testing"); err != nil {
panic(err)
}

return configureCommand
}

// We can't properly run integration tests on code that calls PromptUI.
Expand Down Expand Up @@ -90,7 +94,7 @@ func shouldAskForToken(token string, ui userInterface) bool {
return ui.askUserToConfirm("A CircleCI token is already set. Do you want to change it")
}

func configure(cmd *cobra.Command, args []string) {
func configure(cmd *cobra.Command, args []string) error {
token := viper.GetString("token")

var ui userInterface = interactiveUI{}
Expand All @@ -115,7 +119,9 @@ func configure(cmd *cobra.Command, args []string) {
viper.Set("verbose", false)

if err := viper.WriteConfig(); err != nil {
panic(err)
return errors.Wrap(err, "Failed to save config file")
}

fmt.Println("Configuration has been saved.")
return nil
}
10 changes: 6 additions & 4 deletions cmd/diagnostic.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import (
"github.com/spf13/viper"
)

var diagnosticCmd = &cobra.Command{
Use: "diagnostic",
Short: "Check the status of your CircleCI CLI.",
RunE: diagnostic,
func newDiagnosticCommand() *cobra.Command {
return &cobra.Command{
Use: "diagnostic",
Short: "Check the status of your CircleCI CLI.",
RunE: diagnostic,
}
}

func diagnostic(cmd *cobra.Command, args []string) error {
Expand Down
10 changes: 6 additions & 4 deletions cmd/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import (
"github.com/spf13/viper"
)

var queryCmd = &cobra.Command{
Use: "query",
Short: "Query the CircleCI GraphQL API.",
RunE: query,
func newQueryCommand() *cobra.Command {
return &cobra.Command{
Use: "query",
Short: "Query the CircleCI GraphQL API.",
RunE: query,
}
}

func query(cmd *cobra.Command, args []string) error {
Expand Down
52 changes: 28 additions & 24 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ var defaultEndpoint = "https://circleci.com/graphql-unstable"
// by main.main(). It only needs to happen once to
// the RootCmd.
func Execute() {
if err := rootCmd.Execute(); err != nil {
command := makeCommands()
if err := command.Execute(); err != nil {
os.Exit(-1)
}
}
Expand All @@ -27,20 +28,29 @@ func Execute() {
// This allows us to print to the log at anytime from within the `cmd` package.
var Logger *logger.Logger

var rootCmd = &cobra.Command{
Use: "cli",
Short: "Use CircleCI from the command line.",
Long: `Use CircleCI from the command line.`,
}
func makeCommands() *cobra.Command {

rootCmd := &cobra.Command{
Use: "cli",
Short: "Use CircleCI from the command line.",
Long: `Use CircleCI from the command line.`,
}

func addCommands() {
rootCmd.AddCommand(diagnosticCmd)
rootCmd.AddCommand(queryCmd)
rootCmd.AddCommand(collapseCommand)
rootCmd.AddCommand(configureCommand)
rootCmd.AddCommand(configCmd)
rootCmd.AddCommand(newDiagnosticCommand())
rootCmd.AddCommand(newQueryCommand())
rootCmd.AddCommand(newCollapseCommand())
rootCmd.AddCommand(newConfigureCommand())
rootCmd.AddCommand(newConfigCommand())
rootCmd.AddCommand(newOrbCommand())

rootCmd.PersistentFlags().BoolP("verbose", "v", false, "Enable verbose logging.")
rootCmd.PersistentFlags().StringP("endpoint", "e", defaultEndpoint, "the endpoint of your CircleCI GraphQL API")
rootCmd.PersistentFlags().StringP("token", "t", "", "your token for using CircleCI")

for _, flag := range []string{"endpoint", "token", "verbose"} {
bindCobraFlagToViper(rootCmd, flag)
}

// Cobra has a peculiar default behaviour:
// https://github.com/spf13/cobra/issues/340
// If you expose a command with `RunE`, and return an error from your
Expand All @@ -51,20 +61,22 @@ func addCommands() {
// This flag disables that behaviour, so that if a comment fails, it prints
// just the error message.
rootCmd.SilenceUsage = true

return rootCmd
}

func bindCobraFlagToViper(flag string) {
if err := viper.BindPFlag(flag, rootCmd.PersistentFlags().Lookup(flag)); err != nil {
func bindCobraFlagToViper(command *cobra.Command, flag string) {
if err := viper.BindPFlag(flag, command.PersistentFlags().Lookup(flag)); err != nil {
panic(errors.Wrapf(err, "internal error binding cobra flag '%s' to viper", flag))
}
}

func init() {

configDir := path.Join(settings.UserHomeDir(), ".circleci")

cobra.OnInitialize(setup)

configDir := path.Join(settings.UserHomeDir(), ".circleci")

viper.SetConfigName("cli")
viper.AddConfigPath(configDir)
viper.SetEnvPrefix("circleci_cli")
Expand All @@ -78,14 +90,6 @@ func init() {
panic(err)
}

rootCmd.PersistentFlags().BoolP("verbose", "v", false, "Enable verbose logging.")
rootCmd.PersistentFlags().StringP("endpoint", "e", defaultEndpoint, "the endpoint of your CircleCI GraphQL API")
rootCmd.PersistentFlags().StringP("token", "t", "", "your token for using CircleCI")

for _, flag := range []string{"endpoint", "token", "verbose"} {
bindCobraFlagToViper(flag)
}
addCommands()
}

func setup() {
Expand Down

0 comments on commit a5a853a

Please sign in to comment.