update git behavior

This commit is contained in:
DataHearth 2023-09-22 15:41:15 +02:00
parent 7628516d5a
commit 149a230783
No known key found for this signature in database
GPG Key ID: E88FD356ACC5F3C4
5 changed files with 62 additions and 101 deletions

View File

@ -5,7 +5,7 @@ logging:
time: true # OPTIONAL: [default: false] display time in logs
time-format: 02/01/2006 15:04:05 # OPTIONAL: [default: 02/01/2006 15:04:05] format of time displayed in logs
file: /path/to/logfile # OPTIONAL: [default: no file logging] path to log file
disable-console: true # OPTIONAL: [default: true] should logs be printed in the terminal
disable-console: false # OPTIONAL: [default: false] should logs be printed in the terminal
storage:
git:

3
.gitignore vendored
View File

@ -2,4 +2,5 @@
.DS_STORE
build
dist/
.config-mapper.yml
.config-mapper.yml
config/

View File

@ -37,8 +37,8 @@ type Git struct {
Repository string `yaml:"repository"`
Name string `yaml:"name"`
Email string `yaml:"email"`
BasicAuth BasicAuth `yaml:"basic-auth"`
SSH []SshAuth `yaml:"ssh-auth"`
BasicAuth BasicAuth `yaml:"basic"`
SshAuth []SshAuth `yaml:"ssh"`
}
type BasicAuth struct {

View File

@ -15,16 +15,15 @@ import (
)
type Repository struct {
auth []transport.AuthMethod
repository *git.Repository
repoPath string
url string
author struct {
name string
email string
}
availableAuth []transport.AuthMethod
auth transport.AuthMethod
repository *git.Repository
repoPath string
url string
author *object.Signature
}
// NewRepository creates a new repository struct by either cloning or opening the repository
func NewRepository(config Git, repoPath string, clone bool) (*Repository, error) {
var auth []transport.AuthMethod = nil
if config.Repository == "" {
@ -36,7 +35,7 @@ func NewRepository(config Git, repoPath string, clone bool) (*Repository, error)
return nil, err
}
for i, c := range config.SSH {
for i, c := range config.SshAuth {
sshAuth, err := getSSHAuthMethod(c)
if err != nil {
fmt.Printf("failed to create SSH authentication method for configuration n°%d: %v\n", i, err)
@ -57,16 +56,14 @@ func NewRepository(config Git, repoPath string, clone bool) (*Repository, error)
}
repo := &Repository{
auth: auth,
repository: nil,
repoPath: repoPath,
url: config.Repository,
author: struct {
name string
email string
}{
name: config.Name,
email: config.Email,
availableAuth: auth,
auth: nil,
repository: nil,
repoPath: repoPath,
url: config.Repository,
author: &object.Signature{
Name: config.Name,
Email: config.Email,
},
}
@ -83,6 +80,7 @@ func NewRepository(config Git, repoPath string, clone bool) (*Repository, error)
return repo, nil
}
// openRepository opens the repository at the given path
func (r *Repository) openRepository() error {
repo, err := git.PlainOpen(r.repoPath)
if err != nil {
@ -94,9 +92,9 @@ func (r *Repository) openRepository() error {
return err
}
if r.auth != nil {
if r.availableAuth != nil {
pulled := false
for _, auth := range r.auth {
for _, auth := range r.availableAuth {
err := w.Pull(&git.PullOptions{
Auth: auth,
})
@ -113,6 +111,7 @@ func (r *Repository) openRepository() error {
}
pulled = true
r.auth = auth
break
}
@ -130,6 +129,7 @@ func (r *Repository) openRepository() error {
return nil
}
// PushChanges pushes changes to the remote repository
func (r *Repository) PushChanges(msg string, newLines, removedLines []string) error {
w, err := r.repository.Worktree()
if err != nil {
@ -147,93 +147,41 @@ func (r *Repository) PushChanges(msg string, newLines, removedLines []string) er
}
}
author := r.author
author.When = time.Now()
if _, err := w.Commit(msg, &git.CommitOptions{
Author: r.GetAuthor(),
Author: author,
}); err != nil {
return err
}
if r.auth != nil {
pushed := false
for _, auth := range r.auth {
err := r.repository.Push(&git.PushOptions{
Auth: auth,
})
if err != nil {
if checkAuthErr(err) {
logrus.WithField("auth", auth.String()).Warn("failed to authenticate. Trying next auth if exists")
continue
}
return err
}
pushed = true
break
}
if !pushed {
return fmt.Errorf("authentication failed for git repository")
}
}
return r.repository.Push(&git.PushOptions{})
}
func (r *Repository) GetWorktree() (*git.Worktree, error) {
return r.repository.Worktree()
}
func (r *Repository) GetAuthor() *object.Signature {
return &object.Signature{
Name: r.author.name,
Email: r.author.email,
When: time.Now(),
}
return r.repository.Push(&git.PushOptions{
Auth: r.auth,
})
}
// FetchChanges fetches changes from the remote repository. If changes are fetched,
// the function returns true, otherwise false.
func (r *Repository) FetchChanges() (bool, error) {
if r.auth != nil {
for _, auth := range r.auth {
if err := r.repository.Fetch(&git.FetchOptions{
Auth: auth,
}); err != nil {
if checkAuthErr(err) {
logrus.WithField("auth", auth.String()).Warn("failed to authenticate. Trying next auth if exists")
continue
}
if err == git.NoErrAlreadyUpToDate {
return false, nil
}
return false, err
}
return true, nil
}
} else {
if err := r.repository.Fetch(&git.FetchOptions{}); err != nil {
if err == git.NoErrAlreadyUpToDate {
return false, nil
}
return false, err
if err := r.repository.Fetch(&git.FetchOptions{
Auth: r.auth,
}); err != nil {
if err == git.NoErrAlreadyUpToDate {
return false, nil
}
return true, nil
return false, err
}
return false, nil
return true, nil
}
// cloneRepository clones the repository into the given path
func (r *Repository) cloneRepository() error {
var repo *git.Repository
var err error
if r.auth != nil {
for _, auth := range r.auth {
if r.availableAuth != nil {
for _, auth := range r.availableAuth {
repo, err = git.PlainClone(r.repoPath, false, &git.CloneOptions{
URL: r.url,
Auth: auth,
@ -247,6 +195,7 @@ func (r *Repository) cloneRepository() error {
return err
}
r.auth = auth
break
}
@ -267,15 +216,16 @@ func (r *Repository) cloneRepository() error {
return nil
}
// Pull pulls changes from the remote repository
func (r *Repository) Pull() error {
w, err := r.repository.Worktree()
if err != nil {
return err
}
if r.auth != nil {
}
return nil
return w.Pull(&git.PullOptions{
Auth: r.auth,
})
}
// getSSHAuthMethod returns an authentication method for SSH

22
main.go
View File

@ -67,7 +67,7 @@ var (
UsageText: `Initialize will retrieve your configuration folder from the source location and
copy it into the destination field`,
Action: initCommand,
Before: before,
Before: beforeAction,
},
{
Name: "load",
@ -102,7 +102,7 @@ var (
},
},
},
Before: before,
Before: beforeAction,
},
{
Name: "save",
@ -132,7 +132,7 @@ var (
},
},
},
Before: before,
Before: beforeAction,
},
{
Name: "install",
@ -143,8 +143,9 @@ var (
Action: installCommand,
},
{
Name: "check",
Usage: "Check if remote has updates",
Name: "check",
Aliases: []string{"c"},
Usage: "Check if remote has updates",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "pull",
@ -152,6 +153,7 @@ var (
},
},
Action: checkCommand,
Before: beforeAction,
},
},
}
@ -168,7 +170,13 @@ func main() {
}
func initCommand(ctx *cli.Context) error {
if _, err := os.Stat(configuration.Path); err == nil {
logrus.Warnf("configuration folder already exists at %s", configuration.Path)
return nil
}
logrus.WithField("path", configuration.Path).Infoln("initializing configuration folder...")
if _, err := internal.NewRepository(configuration.Storage.Git, configuration.Path, true); err != nil {
return err
}
@ -208,12 +216,14 @@ func checkCommand(ctx *cli.Context) error {
return err
}
}
} else {
logrus.Infoln("Configuration is up-to-date")
}
return nil
}
func before(ctx *cli.Context) error {
func beforeAction(ctx *cli.Context) error {
configPath, err := internal.ResolvePath(ctx.String("config"))
if err != nil {
return err