Skip to content

Commit

Permalink
feat: add cli package
Browse files Browse the repository at this point in the history
  • Loading branch information
PhilippHeuer committed Aug 1, 2024
1 parent 60cf10c commit 73a2b9e
Show file tree
Hide file tree
Showing 8 changed files with 319 additions and 6 deletions.
31 changes: 31 additions & 0 deletions app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package main

import (
"github.com/cidverse/normalizeci/cmd"
"github.com/rs/zerolog/log"
)

var (
version = "dev"
commit = "none"
date = "unknown"
status = "clean"
)

// Init Hook
func init() {
// Set Version Information
cmd.Version = version
cmd.CommitHash = commit
cmd.BuildAt = date
cmd.RepositoryStatus = status
}

// CLI Main Entrypoint
func main() {
rootCommand := cmd.RootCmd()
cmdErr := rootCommand.Execute()
if cmdErr != nil {
log.Fatal().Err(cmdErr).Msg("cli error")
}
}
80 changes: 80 additions & 0 deletions cmd/denormalize.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package cmd

import (
"fmt"
"os"

"github.com/cidverse/normalizeci/pkg/normalizer"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)

func denormalizeCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "denormalize",
Short: "denormalizes information about the current CI environment",
Run: func(cmd *cobra.Command, args []string) {
format, _ := cmd.Flags().GetString("format")
outputFile, _ := cmd.Flags().GetString("output")
strict, _ := cmd.Flags().GetBool("strict")
targets, _ := cmd.Flags().GetStringArray("target")

// run normalization
var normalized, err = normalizer.Normalize()
if err != nil {
log.Fatal().Err(err).Msg("normalization failed")
}

// output
outputEnv := make(map[string]string)

// targets
if len(targets) > 0 {
for _, target := range targets {
denormalized, err := normalizer.Denormalize(target, normalized)
if err != nil {
log.Fatal().Err(err).Str("target", target).Msg("denormalization failed")
}

for key, value := range denormalized {
outputEnv[key] = value
}
}
}

// set process env
normalizer.SetProcessEnvironment(outputEnv)

// content?
content, err := normalizer.FormatEnvironment(outputEnv, format)
if err != nil {
log.Fatal().Str("format", format).Str("supported", "export,powershell,cmd").Msg("unsupported format!")
}

// validate?
if strict {
errors := normalized.Validate()
if len(errors) > 0 {
for _, line := range errors {
fmt.Printf("%s: %s [%s]\n", line.Field, line.Description, line.Value)
}
os.Exit(1)
}
}

// output
if len(outputFile) > 0 {
fileOutput(outputFile, content)
} else {
consoleOutput(content)
}
},
}

cmd.PersistentFlags().StringP("format", "f", normalizer.GetDefaultFormat(), "The format in which to store the normalized variables. (export, powershell, cmd)")
cmd.PersistentFlags().StringP("output", "o", "", "Write output to this file instead of writing it to stdout.")
cmd.PersistentFlags().Bool("strict", false, "Validate the generated variables against the spec and fail on errors?")
cmd.PersistentFlags().StringArrayP("target", "t", []string{}, "Additionally generates the environment for the target ci services")

return cmd
}
82 changes: 82 additions & 0 deletions cmd/normalize.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package cmd

import (
"fmt"
"os"

"github.com/cidverse/normalizeci/pkg/envstruct"
"github.com/cidverse/normalizeci/pkg/normalizer"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)

func normalizeCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "normalize",
Short: "normalizes information about the current CI environment",
Run: func(cmd *cobra.Command, args []string) {
format, _ := cmd.Flags().GetString("format")
outputFile, _ := cmd.Flags().GetString("output")
strict, _ := cmd.Flags().GetBool("strict")
targets, _ := cmd.Flags().GetStringArray("target")

// run normalization
var normalized, err = normalizer.Normalize()
if err != nil {
log.Fatal().Err(err).Msg("normalization failed")
}

// transform to map
outputEnv := envstruct.StructToEnvMap(normalized)

// targets
if len(targets) > 0 {
for _, target := range targets {
denormalized, err := normalizer.Denormalize(target, normalized)
if err != nil {
log.Fatal().Err(err).Str("target", target).Msg("denormalization failed")
}

for key, value := range denormalized {
outputEnv[key] = value
}
}
}

// set process env
normalizer.SetProcessEnvironment(outputEnv)

// format content
content, err := normalizer.FormatEnvironment(outputEnv, format)
if err != nil {
log.Fatal().Str("format", format).Str("supported", "export,powershell,cmd").Msg("unsupported format!")
}

// validate?
if strict {
errors := normalized.Validate()
if len(errors) > 0 {
for _, line := range errors {
fmt.Printf("%s: %s [%s]\n", line.Field, line.Description, line.Value)
}
os.Exit(1)
}
}

// output
if len(outputFile) > 0 {
fileOutput(outputFile, content)
} else {
consoleOutput(content)
}
},
}

