Skip to content
Draft

init #167

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ require (
golang.org/x/sys v0.34.0 // indirect
golang.org/x/term v0.33.0 // indirect
golang.org/x/time v0.12.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
40 changes: 32 additions & 8 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,44 @@ var knownServices = map[string]string{

func main() {

c, err := initConfig(os.Args[1:])
if err != nil {
log.Fatal(err)
args := os.Args[1:]
if len(args) > 0 {
switch args[0] {
case "create-config":
handleCreateConfig(args[1:])
return
case "validate-config":
handleValidateConfig(args[1:])
return
case "help", "--help", "-h":
printCreateConfigUsage()
return
}
}
err = validateConfig(c)
if err != nil {
log.Fatal(err)

var c *appConfig
if _, err := os.Stat("gitbackup.yml"); err == nil {
c, err = LoadYAMLConfig("gitbackup.yml")
if err != nil {
log.Fatalf("Failed to load gitbackup.yml: %v", err)
}
if err := validateYAMLConfig("gitbackup.yml"); err != nil {
log.Fatalf("Config validation failed: %v", err)
}
} else {
c, err = initConfig(args)
if err != nil {
log.Fatal(err)
}
err = validateConfig(c)
if err != nil {
log.Fatal(err)
}
}

client := newClient(c.service, c.gitHostURL)
var executionErr error

// TODO implement validation of options so that we don't
// allow multiple operations at one go
if c.githubListUserMigrations {
handleGithubListUserMigrations(client, c)
} else if c.githubCreateUserMigration {
Expand Down
41 changes: 41 additions & 0 deletions yaml_cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package main

import (
"fmt"
"os"
)

func printCreateConfigUsage() {
fmt.Println(`Usage:

Check failure on line 9 in yaml_cli.go

View workflow job for this annotation

GitHub Actions / Go 1.24 tests - MacOS

fmt.Println arg list ends with redundant newline

Check failure on line 9 in yaml_cli.go

View workflow job for this annotation

GitHub Actions / Go 1.24 tests - Linux

fmt.Println arg list ends with redundant newline

Check failure on line 9 in yaml_cli.go

View workflow job for this annotation

GitHub Actions / Go 1.24 tests - Windows

fmt.Println arg list ends with redundant newline
gitbackup create-config [path]
gitbackup validate-config [path]

[path] is optional, defaults to ./gitbackup.yml
`)
}

func handleCreateConfig(args []string) {
path := "gitbackup.yml"
if len(args) > 0 {
path = args[0]
}
err := WriteSampleYAMLConfig(path)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to create config: %v\n", err)
os.Exit(1)
}
fmt.Printf("Sample config written to %s\n", path)
}

func handleValidateConfig(args []string) {
path := "gitbackup.yml"
if len(args) > 0 {
path = args[0]
}
err := validateYAMLConfig(path)
if err != nil {
fmt.Fprintf(os.Stderr, "Config validation failed: %v\n", err)
os.Exit(1)
}
fmt.Println("Config is valid.")
}
50 changes: 50 additions & 0 deletions yaml_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package main

import (
"os"
"gopkg.in/yaml.v3"
)

func LoadYAMLConfig(path string) (*appConfig, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close()

var c appConfig
dec := yaml.NewDecoder(f)
if err := dec.Decode(&c); err != nil {
return nil, err
}
return &c, nil
}

func WriteSampleYAMLConfig(path string) error {
c := appConfig{
service: "github",
gitHostURL: "github.com",
backupDir: "./backup",
ignorePrivate: false,
ignoreFork: false,
useHTTPSClone: true,
bare: false,
githubRepoType: "all",
githubNamespaceWhitelist: []string{"user1", "org2"},
githubCreateUserMigration: false,
githubCreateUserMigrationRetry: true,
githubCreateUserMigrationRetryMax: 5,
githubListUserMigrations: false,
githubWaitForMigrationComplete: true,
gitlabProjectVisibility: "internal",
gitlabProjectMembershipType: "all",
}
f, err := os.Create(path)
if err != nil {
return err
}
defer f.Close()
enc := yaml.NewEncoder(f)
defer enc.Close()
return enc.Encode(c)
}
34 changes: 34 additions & 0 deletions yaml_validate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package main

import (
"fmt"
"os"
)

func validateYAMLConfig(path string) error {
c, err := LoadYAMLConfig(path)
if err != nil {
return fmt.Errorf("failed to load config: %w", err)
}
// Validate required fields
if _, ok := knownServices[c.service]; !ok {
return fmt.Errorf("invalid service: %s", c.service)
}
// Check env vars for secrets (example: GITHUB_TOKEN)
if c.service == "github" {
if os.Getenv("GITHUB_TOKEN") == "" {
return fmt.Errorf("GITHUB_TOKEN environment variable not set")
}
}
if c.service == "gitlab" {
if os.Getenv("GITLAB_TOKEN") == "" {
return fmt.Errorf("GITLAB_TOKEN environment variable not set")
}
}
if c.service == "bitbucket" {
if os.Getenv("BITBUCKET_TOKEN") == "" {
return fmt.Errorf("BITBUCKET_TOKEN environment variable not set")
}
}
return nil
}
Loading