Skip to content

Commit

Permalink
Add support to commands:
Browse files Browse the repository at this point in the history
 - validate pipelin syntax
 - export pipeline to config repo format

Update the way renderer handles the writer when output format is not JSON or YAML
  • Loading branch information
nikhilsbhat committed Jul 1, 2023
1 parent f0114c7 commit 65ad32e
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 16 deletions.
6 changes: 2 additions & 4 deletions cmd/agent_profiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import (
"gopkg.in/yaml.v3"
)

var agentProfileRaw bool

func registerAgentProfilesCommand() *cobra.Command {
registerAgentProfilesCmd := &cobra.Command{
Use: "elastic-agent-profile",
Expand Down Expand Up @@ -250,7 +248,7 @@ func getAgentProfilesUsageCommand() *cobra.Command {
return err
}

if agentProfileRaw {
if rawOutput {
return cliRenderer.Render(response)
}

Expand All @@ -266,7 +264,7 @@ func getAgentProfilesUsageCommand() *cobra.Command {
},
}

registerAgentProfileFlags(getAgentProfilesUsageCmd)
registerRawFlags(getAgentProfilesUsageCmd)

return getAgentProfilesUsageCmd
}
6 changes: 3 additions & 3 deletions cmd/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func registerGlobalFlags(cmd *cobra.Command) {
cmd.PersistentFlags().StringVarP(&cliCfg.FromFile, "from-file", "", "",
"file containing configurations of objects that needs to be created in GoCD, config-repo/pipeline-group/environment and etc.")
cmd.PersistentFlags().StringVarP(&cliCfg.ToFile, "to-file", "", "",
"file to which the output needs to be written to (this works only if --yaml or --json is enabled)")
"file to which the output needs to be written to")
cmd.PersistentFlags().StringVarP(&jsonQuery, "query", "q", "",
`query to filter the results, ex: '.material.attributes.type | id eq git'. this uses library gojsonq beneath
more queries can be found here https://github.com/thedevsaddam/gojsonq/wiki/Queries`)
Expand Down Expand Up @@ -110,8 +110,8 @@ func registerMaintenanceFlags(cmd *cobra.Command) {
"set this to disable maintenance mode in GoCD")
}

