diff options
| author | Ibrahim Serdar Acikgoz <serdaracikgoz86@gmail.com> | 2019-01-04 03:24:46 +0300 |
|---|---|---|
| committer | Ibrahim Serdar Acikgoz <serdaracikgoz86@gmail.com> | 2019-01-04 03:24:46 +0300 |
| commit | b4547c56f3c28f0d03ee9437ec93c0e6fb6e0331 (patch) | |
| tree | 0458a9afbabdb34938e287ba8c3bec5edb948f38 | |
| parent | remove unnecessary code (diff) | |
| download | gitbatch-b4547c56f3c28f0d03ee9437ec93c0e6fb6e0331.tar.gz | |
huge refactor, package layour re-organized
| -rw-r--r-- | app/app.go (renamed from pkg/app/app.go) | 2 | ||||
| -rw-r--r-- | app/config.go (renamed from pkg/app/config.go) | 0 | ||||
| -rw-r--r-- | app/files.go (renamed from pkg/app/files.go) | 0 | ||||
| -rw-r--r-- | app/quick.go (renamed from pkg/app/quick.go) | 7 | ||||
| -rw-r--r-- | core/command/cmd-add.go (renamed from pkg/git/cmd-add.go) | 11 | ||||
| -rw-r--r-- | core/command/cmd-commit.go (renamed from pkg/git/cmd-commit.go) | 13 | ||||
| -rw-r--r-- | core/command/cmd-config.go (renamed from pkg/git/cmd-config.go) | 15 | ||||
| -rw-r--r-- | core/command/cmd-diff.go (renamed from pkg/git/cmd-diff.go) | 15 | ||||
| -rw-r--r-- | core/command/cmd-fetch.go (renamed from pkg/git/cmd-fetch.go) | 35 | ||||
| -rw-r--r-- | core/command/cmd-merge.go (renamed from pkg/git/cmd-merge.go) | 14 | ||||
| -rw-r--r-- | core/command/cmd-pull.go (renamed from pkg/git/cmd-pull.go) | 32 | ||||
| -rw-r--r-- | core/command/cmd-reset.go (renamed from pkg/git/cmd-reset.go) | 27 | ||||
| -rw-r--r-- | core/command/cmd-status.go (renamed from pkg/git/cmd-status.go) | 12 | ||||
| -rw-r--r-- | core/command/cmd.go (renamed from pkg/git/cmd.go) | 42 | ||||
| -rw-r--r-- | core/command/file.go (renamed from pkg/git/file.go) | 42 | ||||
| -rw-r--r-- | core/errors/util-errors.go (renamed from pkg/git/util-errors.go) | 8 | ||||
| -rw-r--r-- | core/git/authentication.go (renamed from pkg/git/authentication.go) | 12 | ||||
| -rw-r--r-- | core/git/branch.go (renamed from pkg/git/branch.go) | 56 | ||||
| -rw-r--r-- | core/git/commit.go (renamed from pkg/git/commit.go) | 45 | ||||
| -rw-r--r-- | core/git/random.go (renamed from pkg/git/util-random.go) | 0 | ||||
| -rw-r--r-- | core/git/random_test.go (renamed from pkg/git/util-random_test.go) | 0 | ||||
| -rw-r--r-- | core/git/remote.go (renamed from pkg/git/remote.go) | 0 | ||||
| -rw-r--r-- | core/git/remotebranch.go (renamed from pkg/git/remotebranch.go) | 0 | ||||
| -rw-r--r-- | core/git/repository.go (renamed from pkg/git/repository.go) | 0 | ||||
| -rw-r--r-- | core/git/sort.go (renamed from pkg/git/util-sort.go) | 39 | ||||
| -rw-r--r-- | core/git/stash.go (renamed from pkg/git/cmd-stash.go) | 63 | ||||
| -rw-r--r-- | core/job/job-queue.go (renamed from pkg/git/job-queue.go) | 7 | ||||
| -rw-r--r-- | core/job/job.go (renamed from pkg/git/job.go) | 37 | ||||
| -rw-r--r-- | core/load/load.go (renamed from pkg/git/util-load.go) | 19 | ||||
| -rw-r--r-- | gui/authenticationview.go (renamed from pkg/gui/authenticationview.go) | 16 | ||||
| -rw-r--r-- | gui/commitview.go (renamed from pkg/gui/commitview.go) | 8 | ||||
| -rw-r--r-- | gui/controlsview.go (renamed from pkg/gui/controlsview.go) | 0 | ||||
| -rw-r--r-- | gui/diffview.go (renamed from pkg/gui/diffview.go) | 16 | ||||
| -rw-r--r-- | gui/errorview.go (renamed from pkg/gui/errorview.go) | 0 | ||||
| -rw-r--r-- | gui/gui.go (renamed from pkg/gui/gui.go) | 14 | ||||
| -rw-r--r-- | gui/keybindings.go (renamed from pkg/gui/keybindings.go) | 0 | ||||
| -rw-r--r-- | gui/mainview.go (renamed from pkg/gui/mainview.go) | 18 | ||||
| -rw-r--r-- | gui/sideviews.go (renamed from pkg/gui/sideviews.go) | 15 | ||||
| -rw-r--r-- | gui/stagedview.go (renamed from pkg/gui/stagedview.go) | 8 | ||||
| -rw-r--r-- | gui/stashview.go (renamed from pkg/gui/stashview.go) | 2 | ||||
| -rw-r--r-- | gui/statusview.go (renamed from pkg/gui/statusview.go) | 38 | ||||
| -rw-r--r-- | gui/unstagedview.go (renamed from pkg/gui/unstagedview.go) | 6 | ||||
| -rw-r--r-- | gui/util-common.go (renamed from pkg/gui/util-common.go) | 0 | ||||
| -rw-r--r-- | gui/util-textstyle.go (renamed from pkg/gui/util-textstyle.go) | 9 | ||||
| -rw-r--r-- | main.go | 2 | ||||
| -rw-r--r-- | pkg/git/cmd-rev-list.go | 42 |
46 files changed, 393 insertions, 354 deletions
diff --git a/pkg/app/app.go b/app/app.go index 7d51abb..b8eebc8 100644 --- a/pkg/app/app.go +++ b/app/app.go @@ -3,7 +3,7 @@ package app import ( "os" - "github.com/isacikgoz/gitbatch/pkg/gui" + "github.com/isacikgoz/gitbatch/gui" log "github.com/sirupsen/logrus" ) diff --git a/pkg/app/config.go b/app/config.go index 57c2e6e..57c2e6e 100644 --- a/pkg/app/config.go +++ b/app/config.go diff --git a/pkg/app/files.go b/app/files.go index 1ec05cd..1ec05cd 100644 --- a/pkg/app/files.go +++ b/app/files.go diff --git a/pkg/app/quick.go b/app/quick.go index 90a2283..005c033 100644 --- a/pkg/app/quick.go +++ b/app/quick.go @@ -5,7 +5,8 @@ import ( "sync" "time" - "github.com/isacikgoz/gitbatch/pkg/git" + "github.com/isacikgoz/gitbatch/core/command" + "github.com/isacikgoz/gitbatch/core/git" ) func quick(directories []string, depth int, mode string) { @@ -35,12 +36,12 @@ func operate(directory, mode string) error { } switch mode { case "fetch": - return git.Fetch(r, git.FetchOptions{ + return command.Fetch(r, command.FetchOptions{ RemoteName: "origin", Progress: true, }) case "pull": - return git.Pull(r, git.PullOptions{ + return command.Pull(r, command.PullOptions{ RemoteName: "origin", Progress: true, }) diff --git a/pkg/git/cmd-add.go b/core/command/cmd-add.go index e7faff2..2addb23 100644 --- a/pkg/git/cmd-add.go +++ b/core/command/cmd-add.go @@ -1,8 +1,9 @@ -package git +package command import ( "errors" + "github.com/isacikgoz/gitbatch/core/git" log "github.com/sirupsen/logrus" ) @@ -25,7 +26,7 @@ type AddOptions struct { } // Add is a wrapper function for "git add" command -func Add(e *RepoEntity, file *File, option AddOptions) error { +func Add(e *git.RepoEntity, file *File, option AddOptions) error { addCmdMode = addCmdModeNative if option.Update || option.Force || option.DryRun { addCmdMode = addCmdModeLegacy @@ -42,7 +43,7 @@ func Add(e *RepoEntity, file *File, option AddOptions) error { } // AddAll function is the wrapper of "git add ." command -func AddAll(e *RepoEntity, option AddOptions) error { +func AddAll(e *git.RepoEntity, option AddOptions) error { args := make([]string, 0) args = append(args, addCommand) if option.DryRun { @@ -57,7 +58,7 @@ func AddAll(e *RepoEntity, option AddOptions) error { return nil } -func addWithGit(e *RepoEntity, file *File, option AddOptions) error { +func addWithGit(e *git.RepoEntity, file *File, option AddOptions) error { args := make([]string, 0) args = append(args, addCommand) args = append(args, file.Name) @@ -78,7 +79,7 @@ func addWithGit(e *RepoEntity, file *File, option AddOptions) error { return nil } -func addWithGoGit(e *RepoEntity, file *File) error { +func addWithGoGit(e *git.RepoEntity, file *File) error { w, err := e.Repository.Worktree() if err != nil { return err diff --git a/pkg/git/cmd-commit.go b/core/command/cmd-commit.go index 23c1de1..d81942e 100644 --- a/pkg/git/cmd-commit.go +++ b/core/command/cmd-commit.go @@ -1,11 +1,12 @@ -package git +package command import ( "errors" "time" + "github.com/isacikgoz/gitbatch/core/git" log "github.com/sirupsen/logrus" - "gopkg.in/src-d/go-git.v4" + gogit "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4/plumbing/object" ) @@ -28,7 +29,7 @@ type CommitOptions struct { } // CommitCommand defines which commit command to use. -func CommitCommand(e *RepoEntity, options CommitOptions) (err error) { +func CommitCommand(e *git.RepoEntity, options CommitOptions) (err error) { // here we configure commit operation // default mode is go-git (this may be configured) commitCmdMode = commitCmdModeNative @@ -43,7 +44,7 @@ func CommitCommand(e *RepoEntity, options CommitOptions) (err error) { } // commitWithGit is simply a bare git commit -m <msg> command which is flexible -func commitWithGit(e *RepoEntity, options CommitOptions) (err error) { +func commitWithGit(e *git.RepoEntity, options CommitOptions) (err error) { args := make([]string, 0) args = append(args, commitCommand) args = append(args, "-m") @@ -61,14 +62,14 @@ func commitWithGit(e *RepoEntity, options CommitOptions) (err error) { } // commitWithGoGit is the primary commit method -func commitWithGoGit(e *RepoEntity, options CommitOptions) (err error) { +func commitWithGoGit(e *git.RepoEntity, options CommitOptions) (err error) { config, err := e.Repository.Config() if err != nil { return err } name := config.Raw.Section("user").Option("name") email := config.Raw.Section("user").Option("email") - opt := &git.CommitOptions{ + opt := &gogit.CommitOptions{ Author: &object.Signature{ Name: name, Email: email, diff --git a/pkg/git/cmd-config.go b/core/command/cmd-config.go index e4bacf0..c580ff6 100644 --- a/pkg/git/cmd-config.go +++ b/core/command/cmd-config.go @@ -1,8 +1,9 @@ -package git +package command import ( "errors" + "github.com/isacikgoz/gitbatch/core/git" log "github.com/sirupsen/logrus" ) @@ -35,8 +36,8 @@ const ( ConfgiSiteGlobal ConfigSite = "global" ) -// Config -func Config(e *RepoEntity, options ConfigOptions) (value string, err error) { +// Config adds or reads config of a repository +func Config(e *git.RepoEntity, options ConfigOptions) (value string, err error) { // here we configure config operation // default mode is go-git (this may be configured) configCmdMode = configCmdModeLegacy @@ -51,7 +52,7 @@ func Config(e *RepoEntity, options ConfigOptions) (value string, err error) { } // configWithGit is simply a bare git commit -m <msg> command which is flexible -func configWithGit(e *RepoEntity, options ConfigOptions) (value string, err error) { +func configWithGit(e *git.RepoEntity, options ConfigOptions) (value string, err error) { args := make([]string, 0) args = append(args, configCommand) if len(string(options.Site)) > 0 { @@ -69,7 +70,7 @@ func configWithGit(e *RepoEntity, options ConfigOptions) (value string, err erro } // commitWithGoGit is the primary commit method -func configWithGoGit(e *RepoEntity, options ConfigOptions) (value string, err error) { +func configWithGoGit(e *git.RepoEntity, options ConfigOptions) (value string, err error) { // TODO: add global search config, err := e.Repository.Config() if err != nil { @@ -79,13 +80,13 @@ func configWithGoGit(e *RepoEntity, options ConfigOptions) (value string, err er } // AddConfig adds an entry on the ConfigOptions field. -func AddConfig(e *RepoEntity, options ConfigOptions, value string) (err error) { +func AddConfig(e *git.RepoEntity, options ConfigOptions, value string) (err error) { return addConfigWithGit(e, options, value) } // addConfigWithGit is simply a bare git config --add <option> command which is flexible -func addConfigWithGit(e *RepoEntity, options ConfigOptions, value string) (err error) { +func addConfigWithGit(e *git.RepoEntity, options ConfigOptions, value string) (err error) { args := make([]string, 0) args = append(args, configCommand) if len(string(options.Site)) > 0 { diff --git a/pkg/git/cmd-diff.go b/core/command/cmd-diff.go index f9fcb3f..120037a 100644 --- a/pkg/git/cmd-diff.go +++ b/core/command/cmd-diff.go @@ -1,9 +1,10 @@ -package git +package command import ( "errors" - "gopkg.in/src-d/go-git.v4" + "github.com/isacikgoz/gitbatch/core/git" + gogit "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4/plumbing" ) @@ -18,7 +19,7 @@ var ( // Diff is a wrapper function for "git diff" command // Diff function returns the diff to previous commit detail of the given has // of a specific commit -func Diff(e *RepoEntity, hash string) (diff string, err error) { +func Diff(e *git.RepoEntity, hash string) (diff string, err error) { diffCmdMode = diffCmdModeNative switch diffCmdMode { @@ -30,11 +31,11 @@ func Diff(e *RepoEntity, hash string) (diff string, err error) { return diff, errors.New("Unhandled diff operation") } -func diffWithGit(e *RepoEntity, hash string) (diff string, err error) { +func diffWithGit(e *git.RepoEntity, hash string) (diff string, err error) { return diff, nil } -func diffWithGoGit(e *RepoEntity, hash string) (diff string, err error) { +func diffWithGoGit(e *git.RepoEntity, hash string) (diff string, err error) { currentCommitIndex := 0 for i, cs := range e.Commits { if cs.Hash == hash { @@ -46,9 +47,9 @@ func diffWithGoGit(e *RepoEntity, hash string) (diff string, err error) { } // maybe we dont need to log the repo again? - commits, err := e.Repository.Log(&git.LogOptions{ + commits, err := e.Repository.Log(&gogit.LogOptions{ From: plumbing.NewHash(e.Commit.Hash), - Order: git.LogOrderCommitterTime, + Order: gogit.LogOrderCommitterTime, }) if err != nil { return "", err diff --git a/pkg/git/cmd-fetch.go b/core/command/cmd-fetch.go index 6090f7c..3d60fe9 100644 --- a/pkg/git/cmd-fetch.go +++ b/core/command/cmd-fetch.go @@ -1,11 +1,13 @@ -package git +package command import ( "os" "strings" + gerr "github.com/isacikgoz/gitbatch/core/errors" + "github.com/isacikgoz/gitbatch/core/git" log "github.com/sirupsen/logrus" - git "gopkg.in/src-d/go-git.v4" + gogit "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4/config" "gopkg.in/src-d/go-git.v4/plumbing/transport" "gopkg.in/src-d/go-git.v4/plumbing/transport/http" @@ -26,7 +28,7 @@ type FetchOptions struct { // Name of the remote to fetch from. Defaults to origin. RemoteName string // Credentials holds the user and pswd information - Credentials Credentials + Credentials git.Credentials // Before fetching, remove any remote-tracking references that no longer // exist on the remote. Prune bool @@ -42,7 +44,7 @@ type FetchOptions struct { // Fetch branches refs from one or more other repositories, along with the // objects necessary to complete their histories -func Fetch(e *RepoEntity, options FetchOptions) (err error) { +func Fetch(e *git.RepoEntity, options FetchOptions) (err error) { // here we configure fetch operation // default mode is go-git (this may be configured) fetchCmdMode = fetchCmdModeNative @@ -73,7 +75,7 @@ func Fetch(e *RepoEntity, options FetchOptions) (err error) { // fetchWithGit is simply a bare git fetch <remote> command which is flexible // for complex operations, but on the other hand, it ties the app to another // tool. To avoid that, using native implementation is preferred. -func fetchWithGit(e *RepoEntity, options FetchOptions) (err error) { +func fetchWithGit(e *git.RepoEntity, options FetchOptions) (err error) { args := make([]string, 0) args = append(args, fetchCommand) // parse options to command line arguments @@ -89,11 +91,10 @@ func fetchWithGit(e *RepoEntity, options FetchOptions) (err error) { if options.DryRun { args = append(args, "--dry-run") } - if err := GenericGitCommand(e.AbsPath, args); err != nil { - log.Warn("Error at git command (fetch)") - return err + if out, err := GenericGitCommandWithOutput(e.AbsPath, args); err != nil { + return gerr.ParseGitError(out, err) } - e.SetState(Success) + e.SetState(git.Success) // till this step everything should be ok return e.Refresh() } @@ -104,25 +105,25 @@ func fetchWithGit(e *RepoEntity, options FetchOptions) (err error) { // pattern for references on the remote side and <dst> is where those references // will be written locally. The + tells Git to update the reference even if it // isn’t a fast-forward. -func fetchWithGoGit(e *RepoEntity, options FetchOptions, refspec string) (err error) { - opt := &git.FetchOptions{ +func fetchWithGoGit(e *git.RepoEntity, options FetchOptions, refspec string) (err error) { + opt := &gogit.FetchOptions{ RemoteName: options.RemoteName, RefSpecs: []config.RefSpec{config.RefSpec(refspec)}, Force: options.Force, } // if any credential is given, let's add it to the git.FetchOptions if len(options.Credentials.User) > 0 { - protocol, err := authProtocol(e.Remote) + protocol, err := git.AuthProtocol(e.Remote) if err != nil { return err } - if protocol == authProtocolHTTP || protocol == authProtocolHTTPS { + if protocol == git.AuthProtocolHTTP || protocol == git.AuthProtocolHTTPS { opt.Auth = &http.BasicAuth{ Username: options.Credentials.User, Password: options.Credentials.Password, } } else { - return ErrInvalidAuthMethod + return gerr.ErrInvalidAuthMethod } } if options.Progress { @@ -130,7 +131,7 @@ func fetchWithGoGit(e *RepoEntity, options FetchOptions, refspec string) (err er } if err := e.Repository.Fetch(opt); err != nil { - if err == git.NoErrAlreadyUpToDate { + if err == gogit.NoErrAlreadyUpToDate { // Already up-to-date log.Warn(err.Error()) // TODO: submit a PR for this kind of error, this type of catch is lame @@ -149,14 +150,14 @@ func fetchWithGoGit(e *RepoEntity, options FetchOptions, refspec string) (err er return fetchWithGit(e, options) } else if err == transport.ErrAuthenticationRequired { log.Warn(err.Error()) - return ErrAuthenticationRequired + return gerr.ErrAuthenticationRequired } else { log.Warn(err.Error()) return fetchWithGit(e, options) } } - e.SetState(Success) + e.SetState(git.Success) // till this step everything should be ok return e.Refresh() } diff --git a/pkg/git/cmd-merge.go b/core/command/cmd-merge.go index e89761d..a3c06d1 100644 --- a/pkg/git/cmd-merge.go +++ b/core/command/cmd-merge.go @@ -1,7 +1,8 @@ -package git +package command import ( - log "github.com/sirupsen/logrus" + gerr "github.com/isacikgoz/gitbatch/core/errors" + "github.com/isacikgoz/gitbatch/core/git" ) var mergeCommand = "merge" @@ -18,7 +19,7 @@ type MergeOptions struct { // Merge incorporates changes from the named commits or branches into the // current branch -func Merge(e *RepoEntity, options MergeOptions) error { +func Merge(e *git.RepoEntity, options MergeOptions) error { args := make([]string, 0) args = append(args, mergeCommand) if len(options.BranchName) > 0 { @@ -30,10 +31,9 @@ func Merge(e *RepoEntity, options MergeOptions) error { if options.NoStat { args = append(args, "-n") } - if err := GenericGitCommand(e.AbsPath, args); err != nil { - log.Warn("Error while merging") - return err + if out, err := GenericGitCommandWithOutput(e.AbsPath, args); err != nil { + return gerr.ParseGitError(out, err) } - e.SetState(Success) + e.SetState(git.Success) return e.Refresh() } diff --git a/pkg/git/cmd-pull.go b/core/command/cmd-pull.go index 769d6b5..237303e 100644 --- a/pkg/git/cmd-pull.go +++ b/core/command/cmd-pull.go @@ -1,11 +1,13 @@ -package git +package command import ( "os" "strings" + gerr "github.com/isacikgoz/gitbatch/core/errors" + "github.com/isacikgoz/gitbatch/core/git" log "github.com/sirupsen/logrus" - git "gopkg.in/src-d/go-git.v4" + gogit "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4/plumbing" "gopkg.in/src-d/go-git.v4/plumbing/transport" "gopkg.in/src-d/go-git.v4/plumbing/transport/http" @@ -31,7 +33,7 @@ type PullOptions struct { // Fetch only ReferenceName if true. SingleBranch bool // Credentials holds the user and pswd information - Credentials Credentials + Credentials git.Credentials // Process logs the output to stdout Progress bool // Force allows the pull to update a local branch even when the remote @@ -40,7 +42,7 @@ type PullOptions struct { } // Pull ncorporates changes from a remote repository into the current branch. -func Pull(e *RepoEntity, options PullOptions) (err error) { +func Pull(e *git.RepoEntity, options PullOptions) (err error) { // here we configure pull operation // default mode is go-git (this may be configured) pullCmdMode = pullCmdModeNative @@ -57,7 +59,7 @@ func Pull(e *RepoEntity, options PullOptions) (err error) { return nil } -func pullWithGit(e *RepoEntity, options PullOptions) (err error) { +func pullWithGit(e *git.RepoEntity, options PullOptions) (err error) { args := make([]string, 0) args = append(args, pullCommand) // parse options to command line arguments @@ -68,14 +70,14 @@ func pullWithGit(e *RepoEntity, options PullOptions) (err error) { args = append(args, "-f") } if out, err := GenericGitCommandWithOutput(e.AbsPath, args); err != nil { - return parseGitError(out, err) + return gerr.ParseGitError(out, err) } - e.SetState(Success) + e.SetState(git.Success) return e.Refresh() } -func pullWithGoGit(e *RepoEntity, options PullOptions) (err error) { - opt := &git.PullOptions{ +func pullWithGoGit(e *git.RepoEntity, options PullOptions) (err error) { + opt := &gogit.PullOptions{ RemoteName: options.RemoteName, SingleBranch: options.SingleBranch, Force: options.Force, @@ -86,17 +88,17 @@ func pullWithGoGit(e *RepoEntity, options PullOptions) (err error) { } // if any credential is given, let's add it to the git.PullOptions if len(options.Credentials.User) > 0 { - protocol, err := authProtocol(e.Remote) + protocol, err := git.AuthProtocol(e.Remote) if err != nil { return err } - if protocol == authProtocolHTTP || protocol == authProtocolHTTPS { + if protocol == git.AuthProtocolHTTP || protocol == git.AuthProtocolHTTPS { opt.Auth = &http.BasicAuth{ Username: options.Credentials.User, Password: options.Credentials.Password, } } else { - return ErrInvalidAuthMethod + return gerr.ErrInvalidAuthMethod } } if options.Progress { @@ -108,7 +110,7 @@ func pullWithGoGit(e *RepoEntity, options PullOptions) (err error) { } if err = w.Pull(opt); err != nil { - if err == git.NoErrAlreadyUpToDate { + if err == gogit.NoErrAlreadyUpToDate { // log.Error("error: " + err.Error()) // Already up-to-date log.Warn(err.Error()) @@ -127,13 +129,13 @@ func pullWithGoGit(e *RepoEntity, options PullOptions) (err error) { return pullWithGit(e, options) } else if err == transport.ErrAuthenticationRequired { log.Warn(err.Error()) - return ErrAuthenticationRequired + return gerr.ErrAuthenticationRequired } else { log.Warn(err.Error()) return pullWithGit(e, options) } } - e.SetState(Success) + e.SetState(git.Success) return e.Refresh() } diff --git a/pkg/git/cmd-reset.go b/core/command/cmd-reset.go index bea436c..d8e36ab 100644 --- a/pkg/git/cmd-reset.go +++ b/core/command/cmd-reset.go @@ -1,10 +1,11 @@ -package git +package command import ( "errors" + "github.com/isacikgoz/gitbatch/core/git" log "github.com/sirupsen/logrus" - "gopkg.in/src-d/go-git.v4" + gogit "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4/plumbing" ) @@ -52,7 +53,7 @@ const ( ) // Reset is the wrapper of "git reset" command -func Reset(e *RepoEntity, file *File, option ResetOptions) error { +func Reset(e *git.RepoEntity, file *File, option ResetOptions) error { resetCmdMode = resetCmdModeLegacy switch resetCmdMode { @@ -65,7 +66,7 @@ func Reset(e *RepoEntity, file *File, option ResetOptions) error { return errors.New("Unhandled reset operation") } -func resetWithGit(e *RepoEntity, file *File, option ResetOptions) error { +func resetWithGit(e *git.RepoEntity, file *File, option ResetOptions) error { args := make([]string, 0) args = append(args, resetCommand) @@ -83,7 +84,7 @@ func resetWithGit(e *RepoEntity, file *File, option ResetOptions) error { } // ResetAll resets the changes in a repository, should be used wise -func ResetAll(e *RepoEntity, option ResetOptions) error { +func ResetAll(e *git.RepoEntity, option ResetOptions) error { resetCmdMode = addCmdModeNative switch resetCmdMode { @@ -97,7 +98,7 @@ func ResetAll(e *RepoEntity, option ResetOptions) error { return errors.New("Unhandled reset operation") } -func resetAllWithGit(e *RepoEntity, option ResetOptions) error { +func resetAllWithGit(e *git.RepoEntity, option ResetOptions) error { args := make([]string, 0) args = append(args, resetCommand) if len(option.Rtype) > 0 { @@ -111,23 +112,23 @@ func resetAllWithGit(e *RepoEntity, option ResetOptions) error { return nil } -func resetAllWithGoGit(e *RepoEntity, option ResetOptions) error { +func resetAllWithGoGit(e *git.RepoEntity, option ResetOptions) error { w, err := e.Repository.Worktree() if err != nil { return err } - var mode git.ResetMode + var mode gogit.ResetMode switch option.Rtype { case ResetHard: - mode = git.HardReset + mode = gogit.HardReset case ResetMixed: - mode = git.MixedReset + mode = gogit.MixedReset case ResetMerge: - mode = git.MergeReset + mode = gogit.MergeReset case ResetSoft: - mode = git.SoftReset + mode = gogit.SoftReset } - err = w.Reset(&git.ResetOptions{ + err = w.Reset(&gogit.ResetOptions{ Commit: plumbing.NewHash(option.Hash), Mode: mode, }) diff --git a/pkg/git/cmd-status.go b/core/command/cmd-status.go index eec9b57..f6a9dc8 100644 --- a/pkg/git/cmd-status.go +++ b/core/command/cmd-status.go @@ -1,4 +1,4 @@ -package git +package command import ( "errors" @@ -7,6 +7,7 @@ import ( "sort" "strings" + "github.com/isacikgoz/gitbatch/core/git" log "github.com/sirupsen/logrus" ) @@ -18,7 +19,7 @@ var ( statusCmdModeNative = "go-git" ) -func shortStatus(e *RepoEntity, option string) string { +func shortStatus(e *git.RepoEntity, option string) string { args := make([]string, 0) args = append(args, statusCommand) args = append(args, option) @@ -31,7 +32,8 @@ func shortStatus(e *RepoEntity, option string) string { return out } -func Status(e *RepoEntity) ([]*File, error) { +// Status returns the dirty files +func Status(e *git.RepoEntity) ([]*File, error) { statusCmdMode = statusCmdModeNative switch statusCmdMode { @@ -45,7 +47,7 @@ func Status(e *RepoEntity) ([]*File, error) { // LoadFiles function simply commands a git status and collects output in a // structured way -func statusWithGit(e *RepoEntity) ([]*File, error) { +func statusWithGit(e *git.RepoEntity) ([]*File, error) { files := make([]*File, 0) output := shortStatus(e, "--untracked-files=all") if len(output) == 0 { @@ -69,7 +71,7 @@ func statusWithGit(e *RepoEntity) ([]*File, error) { return files, nil } -func statusWithGoGit(e *RepoEntity) ([]*File, error) { +func statusWithGoGit(e *git.RepoEntity) ([]*File, error) { files := make([]*File, 0) w, err := e.Repository.Worktree() if err != nil { diff --git a/pkg/git/cmd.go b/core/command/cmd.go index b177b88..536495b 100644 --- a/pkg/git/cmd.go +++ b/core/command/cmd.go @@ -1,4 +1,4 @@ -package git +package command import ( "log" @@ -96,43 +96,3 @@ func GitShow(repoPath, hash string) string { } return diff } - -// GitShowEmail gets author's e-mail with git show command -func GitShowEmail(repoPath, hash string) string { - args := []string{"show", "--quiet", "--pretty=format:%ae", hash} - diff, err := RunCommandWithOutput(repoPath, "git", args) - if err != nil { - return "?" - } - return diff -} - -// GitShowBody gets body of the commit with git show -func GitShowBody(repoPath, hash string) string { - args := []string{"show", "--quiet", "--pretty=format:%B", hash} - diff, err := RunCommandWithOutput(repoPath, "git", args) - if err != nil { - return err.Error() - } - return diff -} - -// GitShowDate gets commit's date with git show as string -func GitShowDate(repoPath, hash string) string { - args := []string{"show", "--quiet", "--pretty=format:%ai", hash} - diff, err := RunCommandWithOutput(repoPath, "git", args) - if err != nil { - return "?" - } - return diff -} - -// StatusWithGit returns the plaintext short status of the repo -func (e *RepoEntity) StatusWithGit() string { - args := []string{"status"} - status, err := RunCommandWithOutput(e.AbsPath, "git", args) - if err != nil { - return "?" - } - return status -} diff --git a/pkg/git/file.go b/core/command/file.go index 1e086bc..ebfbdcf 100644 --- a/pkg/git/file.go +++ b/core/command/file.go @@ -1,7 +1,8 @@ -package git +package command import ( "strings" + "unicode" log "github.com/sirupsen/logrus" ) @@ -50,3 +51,42 @@ func (f *File) Diff() (output string, err error) { } return output, err } + +// filesAlphabetical slice is the re-ordered *File slice that sorted according +// to alphabetical order (A-Z) +type filesAlphabetical []*File + +// Len is the interface implementation for Alphabetical sorting function +func (s filesAlphabetical) Len() int { return len(s) } + +// Swap is the interface implementation for Alphabetical sorting function +func (s filesAlphabetical) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// Less is the interface implementation for Alphabetical sorting function +func (s filesAlphabetical) Less(i, j int) bool { + iRunes := []rune(s[i].Name) + jRunes := []rune(s[j].Name) + + max := len(iRunes) + if max > len(jRunes) { + max = len(jRunes) + } + + for idx := 0; idx < max; idx++ { + ir := iRunes[idx] + jr := jRunes[idx] + + lir := unicode.ToLower(ir) + ljr := unicode.ToLower(jr) + + if lir != ljr { + return lir < ljr + } + + // the lowercase runes are the same, so compare the original + if ir != jr { + return ir < jr + } + } + return false +} diff --git a/pkg/git/util-errors.go b/core/errors/util-errors.go index 33eb15f..c734904 100644 --- a/pkg/git/util-errors.go +++ b/core/errors/util-errors.go @@ -1,4 +1,4 @@ -package git +package errors import ( "errors" @@ -22,7 +22,7 @@ var ( // ErrCouldNotFindRemoteRef is thrown when trying to fetch/pull cannot // find suitable remote reference ErrCouldNotFindRemoteRef = errors.New("could not find remote ref") - // ErrPullAbortedTryCommit indicates that the repositort is not clean and + // ErrMergeAbortedTryCommit indicates that the repositort is not clean and // some changes may conflict with the merge ErrMergeAbortedTryCommit = errors.New("stash/commit changes. aborted") // ErrRemoteBranchNotSpecified means that default remote branch is not set @@ -41,9 +41,9 @@ var ( ErrUnclassified = errors.New("unclassified error") ) -// parseGitError takes git output as an input and tries to find some meaningful +// ParseGitError takes git output as an input and tries to find some meaningful // errors can be used by the app -func parseGitError(out string, err error) error { +func ParseGitError(out string, err error) error { if strings.Contains(out, "error: Your local changes to the following files would be overwritten by merge") { return ErrMergeAbortedTryCommit } else if strings.Contains(out, "ERROR: Repository not found") { diff --git a/pkg/git/authentication.go b/core/git/authentication.go index a33816b..77c8edb 100644 --- a/pkg/git/authentication.go +++ b/core/git/authentication.go @@ -13,15 +13,15 @@ type Credentials struct { Password string } -var ( - authProtocolHTTP = "http" - authProtocolHTTPS = "https" - authProtocolSSH = "ssh" +const ( + AuthProtocolHTTP = "http" + AuthProtocolHTTPS = "https" + AuthProtocolSSH = "ssh" ) -// authentication protocol returns the type of protocol for given remote's URL +// AuthProtocol returns the type of protocol for given remote's URL // various auth protocols require different kind of authentication -func authProtocol(r *Remote) (p string, err error) { +func AuthProtocol(r *Remote) (p string, err error) { u, err := url.Parse(r.URL[0]) if err != nil { return p, err diff --git a/pkg/git/branch.go b/core/git/branch.go index 084288a..cc29f17 100644 --- a/pkg/git/branch.go +++ b/core/git/branch.go @@ -1,6 +1,7 @@ package git import ( + "os/exec" "strconv" "strings" @@ -21,6 +22,11 @@ type Branch struct { Clean bool } +var ( + revlistCommand = "rev-list" + hashLength = 40 +) + // search for branches in go-git way. It is useful to do so that checkout and // checkout error handling can be handled by code rather than struggling with // git cammand and its output @@ -143,9 +149,18 @@ func (e *RepoEntity) Checkout(b *Branch) error { // I implemented this with go-git but it was incredibly slow and there is also // an issue about it: https://github.com/src-d/go-git/issues/844 func (e *RepoEntity) isClean() bool { - s := e.StatusWithGit() - s = TrimTrailingNewline(s) - if s != "?" { + args := []string{"status"} + cmd := exec.Command("git", args...) + cmd.Dir = e.AbsPath + out, err := cmd.CombinedOutput() + if err != nil { + return false + } + s := string(out) + if strings.HasSuffix(s, "\n") { + s = s[:len(s)-1] + } + if len(s) >= 0 { vs := strings.Split(s, "\n") line := vs[len(vs)-1] // earlier versions of git returns "working directory clean" instead of @@ -157,3 +172,38 @@ func (e *RepoEntity) isClean() bool { } return false } + +// RevListOptions defines the rules of rev-list func +type RevListOptions struct { + // Ref1 is the first reference hash to link + Ref1 string + // Ref2 is the second reference hash to link + Ref2 string +} + +// RevList returns the commit hashes that are links from the given commit(s). +// The output is given in reverse chronological order by default. +func RevList(e *RepoEntity, options RevListOptions) ([]string, error) { + args := make([]string, 0) + args = append(args, revlistCommand) + if len(options.Ref1) > 0 && len(options.Ref2) > 0 { + arg1 := options.Ref1 + ".." + options.Ref2 + args = append(args, arg1) + } + cmd := exec.Command("git", args...) + cmd.Dir = e.AbsPath + out, err := cmd.CombinedOutput() + if err != nil { + return []string{"?"}, err + } + s := string(out) + + hashes := strings.Split(s, "\n") + for _, hash := range hashes { + if len(hash) != hashLength { + return make([]string, 0), nil + } + break + } + return hashes, nil +} diff --git a/pkg/git/commit.go b/core/git/commit.go index f78bb64..fa4e317 100644 --- a/pkg/git/commit.go +++ b/core/git/commit.go @@ -1,10 +1,11 @@ package git import ( + "os/exec" "regexp" log "github.com/sirupsen/logrus" - "gopkg.in/src-d/go-git.v4" + git "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4/plumbing/object" ) @@ -117,9 +118,9 @@ func (e *RepoEntity) pullDiffsToUpstream() ([]*Commit, error) { for _, s := range pullables { commit := &Commit{ Hash: s, - Author: GitShowEmail(e.AbsPath, s), - Message: re.ReplaceAllString(GitShowBody(e.AbsPath, s), " "), - Time: GitShowDate(e.AbsPath, s), + Author: gitShowEmail(e.AbsPath, s), + Message: re.ReplaceAllString(gitShowBody(e.AbsPath, s), " "), + Time: gitShowDate(e.AbsPath, s), CommitType: RemoteCommit, } remoteCommits = append(remoteCommits, commit) @@ -140,3 +141,39 @@ func (e *RepoEntity) pushDiffsToUpstream() ([]string, error) { } return pushables, nil } + +// gitShowEmail gets author's e-mail with git show command +func gitShowEmail(repoPath, hash string) string { + args := []string{"show", "--quiet", "--pretty=format:%ae", hash} + cmd := exec.Command("git", args...) + cmd.Dir = repoPath + out, err := cmd.CombinedOutput() + if err != nil { + return "?" + } + return string(out) +} + +// gitShowBody gets body of the commit with git show +func gitShowBody(repoPath, hash string) string { + args := []string{"show", "--quiet", "--pretty=format:%B", hash} + cmd := exec.Command("git", args...) + cmd.Dir = repoPath + out, err := cmd.CombinedOutput() + if err != nil { + return "?" + } + return string(out) +} + +// gitShowDate gets commit's date with git show as string +func gitShowDate(repoPath, hash string) string { + args := []string{"show", "--quiet", "--pretty=format:%ai", hash} + cmd := exec.Command("git", args...) + cmd.Dir = repoPath + out, err := cmd.CombinedOutput() + if err != nil { + return "?" + } + return string(out) +} diff --git a/pkg/git/util-random.go b/core/git/random.go index c388613..c388613 100644 --- a/pkg/git/util-random.go +++ b/core/git/random.go diff --git a/pkg/git/util-random_test.go b/core/git/random_test.go index 2eeb00c..2eeb00c 100644 --- a/pkg/git/util-random_test.go +++ b/core/git/random_test.go diff --git a/pkg/git/remote.go b/core/git/remote.go index 72c8ddd..72c8ddd 100644 --- a/pkg/git/remote.go +++ b/core/git/remote.go diff --git a/pkg/git/remotebranch.go b/core/git/remotebranch.go index 337b28b..337b28b 100644 --- a/pkg/git/remotebranch.go +++ b/core/git/remotebranch.go diff --git a/pkg/git/repository.go b/core/git/repository.go index 31b926d..31b926d 100644 --- a/pkg/git/repository.go +++ b/core/git/repository.go diff --git a/pkg/git/util-sort.go b/core/git/sort.go index e3067bc..de5f454 100644 --- a/pkg/git/util-sort.go +++ b/core/git/sort.go @@ -57,42 +57,3 @@ func (s LastModified) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s LastModified) Less(i, j int) bool { return s[i].ModTime.Unix() > s[j].ModTime.Unix() } - -// filesAlphabetical slice is the re-ordered *File slice that sorted according -// to alphabetical order (A-Z) -type filesAlphabetical []*File - -// Len is the interface implementation for Alphabetical sorting function -func (s filesAlphabetical) Len() int { return len(s) } - -// Swap is the interface implementation for Alphabetical sorting function -func (s filesAlphabetical) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -// Less is the interface implementation for Alphabetical sorting function -func (s filesAlphabetical) Less(i, j int) bool { - iRunes := []rune(s[i].Name) - jRunes := []rune(s[j].Name) - - max := len(iRunes) - if max > len(jRunes) { - max = len(jRunes) - } - - for idx := 0; idx < max; idx++ { - ir := iRunes[idx] - jr := jRunes[idx] - - lir := unicode.ToLower(ir) - ljr := unicode.ToLower(jr) - - if lir != ljr { - return lir < ljr - } - - // the lowercase runes are the same, so compare the original - if ir != jr { - return ir < jr - } - } - return false -} diff --git a/pkg/git/cmd-stash.go b/core/git/stash.go index d2708ec..2d7fab0 100644 --- a/pkg/git/cmd-stash.go +++ b/core/git/stash.go @@ -1,6 +1,7 @@ package git import ( + "os/exec" "regexp" "strconv" "strings" @@ -19,18 +20,6 @@ type StashedItem struct { EntityPath string } -func stashGet(e *RepoEntity, option string) string { - args := make([]string, 0) - args = append(args, stashCommand) - args = append(args, option) - out, err := GenericGitCommandWithOutput(e.AbsPath, args) - if err != nil { - log.Warn("Error while stash command") - return "?" - } - return out -} - func (e *RepoEntity) loadStashedItems() error { e.Stasheds = make([]*StashedItem, 0) output := stashGet(e, "list") @@ -86,33 +75,53 @@ func (e *RepoEntity) loadStashedItems() error { return nil } -// Stash is the wrapper of convetional "git stash" command -func (e *RepoEntity) Stash() (output string, err error) { +func stashGet(e *RepoEntity, option string) string { args := make([]string, 0) - args = append(args, stashCommand) - - output, err = GenericGitCommandWithErrorOutput(e.AbsPath, args) - e.Refresh() - return output, err + args = append(args, "stash") + args = append(args, option) + cmd := exec.Command("git", args...) + cmd.Dir = e.AbsPath + output, err := cmd.CombinedOutput() + if err != nil { + return "?" + } + return string(output) } // Pop is the wrapper of "git stash pop" command that used for a file -func (stashedItem *StashedItem) Pop() (output string, err error) { +func (stashedItem *StashedItem) Pop() (string, error) { args := make([]string, 0) - args = append(args, stashCommand) + args = append(args, "stash") args = append(args, "pop") args = append(args, "stash@{"+strconv.Itoa(stashedItem.StashID)+"}") - output, err = GenericGitCommandWithErrorOutput(stashedItem.EntityPath, args) - return output, err + cmd := exec.Command("git", args...) + cmd.Dir = stashedItem.EntityPath + output, err := cmd.CombinedOutput() + return string(output), err } // Show is the wrapper of "git stash show -p " command -func (stashedItem *StashedItem) Show() (output string, err error) { +func (stashedItem *StashedItem) Show() (string, error) { args := make([]string, 0) - args = append(args, stashCommand) + args = append(args, "stash") args = append(args, "show") args = append(args, "-p") args = append(args, "stash@{"+strconv.Itoa(stashedItem.StashID)+"}") - output, err = GenericGitCommandWithErrorOutput(stashedItem.EntityPath, args) - return output, err + cmd := exec.Command("git", args...) + cmd.Dir = stashedItem.EntityPath + output, err := cmd.CombinedOutput() + + return string(output), err +} + +// Stash is the wrapper of convetional "git stash" command +func (e *RepoEntity) Stash() (string, error) { + args := make([]string, 0) + args = append(args, "stash") + + cmd := exec.Command("git", args...) + cmd.Dir = e.AbsPath + output, err := cmd.CombinedOutput() + e.Refresh() + return string(output), err } diff --git a/pkg/git/job-queue.go b/core/job/job-queue.go index 975b8af..02f7f0b 100644 --- a/pkg/git/job-queue.go +++ b/core/job/job-queue.go @@ -1,4 +1,4 @@ -package git +package job import ( "context" @@ -6,6 +6,7 @@ import ( "runtime" "sync" + "github.com/isacikgoz/gitbatch/core/git" log "github.com/sirupsen/logrus" "golang.org/x/sync/semaphore" ) @@ -55,7 +56,7 @@ func (jq *JobQueue) StartNext() (j *Job, finished bool, err error) { // RemoveFromQueue deletes the given entity and its job from the queue // TODO: it is not safe if the job has been started -func (jq *JobQueue) RemoveFromQueue(entity *RepoEntity) error { +func (jq *JobQueue) RemoveFromQueue(entity *git.RepoEntity) error { removed := false for i, job := range jq.series { if job.Entity.RepoID == entity.RepoID { @@ -72,7 +73,7 @@ func (jq *JobQueue) RemoveFromQueue(entity *RepoEntity) error { // IsInTheQueue function; since the job and entity is not tied with its own // struct, this function returns true if that entity is in the queue along with // the jobs type -func (jq *JobQueue) IsInTheQueue(entity *RepoEntity) (inTheQueue bool, j *Job) { +func (jq *JobQueue) IsInTheQueue(entity *git.RepoEntity) (inTheQueue bool, j *Job) { inTheQueue = false for _, job := range jq.series { if job.Entity.RepoID == entity.RepoID { diff --git a/pkg/git/job.go b/core/job/job.go index 82a14f6..6156275 100644 --- a/pkg/git/job.go +++ b/core/job/job.go @@ -1,11 +1,16 @@ -package git +package job + +import ( + "github.com/isacikgoz/gitbatch/core/command" + "github.com/isacikgoz/gitbatch/core/git" +) // Job relates the type of the operation and the entity type Job struct { // JobType is to select operation type that will be applied to repository JobType JobType // Entity points to the repository that will be used for operation - Entity *RepoEntity + Entity *git.RepoEntity // Options is a placeholder for operation options Options interface{} } @@ -26,48 +31,48 @@ const ( // starts the job func (j *Job) start() error { - j.Entity.SetState(Working) + j.Entity.SetState(git.Working) // TODO: Handle errors? // TOOD: Better implementation required switch mode := j.JobType; mode { case FetchJob: - var opts FetchOptions + var opts command.FetchOptions if j.Options != nil { - opts = j.Options.(FetchOptions) + opts = j.Options.(command.FetchOptions) } else { - opts = FetchOptions{ + opts = command.FetchOptions{ RemoteName: j.Entity.Remote.Name, } } - if err := Fetch(j.Entity, opts); err != nil { - j.Entity.SetState(Fail) + if err := command.Fetch(j.Entity, opts); err != nil { + j.Entity.SetState(git.Fail) j.Entity.SetStateMessage(err.Error()) return err } case PullJob: - var opts PullOptions + var opts command.PullOptions if j.Options != nil { - opts = j.Options.(PullOptions) + opts = j.Options.(command.PullOptions) } else { - opts = PullOptions{ + opts = command.PullOptions{ RemoteName: j.Entity.Remote.Name, } } - if err := Pull(j.Entity, opts); err != nil { - j.Entity.SetState(Fail) + if err := command.Pull(j.Entity, opts); err != nil { + j.Entity.SetState(git.Fail) j.Entity.SetStateMessage(err.Error()) return err } case MergeJob: - if err := Merge(j.Entity, MergeOptions{ + if err := command.Merge(j.Entity, command.MergeOptions{ BranchName: j.Entity.Remote.Branch.Name, }); err != nil { - j.Entity.SetState(Fail) + j.Entity.SetState(git.Fail) j.Entity.SetStateMessage(err.Error()) return nil } default: - j.Entity.SetState(Available) + j.Entity.SetState(git.Available) return nil } return nil diff --git a/pkg/git/util-load.go b/core/load/load.go index 091716a..6456f64 100644 --- a/pkg/git/util-load.go +++ b/core/load/load.go @@ -1,4 +1,4 @@ -package git +package load import ( log "github.com/sirupsen/logrus" @@ -8,16 +8,18 @@ import ( "runtime" "sync" + "github.com/isacikgoz/gitbatch/core/git" "golang.org/x/sync/semaphore" ) -type AsyncAdd func(e *RepoEntity) +// AsyncAdd is interface to caller +type AsyncAdd func(e *git.RepoEntity) -// LoadRepositoryEntities initializes the go-git's repository obejcts with given +// RepositoryEntities initializes the go-git's repository obejcts with given // slice of paths. since this job is done parallel, the order of the directories // is not kept -func LoadRepositoryEntities(directories []string) (entities []*RepoEntity, err error) { - entities = make([]*RepoEntity, 0) +func RepositoryEntities(directories []string) (entities []*git.RepoEntity, err error) { + entities = make([]*git.RepoEntity, 0) var wg sync.WaitGroup var mu sync.Mutex @@ -30,7 +32,7 @@ func LoadRepositoryEntities(directories []string) (entities []*RepoEntity, err e // decrement the wait counter by one, we call it in a defer so it's // called at the end of this goroutine defer wg.Done() - entity, err := InitializeRepo(d) + entity, err := git.InitializeRepo(d) if err != nil { log.WithFields(log.Fields{ "directory": d, @@ -53,7 +55,8 @@ func LoadRepositoryEntities(directories []string) (entities []*RepoEntity, err e return entities, nil } -func LoadRepositoryEntitiesAsync(directories []string, add AsyncAdd) error { +// AddRepositoryEntitiesAsync asynchronously adds to caller +func AddRepositoryEntitiesAsync(directories []string, add AsyncAdd) error { ctx := context.TODO() var ( @@ -71,7 +74,7 @@ func LoadRepositoryEntitiesAsync(directories []string, add AsyncAdd) error { go func(d string) { defer sem.Release(1) - entity, err := InitializeRepo(d) + entity, err := git.InitializeRepo(d) if err != nil { log.WithFields(log.Fields{ "directory": d, diff --git a/pkg/gui/authenticationview.go b/gui/authenticationview.go index 7d4861f..1b5c98f 100644 --- a/pkg/gui/authenticationview.go +++ b/gui/authenticationview.go @@ -4,7 +4,9 @@ import ( "fmt" "regexp" - "github.com/isacikgoz/gitbatch/pkg/git" + "github.com/isacikgoz/gitbatch/core/command" + "github.com/isacikgoz/gitbatch/core/git" + "github.com/isacikgoz/gitbatch/core/job" "github.com/jroimartin/gocui" log "github.com/sirupsen/logrus" ) @@ -27,11 +29,11 @@ var ( authLabels = []viewFeature{authenticationViewFeature, authUserLabelFeature, authPswdLabelViewFeature} // we can hold the job that is required to authenticate - jobRequiresAuth *git.Job + jobRequiresAuth *job.Job ) // open an auth view to get user credentials -func (gui *Gui) openAuthenticationView(g *gocui.Gui, jobQueue *git.JobQueue, job *git.Job, returnViewName string) error { +func (gui *Gui) openAuthenticationView(g *gocui.Gui, jobQueue *job.JobQueue, job *job.Job, returnViewName string) error { maxX, maxY := g.Size() // lets add this job since it is removed from the queue // also it is already unsuccessfully finished @@ -100,17 +102,17 @@ func (gui *Gui) submitAuthenticationView(g *gocui.Gui, v *gocui.View) error { // since the git ops require different types of options we better switch switch mode := jobRequiresAuth.JobType; mode { - case git.FetchJob: - jobRequiresAuth.Options = git.FetchOptions{ + case job.FetchJob: + jobRequiresAuth.Options = command.FetchOptions{ RemoteName: jobRequiresAuth.Entity.Remote.Name, Credentials: git.Credentials{ User: creduser, Password: credpswd, }, } - case git.PullJob: + case job.PullJob: // we handle pull as fetch&merge so same rule applies - jobRequiresAuth.Options = git.PullOptions{ + jobRequiresAuth.Options = command.PullOptions{ RemoteName: jobRequiresAuth.Entity.Remote.Name, Credentials: git.Credentials{ User: creduser, diff --git a/pkg/gui/commitview.go b/gui/commitview.go index 3359037..ad8adee 100644 --- a/pkg/gui/commitview.go +++ b/gui/commitview.go @@ -5,7 +5,7 @@ import ( "fmt" "regexp" - "github.com/isacikgoz/gitbatch/pkg/git" + "github.com/isacikgoz/gitbatch/core/command" "github.com/jroimartin/gocui" ) @@ -74,7 +74,7 @@ func (gui *Gui) openCommitUserNameView(g *gocui.Gui) error { if err != gocui.ErrUnknownView { return err } - name, err := git.Config(e, git.ConfigOptions{ + name, err := command.Config(e, command.ConfigOptions{ Section: "user", Option: "name", }) @@ -107,7 +107,7 @@ func (gui *Gui) openCommitUserEmailView(g *gocui.Gui) error { if err != gocui.ErrUnknownView { return err } - email, err := git.Config(e, git.ConfigOptions{ + email, err := command.Config(e, command.ConfigOptions{ Section: "user", Option: "email", }) @@ -151,7 +151,7 @@ func (gui *Gui) submitCommitMessageView(g *gocui.Gui, v *gocui.View) error { return errors.New("User email needs to be provided") } - err = git.CommitCommand(e, git.CommitOptions{ + err = command.CommitCommand(e, command.CommitOptions{ CommitMsg: msg, User: name, Email: email, diff --git a/pkg/gui/controlsview.go b/gui/controlsview.go index 4b2f97e..4b2f97e 100644 --- a/pkg/gui/controlsview.go +++ b/gui/controlsview.go diff --git a/pkg/gui/diffview.go b/gui/diffview.go index 9a47f95..e78dcaf 100644 --- a/pkg/gui/diffview.go +++ b/gui/diffview.go @@ -3,7 +3,7 @@ package gui import ( "fmt" - "github.com/isacikgoz/gitbatch/pkg/git" + "github.com/isacikgoz/gitbatch/core/command" "github.com/jroimartin/gocui" ) @@ -38,7 +38,7 @@ func (gui *Gui) openCommitDiffView(g *gocui.Gui, v *gocui.View) (err error) { commit := e.Commit commitDetail := []string{("Hash: " + cyan.Sprint(commit.Hash) + "\n" + "Author: " + commit.Author + "\n" + commit.Time + "\n" + "\n" + "\t\t" + commit.Message + "\n")} - diff, err := git.Diff(e, e.Commit.Hash) + diff, err := command.Diff(e, e.Commit.Hash) if err != nil { return err } @@ -56,19 +56,17 @@ func (gui *Gui) openCommitDiffView(g *gocui.Gui, v *gocui.View) (err error) { // called from status, so initial view may be stagedview or unstaged view func (gui *Gui) openFileDiffView(g *gocui.Gui, v *gocui.View) (err error) { - e := gui.getSelectedRepository() + _, cy := v.Cursor() _, oy := v.Origin() - var files []*git.File + var files []*command.File switch v.Name() { case unstageViewFeature.Name: - _, files, err = populateFileLists(e) + files = unstagedFiles case stageViewFeature.Name: - files, _, err = populateFileLists(e) - } - if err != nil { - return err + files = stagedFiles } + if len(files) <= 0 { return nil } diff --git a/pkg/gui/errorview.go b/gui/errorview.go index f679b54..f679b54 100644 --- a/pkg/gui/errorview.go +++ b/gui/errorview.go diff --git a/pkg/gui/gui.go b/gui/gui.go index 2a9fb8b..e593b5f 100644 --- a/pkg/gui/gui.go +++ b/gui/gui.go @@ -3,7 +3,9 @@ package gui import ( "sync" - "github.com/isacikgoz/gitbatch/pkg/git" + "github.com/isacikgoz/gitbatch/core/git" + "github.com/isacikgoz/gitbatch/core/job" + "github.com/isacikgoz/gitbatch/core/load" "github.com/jroimartin/gocui" log "github.com/sirupsen/logrus" ) @@ -23,8 +25,8 @@ type guiState struct { Repositories []*git.RepoEntity Directories []string Mode mode - Queue *git.JobQueue - FailoverQueue *git.JobQueue + Queue *job.JobQueue + FailoverQueue *job.JobQueue } // this struct encapsulates the name and title of a view. the name of a view is @@ -79,8 +81,8 @@ func NewGui(mode string, directoies []string) (*Gui, error) { initialState := guiState{ Directories: directoies, Mode: fetchMode, - Queue: git.CreateJobQueue(), - FailoverQueue: git.CreateJobQueue(), + Queue: job.CreateJobQueue(), + FailoverQueue: job.CreateJobQueue(), } gui := &Gui{ State: initialState, @@ -112,7 +114,7 @@ func (gui *Gui) Run() error { g.InputEsc = true g.SetManagerFunc(gui.layout) - go git.LoadRepositoryEntitiesAsync(gui.State.Directories, gui.addRepository) + go load.AddRepositoryEntitiesAsync(gui.State.Directories, gui.addRepository) if err := gui.generateKeybindings(); err != nil { log.Error("Keybindings could not be created.") diff --git a/pkg/gui/keybindings.go b/gui/keybindings.go index 668fe90..668fe90 100644 --- a/pkg/gui/keybindings.go +++ b/gui/keybindings.go diff --git a/pkg/gui/mainview.go b/gui/mainview.go index bcf58ed..288ca8f 100644 --- a/pkg/gui/mainview.go +++ b/gui/mainview.go @@ -4,7 +4,9 @@ import ( "fmt" "sort" - "github.com/isacikgoz/gitbatch/pkg/git" + gerr "github.com/isacikgoz/gitbatch/core/errors" + "github.com/isacikgoz/gitbatch/core/git" + "github.com/isacikgoz/gitbatch/core/job" "github.com/jroimartin/gocui" log "github.com/sirupsen/logrus" ) @@ -172,18 +174,18 @@ func (gui *Gui) getSelectedRepository() *git.RepoEntity { // adds given entity to job queue func (gui *Gui) addToQueue(entity *git.RepoEntity) error { - var jt git.JobType + var jt job.JobType switch mode := gui.State.Mode.ModeID; mode { case FetchMode: - jt = git.FetchJob + jt = job.FetchJob case PullMode: - jt = git.PullJob + jt = job.PullJob case MergeMode: - jt = git.MergeJob + jt = job.MergeJob default: return nil } - err := gui.State.Queue.AddJob(&git.Job{ + err := gui.State.Queue.AddJob(&job.Job{ JobType: jt, Entity: entity, }) @@ -209,9 +211,9 @@ func (gui *Gui) removeFromQueue(entity *git.RepoEntity) error { func (gui *Gui) startQueue(g *gocui.Gui, v *gocui.View) error { go func(gui_go *Gui) { fails := gui_go.State.Queue.StartJobsAsync() - gui_go.State.Queue = git.CreateJobQueue() + gui_go.State.Queue = job.CreateJobQueue() for j, err := range fails { - if err == git.ErrAuthenticationRequired { + if err == gerr.ErrAuthenticationRequired { j.Entity.SetState(git.Paused) gui_go.State.FailoverQueue.AddJob(j) } diff --git a/pkg/gui/sideviews.go b/gui/sideviews.go index fcd7f13..1139054 100644 --- a/pkg/gui/sideviews.go +++ b/gui/sideviews.go @@ -3,7 +3,8 @@ package gui import ( "fmt" - "github.com/isacikgoz/gitbatch/pkg/git" + "github.com/isacikgoz/gitbatch/core/command" + "github.com/isacikgoz/gitbatch/core/git" "github.com/jroimartin/gocui" ) @@ -12,7 +13,7 @@ var ( sideViews = []viewFeature{remoteViewFeature, remoteBranchViewFeature, branchViewFeature, commitViewFeature} ) -// refreshes the side views of the application for given git.RepoEntity struct +// refreshes the side views of the application for given repository.RepoEntity struct func (gui *Gui) renderSideViews(e *git.RepoEntity) error { if e == nil { return nil @@ -178,7 +179,7 @@ func (gui *Gui) sideViewsPreviousItem(g *gocui.Gui, v *gocui.View) error { // basically does fetch --prune func (gui *Gui) syncRemoteBranch(g *gocui.Gui, v *gocui.View) error { e := gui.getSelectedRepository() - return git.Fetch(e, git.FetchOptions{ + return command.Fetch(e, command.FetchOptions{ RemoteName: e.Remote.Name, Prune: true, }) @@ -204,17 +205,17 @@ func (gui *Gui) setUpstreamToBranch(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) confirmSetUpstreamToBranch(g *gocui.Gui, v *gocui.View) error { var err error e := gui.getSelectedRepository() - if err = git.AddConfig(e, git.ConfigOptions{ + if err = command.AddConfig(e, command.ConfigOptions{ Section: "branch." + e.Branch.Name, Option: "remote", - Site: git.ConfigSiteLocal, + Site: command.ConfigSiteLocal, }, e.Remote.Name); err != nil { return err } - if err = git.AddConfig(e, git.ConfigOptions{ + if err = command.AddConfig(e, command.ConfigOptions{ Section: "branch." + e.Branch.Name, Option: "merge", - Site: git.ConfigSiteLocal, + Site: command.ConfigSiteLocal, }, e.Branch.Reference.Name().String()); err != nil { return err } diff --git a/pkg/gui/stagedview.go b/gui/stagedview.go index a1c9737..5f68f5a 100644 --- a/pkg/gui/stagedview.go +++ b/gui/stagedview.go @@ -3,7 +3,7 @@ package gui import ( "fmt" - "github.com/isacikgoz/gitbatch/pkg/git" + "github.com/isacikgoz/gitbatch/core/command" "github.com/jroimartin/gocui" ) @@ -32,7 +32,7 @@ func (gui *Gui) resetChanges(g *gocui.Gui, v *gocui.View) error { if len(stagedFiles) <= 0 || len(stagedFiles) <= cy+oy { return nil } - if err := git.Reset(e, stagedFiles[cy+oy], git.ResetOptions{}); err != nil { + if err := command.Reset(e, stagedFiles[cy+oy], command.ResetOptions{}); err != nil { return err } return refreshAllStatusView(g, e, true) @@ -44,9 +44,9 @@ func (gui *Gui) resetAllChanges(g *gocui.Gui, v *gocui.View) error { if err != nil { return err } - if err := git.ResetAll(e, git.ResetOptions{ + if err := command.ResetAll(e, command.ResetOptions{ Hash: ref.Hash().String(), - Rtype: git.ResetMixed, + Rtype: command.ResetMixed, }); err != nil { return err } diff --git a/pkg/gui/stashview.go b/gui/stashview.go index 0afc983..05f0a09 100644 --- a/pkg/gui/stashview.go +++ b/gui/stashview.go @@ -3,7 +3,7 @@ package gui import ( "fmt" - "github.com/isacikgoz/gitbatch/pkg/git" + "github.com/isacikgoz/gitbatch/core/git" "github.com/jroimartin/gocui" ) diff --git a/pkg/gui/statusview.go b/gui/statusview.go index b66d49f..1648c4e 100644 --- a/pkg/gui/statusview.go +++ b/gui/statusview.go @@ -3,7 +3,8 @@ package gui import ( "fmt" - "github.com/isacikgoz/gitbatch/pkg/git" + "github.com/isacikgoz/gitbatch/core/command" + "github.com/isacikgoz/gitbatch/core/git" "github.com/jroimartin/gocui" ) @@ -16,13 +17,13 @@ var ( statusViews = []viewFeature{stageViewFeature, unstageViewFeature, stashViewFeature} commitMesageReturnView string - stagedFiles []*git.File - unstagedFiles []*git.File + stagedFiles []*command.File + unstagedFiles []*command.File ) // open the status layout func (gui *Gui) openStatusView(g *gocui.Gui, v *gocui.View) error { - if err := reloadFiles(gui.getSelectedRepository()); err != nil { + if err := populateFileLists(gui.getSelectedRepository()); err != nil { return err } gui.openStatusHeaderView(g) @@ -32,11 +33,6 @@ func (gui *Gui) openStatusView(g *gocui.Gui, v *gocui.View) error { return nil } -func reloadFiles(e *git.RepoEntity) error { - _, _, err := populateFileLists(e) - return err -} - // focus to next view func (gui *Gui) nextStatusView(g *gocui.Gui, v *gocui.View) error { return gui.nextViewOfGroup(g, v, statusViews) @@ -115,32 +111,34 @@ func (gui *Gui) closeStatusView(g *gocui.Gui, v *gocui.View) error { if err := g.DeleteView(statusHeaderViewFeature.Name); err != nil { return err } - stagedFiles = make([]*git.File, 0) - unstagedFiles = make([]*git.File, 0) + stagedFiles = make([]*command.File, 0) + unstagedFiles = make([]*command.File, 0) return gui.closeViewCleanup(mainViewFeature.Name) } // generate file lists by git status command -func populateFileLists(e *git.RepoEntity) (staged, unstaged []*git.File, err error) { - files, err := git.Status(e) +func populateFileLists(e *git.RepoEntity) error { + files, err := command.Status(e) if err != nil { - return nil, nil, err + return err } + stagedFiles = make([]*command.File, 0) + unstagedFiles = make([]*command.File, 0) for _, file := range files { - if file.X != git.StatusNotupdated && file.X != git.StatusUntracked && file.X != git.StatusIgnored && file.X != git.StatusUpdated { - staged = append(staged, file) + if file.X != command.StatusNotupdated && file.X != command.StatusUntracked && file.X != command.StatusIgnored && file.X != command.StatusUpdated { + stagedFiles = append(stagedFiles, file) } - if file.Y != git.StatusNotupdated { - unstaged = append(unstaged, file) + if file.Y != command.StatusNotupdated { + unstagedFiles = append(unstagedFiles, file) } } - return staged, unstaged, err + return err } func refreshStatusView(viewName string, g *gocui.Gui, e *git.RepoEntity, reload bool) error { if reload { - reloadFiles(e) + populateFileLists(e) } var err error switch viewName { diff --git a/pkg/gui/unstagedview.go b/gui/unstagedview.go index 8d152c9..ce19388 100644 --- a/pkg/gui/unstagedview.go +++ b/gui/unstagedview.go @@ -3,7 +3,7 @@ package gui import ( "fmt" - "github.com/isacikgoz/gitbatch/pkg/git" + "github.com/isacikgoz/gitbatch/core/command" "github.com/jroimartin/gocui" ) @@ -30,7 +30,7 @@ func (gui *Gui) addChanges(g *gocui.Gui, v *gocui.View) error { if len(unstagedFiles) <= 0 || len(unstagedFiles) < cy+oy { return nil } - if err := git.Add(e, unstagedFiles[cy+oy], git.AddOptions{}); err != nil { + if err := command.Add(e, unstagedFiles[cy+oy], command.AddOptions{}); err != nil { return err } @@ -39,7 +39,7 @@ func (gui *Gui) addChanges(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) addAllChanges(g *gocui.Gui, v *gocui.View) error { e := gui.getSelectedRepository() - if err := git.AddAll(e, git.AddOptions{}); err != nil { + if err := command.AddAll(e, command.AddOptions{}); err != nil { return err } diff --git a/pkg/gui/util-common.go b/gui/util-common.go index b25848c..b25848c 100644 --- a/pkg/gui/util-common.go +++ b/gui/util-common.go diff --git a/pkg/gui/util-textstyle.go b/gui/util-textstyle.go index c42857b..f14e6c2 100644 --- a/pkg/gui/util-textstyle.go +++ b/gui/util-textstyle.go @@ -5,7 +5,8 @@ import ( "strings" "github.com/fatih/color" - "github.com/isacikgoz/gitbatch/pkg/git" + "github.com/isacikgoz/gitbatch/core/git" + "github.com/isacikgoz/gitbatch/core/job" ) var ( @@ -86,11 +87,11 @@ func (gui *Gui) repositoryLabel(e *git.RepoEntity) string { if e.State() == git.Queued { if inQueue, j := gui.State.Queue.IsInTheQueue(e); inQueue { switch mode := j.JobType; mode { - case git.FetchJob: + case job.FetchJob: suffix = blue.Sprint(queuedSymbol) - case git.PullJob: + case job.PullJob: suffix = magenta.Sprint(queuedSymbol) - case git.MergeJob: + case job.MergeJob: suffix = cyan.Sprint(queuedSymbol) default: suffix = green.Sprint(queuedSymbol) @@ -3,7 +3,7 @@ package main import ( "os" - "github.com/isacikgoz/gitbatch/pkg/app" + "github.com/isacikgoz/gitbatch/app" log "github.com/sirupsen/logrus" kingpin "gopkg.in/alecthomas/kingpin.v2" ) diff --git a/pkg/git/cmd-rev-list.go b/pkg/git/cmd-rev-list.go deleted file mode 100644 index 624e290..0000000 --- a/pkg/git/cmd-rev-list.go +++ /dev/null @@ -1,42 +0,0 @@ -package git - -import ( - "strings" - - log "github.com/sirupsen/logrus" -) - -var revlistCommand = "rev-list" -var hashLength = 40 - -// RevListOptions defines the rules of rev-list func -type RevListOptions struct { - // Ref1 is the first reference hash to link - Ref1 string - // Ref2 is the second reference hash to link - Ref2 string -} - -// RevList returns the commit hashes that are links from the given commit(s). -// The output is given in reverse chronological order by default. -func RevList(e *RepoEntity, options RevListOptions) ([]string, error) { - args := make([]string, 0) - args = append(args, revlistCommand) - if len(options.Ref1) > 0 && len(options.Ref2) > 0 { - arg1 := options.Ref1 + ".." + options.Ref2 - args = append(args, arg1) - } - out, err := GenericGitCommandWithOutput(e.AbsPath, args) - if err != nil { - log.Warn("Error while rev-list command") - return []string{"?"}, err - } - hashes := strings.Split(out, "\n") - for _, hash := range hashes { - if len(hash) != hashLength { - return make([]string, 0), nil - } - break - } - return hashes, nil -} |
