diff options
| author | Ibrahim Serdar Acikgoz <serdaracikgoz86@gmail.com> | 2018-12-03 01:25:42 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-12-03 01:25:42 +0300 |
| commit | 365d769b589ff271bdb4db3d91f1184d23a3a5b2 (patch) | |
| tree | 9aac4d248fecce6e0c9ead05c6a019848641e017 | |
| parent | some refactor, minor bugfixes and added gui documentation (diff) | |
| parent | resolved conflicts with origin/master (diff) | |
| download | gitbatch-365d769b589ff271bdb4db3d91f1184d23a3a5b2.tar.gz | |
Merge pull request #15 from isacikgoz/develop
Develop
| -rw-r--r-- | main.go | 6 | ||||
| -rw-r--r-- | pkg/app/app.go | 86 | ||||
| -rw-r--r-- | pkg/app/files.go | 62 | ||||
| -rw-r--r-- | pkg/git/branch.go | 36 | ||||
| -rw-r--r-- | pkg/git/commit.go | 38 | ||||
| -rw-r--r-- | pkg/git/git-commands.go | 52 | ||||
| -rw-r--r-- | pkg/git/load.go | 5 | ||||
| -rw-r--r-- | pkg/git/remote.go | 6 | ||||
| -rw-r--r-- | pkg/git/remotebranch.go | 4 | ||||
| -rw-r--r-- | pkg/git/repository.go | 40 | ||||
| -rw-r--r-- | pkg/gui/branchview.go | 2 | ||||
| -rw-r--r-- | pkg/gui/commitsview.go | 14 | ||||
| -rw-r--r-- | pkg/gui/diffview.go | 2 | ||||
| -rw-r--r-- | pkg/gui/errorview.go | 2 | ||||
| -rw-r--r-- | pkg/gui/gui-util.go | 18 | ||||
| -rw-r--r-- | pkg/gui/gui.go | 27 | ||||
| -rw-r--r-- | pkg/gui/keybindings.go | 6 | ||||
| -rw-r--r-- | pkg/gui/mainview.go | 18 | ||||
| -rw-r--r-- | pkg/gui/queuehandler.go | 9 | ||||
| -rw-r--r-- | pkg/gui/remotesview.go | 2 | ||||
| -rw-r--r-- | pkg/gui/textstyle.go | 47 | ||||
| -rw-r--r-- | pkg/helpers/command.go (renamed from pkg/command/command.go) | 14 | ||||
| -rw-r--r-- | pkg/helpers/utils.go (renamed from pkg/utils/utils.go) | 8 | ||||
| -rw-r--r-- | pkg/queue/queue.go (renamed from pkg/job/job.go) | 28 |
24 files changed, 295 insertions, 237 deletions
@@ -1,19 +1,19 @@ package main import ( - "log" "os" "github.com/isacikgoz/gitbatch/pkg/app" + log "github.com/sirupsen/logrus" "gopkg.in/alecthomas/kingpin.v2" ) - var ( // take this as default directory if user does not start app with -d flag currentDir, err = os.Getwd() dir = kingpin.Flag("directory", "Directory to roam for git repositories.").Default(currentDir).Short('d').String() repoPattern = kingpin.Flag("pattern", "Pattern to filter repositories").Short('p').String() + logLevel = kingpin.Flag("log-level", "Logging level; trace,debug,info,warn,error").Default("error").Short('l').String() ) func main() { @@ -21,7 +21,7 @@ func main() { kingpin.Parse() // set the app - app, err := app.Setup(*dir, *repoPattern) + app, err := app.Setup(*dir, *repoPattern, *logLevel) if err != nil { log.Fatal(err) } diff --git a/pkg/app/app.go b/pkg/app/app.go index f23837a..d1ab15b 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -1,27 +1,22 @@ package app import ( - "io/ioutil" - "log" - "os" - "path/filepath" - "strings" - "github.com/isacikgoz/gitbatch/pkg/gui" + log "github.com/sirupsen/logrus" ) // The App struct is responsible to hold app-wide related entities. Currently // it has only the gui.Gui pointer for interface entity. type App struct { - Gui *gui.Gui + Gui *gui.Gui } -// If any pre-required operation is needed, setup will handle that task. It is -// designed to be a wrapper for main method right now. -func Setup(directory string, repoPattern string) (*App, error) { +// Setup will handle pre-required operations. It is designed to be a wrapper for +// main method right now. +func Setup(directory, repoPattern, logLevel string) (*App, error) { // initiate the app and give it initial values - app := &App{ - } + app := &App{} + setLogLevel(logLevel) var err error directories := generateDirectories(directory, repoPattern) @@ -29,62 +24,37 @@ func Setup(directory string, repoPattern string) (*App, error) { app.Gui, err = gui.NewGui(directories) if err != nil { // the error types and handling is not considered yer + log.Error(err) return app, err } // hopefull everything went smooth as butter + log.Trace("App configuration completed") return app, nil } -// If any cleanup is required Close method with handle it. e.g. closing streams +// Close function will handle if any cleanup is required. e.g. closing streams // or cleaning temproray files so on and so forth func (app *App) Close() error { return nil } -// generateDirectories is to find all the files in given path. This method -// does not check if the given file is a valid git repositories -func generateDirectories(directory string, repoPattern string) (directories []string) { - files, err := ioutil.ReadDir(directory) - - // can we read the directory? - if err != nil { - log.Fatal(err) - } - - // filter according to a pattern - filteredFiles := filterDirectories(files, repoPattern) - - // now let's iterate over the our desired git directories - for _, f := range filteredFiles { - repo := directory + string(os.PathSeparator) + f.Name() - file, err := os.Open(repo) - - // if we cannot open it, simply continue to iteration and don't consider - if err != nil { - continue - } - dir, err := filepath.Abs(file.Name()) - if err != nil { - log.Fatal(err) - } - - // shaping our directory slice - directories = append(directories, dir) - } - return directories -} - -// takes a fileInfo slice and returns it with the ones matches with the -// repoPattern string -func filterDirectories(files []os.FileInfo, repoPattern string) []os.FileInfo { - var filteredRepos []os.FileInfo - for _, f := range files { - // it is just a simple filter - if strings.Contains(f.Name(), repoPattern) { - filteredRepos = append(filteredRepos, f) - } else { - continue - } +// set the level of logging it is fatal by default +func setLogLevel(logLevel string) { + switch logLevel { + case "trace": + log.SetLevel(log.TraceLevel) + case "debug": + log.SetLevel(log.DebugLevel) + case "info": + log.SetLevel(log.InfoLevel) + case "warn": + log.SetLevel(log.WarnLevel) + case "error": + log.SetLevel(log.ErrorLevel) + default: + log.SetLevel(log.FatalLevel) } - return filteredRepos + log.WithFields(log.Fields{ + "level": logLevel, + }).Trace("logging level has been set") } diff --git a/pkg/app/files.go b/pkg/app/files.go new file mode 100644 index 0000000..f6ae947 --- /dev/null +++ b/pkg/app/files.go @@ -0,0 +1,62 @@ +package app + +import ( + "io/ioutil" + "os" + "path/filepath" + "strings" + + log "github.com/sirupsen/logrus" +) + +// generateDirectories is to find all the files in given path. This method +// does not check if the given file is a valid git repositories +func generateDirectories(directory string, repoPattern string) (directories []string) { + files, err := ioutil.ReadDir(directory) + + // can we read the directory? + if err != nil { + log.Fatal(err) + } + + // filter according to a pattern + filteredFiles := filterDirectories(files, repoPattern) + + // now let's iterate over the our desired git directories + for _, f := range filteredFiles { + repo := directory + string(os.PathSeparator) + f.Name() + file, err := os.Open(repo) + + // if we cannot open it, simply continue to iteration and don't consider + if err != nil { + log.WithFields(log.Fields{ + "file": file, + "directory": directory, + }).Trace("Failed to open file in the directory") + continue + } + dir, err := filepath.Abs(file.Name()) + if err != nil { + log.Fatal(err) + } + + // shaping our directory slice + directories = append(directories, dir) + } + return directories +} + +// takes a fileInfo slice and returns it with the ones matches with the +// repoPattern string +func filterDirectories(files []os.FileInfo, repoPattern string) []os.FileInfo { + var filteredRepos []os.FileInfo + for _, f := range files { + // it is just a simple filter + if strings.Contains(f.Name(), repoPattern) { + filteredRepos = append(filteredRepos, f) + } else { + continue + } + } + return filteredRepos +} diff --git a/pkg/git/branch.go b/pkg/git/branch.go index 3a4f7ce..4eb5ffe 100644 --- a/pkg/git/branch.go +++ b/pkg/git/branch.go @@ -1,11 +1,11 @@ package git import ( - "github.com/isacikgoz/gitbatch/pkg/utils" + "github.com/isacikgoz/gitbatch/pkg/helpers" "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4/plumbing" - "strings" "regexp" + "strings" ) // Branch is the wrapper of go-git's Reference struct. In addition to that, it @@ -20,7 +20,7 @@ type Branch struct { Clean bool } -// returns the active branch of the repository entity by simply getting the +// returns the active branch of the repository entity by simply getting the // head reference and searching it from the entities branch slice func (entity *RepoEntity) getActiveBranch() (branch *Branch) { headRef, _ := entity.Repository.Head() @@ -32,7 +32,7 @@ func (entity *RepoEntity) getActiveBranch() (branch *Branch) { return nil } -// search for branches in go-git way. It is useful to do so that checkout and +// 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 func (entity *RepoEntity) loadLocalBranches() error { @@ -55,7 +55,7 @@ func (entity *RepoEntity) loadLocalBranches() error { return err } -// checkouts the next branch +// NextBranch checkouts the next branch func (entity *RepoEntity) NextBranch() *Branch { currentBranch := entity.Branch currentBranchIndex := 0 @@ -70,7 +70,7 @@ func (entity *RepoEntity) NextBranch() *Branch { return entity.Branches[currentBranchIndex+1] } -// checkout to given branch. If any errors occur, the method returns it instead +// Checkout to given branch. If any errors occur, the method returns it instead // of returning nil func (entity *RepoEntity) Checkout(branch *Branch) error { if branch.Name == entity.Branch.Name { @@ -93,19 +93,19 @@ func (entity *RepoEntity) Checkout(branch *Branch) error { entity.Branch.Pushables, entity.Branch.Pullables = UpstreamDifferenceCount(entity.AbsPath) // TODO: same code on 3 different occasion, maybe something wrong? // make this conditional on global scale - if err = entity.Remote.switchRemoteBranch(entity.Remote.Name + "/" + entity.Branch.Name); err !=nil { + if err = entity.Remote.switchRemoteBranch(entity.Remote.Name + "/" + entity.Branch.Name); err != nil { // probably couldn't find, but its ok. return nil } return nil } -// checking the branch if it has any changes from its head revision. Initially +// checking the branch if it has any changes from its head revision. Initially // 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 (entity *RepoEntity) isClean() bool { status := entity.StatusWithGit() - status = utils.TrimTrailingNewline(status) + status = helpers.TrimTrailingNewline(status) if status != "?" { verbose := strings.Split(status, "\n") lastLine := verbose[len(verbose)-1] @@ -116,7 +116,7 @@ func (entity *RepoEntity) isClean() bool { return false } -// refreshes the active branchs pushable and pullable count +// RefreshPushPull refreshes the active branchs pushable and pullable count func (entity *RepoEntity) RefreshPushPull() { entity.Branch.Pushables, entity.Branch.Pullables = UpstreamDifferenceCount(entity.AbsPath) } @@ -132,15 +132,15 @@ func (entity *RepoEntity) pullDiffsToUpstream() ([]*Commit, error) { for _, s := range sliced { if len(s) == 40 { commit := &Commit{ - Hash: s, - Author: GitShowEmail(entity.AbsPath, s), - Message: re.ReplaceAllString(GitShowBody(entity.AbsPath, s), " "), - Time: GitShowDate(entity.AbsPath, s), - CommitType: RemoteCommit, - } - remoteCommits = append(remoteCommits, commit) + Hash: s, + Author: GitShowEmail(entity.AbsPath, s), + Message: re.ReplaceAllString(GitShowBody(entity.AbsPath, s), " "), + Time: GitShowDate(entity.AbsPath, s), + CommitType: RemoteCommit, + } + remoteCommits = append(remoteCommits, commit) } } } return remoteCommits, nil -} +}
\ No newline at end of file diff --git a/pkg/git/commit.go b/pkg/git/commit.go index 9045555..b0ba381 100644 --- a/pkg/git/commit.go +++ b/pkg/git/commit.go @@ -8,26 +8,28 @@ import ( "gopkg.in/src-d/go-git.v4/plumbing/object" ) -// Commit is the lightweight version of go-git's Reference struct. it holds -// hash of the commit, author's e-mail address, Message (subject and body +// Commit is the lightweight version of go-git's Reference struct. it holds +// hash of the commit, author's e-mail address, Message (subject and body // combined) commit date and commit type wheter it is local commit or a remote type Commit struct { - Hash string - Author string - Message string - Time string - CommitType CommitType + Hash string + Author string + Message string + Time string + CommitType CommitType } -// type of the commit; it can be local or remote (upstream diff) +// CommitType is the Type of the commit; it can be local or remote (upstream diff) type CommitType string const ( - LocalCommit CommitType = "local" + // LocalCommit is the commit that recorded locally + LocalCommit CommitType = "local" + // RemoteCommit is the commit that not merged to local branch RemoteCommit CommitType = "remote" ) -// iterate over next commit of a branch +// NextCommit iterates over next commit of a branch // TODO: the commits entites can tied to branch instead ot the repository func (entity *RepoEntity) NextCommit() error { currentCommitIndex := 0 @@ -63,6 +65,9 @@ func (entity *RepoEntity) loadCommits() error { } defer cIter.Close() rmcs, err := entity.pullDiffsToUpstream() + if err != nil { + return err + } for _, rmc := range rmcs { entity.Commits = append(entity.Commits, rmc) } @@ -70,10 +75,10 @@ func (entity *RepoEntity) loadCommits() error { err = cIter.ForEach(func(c *object.Commit) error { re := regexp.MustCompile(`\r?\n`) commit := &Commit{ - Hash: re.ReplaceAllString(c.Hash.String(), " "), - Author: c.Author.Email, - Message: re.ReplaceAllString(c.Message, " "), - Time: c.Author.When.String(), + Hash: re.ReplaceAllString(c.Hash.String(), " "), + Author: c.Author.Email, + Message: re.ReplaceAllString(c.Message, " "), + Time: c.Author.When.String(), CommitType: LocalCommit, } entity.Commits = append(entity.Commits, commit) @@ -87,9 +92,8 @@ func (entity *RepoEntity) loadCommits() error { return nil } - -// returns the diff to previous commit detail of the given hash of a specific -// commit +// Diff function returns the diff to previous commit detail of the given has +// of a specific commit func (entity *RepoEntity) Diff(hash string) (diff string, err error) { currentCommitIndex := 0 diff --git a/pkg/git/git-commands.go b/pkg/git/git-commands.go index 7216b17..9518322 100644 --- a/pkg/git/git-commands.go +++ b/pkg/git/git-commands.go @@ -3,7 +3,7 @@ package git import ( "strings" - "github.com/isacikgoz/gitbatch/pkg/command" + "github.com/isacikgoz/gitbatch/pkg/helpers" ) // UpstreamDifferenceCount checks how many pushables/pullables there are for the @@ -11,124 +11,124 @@ import ( // TODO: get pull pushes to remote branch vs local branch func UpstreamDifferenceCount(repoPath string) (string, string) { args := []string{"rev-list", "@{u}..HEAD", "--count"} - pushableCount, err := command.RunCommandWithOutput(repoPath, "git", args) + pushableCount, err := helpers.RunCommandWithOutput(repoPath, "git", args) if err != nil { return "?", "?" } args = []string{"rev-list", "HEAD..@{u}", "--count"} - pullableCount, err := command.RunCommandWithOutput(repoPath, "git", args) + pullableCount, err := helpers.RunCommandWithOutput(repoPath, "git", args) if err != nil { return "?", "?" } return strings.TrimSpace(pushableCount), strings.TrimSpace(pullableCount) } -// Instead of returning the count, this method returns the hash list +// UpstreamPushDiffs returns the hash list func UpstreamPushDiffs(repoPath string) string { args := []string{"rev-list", "@{u}..HEAD"} - pushableCount, err := command.RunCommandWithOutput(repoPath, "git", args) + pushableCount, err := helpers.RunCommandWithOutput(repoPath, "git", args) if err != nil { return "?" } return pushableCount } -// Instead of returning the count, this method returns the hash list +// UpstreamPullDiffs returns the hash list func UpstreamPullDiffs(repoPath string) string { args := []string{"rev-list", "HEAD..@{u}"} - pullableCount, err := command.RunCommandWithOutput(repoPath, "git", args) + pullableCount, err := helpers.RunCommandWithOutput(repoPath, "git", args) if err != nil { return "?" } return pullableCount } -// Conventional git show command without any argument +// GitShow is conventional git show command without any argument func GitShow(repoPath, hash string) string { args := []string{"show", hash} - diff, err := command.RunCommandWithOutput(repoPath, "git", args) + diff, err := helpers.RunCommandWithOutput(repoPath, "git", args) if err != nil { return "?" } return diff } -// get author's e-mail with git show command +// 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 := command.RunCommandWithOutput(repoPath, "git", args) + diff, err := helpers.RunCommandWithOutput(repoPath, "git", args) if err != nil { return "?" } return diff } -// get body of the commit with git show +// 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 := command.RunCommandWithOutput(repoPath, "git", args) + diff, err := helpers.RunCommandWithOutput(repoPath, "git", args) if err != nil { return err.Error() } return diff } -// get commit's date with git show as string +// 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 := command.RunCommandWithOutput(repoPath, "git", args) + diff, err := helpers.RunCommandWithOutput(repoPath, "git", args) if err != nil { return "?" } return diff } -// wrapper of the git fetch <remote> command +// FetchWithGit is wrapper of the git fetch <remote> command func (entity *RepoEntity) FetchWithGit(remote string) error { args := []string{"fetch", remote} - _, err := command.RunCommandWithOutput(entity.AbsPath, "git", args) + _, err := helpers.RunCommandWithOutput(entity.AbsPath, "git", args) if err != nil { return err } return nil } -// wrapper of the git pull <remote>/<branch> command +// PullWithGit is wrapper of the git pull <remote>/<branch> command func (entity *RepoEntity) PullWithGit(remote, branch string) error { args := []string{"pull", remote, branch} - _, err := command.RunCommandWithOutput(entity.AbsPath, "git", args) + _, err := helpers.RunCommandWithOutput(entity.AbsPath, "git", args) if err != nil { return err } return nil } -// wrapper of the git merge <branch> command +// MergeWithGit is wrapper of the git merge <branch> command func (entity *RepoEntity) MergeWithGit(mergeFrom string) error { args := []string{"merge", mergeFrom} - _, err := command.RunCommandWithOutput(entity.AbsPath, "git", args) + _, err := helpers.RunCommandWithOutput(entity.AbsPath, "git", args) if err != nil { return err } return nil } -// wrapper of the git checkout <branch> command +// CheckoutWithGit is wrapper of the git checkout <branch> command func (entity *RepoEntity) CheckoutWithGit(branch string) error { args := []string{"checkout", branch} - _, err := command.RunCommandWithOutput(entity.AbsPath, "git", args) + _, err := helpers.RunCommandWithOutput(entity.AbsPath, "git", args) if err != nil { return err } return nil } -// GitStatus returns the plaintext short status of the repo +// StatusWithGit returns the plaintext short status of the repo func (entity *RepoEntity) StatusWithGit() string { args := []string{"status"} - status, err := command.RunCommandWithOutput(entity.AbsPath, "git", args) + status, err := helpers.RunCommandWithOutput(entity.AbsPath, "git", args) if err != nil { return "?" } return status -}
\ No newline at end of file +} diff --git a/pkg/git/load.go b/pkg/git/load.go index dd92ec5..6e1d6c9 100644 --- a/pkg/git/load.go +++ b/pkg/git/load.go @@ -4,8 +4,9 @@ import ( "sync" ) -// 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 +// LoadRepositoryEntities 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) diff --git a/pkg/git/remote.go b/pkg/git/remote.go index b7bd907..bac39d9 100644 --- a/pkg/git/remote.go +++ b/pkg/git/remote.go @@ -1,6 +1,6 @@ package git -// this struct is simply a collection of remote branches and wraps it with the +// Remote struct is simply a collection of remote branches and wraps it with the // name of the remote and fetch/push urls. It also holds the *selected* remote // branch type Remote struct { @@ -10,7 +10,7 @@ type Remote struct { Branches []*RemoteBranch } -// iterate over next branch of a remote +// NextRemote iterates over next branch of a remote func (entity *RepoEntity) NextRemote() error { currentRemoteIndex := 0 for i, remote := range entity.Remotes { @@ -25,7 +25,7 @@ func (entity *RepoEntity) NextRemote() error { entity.Remote = entity.Remotes[currentRemoteIndex+1] } // TODO: same code on 3 different occasion, maybe something wrong? - if err := entity.Remote.switchRemoteBranch(entity.Remote.Name + "/" + entity.Branch.Name); err !=nil { + if err := entity.Remote.switchRemoteBranch(entity.Remote.Name + "/" + entity.Branch.Name); err != nil { // probably couldn't find, but its ok. } return nil diff --git a/pkg/git/remotebranch.go b/pkg/git/remotebranch.go index b37d3b7..770b016 100644 --- a/pkg/git/remotebranch.go +++ b/pkg/git/remotebranch.go @@ -9,14 +9,14 @@ import ( "gopkg.in/src-d/go-git.v4/plumbing/storer" ) -// RemoteBranch is the wrapper of go-git's Reference struct. In addition to +// RemoteBranch is the wrapper of go-git's Reference struct. In addition to // that, it also holds name of the remote branch type RemoteBranch struct { Name string Reference *plumbing.Reference } -// iterates to the next remote branch +// NextRemoteBranch iterates to the next remote branch func (remote *Remote) NextRemoteBranch() error { currentRemoteIndex := 0 for i, rb := range remote.Branches { diff --git a/pkg/git/repository.go b/pkg/git/repository.go index e6a7c6d..822e820 100644 --- a/pkg/git/repository.go +++ b/pkg/git/repository.go @@ -4,13 +4,13 @@ import ( "errors" "os" - "github.com/isacikgoz/gitbatch/pkg/utils" + "github.com/isacikgoz/gitbatch/pkg/helpers" "gopkg.in/src-d/go-git.v4" ) -// the main entity of the application. The repository name is actually the name -// of its folder in the host's filesystem. It holds the go-git repository entity -// along with critic entites such as remote/branches and commits +// RepoEntity is the main entity of the application. The repository name is +// actually the name of its folder in the host's filesystem. It holds the go-git +// repository entity along with critic entites such as remote/branches and commits type RepoEntity struct { RepoID string Name string @@ -25,18 +25,23 @@ type RepoEntity struct { State RepoState } -// it is the state of the repository for an operation +// RepoState is the state of the repository for an operation type RepoState uint8 const ( - Available RepoState = 0 + // Available implies repo is ready for the operation + Available RepoState = 0 + // Queued means repo is queued for a operation Queued RepoState = 1 + // Working means an operation is jsut started for this repository Working RepoState = 2 + // Success is the expected outcome of the operation Success RepoState = 3 + // Fail is the unexpected outcome of the operation Fail RepoState = 4 ) -// initializee a RepoEntity struct with its belongings. +// InitializeRepository initializes a RepoEntity struct with its belongings. func InitializeRepository(directory string) (entity *RepoEntity, err error) { file, err := os.Open(directory) if err != nil { @@ -50,11 +55,11 @@ func InitializeRepository(directory string) (entity *RepoEntity, err error) { if err != nil { return nil, err } - entity = &RepoEntity{RepoID: utils.RandomString(8), + entity = &RepoEntity{RepoID: helpers.RandomString(8), Name: fileInfo.Name(), AbsPath: directory, Repository: *r, - State: Available, + State: Available, } // after we intiate the struct we can fill its values entity.loadLocalBranches() @@ -74,8 +79,8 @@ func InitializeRepository(directory string) (entity *RepoEntity, err error) { // TODO: tend to take origin/master as default entity.Remote = entity.Remotes[0] // TODO: same code on 3 different occasion, maybe something wrong? - if err = entity.Remote.switchRemoteBranch(entity.Remote.Name + "/" + entity.Branch.Name); err !=nil { - // probably couldn't find, but its ok. + if err = entity.Remote.switchRemoteBranch(entity.Remote.Name + "/" + entity.Branch.Name); err != nil { + // probably couldn't find, but its ok. } } else { // if there is no remote, this project is totally useless actually @@ -84,9 +89,9 @@ func InitializeRepository(directory string) (entity *RepoEntity, err error) { return entity, nil } -// Incorporates changes from a remote repository into the current branch. In -// its default mode, git pull is shorthand for git fetch followed by git merge -// <branch> +// Pull incorporates changes from a remote repository into the current branch. +// In its default mode, git pull is shorthand for git fetch followed by git +// merge <branch> func (entity *RepoEntity) Pull() error { // TODO: Migrate this code to src-d/go-git // 2018-11-25: tried but it fails, will investigate. @@ -116,8 +121,8 @@ func (entity *RepoEntity) Fetch() error { return nil } -// Incorporates changes from the named commits or branches into the current -// branch +// Merge incorporates changes from the named commits or branches into the +// current branch func (entity *RepoEntity) Merge() error { entity.Checkout(entity.Branch) if err := entity.MergeWithGit(entity.Remote.Branch.Name); err != nil { @@ -128,9 +133,10 @@ func (entity *RepoEntity) Merge() error { return nil } -// refresh the belongings of a repositoriy, this function is called right after +// Refresh the belongings of a repositoriy, this function is called right after // fetch/pull/merge operations func (entity *RepoEntity) Refresh() error { + var err error r, err := git.PlainOpen(entity.AbsPath) if err != nil { return err diff --git a/pkg/gui/branchview.go b/pkg/gui/branchview.go index cb6e32f..08a717f 100644 --- a/pkg/gui/branchview.go +++ b/pkg/gui/branchview.go @@ -41,7 +41,7 @@ func (gui *Gui) nextBranch(g *gocui.Gui, v *gocui.View) error { } if err = entity.Checkout(entity.NextBranch()); err != nil { if err = gui.openErrorView(g, err.Error(), - "You should manually resolve this issue"); err != nil { + "You should manually resolve this issue"); err != nil { return err } return nil diff --git a/pkg/gui/commitsview.go b/pkg/gui/commitsview.go index 8d162f6..0beacce 100644 --- a/pkg/gui/commitsview.go +++ b/pkg/gui/commitsview.go @@ -19,12 +19,12 @@ func (gui *Gui) updateCommits(g *gocui.Gui, entity *git.RepoEntity) error { currentindex := 0 totalcommits := len(entity.Commits) for i, c := range entity.Commits { - var body string = "" + var body string if c.CommitType == git.LocalCommit { - body = cyan.Sprint(c.Hash[:hashLength])+" "+c.Message - } else { - body = yellow.Sprint(c.Hash[:hashLength])+" "+c.Message - } + body = cyan.Sprint(c.Hash[:hashLength]) + " " + c.Message + } else { + body = yellow.Sprint(c.Hash[:hashLength]) + " " + c.Message + } if c.Hash == entity.Commit.Hash { currentindex = i fmt.Fprintln(out, selectionIndicator+body) @@ -35,7 +35,7 @@ func (gui *Gui) updateCommits(g *gocui.Gui, entity *git.RepoEntity) error { if err = gui.smartAnchorRelativeToLine(out, currentindex, totalcommits); err != nil { return err } - return nil + return err } // iteration handler for the commitsview @@ -51,5 +51,5 @@ func (gui *Gui) nextCommit(g *gocui.Gui, v *gocui.View) error { if err = gui.updateCommits(g, entity); err != nil { return err } - return nil + return err } diff --git a/pkg/gui/diffview.go b/pkg/gui/diffview.go index 8011de6..4ebf82e 100644 --- a/pkg/gui/diffview.go +++ b/pkg/gui/diffview.go @@ -28,7 +28,7 @@ func (gui *Gui) openCommitDiffView(g *gocui.Gui, v *gocui.View) error { } commit := entity.Commit commitDetail := "Hash: " + cyan.Sprint(commit.Hash) + "\n" + "Author: " + commit.Author + - "\n" + commit.Time + "\n" + "\n" + "\t\t" + commit.Message + "\n" + "\n" + commit.Time + "\n" + "\n" + "\t\t" + commit.Message + "\n" fmt.Fprintln(v, commitDetail) diff, err := entity.Diff(entity.Commit.Hash) if err != nil { diff --git a/pkg/gui/errorview.go b/pkg/gui/errorview.go index cca3853..362a656 100644 --- a/pkg/gui/errorview.go +++ b/pkg/gui/errorview.go @@ -6,7 +6,7 @@ import ( "github.com/jroimartin/gocui" ) -// open an error view to inform user with a message and a useful note +// open an error view to inform user with a message and a useful note func (gui *Gui) openErrorView(g *gocui.Gui, message string, note string) error { maxX, maxY := g.Size() diff --git a/pkg/gui/gui-util.go b/pkg/gui/gui-util.go index 3622705..c09ae6c 100644 --- a/pkg/gui/gui-util.go +++ b/pkg/gui/gui-util.go @@ -2,29 +2,29 @@ package gui import ( "github.com/isacikgoz/gitbatch/pkg/git" - "github.com/isacikgoz/gitbatch/pkg/utils" + "github.com/isacikgoz/gitbatch/pkg/helpers" "github.com/jroimartin/gocui" ) // refreshes the side views of the application for given git.RepoEntity struct func (gui *Gui) refreshViews(g *gocui.Gui, entity *git.RepoEntity) error { - - if err := gui.updateRemotes(g, entity); err != nil { + var err error + if err = gui.updateRemotes(g, entity); err != nil { return err } - if err := gui.updateBranch(g, entity); err != nil { + if err = gui.updateBranch(g, entity); err != nil { return err } - if err := gui.updateRemoteBranches(g, entity); err != nil { + if err = gui.updateRemoteBranches(g, entity); err != nil { return err } - if err := gui.updateCommits(g, entity); err != nil { + if err = gui.updateCommits(g, entity); err != nil { return err } - return nil + return err } -// siwtch the app mode +// siwtch the app mode // TODO: switching can be made with conventional iteration func (gui *Gui) switchMode(g *gocui.Gui, v *gocui.View) error { switch mode := gui.State.Mode.ModeID; mode { @@ -59,7 +59,7 @@ func (gui *Gui) correctCursor(v *gocui.View) error { if oy+cy <= ly { return nil } - newCy := utils.Min(ly, maxY) + newCy := helpers.Min(ly, maxY) if err := v.SetCursor(cx, newCy); err != nil { return err } diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index 5898cb1..7c8f141 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -4,8 +4,9 @@ import ( "fmt" "github.com/isacikgoz/gitbatch/pkg/git" - "github.com/isacikgoz/gitbatch/pkg/job" + "github.com/isacikgoz/gitbatch/pkg/queue" "github.com/jroimartin/gocui" + log "github.com/sirupsen/logrus" ) // Gui struct hold the gocui struct along with the gui's state, also keybindings @@ -16,13 +17,13 @@ type Gui struct { State guiState } -// guiState struct holds the repositories, directiories, mode and queue of the +// guiState struct holds the repositories, directiories, mode and queue of the // gui object. These values are not static type guiState struct { Repositories []*git.RepoEntity Directories []string Mode mode - Queue *job.JobQueue + Queue *queue.JobQueue } // this struct encapsulates the name and title of a view. the name of a view is @@ -39,11 +40,15 @@ type mode struct { CommandString string } +// ModeID is the mode indicator for the gui type ModeID int8 const ( + // FetchMode puts the gui in fetch state FetchMode ModeID = 0 - PullMode ModeID = 1 + // PullMode puts the gui in pull state + PullMode ModeID = 1 + // MergeMode puts the gui in merge state MergeMode ModeID = 2 ) @@ -62,15 +67,15 @@ var ( fetchMode = mode{ModeID: FetchMode, DisplayString: "Fetch", CommandString: "fetch"} pullMode = mode{ModeID: PullMode, DisplayString: "Pull", CommandString: "pull"} - mergeMode = mode{ModeID: MergeMode, DisplayString: "Merge", CommandString: "merge"} + mergeMode = mode{ModeID: MergeMode, DisplayString: "Merge", CommandString: "merge"} ) -// create a Gui opject and fill it's state related entites +// NewGui creates a Gui opject and fill it's state related entites func NewGui(directoies []string) (*Gui, error) { initialState := guiState{ Directories: directoies, Mode: fetchMode, - Queue: job.CreateJobQueue(), + Queue: queue.CreateJobQueue(), } gui := &Gui{ State: initialState, @@ -78,7 +83,7 @@ func NewGui(directoies []string) (*Gui, error) { return gui, nil } -// run the main loop with intial values +// Run function runs the main loop with initial values func (gui *Gui) Run() error { g, err := gocui.NewGui(gocui.OutputNormal) if err != nil { @@ -92,15 +97,18 @@ func (gui *Gui) Run() error { v, err := g.SetView(loadingViewFeature.Name, maxX/2-10, maxY/2-1, maxX/2+10, maxY/2+1) if err != nil { if err != gocui.ErrUnknownView { + log.Warn("Loading view cannot be created.") return } fmt.Fprintln(v, "Loading...") } if _, err := g.SetCurrentView(loadingViewFeature.Name); err != nil { + log.Warn("Loading view cannot be focused.") return } rs, err := git.LoadRepositoryEntities(g_ui.State.Directories) if err != nil { + log.Error("Error while loading repositories.") return } g_ui.State.Repositories = rs @@ -112,12 +120,15 @@ func (gui *Gui) Run() error { g.SetManagerFunc(gui.layout) if err := gui.generateKeybindings(); err != nil { + log.Error("Keybindings could not be created.") return err } if err := gui.keybindings(g); err != nil { + log.Error("Keybindings could not be set.") return err } if err := g.MainLoop(); err != nil && err != gocui.ErrQuit { + log.Error("Error in the main loop. " + err.Error()) return err } return nil diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index bc9d9fd..df3e4d8 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -6,7 +6,7 @@ import ( "github.com/jroimartin/gocui" ) -// keybinding structs is helpful for not re-writinh the same function over and +// KeyBinding structs is helpful for not re-writinh the same function over and // over again. it hold useful values to generate a controls view type KeyBinding struct { View string @@ -213,7 +213,7 @@ func (gui *Gui) keybindings(g *gocui.Gui) error { } // the bottom line of the gui is mode indicator and keybindings view. Only the -// important controls (marked as vital) are shown +// important controls (marked as vital) are shown func (gui *Gui) updateKeyBindingsView(g *gocui.Gui, viewName string) error { v, err := g.View(keybindingsViewFeature.Name) if err != nil { @@ -242,7 +242,7 @@ func (gui *Gui) updateKeyBindingsView(g *gocui.Gui, viewName string) error { modeLabel = "No mode selected" } - fmt.Fprint(v, ws + modeLabel + ws + modeSeperator) + fmt.Fprint(v, ws+modeLabel+ws+modeSeperator) for _, k := range gui.KeyBindings { if k.View == viewName && k.Vital { diff --git a/pkg/gui/mainview.go b/pkg/gui/mainview.go index e526f60..942b74d 100644 --- a/pkg/gui/mainview.go +++ b/pkg/gui/mainview.go @@ -4,12 +4,12 @@ import ( "fmt" "github.com/isacikgoz/gitbatch/pkg/git" - "github.com/isacikgoz/gitbatch/pkg/job" + "github.com/isacikgoz/gitbatch/pkg/queue" "github.com/jroimartin/gocui" ) -// this is the inital function for filling the values for the main view. the -// function waits a seperate routine to fill the gui's repositiory slice +// this is the initial function for filling the values for the main view. the +// function waits a separate routine to fill the gui's repository slice func (gui *Gui) fillMain(g *gocui.Gui) error { g.Update(func(g *gocui.Gui) error { v, err := g.View(mainViewFeature.Name) @@ -36,7 +36,7 @@ func (gui *Gui) fillMain(g *gocui.Gui) error { return nil } -// moves the cursor downwards for the main view and if it goes to bottom it +// moves the cursor downwards for the main view and if it goes to bottom it // prevents from going further func (gui *Gui) cursorDown(g *gocui.Gui, v *gocui.View) error { if v != nil { @@ -106,18 +106,18 @@ func (gui *Gui) markRepository(g *gocui.Gui, v *gocui.View) error { return err } if r.State == git.Available || r.State == git.Success { - var jt job.JobType + var jt queue.JobType switch mode := gui.State.Mode.ModeID; mode { case FetchMode: - jt = job.Fetch + jt = queue.Fetch case PullMode: - jt = job.Pull + jt = queue.Pull case MergeMode: - jt = job.Merge + jt = queue.Merge default: return nil } - err := gui.State.Queue.AddJob(&job.Job{ + err := gui.State.Queue.AddJob(&queue.Job{ JobType: jt, Entity: r, }) diff --git a/pkg/gui/queuehandler.go b/pkg/gui/queuehandler.go index af33e21..8801488 100644 --- a/pkg/gui/queuehandler.go +++ b/pkg/gui/queuehandler.go @@ -21,11 +21,10 @@ func (gui *Gui) startQueue(g *gocui.Gui, v *gocui.View) error { } if finished { return - } else { - selectedEntity, _ := gui_go.getSelectedRepository(g, v) - if job.Entity == selectedEntity { - gui_go.refreshViews(g, job.Entity) - } + } + selectedEntity, _ := gui_go.getSelectedRepository(g, v) + if job.Entity == selectedEntity { + gui_go.refreshViews(g, job.Entity) } } }(gui, g) diff --git a/pkg/gui/remotesview.go b/pkg/gui/remotesview.go index 219b0d7..b762b41 100644 --- a/pkg/gui/remotesview.go +++ b/pkg/gui/remotesview.go @@ -53,5 +53,5 @@ func (gui *Gui) nextRemote(g *gocui.Gui, v *gocui.View) error { if err = gui.updateRemoteBranches(g, entity); err != nil { return err } - return nil + return err } diff --git a/pkg/gui/textstyle.go b/pkg/gui/textstyle.go index 1485572..3f9e7bb 100644 --- a/pkg/gui/textstyle.go +++ b/pkg/gui/textstyle.go @@ -5,7 +5,7 @@ import ( "github.com/fatih/color" "github.com/isacikgoz/gitbatch/pkg/git" - "github.com/isacikgoz/gitbatch/pkg/job" + "github.com/isacikgoz/gitbatch/pkg/queue" ) var ( @@ -20,35 +20,35 @@ var ( bold = color.New(color.Bold) - maxBranchLength = 15 + maxBranchLength = 15 maxRepositoryLength = 20 - hashLength = 7 + hashLength = 7 - ws = " " - pushable = string(blue.Sprint("↖")) - pullable = string(blue.Sprint("↘")) - confidentArrow = string(magenta.Sprint("→")) + ws = " " + pushable = string(blue.Sprint("↖")) + pullable = string(blue.Sprint("↘")) + confidentArrow = string(magenta.Sprint("→")) unconfidentArrow = string(yellow.Sprint("→")) - dirty = string(yellow.Sprint("✗")) - unkown = magenta.Sprint("?") + dirty = string(yellow.Sprint("✗")) + unknown = magenta.Sprint("?") - queuedSymbol = "•" + queuedSymbol = "•" workingSymbol = "•" successSymbol = "✔" - failSymbol = "✗" + failSymbol = "✗" fetchSymbol = "↓" - pullSymbol = "↓↳" + pullSymbol = "↓↳" mergeSymbol = "↳" - modeSeperator = "" + modeSeperator = "" keyBindingSeperator = "░" selectionIndicator = string(green.Sprint("→")) + ws - tab = ws + ws + tab = ws + ws ) -// this fucntion handles the render and representation of the repository +// this function handles the render and representation of the repository // TODO: cleanup is required, right now it looks too complicated func (gui *Gui) displayString(entity *git.RepoEntity) string { suffix := "" @@ -68,20 +68,20 @@ func (gui *Gui) displayString(entity *git.RepoEntity) string { prefix = prefix + string(cyan.Sprint(branch)) if !entity.Branch.Clean { - prefix = prefix + ws + dirty + ws + prefix = prefix + ws + dirty + ws } else { - prefix = prefix + ws + prefix = prefix + ws } // rendering the satus according to repository's state if entity.State == git.Queued { if inQueue, ty := gui.State.Queue.IsInTheQueue(entity); inQueue { - switch mode := ty; mode { - case job.Fetch: + switch mode := ty; mode { + case queue.Fetch: suffix = blue.Sprint(queuedSymbol) - case job.Pull: + case queue.Pull: suffix = magenta.Sprint(queuedSymbol) - case job.Merge: + case queue.Merge: suffix = cyan.Sprint(queuedSymbol) default: suffix = green.Sprint(queuedSymbol) @@ -105,9 +105,8 @@ func adjustTextLength(text string, maxLength int) (adjusted string) { if len(text) > maxLength { adjusted := text[:maxLength-2] + ".." return adjusted - } else { - return text } + return text } // the remote link can be too verbose sometimes, so it is good to trim it @@ -123,7 +122,7 @@ func trimRemoteURL(url string) (urltype string, shorturl string) { rehttp := regexp.MustCompile(`http://`) rehttps := regexp.MustCompile(`https://`) - // seperate the protocol and remote link + // separate the protocol and remote link if ressh.MatchString(url) { shorturl = ressh.Split(url, 5)[1] urltype = "ssh" diff --git a/pkg/command/command.go b/pkg/helpers/command.go index 218f5c6..2485b56 100644 --- a/pkg/command/command.go +++ b/pkg/helpers/command.go @@ -1,4 +1,4 @@ -package command +package helpers import ( "log" @@ -6,9 +6,9 @@ import ( "syscall" ) -// run the OS command and return its output. If the output returns error it also -// encapsulates it as a golang.error which is a return code of the command except -// zero +// RunCommandWithOutput runs the OS command and return its output. If the output +// returns error it also encapsulates it as a golang.error which is a return code +// of the command except zero func RunCommandWithOutput(dir string, command string, args []string) (string, error) { cmd := exec.Command(command, args...) if dir != "" { @@ -18,9 +18,9 @@ func RunCommandWithOutput(dir string, command string, args []string) (string, er return string(output), err } -// if we supposed to get return value as an int of a command this method can be -// used. It is practical when you use a command and process a failover acoording -// to a soecific return code +// GetCommandStatus returns if we supposed to get return value as an int of a command +// this method can be used. It is practical when you use a command and process a +// failover acoording to a soecific return code func GetCommandStatus(dir string, command string, args []string) (int, error) { cmd := exec.Command(command, args...) if dir != "" { diff --git a/pkg/utils/utils.go b/pkg/helpers/utils.go index 793339c..1a3f411 100644 --- a/pkg/utils/utils.go +++ b/pkg/helpers/utils.go @@ -1,4 +1,4 @@ -package utils +package helpers import ( "math/rand" @@ -9,8 +9,8 @@ import ( var characterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") var src = rand.NewSource(time.Now().UnixNano()) -// remove the trailing new line form a string. this method is used mostly on -// outputs of a command +// TrimTrailingNewline removes the trailing new line form a string. this method +// is used mostly on outputs of a command func TrimTrailingNewline(str string) string { if strings.HasSuffix(str, "\n") { return str[:len(str)-1] @@ -18,7 +18,7 @@ func TrimTrailingNewline(str string) string { return str } -// find the minumum value of two int +// Min finds the minimum value of two int func Min(x, y int) int { if x < y { return x diff --git a/pkg/job/job.go b/pkg/queue/queue.go index 6ba2997..b61d43b 100644 --- a/pkg/job/job.go +++ b/pkg/queue/queue.go @@ -1,4 +1,4 @@ -package job +package queue import ( "errors" @@ -14,20 +14,24 @@ type Job struct { Entity *git.RepoEntity } -// only holds the slice of Jobs +// JobQueue holds the slice of Jobs type JobQueue struct { series []*Job } +// JobType is the a git operation supported type JobType string const ( + // Fetch is wrapper of git fetch command Fetch JobType = "fetch" - Pull JobType = "pull" + // Pull is wrapper of git pull command + Pull JobType = "pull" + // Merge is wrapper of git merge command Merge JobType = "merge" ) -// creates a job struct and return its pointer +// CreateJob es its name implies creates a job struct and return its pointer func CreateJob() (j *Job, err error) { fmt.Println("Job created.") return j, nil @@ -68,7 +72,8 @@ func (job *Job) start() error { return nil } -// creates a jobqueue struct and initialize its slice then return its pointer +// CreateJobQueue creates a jobqueue struct and initialize its slice then return +// its pointer func CreateJobQueue() (jobQueue *JobQueue) { s := make([]*Job, 0) return &JobQueue{ @@ -76,7 +81,7 @@ func CreateJobQueue() (jobQueue *JobQueue) { } } -// add job to the queue +// AddJob adds a job to the queue func (jobQueue *JobQueue) AddJob(j *Job) error { for _, job := range jobQueue.series { if job.Entity.RepoID == j.Entity.RepoID && job.JobType == j.JobType { @@ -87,14 +92,14 @@ func (jobQueue *JobQueue) AddJob(j *Job) error { return nil } -// start the next job of the queue +// StartNext starts the next job in the queue func (jobQueue *JobQueue) StartNext() (j *Job, finished bool, err error) { finished = false if len(jobQueue.series) < 1 { finished = true return nil, finished, nil } - i := len(jobQueue.series)-1 + i := len(jobQueue.series) - 1 lastJob := jobQueue.series[i] jobQueue.series = jobQueue.series[:i] if err = lastJob.start(); err != nil { @@ -103,7 +108,7 @@ func (jobQueue *JobQueue) StartNext() (j *Job, finished bool, err error) { return lastJob, finished, nil } -// delete it from the queue +// RemoveFromQueue deletes the given entity and its job from the queue // TODO: it is not safe if the job has been started func (jobQueue *JobQueue) RemoveFromQueue(entity *git.RepoEntity) error { removed := false @@ -119,8 +124,9 @@ func (jobQueue *JobQueue) RemoveFromQueue(entity *git.RepoEntity) error { return nil } -// 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 +// 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 (jobQueue *JobQueue) IsInTheQueue(entity *git.RepoEntity) (inTheQueue bool, jt JobType) { inTheQueue = false for _, job := range jobQueue.series { |