func registerAgentProfileFlags(cmd *cobra.Command) {
cmd.PersistentFlags().BoolVarP(&agentProfileRaw, "raw", "", false,
func registerRawFlags(cmd *cobra.Command) {
cmd.PersistentFlags().BoolVarP(&rawOutput, "raw", "", false,
"enable this to see the raw output")
}

Expand Down
4 changes: 2 additions & 2 deletions cmd/log.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package cmd

import (
"github.com/nikhilsbhat/gocd-sdk-go"
goCdLogger "github.com/nikhilsbhat/gocd-sdk-go/pkg/logger"
"github.com/sirupsen/logrus"
)

var cliLogger *logrus.Logger

func SetLogger(logLevel string) {
logger := logrus.New()
logger.SetLevel(gocd.GetLoglevel(logLevel))
logger.SetLevel(goCdLogger.GetLoglevel(logLevel))
logger.WithField("gocd-cli", true)
logger.SetFormatter(&logrus.JSONFormatter{})
cliLogger = logger
Expand Down
2 changes: 1 addition & 1 deletion cmd/materials.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ func getMaterialUsageCommand() *cobra.Command {
},
}

registerAgentProfileFlags(getAgentProfilesUsageCmd)
registerRawFlags(getAgentProfilesUsageCmd)

return getAgentProfilesUsageCmd
}
126 changes: 126 additions & 0 deletions cmd/pipelines.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@ package cmd
import (
"encoding/json"
"fmt"
"os"
"strings"
"time"

"github.com/nikhilsbhat/gocd-cli/pkg/errors"
"github.com/nikhilsbhat/gocd-cli/pkg/render"
"github.com/nikhilsbhat/gocd-sdk-go"
"github.com/nikhilsbhat/gocd-sdk-go/pkg/plugin"
"github.com/spf13/cobra"
"gopkg.in/yaml.v3"
)

var (
rawOutput bool
goCDPipelineInstance int
goCDPipelineName string
goCDPipelineMessage string
Expand All @@ -22,6 +25,7 @@ var (
goCDPausePipelineAtStart bool
goCDPipelinePause bool
goCDPipelineUnPause bool
pluginID string
numberOfDays time.Duration
)

Expand Down Expand Up @@ -58,6 +62,8 @@ GET/PAUSE/UNPAUSE/UNLOCK/SCHEDULE and comment on a GoCD pipeline`,
pipelineCommand.AddCommand(getPipelineScheduleCommand())
pipelineCommand.AddCommand(getPipelineHistoryCommand())
pipelineCommand.AddCommand(getPipelineNotSchedulesCommand())
pipelineCommand.AddCommand(validatePipelinesCommand())
pipelineCommand.AddCommand(exportPipelineToConfigRepoFormatCommand())

for _, command := range pipelineCommand.Commands() {
command.SilenceUsage = true
Expand Down Expand Up @@ -641,3 +647,123 @@ func listPipelinesCommand() *cobra.Command {

return listPipelinesCmd
}

func validatePipelinesCommand() *cobra.Command {
type pipelineValidate struct {
pipelines []string
pluginVersion string
pluginLocalPath string
pluginDownloadURL string
}

var pipelineValidateObj pipelineValidate

validatePipelinesCmd := &cobra.Command{
Use: "validate-syntax",
Short: "Command validate pipeline syntax by running it against appropriate GoCD plugin",
Args: cobra.NoArgs,
PreRunE: setCLIClient,
Example: `gocd-cli pipeline validate-syntax --pipeline pipeline1 --pipeline pipeline2`,
RunE: func(cmd *cobra.Command, args []string) error {
pluginCfg := plugin.NewPluginConfig(
pipelineValidateObj.pluginVersion,
pipelineValidateObj.pluginLocalPath,
pipelineValidateObj.pluginDownloadURL,
cliCfg.LogLevel,
)

success, err := client.ValidatePipelineSyntax(pluginCfg, pipelineValidateObj.pipelines)
if err != nil {
return err
}

if !success {
cliLogger.Error("oops...!! pipeline syntax validation failed")
os.Exit(1)
}

fmt.Println("SUCCESS")

return nil
},
}

validatePipelinesCmd.PersistentFlags().StringVarP(&pipelineValidateObj.pluginVersion, "plugin-version", "", "",
"GoCD plugin version against which the pipeline has to be validated (the plugin type would be auto-detected);"+
" if missed, the pipeline would be validated against the latest version of the auto-detected plugin")
validatePipelinesCmd.PersistentFlags().StringSliceVarP(&pipelineValidateObj.pipelines, "pipeline", "", nil,
"list of pipelines for which the syntax has to be validated")
validatePipelinesCmd.PersistentFlags().StringVarP(&pipelineValidateObj.pluginDownloadURL, "plugin-download-url", "", "",
"Auto-detection of the plugin sets the download URL too (Github's release URL);"+
" if the URL needs to be set to something else, then it can be set using this")
validatePipelinesCmd.PersistentFlags().StringVarP(&pipelineValidateObj.pluginLocalPath, "plugin-path", "", "",
"if you prefer managing plugins outside the gocd-cli, the path to already downloaded plugins can be set using this")

return validatePipelinesCmd
}

func exportPipelineToConfigRepoFormatCommand() *cobra.Command {
var renderToFile bool

exportPipelineToConfigRepoFormatCmd := &cobra.Command{
Use: "export-format",
Short: "Command to export specified pipeline present in GoCD to appropriate config repo format " +
"[https://api.gocd.org/current/#export-pipeline-config-to-config-repo-format]",
Args: cobra.RangeArgs(1, 1),
PreRunE: setCLIClient,
Example: `gocd-cli pipeline change-config-repo-format pipeline1 --plugin-id yaml.config.plugin`,
RunE: func(cmd *cobra.Command, args []string) error {
response, err := client.ExportPipelineToConfigRepoFormat(args[0], pluginID)
if err != nil {
return err
}

if renderToFile {
cliLogger.Debugf("--render-to-file is enabled, writing exported plugin to file '%s'", response.PipelineFileName)

file, err := os.Create(response.PipelineFileName)
if err != nil {
return err
}

if _, err = file.Write([]byte(response.PipelineContent)); err != nil {
return err
}

cliLogger.Debug("exported plugin was written to file successfully")

return nil
}

if !rawOutput {
fmt.Printf("%s\n", response.PipelineContent)

return nil
}

if len(jsonQuery) != 0 {
cliLogger.Debugf(queryEnabledMessage, jsonQuery)

baseQuery, err := render.SetQuery(response, jsonQuery)
if err != nil {
return err
}

cliLogger.Debugf(baseQuery.Print())

return cliRenderer.Render(baseQuery.RunQuery())
}

return cliRenderer.Render(response)
},
}

exportPipelineToConfigRepoFormatCmd.PersistentFlags().StringVarP(&pluginID, "plugin-id", "", "",
"if you prefer managing plugins outside the gocd-cli, the path to already downloaded plugins can be set using this")
exportPipelineToConfigRepoFormatCmd.PersistentFlags().BoolVarP(&rawOutput, "raw", "", false,
"if enabled, prints response in raw format")
exportPipelineToConfigRepoFormatCmd.PersistentFlags().BoolVarP(&renderToFile, "render-to-file", "", false,
"if enabled, the exported pipeline would we written to a file")

return exportPipelineToConfigRepoFormatCmd
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.19

require (
github.com/ghodss/yaml v1.0.0
github.com/nikhilsbhat/gocd-sdk-go v0.1.5
github.com/nikhilsbhat/gocd-sdk-go v0.1.6-0.20230701140346-f8bdb47eaeb7
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.6.1
github.com/stretchr/testify v1.8.2
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/nikhilsbhat/gocd-sdk-go v0.1.5 h1:LhjBuxFXTnRuhSjtNFSRQSjgJu+CDxqcmXLlmRoMt04=
github.com/nikhilsbhat/gocd-sdk-go v0.1.5/go.mod h1:bIE3Xr7rRzOo0xSX/oa13kXNdFTgCR3JtCh/SontbwM=
github.com/nikhilsbhat/gocd-sdk-go v0.1.6-0.20230701140346-f8bdb47eaeb7 h1:15zV8U3NmeSXUhSHjDatPl0cLr9KaFVs5eR3PenPRF0=
github.com/nikhilsbhat/gocd-sdk-go v0.1.6-0.20230701140346-f8bdb47eaeb7/go.mod h1:bIE3Xr7rRzOo0xSX/oa13kXNdFTgCR3JtCh/SontbwM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
Expand Down
4 changes: 2 additions & 2 deletions pkg/render/object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"testing"

"github.com/nikhilsbhat/gocd-cli/pkg/render"
"github.com/nikhilsbhat/gocd-sdk-go"
goCdLogger "github.com/nikhilsbhat/gocd-sdk-go/pkg/logger"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
)
Expand All @@ -14,7 +14,7 @@ var log *logrus.Logger
//nolint:gochecknoinits
func init() {
logger := logrus.New()
logger.SetLevel(gocd.GetLoglevel("info"))
logger.SetLevel(goCdLogger.GetLoglevel("info"))
logger.WithField("gocd-cli", true)
logger.SetFormatter(&logrus.JSONFormatter{})
log = logger
Expand Down
12 changes: 11 additions & 1 deletion pkg/render/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,17 @@ func (r *Renderer) Render(value interface{}) error {

r.logger.Debug("no format was specified for rendering output to defaults")

fmt.Printf("%v\n", value)
_, err := r.writer.Write([]byte(fmt.Sprintf("%v\n", value)))
if err != nil {
r.logger.Fatalln(err)
}

defer func(writer *bufio.Writer) {
err = writer.Flush()
if err != nil {
r.logger.Fatalln(err)
}
}(r.writer)

return nil
}
Expand Down

0 comments on commit 65ad32e

Please sign in to comment.