wip
This commit is contained in:
parent
3a892d628e
commit
7628516d5a
174
internal/git.go
174
internal/git.go
|
@ -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
142
main.go
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Reference in New Issue