cmd.PersistentFlags().StringP("format", "f", normalizer.GetDefaultFormat(), "The format in which to store the normalized variables. (export, powershell, cmd)")
cmd.PersistentFlags().StringP("output", "o", "", "Write output to this file instead of writing it to stdout.")
cmd.PersistentFlags().Bool("strict", false, "Validate the generated variables against the spec and fail on errors?")
cmd.PersistentFlags().BoolP("version", "v", false, "all software has versions, this prints version information for normalizeci")
cmd.PersistentFlags().StringArrayP("target", "t", []string{}, "Additionally generates the environment for the target ci services")

return cmd
}
44 changes: 44 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package cmd

import (
"os"
"strings"

"github.com/cidverse/cidverseutils/zerologconfig"
"github.com/spf13/cobra"
)

var cfg zerologconfig.LogConfig

func RootCmd() *cobra.Command {
cmd := &cobra.Command{
Use: `normalizeci`,
Short: `normalizeci provides a foundation for platform-agnostic CI-CD processes.`,
Long: `normalizeci provides a foundation for platform-agnostic CI-CD processes.`,
PersistentPreRun: func(cmd *cobra.Command, args []string) {
if cfg.LogLevel == "" {
if os.Getenv("NCI_LOG_LEVEL") != "" {
cfg.LogLevel = os.Getenv("NCI_LOG_LEVEL")
} else if os.Getenv("NCI_DEBUG") == "true" { // legacy 0.x toggle for debug mode
cfg.LogLevel = "trace"
}
}

zerologconfig.Configure(cfg)
},
Run: func(cmd *cobra.Command, args []string) {
_ = cmd.Help()
os.Exit(0)
},
}

cmd.PersistentFlags().StringVar(&cfg.LogLevel, "log-level", "info", "log level - allowed: "+strings.Join(zerologconfig.ValidLogLevels, ","))
cmd.PersistentFlags().StringVar(&cfg.LogFormat, "log-format", "color", "log format - allowed: "+strings.Join(zerologconfig.ValidLogFormats, ","))
cmd.PersistentFlags().BoolVar(&cfg.LogCaller, "log-caller", false, "include caller in log functions")

cmd.AddCommand(versionCmd())
cmd.AddCommand(normalizeCmd())
cmd.AddCommand(denormalizeCmd())

return cmd
}
23 changes: 23 additions & 0 deletions cmd/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package cmd

import (
"io"
"os"

"github.com/rs/zerolog/log"
)

func fileOutput(file string, content string) {
contentByteArray := []byte(content)
err := os.WriteFile(file, contentByteArray, 0644)
if err != nil {
log.Err(err).Str("file", file).Msg("failed to generate file")
}
}

func consoleOutput(content string) {
_, err := io.WriteString(os.Stdout, content)
if err != nil {
log.Err(err).Msg("failed to write content to stdout")
}
}
39 changes: 39 additions & 0 deletions cmd/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package cmd

import (
"fmt"
"os"
"runtime"

"github.com/spf13/cobra"
)

// Version will be set at build time
var Version string

// RepositoryStatus will be set at build time
var RepositoryStatus string

// CommitHash will be set at build time
var CommitHash string

// BuildAt will be set at build time
var BuildAt string

func versionCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "version",
Short: "print version information",
Run: func(cmd *cobra.Command, args []string) {
_, _ = fmt.Fprintf(os.Stdout, "GitVersion: %s\n", Version)
_, _ = fmt.Fprintf(os.Stdout, "GitCommit: %s\n", CommitHash)
_, _ = fmt.Fprintf(os.Stdout, "GitTreeState: %s\n", RepositoryStatus)
_, _ = fmt.Fprintf(os.Stdout, "BuildDate: %s\n", BuildAt)
_, _ = fmt.Fprintf(os.Stdout, "GoVersion: %s\n", runtime.Version())
_, _ = fmt.Fprintf(os.Stdout, "Compiler: %s\n", runtime.Compiler)
_, _ = fmt.Fprintf(os.Stdout, "Platform: %s\n", runtime.GOOS+"/"+runtime.GOARCH)
},
}

return cmd
}
8 changes: 6 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ go 1.21

require (
github.com/bwmarrin/snowflake v0.3.0
github.com/cidverse/go-vcs v0.0.0-20240628195958-27702663f242
github.com/cidverse/cidverseutils/zerologconfig v0.1.0
github.com/cidverse/go-vcs v0.0.0-20240727232508-6da7d96dca90
github.com/go-playground/validator/v10 v10.22.0
github.com/google/go-github/v63 v63.0.0
github.com/gosimple/slug v1.14.0
github.com/jarcoal/httpmock v1.3.1
github.com/rs/zerolog v1.33.0
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.9.0
github.com/xanzy/go-gitlab v0.107.0
golang.org/x/oauth2 v0.21.0
Expand All @@ -25,7 +27,7 @@ require (
github.com/cyphar/filepath-securejoin v0.3.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.4 // indirect
github.com/gabriel-vasile/mimetype v1.4.5 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.5.0 // indirect
github.com/go-git/go-git/v5 v5.12.0 // indirect
Expand All @@ -36,6 +38,7 @@ require (
github.com/gosimple/unidecode v1.0.1 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
Expand All @@ -45,6 +48,7 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/skeema/knownhosts v1.3.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
golang.org/x/crypto v0.25.0 // indirect
Expand Down
Loading

0 comments on commit 73a2b9e

Please sign in to comment.