From 2356fab9d4f1cb831a1f51b5bd139be8a1aa7f0b Mon Sep 17 00:00:00 2001 From: Marcus Kok <47163063+Marcusk19@users.noreply.github.com> Date: Sat, 23 Mar 2024 15:30:59 -0400 Subject: [PATCH] Add sync (#14) * adding sync command * changing version in go.mod --- cmd/backup.go | 14 ----- cmd/root.go | 8 ++- cmd/sync.go | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 4 +- go.sum | 9 +++ 5 files changed, 176 insertions(+), 16 deletions(-) create mode 100644 cmd/sync.go diff --git a/cmd/backup.go b/cmd/backup.go index 0808d9d..ccd5607 100644 --- a/cmd/backup.go +++ b/cmd/backup.go @@ -8,7 +8,6 @@ import ( "github.com/Marcusk19/bender/tools" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing/object" - "github.com/spf13/afero" "github.com/spf13/cobra" ) @@ -22,19 +21,6 @@ var backupCommand = &cobra.Command { Run: runBackup, } -func gitAddFiles(worktree *git.Worktree, fs afero.Fs) error { - entries, err := afero.ReadDir(fs, DotfilePath) - if err != nil { - return err - } - for _, entry := range(entries) { - _, err = worktree.Add(entry.Name()) - if err != nil { - return err - } - } - return nil -} func runBackup(cmd *cobra.Command, args []string) { fmt.Fprintf(cmd.OutOrStdout(), "Backing up %s...\n", DotfilePath) diff --git a/cmd/root.go b/cmd/root.go index 073107a..71dd675 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -88,5 +88,11 @@ func UseFilesystem() afero.Fs { } } -// TODO: this can probably be removed +func CheckIfError(err error) { + if err != nil { + panic(err) + } + return +} + diff --git a/cmd/sync.go b/cmd/sync.go new file mode 100644 index 0000000..86e4e49 --- /dev/null +++ b/cmd/sync.go @@ -0,0 +1,157 @@ +package cmd + +import ( + "errors" + "fmt" + "log" + "time" + + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/config" + "github.com/go-git/go-git/v5/plumbing/object" + "github.com/go-git/go-git/v5/plumbing/transport/http" + "github.com/manifoldco/promptui" + "github.com/spf13/afero" + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +var remoteRepository string + +func init() { + RootCmd.AddCommand(syncCommand) + syncCommand.Flags().StringVarP( + &remoteRepository, + "remote", + "r", + "", + "URL of remote repository", + ) + + viper.BindPFlag("bender-origin", syncCommand.Flags().Lookup("remote")) +} + +var syncCommand = &cobra.Command{ + Use: "sync", + Short: "Sync dotfiles with git", + Long: "TODO: add longer description", + Run: runSyncCommand, +} + +func validateInput(input string) error { + if input == "" { + return errors.New("Missing input") + } + + return nil +} + +func gitAddFiles(worktree *git.Worktree, fs afero.Fs) error { + dotfilepath := viper.GetString("dotfile-path") + entries, err := afero.ReadDir(fs, dotfilepath) + if err != nil { + return err + } + for _, entry := range(entries) { + _, err = worktree.Add(entry.Name()) + if err != nil { + return err + } + } + return nil +} + +func runSyncCommand(cmd *cobra.Command, args []string) { + origin := viper.GetString("bender-origin") + if origin == "" { + fmt.Fprintln(cmd.OutOrStdout(), "No remote repository found") + return + } + + dotfilepath := viper.GetString("dotfile-path") + r, err := git.PlainOpen(dotfilepath) + CheckIfError(err) + + // check remotes and if origin does not exist + // we need to create it + list, err := r.Remotes() + CheckIfError(err) + + if len(list) == 0 { + r.CreateRemote(&config.RemoteConfig{ + Name: "origin", + URLs: []string{origin}, + }) + } + + w, err := r.Worktree() + CheckIfError(err) + + username := promptui.Prompt{ + Label: "username", + Validate: validateInput, + } + + password := promptui.Prompt{ + Label: "password", + Validate: validateInput, + } + + usernameVal, err := username.Run() + CheckIfError(err) + + passwordVal, err := password.Run() + CheckIfError(err) + + err = w.Pull(&git.PullOptions{ + RemoteName: "origin", + Auth: &http.BasicAuth { + Username: usernameVal, + Password: passwordVal, + }, + }) + + if err != nil{ + fmt.Println(err) + } else { + fmt.Fprintf(cmd.OutOrStdout(), "successfully pulled from %s", origin) + } + + err = gitAddFiles(w, FileSystem) + if err != nil { + log.Fatalf("Could not add files: %s\n", err) + } + + commitMessage := "backup " + time.Now().String() + + commit, err := w.Commit(commitMessage, &git.CommitOptions{ + Author: &object.Signature{ + Name: "bender CLI", + Email: "example@example.com", + When: time.Now(), + }, + }) + + if err != nil { + log.Fatal(err.Error()) + } + + obj, err := r.CommitObject(commit) + + if err != nil { + log.Fatalf("Cannot commit: %s",err) + } + + fmt.Println(obj) + + err = r.Push(&git.PushOptions{ + RemoteName: "origin", + Auth: &http.BasicAuth { + Username: usernameVal, + Password: passwordVal, + }, + }) + CheckIfError(err) + viper.WriteConfig() + +} diff --git a/go.mod b/go.mod index e6458e8..dfbc84f 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,10 @@ module github.com/Marcusk19/bender -go 1.22.0 +go 1.21.0 require ( github.com/go-git/go-git/v5 v5.11.0 + github.com/manifoldco/promptui v0.9.0 github.com/spf13/afero v1.11.0 github.com/spf13/cobra v1.8.0 github.com/spf13/viper v1.18.2 @@ -14,6 +15,7 @@ require ( dario.cat/mergo v1.0.0 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect + github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect github.com/cloudflare/circl v1.3.3 // indirect github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect diff --git a/go.sum b/go.sum index 7b0423d..1afaad4 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,12 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuW github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -58,6 +64,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= +github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= @@ -142,6 +150,7 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=