This commit is contained in:
2025-10-20 00:15:57 +02:00
parent 68902f86af
commit 8ca8918966
7 changed files with 204 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
package apply
import (
"context"
"flag"
"fmt"
"mirror-sync/pkg/project"
"os"
"github.com/google/subcommands"
)
type (
ApplyCmd struct {
}
)
func (*ApplyCmd) Name() string { return "apply" }
func (*ApplyCmd) Synopsis() string { return "apply the current project settings" }
func (*ApplyCmd) Usage() string {
return `Usage: git-sync apply
apply the current project settings
Options:
`
}
func (p *ApplyCmd) SetFlags(f *flag.FlagSet) {
}
func (p *ApplyCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
projectConfig, err := project.LoadCurrent()
if err != nil {
fmt.Fprintf(os.Stderr, "error: %s\n", err)
return subcommands.ExitFailure
}
return subcommands.ExitSuccess
}

View File

@@ -0,0 +1,44 @@
package version
import (
"context"
"flag"
"fmt"
"mirror-sync/pkg/constants"
"runtime"
"strconv"
"github.com/google/subcommands"
)
type (
VersionCmd struct {
}
)
func (*VersionCmd) Name() string { return "version" }
func (*VersionCmd) Synopsis() string { return "show version and system information" }
func (*VersionCmd) Usage() string {
return `Usage: cloudsave version
Print the version of the software
Options:
`
}
func (p *VersionCmd) SetFlags(f *flag.FlagSet) {
}
func (p *VersionCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
local()
return subcommands.ExitSuccess
}
func local() {
fmt.Println("Client: git-sync cli")
fmt.Println(" Version: " + constants.Version)
fmt.Println(" API version: " + strconv.Itoa(constants.ApiVersion))
fmt.Println(" Go version: " + runtime.Version())
fmt.Println(" OS/Arch: " + runtime.GOOS + "/" + runtime.GOARCH)
}

25
cmd/cli/main.go Normal file
View File

@@ -0,0 +1,25 @@
package main
import (
"context"
"flag"
"mirror-sync/cmd/cli/commands/apply"
"mirror-sync/cmd/cli/commands/version"
"os"
"github.com/google/subcommands"
)
func main() {
subcommands.Register(subcommands.HelpCommand(), "help")
subcommands.Register(subcommands.FlagsCommand(), "help")
subcommands.Register(subcommands.CommandsCommand(), "help")
subcommands.Register(&version.VersionCmd{}, "help")
subcommands.Register(&apply.ApplyCmd{}, "projects")
flag.Parse()
ctx := context.Background()
os.Exit(int(subcommands.Execute(ctx)))
}

2
go.mod
View File

@@ -5,6 +5,8 @@ go 1.25
require (
github.com/go-chi/chi/v5 v5.2.3
github.com/go-git/go-git/v6 v6.0.0-20250929195514-145daf2492dd
github.com/goccy/go-yaml v1.18.0
github.com/google/subcommands v1.2.0
)
require (

4
go.sum
View File

@@ -29,8 +29,12 @@ github.com/go-git/go-git-fixtures/v5 v5.1.1 h1:OH8i1ojV9bWfr0ZfasfpgtUXQHQyVS8HX
github.com/go-git/go-git-fixtures/v5 v5.1.1/go.mod h1:Altk43lx3b1ks+dVoAG2300o5WWUnktvfY3VI6bcaXU=
github.com/go-git/go-git/v6 v6.0.0-20250929195514-145daf2492dd h1:30HEd5KKVM7GgMJ1GSNuYxuZXEg8Pdlngp6T51faxoc=
github.com/go-git/go-git/v6 v6.0.0-20250929195514-145daf2492dd/go.mod h1:lz8PQr/p79XpFq5ODVBwRJu5LnOF8Et7j95ehqmCMJU=
github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
github.com/google/subcommands v1.2.0 h1:vWQspBTo2nEqTUFita5/KeEWlUL8kQObDFbub/EN9oE=
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/kevinburke/ssh_config v1.4.0 h1:6xxtP5bZ2E4NF5tuQulISpTO2z8XbtH8cg1PWkxoFkQ=
github.com/kevinburke/ssh_config v1.4.0/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M=
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=

72
pkg/project/file.go Normal file
View File

@@ -0,0 +1,72 @@
package project
import (
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/goccy/go-yaml"
)
type (
MainFile struct {
Repositories map[string]RepositoryDescriptor `yaml:"repositories"`
ProjectName string `yaml:"project_name"`
}
RepositoryDescriptor struct {
Storage GitStorage `yaml:"storage"`
Schedule string `yaml:"schedule"`
}
GitStorage struct {
Source string `yaml:"source"`
Destination string `yaml:"destination"`
}
)
var (
ErrOS error = errors.New("failed to get os parameters")
ErrIO error = errors.New("failed to open file")
ErrParsing error = errors.New("failed to parse file")
)
func LoadCurrent() (Project, error) {
wd, err := os.Getwd()
if err != nil {
return Project{}, fmt.Errorf("%w: cannot get current working directory path: %s", ErrOS, err)
}
f, err := os.OpenFile("./git-compose.yaml", os.O_RDONLY, 0)
if err != nil {
return Project{}, fmt.Errorf("%w: %s", ErrIO, err)
}
defer f.Close()
var mainFile MainFile
d := yaml.NewDecoder(f)
if err := d.Decode(&mainFile); err != nil {
return Project{}, fmt.Errorf("%w: %s", ErrParsing, err)
}
pr := Project{
Name: filepath.Base(wd),
}
if len(strings.TrimSpace(mainFile.ProjectName)) > 0 {
pr.Name = mainFile.ProjectName
}
for repoName, repo := range mainFile.Repositories {
pr.Repositories = append(pr.Repositories, Repository{
Name: fmt.Sprintf("%s-%s", pr.Name, strings.ToLower(repoName)),
Source: repo.Storage.Source,
Destination: repo.Storage.Destination,
Schedule: repo.Schedule,
})
}
return pr, nil
}

15
pkg/project/project.go Normal file
View File

@@ -0,0 +1,15 @@
package project
type (
Project struct {
Name string `json:"name"`
Repositories []Repository `json:"repositories"`
}
Repository struct {
Name string `json:"name"`
Schedule string `json:"schedule"`
Source string `json:"source"`
Destination string `json:"destination"`
}
)