Skip to content

Commit

Permalink
feat: ✨ add sensible defaults
Browse files Browse the repository at this point in the history
  • Loading branch information
AkashRajpurohit committed Jan 9, 2025
1 parent ceec51d commit fcaf024
Show file tree
Hide file tree
Showing 6 changed files with 273 additions and 33 deletions.
2 changes: 2 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ var rootCmd = &cobra.Command{
var cfg config.Config
cfg, err := config.LoadConfig(cfgFile)

config.SetSensibleDefaults(&cfg)

if err != nil {
logger.Debugf("Error in loading config file: ", err)
logger.Info("Config file not found, creating a new one...")
Expand Down
32 changes: 0 additions & 32 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,37 +40,6 @@ type Config struct {
Retry RetryConfig `mapstructure:"retry"`
}

// PreprocessConfig handles backward compatibility for token field
func PreprocessConfig(cfg *Config) {
// TODO: Remove these before v1.0.0 release
// If concurrency is not set, set it to 5
if cfg.Concurrency == 0 {
logger.Warn("Concurrency is required but not set. Add the 'concurrency' field to the config file as mentioned in the docs: https://github.com/AkashRajpurohit/git-sync/wiki/Configuration. Setting it to 5.")
cfg.Concurrency = 5
}

// If no clone_type is not set in the config file, set it to bare
if cfg.CloneType == "" {
logger.Warn("Clone type is required but not set. Add the 'clone_type' field to the config file as mentioned in the docs: https://github.com/AkashRajpurohit/git-sync/wiki/Configuration. Setting it to 'bare'.")
cfg.CloneType = "bare"
}

// If both are set, merge them with single token being first
if cfg.Token != "" && len(cfg.Tokens) > 0 {
logger.Warn("Both 'token' and 'tokens' fields are set. 'token' field is deprecated and will be merged with 'tokens'.")
cfg.Tokens = append([]string{cfg.Token}, cfg.Tokens...)
}

// If single token is set and tokens array is empty, convert single token to array
if cfg.Token != "" && len(cfg.Tokens) == 0 {
logger.Warn("Using 'token' field is deprecated. Please use 'tokens' array instead.")
cfg.Tokens = []string{cfg.Token}
}

// Clear the deprecated token field
cfg.Token = ""
}

func expandPath(path string) string {
if strings.HasPrefix(path, "~/") {
homeDir, _ := os.UserHomeDir()
Expand Down Expand Up @@ -128,7 +97,6 @@ func LoadConfig(cfgFile string) (Config, error) {
return config, err
}

PreprocessConfig(&config)
return config, nil
}

Expand Down
55 changes: 55 additions & 0 deletions pkg/config/defaults.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package config

import "github.com/AkashRajpurohit/git-sync/pkg/logger"

func SetSensibleDefaults(cfg *Config) {
if cfg.Platform != "" && (cfg.Server.Domain == "" || cfg.Server.Protocol == "") {
if cfg.Platform == "github" {
cfg.Server.Domain = "github.com"
cfg.Server.Protocol = "https"
}

if cfg.Platform == "gitlab" {
cfg.Server.Domain = "gitlab.com"
cfg.Server.Protocol = "https"
}

if cfg.Platform == "bitbucket" {
cfg.Server.Domain = "bitbucket.org"
cfg.Server.Protocol = "https"
}

if cfg.Platform == "forgejo" {
cfg.Server.Domain = "v9.next.forgejo.org"
cfg.Server.Protocol = "https"
}
}

// TODO: Remove these before v1.0.0 release
// If concurrency is not set, set it to 5
if cfg.Concurrency == 0 {
logger.Warn("Concurrency is required but not set. Add the 'concurrency' field to the config file as mentioned in the docs: https://github.com/AkashRajpurohit/git-sync/wiki/Configuration. Setting it to 5.")
cfg.Concurrency = 5
}

// If no clone_type is not set in the config file, set it to bare
if cfg.CloneType == "" {
logger.Warn("Clone type is required but not set. Add the 'clone_type' field to the config file as mentioned in the docs: https://github.com/AkashRajpurohit/git-sync/wiki/Configuration. Setting it to 'bare'.")
cfg.CloneType = "bare"
}

// If both are set, merge them with single token being first
if cfg.Token != "" && len(cfg.Tokens) > 0 {
logger.Warn("Both 'token' and 'tokens' fields are set. 'token' field is deprecated and will be merged with 'tokens'.")
cfg.Tokens = append([]string{cfg.Token}, cfg.Tokens...)
}

// If single token is set and tokens array is empty, convert single token to array
if cfg.Token != "" && len(cfg.Tokens) == 0 {
logger.Warn("Using 'token' field is deprecated. Please use 'tokens' array instead.")
cfg.Tokens = []string{cfg.Token}
}

// Clear the deprecated token field
cfg.Token = ""
}
191 changes: 191 additions & 0 deletions pkg/config/defaults_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
package config

import (
"testing"

"github.com/AkashRajpurohit/git-sync/pkg/logger"
)

func TestSetSensibleDefaults(t *testing.T) {
tests := []struct {
name string
cfg Config
expected Config
}{
{
name: "GitHub platform defaults",
cfg: Config{
Platform: "github",
},
expected: Config{
Platform: "github",
Server: Server{
Domain: "github.com",
Protocol: "https",
},
CloneType: "bare",
Concurrency: 5,
},
},
{
name: "GitLab platform defaults",
cfg: Config{
Platform: "gitlab",
},
expected: Config{
Platform: "gitlab",
Server: Server{
Domain: "gitlab.com",
Protocol: "https",
},
CloneType: "bare",
Concurrency: 5,
},
},
{
name: "Bitbucket platform defaults",
cfg: Config{
Platform: "bitbucket",
},
expected: Config{
Platform: "bitbucket",
Server: Server{
Domain: "bitbucket.org",
Protocol: "https",
},
CloneType: "bare",
Concurrency: 5,
},
},
{
name: "Forgejo platform defaults",
cfg: Config{
Platform: "forgejo",
},
expected: Config{
Platform: "forgejo",
Server: Server{
Domain: "v9.next.forgejo.org",
Protocol: "https",
},
CloneType: "bare",
Concurrency: 5,
},
},
{
name: "Default concurrency when not set",
cfg: Config{
Platform: "github",
Server: Server{
Domain: "github.com",
Protocol: "https",
},
},
expected: Config{
Platform: "github",
Server: Server{
Domain: "github.com",
Protocol: "https",
},
CloneType: "bare",
Concurrency: 5,
},
},
{
name: "Default clone type when not set",
cfg: Config{
Platform: "github",
Server: Server{
Domain: "github.com",
Protocol: "https",
},
Concurrency: 5,
},
expected: Config{
Platform: "github",
Server: Server{
Domain: "github.com",
Protocol: "https",
},
CloneType: "bare",
Concurrency: 5,
},
},
{
name: "Merge single token with tokens array",
cfg: Config{
Token: "single-token",
Tokens: []string{"token1", "token2"},
},
expected: Config{
Tokens: []string{"single-token", "token1", "token2"},
CloneType: "bare",
Concurrency: 5,
},
},
{
name: "Convert single token to tokens array",
cfg: Config{
Token: "single-token",
},
expected: Config{
Tokens: []string{"single-token"},
CloneType: "bare",
Concurrency: 5,
},
},
{
name: "Keep existing values if already set",
cfg: Config{
Platform: "github",
CloneType: "mirror",
Concurrency: 10,
Server: Server{
Domain: "custom.github.com",
Protocol: "ssh",
},
},
expected: Config{
Platform: "github",
CloneType: "mirror",
Concurrency: 10,
Server: Server{
Domain: "custom.github.com",
Protocol: "ssh",
},
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
logger.InitLogger("fatal")
cfg := tt.cfg
SetSensibleDefaults(&cfg)

if cfg.Server.Domain != tt.expected.Server.Domain {
t.Errorf("Server Domain = %v, want %v", cfg.Server.Domain, tt.expected.Server.Domain)
}
if cfg.Server.Protocol != tt.expected.Server.Protocol {
t.Errorf("Server Protocol = %v, want %v", cfg.Server.Protocol, tt.expected.Server.Protocol)
}
if cfg.CloneType != tt.expected.CloneType {
t.Errorf("CloneType = %v, want %v", cfg.CloneType, tt.expected.CloneType)
}
if cfg.Concurrency != tt.expected.Concurrency {
t.Errorf("Concurrency = %v, want %v", cfg.Concurrency, tt.expected.Concurrency)
}
if cfg.Token != "" {
t.Error("Token should be cleared after conversion")
}
if len(cfg.Tokens) != len(tt.expected.Tokens) {
t.Errorf("Tokens length = %v, want %v", len(cfg.Tokens), len(tt.expected.Tokens))
}
for i, token := range tt.expected.Tokens {
if i < len(cfg.Tokens) && cfg.Tokens[i] != token {
t.Errorf("Token at index %d = %v, want %v", i, cfg.Tokens[i], token)
}
}
})
}
}
4 changes: 4 additions & 0 deletions pkg/config/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ func ValidateConfig(cfg Config) error {
return fmt.Errorf("at least one token must be provided when no raw git URLs are provided. See here: https://github.com/AkashRajpurohit/git-sync/wiki/Configuration")
}

if cfg.Platform != "github" && cfg.Platform != "gitlab" && cfg.Platform != "bitbucket" && cfg.Platform != "forgejo" {
return fmt.Errorf("platform can only be `github`, `gitlab`, `bitbucket` or `forgejo` when no raw git URLs are provided")
}

// Server configuration is required for platform-specific sync
if cfg.Server.Domain == "" {
return fmt.Errorf("server domain cannot be empty when no raw git URLs are provided")
Expand Down
Loading

0 comments on commit fcaf024

Please sign in to comment.