This commit is contained in:
DataHearth 2023-09-22 11:04:49 +02:00
parent 3a892d628e
commit 7628516d5a
No known key found for this signature in database
GPG Key ID: E88FD356ACC5F3C4
2 changed files with 158 additions and 158 deletions

View File

@ -14,31 +14,18 @@ import (
"github.com/sirupsen/logrus"
)
var (
ErrDirIsFile = errors.New("path is a file")
)
type RepositoryActions interface {
PushChanges(msg string, newLines, removedLines []string) error
GetWorktree() (*git.Worktree, error)
GetAuthor() *object.Signature
openRepository() error
}
type Repository struct {
auth []transport.AuthMethod
repository *git.Repository
repoPath string
author author
url string
author struct {
name string
email string
}
}
type author struct {
name string
email string
}
func NewRepository(config Git, repoPath string) (RepositoryActions, error) {
func NewRepository(config Git, repoPath string, clone bool) (*Repository, error) {
var auth []transport.AuthMethod = nil
if config.Repository == "" {
return nil, errors.New("a repository URI is needed (either using GIT protocol or HTTPS)")
@ -74,68 +61,29 @@ func NewRepository(config Git, repoPath string) (RepositoryActions, error) {
repository: nil,
repoPath: repoPath,
url: config.Repository,
author: author{
author: struct {
name string
email string
}{
name: config.Name,
email: config.Email,
},
}
if err := repo.openRepository(); err != nil {
return nil, err
if clone {
if err := repo.cloneRepository(); err != nil {
return nil, err
}
} else {
if err := repo.openRepository(); err != nil {
return nil, err
}
}
return repo, nil
}
func (r *Repository) openRepository() error {
s, err := os.Stat(r.repoPath)
if err != nil {
if os.IsNotExist(err) {
var repo *git.Repository
var err error
if r.auth != nil {
for _, auth := range r.auth {
repo, err = git.PlainClone(r.repoPath, false, &git.CloneOptions{
URL: r.url,
Progress: os.Stdout,
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
}
break
}
if repo == nil {
return fmt.Errorf("authentication failed for git repository")
}
} else {
repo, err = git.PlainClone(r.repoPath, false, &git.CloneOptions{
URL: r.url,
Progress: os.Stdout,
})
if err != nil {
return err
}
}
r.repository = repo
return nil
}
return err
}
if !s.IsDir() {
return ErrDirIsFile
}
repo, err := git.PlainOpen(r.repoPath)
if err != nil {
return err
@ -244,6 +192,93 @@ func (r *Repository) GetAuthor() *object.Signature {
}
}
// 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
}
return true, nil
}
return false, 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 {
repo, err = git.PlainClone(r.repoPath, false, &git.CloneOptions{
URL: r.url,
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
}
break
}
if repo == nil {
return fmt.Errorf("authentication failed for git repository")
}
} else {
repo, err = git.PlainClone(r.repoPath, false, &git.CloneOptions{
URL: r.url,
})
if err != nil {
return err
}
}
r.repository = repo
return nil
}
func (r *Repository) Pull() error {
w, err := r.repository.Worktree()
if err != nil {
return err
}
if r.auth != nil {
}
return nil
}
// getSSHAuthMethod returns an authentication method for SSH
func getSSHAuthMethod(config SshAuth) (transport.AuthMethod, error) {
if config.PrivateKey == "" {
return nil, errors.New("\"private-key\" field is empty")
@ -270,6 +305,7 @@ func getSSHAuthMethod(config SshAuth) (transport.AuthMethod, error) {
return auth, nil
}
// checkAuthErr checks if the error is an authentication error
func checkAuthErr(err error) bool {
return err == transport.ErrAuthorizationFailed || err == transport.ErrAuthenticationRequired
}

142
main.go
View File

@ -32,11 +32,6 @@ var (
Suggest: true,
EnableBashCompletion: true,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "verbose",
Aliases: []string{"v"},
Usage: "logs will be more verbose",
},
&cli.StringFlag{
Name: "config",
Aliases: []string{"c"},
@ -139,6 +134,25 @@ var (
},
Before: before,
},
{
Name: "install",
Usage: "Install additional tools",
UsageText: `Install additional tools like package managers (brew, nala),
programming language (golang, rust, python)`,
ArgsUsage: "TOOLS",
Action: installCommand,
},
{
Name: "check",
Usage: "Check if remote has updates",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "pull",
Usage: "Pull updates if any",
},
},
Action: checkCommand,
},
},
}
)
@ -148,104 +162,54 @@ func init() {
}
func main() {
cli.VersionFlag = &cli.BoolFlag{
Name: "version",
Aliases: []string{"V"},
Usage: "config-mapper version",
}
if err := app.Run(os.Args); err != nil {
logrus.Fatalln(err)
}
}
// func save(cmd *cobra.Command, args []string) {
// var c configuration.Configuration
// if err := viper.Unmarshal(&c); err != nil {
// logrus.Fatal("failed to decode configuration", "err", err)
// }
// indexer, err := mapper.NewIndexer(c.Storage.Path)
// if err != nil {
// logrus.Fatal("failed to open the indexer", "err", err)
// }
// r, err := git.NewRepository(c.Storage.Git, c.Storage.Path)
// if err != nil {
// logrus.Fatal("failed to open repository", "path", c.Storage.Path, "err", err)
// }
// el := mapper.NewItemsActions(nil, c.Storage.Path, r, indexer)
// if !viper.GetBool("save-disable-files") {
// el.AddItems(c.Files)
// }
// if !viper.GetBool("save-disable-folders") {
// el.AddItems(c.Folders)
// }
// el.Action("save")
// if err := el.CleanUp(indexer.RemovedLines()); err != nil {
// logrus.Fatal("failed to clean repository", "err", err)
// }
// if viper.GetBool("push") {
// logrus.Info("pushing changes...")
// if err := r.PushChanges(viper.GetString("message"), indexer.Lines(), indexer.RemovedLines()); err != nil {
// logrus.Fatal("failed to push changes to repository", "err", err)
// }
// }
// }
// func load(cmd *cobra.Command, args []string) {
// var c configuration.Configuration
// if err := viper.Unmarshal(&c); err != nil {
// logrus.Fatal("failed to decode configuration", "err", err)
// }
// i, err := mapper.NewIndexer(c.Storage.Path)
// if err != nil {
// logrus.Fatal("failed to open the indexer", "err", err)
// }
// r, err := git.NewRepository(c.Storage.Git, c.Storage.Path)
// if err != nil {
// logrus.Fatal("failed to open repository", "path", c.Storage.Path, "err", err)
// }
// el := mapper.NewItemsActions(nil, c.Storage.Path, r, i)
// if !viper.GetBool("load-disable-files") {
// el.AddItems(c.Files)
// }
// if !viper.GetBool("load-disable-folders") {
// el.AddItems(c.Folders)
// }
// el.Action("load")
// if viper.GetBool("load-enable-pkgs") {
// if err := mapper.InstallPackages(c.PackageManagers); err != nil {
// logrus.Fatal(err)
// }
// }
// }
func initCommand(Ctx *cli.Context) error {
if _, err := internal.NewRepository(configuration.Storage.Git, configuration.Path); err != nil {
func initCommand(ctx *cli.Context) error {
logrus.WithField("path", configuration.Path).Infoln("initializing configuration folder...")
if _, err := internal.NewRepository(configuration.Storage.Git, configuration.Path, true); err != nil {
return err
}
logrus.Infoln("Everything is ready to go!")
return nil
}
func saveCommand(Ctx *cli.Context) error {
func saveCommand(ctx *cli.Context) error {
return nil
}
func loadCommand(Ctx *cli.Context) error {
func loadCommand(ctx *cli.Context) error {
return nil
}
func installCommand(ctx *cli.Context) error {
return nil
}
func checkCommand(ctx *cli.Context) error {
repo, err := internal.NewRepository(configuration.Storage.Git, configuration.Path, false)
if err != nil {
return err
}
changes, err := repo.FetchChanges()
if err != nil {
return err
}
if changes {
logrus.Infoln("Configuration has changed upstream")
if ctx.Bool("pull") {
logrus.Infoln("Pulling changes...")
if err := repo.Pull(); err != nil {
return err
}
}
}
return nil
}