summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrei Miulescu <lusu777@gmail.com>2018-08-12 19:31:27 +1000
committerAndrei Miulescu <lusu777@gmail.com>2018-08-12 19:31:27 +1000
commitdcd461d29f21a9626d5298a03283b6d8b46312c3 (patch)
tree42f43f27eb7403c60cc05805fc627debff76417b
parent98c22a36fdaf8806f8fafe8f1e23e53f8e97658d (diff)
Restrucure project in a way where it is more modular
-rw-r--r--main.go31
-rw-r--r--pkg/app/app.go49
-rw-r--r--pkg/commands/git.go71
-rw-r--r--pkg/commands/gitcommands.go (renamed from gitcommands.go)27
-rw-r--r--pkg/commands/os.go77
-rw-r--r--pkg/config/app_config.go45
-rw-r--r--pkg/git/branch.go (renamed from branch.go)12
-rw-r--r--pkg/git/branch_list_builder.go (renamed from branch_list_builder.go)2
-rw-r--r--pkg/git/git_structs.go28
-rw-r--r--pkg/gui/gui.go (renamed from gui.go)11
-rw-r--r--pkg/gui/keybindings.go (renamed from keybindings.go)2
-rw-r--r--pkg/gui/panels/branches_panel.go (renamed from branches_panel.go)0
-rw-r--r--pkg/gui/panels/commit_message_panel.go (renamed from commit_message_panel.go)0
-rw-r--r--pkg/gui/panels/commits_panel.go (renamed from commits_panel.go)0
-rw-r--r--pkg/gui/panels/confirmation_panel.go (renamed from confirmation_panel.go)0
-rw-r--r--pkg/gui/panels/files_panel.go (renamed from files_panel.go)0
-rw-r--r--pkg/gui/panels/merge_panel.go (renamed from merge_panel.go)0
-rw-r--r--pkg/gui/panels/stash_panel.go (renamed from stash_panel.go)0
-rw-r--r--pkg/gui/panels/status_panel.go (renamed from status_panel.go)0
-rw-r--r--pkg/gui/view_helpers.go (renamed from view_helpers.go)6
-rw-r--r--pkg/utils/utils.go49
-rw-r--r--utils.go5
22 files changed, 357 insertions, 58 deletions
diff --git a/main.go b/main.go
index aec4051bf..aa157c108 100644
--- a/main.go
+++ b/main.go
@@ -14,6 +14,8 @@ import (
"github.com/davecgh/go-spew/spew"
"github.com/jesseduffield/gocui"
+ "github.com/jesseduffield/lazygit/pkg/app"
+ "github.com/jesseduffield/lazygit/pkg/config"
git "gopkg.in/src-d/go-git.v4"
)
@@ -24,8 +26,8 @@ var (
commit string
version = "unversioned"
+ date string
- date string
debuggingFlag = flag.Bool("debug", false, "a boolean")
versionFlag = flag.Bool("v", false, "Print the current version")
@@ -77,15 +79,6 @@ func localLog(path string, objects ...interface{}) {
}
}
-func navigateToRepoRootDirectory() {
- _, err := os.Stat(".git")
- for os.IsNotExist(err) {
- devLog("going up a directory to find the root")
- os.Chdir("..")
- _, err = os.Stat(".git")
- }
-}
-
// when building the binary, `version` is set as a compile-time variable, along
// with `date` and `commit`. If this program has been opened directly via go,
// we will populate the `version` with VERSION in the lazygit root directory
@@ -112,7 +105,6 @@ func setupWorktree() {
}
func main() {
- devLog("\n\n\n\n\n\n\n\n\n\n")
flag.Parse()
if version == "unversioned" {
version = fallbackVersion()
@@ -121,9 +113,22 @@ func main() {
fmt.Printf("commit=%s, build date=%s, version=%s", commit, date, version)
os.Exit(0)
}
- verifyInGitRepo()
- navigateToRepoRootDirectory()
+ appConfig := &config.AppConfig{
+ Name: "lazygit",
+ Version: version,
+ Commit: commit,
+ BuildDate: date,
+ Debug: *debuggingFlag,
+ }
+ app, err := app.NewApp(appConfig)
+ app.Log.Info(err)
+
+ app.GitCommand.SetupGit()
+ // TODO remove this once r, w not used
setupWorktree()
+
+ app.Gui.Run()
+
for {
if err := run(); err != nil {
if err == gocui.ErrQuit {
diff --git a/pkg/app/app.go b/pkg/app/app.go
new file mode 100644
index 000000000..726567b01
--- /dev/null
+++ b/pkg/app/app.go
@@ -0,0 +1,49 @@
+package app
+
+import (
+ "io"
+
+ "github.com/Sirupsen/logrus"
+ "github.com/jesseduffield/lazygit/pkg/commands"
+ "github.com/jesseduffield/lazygit/pkg/config"
+)
+
+// App struct
+type App struct {
+ closers []io.Closer
+
+ Config config.AppConfigurer
+ Log *logrus.Logger
+ OSCommand *commands.OSCommand
+ GitCommand *commands.GitCommand
+}
+
+// NewApp retruns a new applications
+func NewApp(config config.AppConfigurer) (*App, error) {
+ app := &App{
+ closers: []io.Closer{},
+ Config: config,
+ }
+ var err error
+ app.Log = logrus.New()
+ app.OSCommand, err = commands.NewOSCommand(app.Log)
+ if err != nil {
+ return nil, err
+ }
+ app.GitCommand, err = commands.NewGitCommand(app.Log, app.OSCommand)
+ if err != nil {
+ return nil, err
+ }
+ return app, nil
+}
+
+// Close closes any resources
+func (app *App) Close() error {
+ for _, closer := range app.closers {
+ err := closer.Close()
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
diff --git a/pkg/commands/git.go b/pkg/commands/git.go
new file mode 100644
index 000000000..17855b98e
--- /dev/null
+++ b/pkg/commands/git.go
@@ -0,0 +1,71 @@
+package commands
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/Sirupsen/logrus"
+ git "gopkg.in/src-d/go-git.v4"
+)
+
+// GitCommand is our main git interface
+type GitCommand struct {
+ Log *logrus.Logger
+ OSCommand *OSCommand
+ Worktree *git.Worktree
+ Repo *git.Repository
+}
+
+// NewGitCommand it runs git commands
+func NewGitCommand(log *logrus.Logger, osCommand *OSCommand) (*GitCommand, error) {
+ gitCommand := &GitCommand{
+ Log: log,
+ OSCommand: osCommand,
+ }
+ return gitCommand, nil
+}
+
+// SetupGit sets git repo up
+func (c *GitCommand) SetupGit() {
+ c.verifyInGitRepo()
+ c.navigateToRepoRootDirectory()
+ c.setupWorktree()
+}
+
+func (c *GitCommand) GitIgnore(filename string) {
+ if _, err := c.OSCommand.RunDirectCommand("echo '" + filename + "' >> .gitignore"); err != nil {
+ panic(err)
+ }
+}
+
+func (c *GitCommand) verifyInGitRepo() {
+ if output, err := c.OSCommand.RunCommand("git status"); err != nil {
+ fmt.Println(output)
+ os.Exit(1)
+ }
+}
+
+func (c *GitCommand) navigateToRepoRootDirectory() {
+ _, err := os.Stat(".git")
+ for os.IsNotExist(err) {
+ c.Log.Debug("going up a directory to find the root")
+ os.Chdir("..")
+ _, err = os.Stat(".git")
+ }
+}
+
+func (c *GitCommand) setupWorktree() {
+ var err error
+ r, err := git.PlainOpen(".")
+ if err != nil {
+ panic(err)
+ }
+ c.Repo = r
+
+ w, err := r.Worktree()
+ c.Worktree = w
+ if err != nil {
+ panic(err)
+ }
+ c.Worktree = w
+}
diff --git a/gitcommands.go b/pkg/commands/gitcommands.go
index 14dee6dac..bdc23fef2 100644
--- a/gitcommands.go
+++ b/pkg/commands/gitcommands.go
@@ -21,33 +21,6 @@ var (
ErrNoOpenCommand = errors.New("Unsure what command to use to open this file")
)
-// GitFile : A staged/unstaged file
-// TODO: decide whether to give all of these the Git prefix
-type GitFile struct {
- Name string
- HasStagedChanges bool
- HasUnstagedChanges bool
- Tracked bool
- Deleted bool
- HasMergeConflicts bool
- DisplayString string
-}
-
-// Commit : A git commit
-type Commit struct {
- Sha string
- Name string
- Pushed bool
- DisplayString string
-}
-
-// StashEntry : A git stash entry
-type StashEntry struct {
- Index int
- Name string
- DisplayString string
-}
-
// Map (from https://gobyexample.com/collection-functions)
func Map(vs []string, f func(string) string) []string {
vsm := make([]string, len(vs))
diff --git a/pkg/commands/os.go b/pkg/commands/os.go
new file mode 100644
index 000000000..c36990aff
--- /dev/null
+++ b/pkg/commands/os.go
@@ -0,0 +1,77 @@
+package commands
+
+import (
+ "os/exec"
+ "runtime"
+ "strings"
+
+ "github.com/Sirupsen/logrus"
+)
+
+// Platform stores the os state
+type platform struct {
+ os string
+ shell string
+ shellArg string
+ escapedQuote string
+}
+
+// OSCommand holds all the os commands
+type OSCommand struct {
+ Log *logrus.Logger
+ Platform platform
+}
+
+// NewOSCommand os command runner
+func NewOSCommand(log *logrus.Logger) (*OSCommand, error) {
+ osCommand := &OSCommand{
+ Log: log,
+ Platform: getPlatform(),
+ }
+ return osCommand, nil
+}
+
+// RunCommand wrapper around commands
+func (c *OSCommand) RunCommand(command string) (string, error) {
+ c.Log.WithField("command", command).Info("RunCommand")
+ splitCmd := strings.Split(command, " ")
+ cmdOut, err := exec.Command(splitCmd[0], splitCmd[1:]...).CombinedOutput()
+ return sanitisedCommandOutput(cmdOut, err)
+}
+
+// RunDirectCommand wrapper around direct commands
+func (c *OSCommand) RunDirectCommand(command string) (string, error) {
+ c.Log.WithField("command", command).Info("RunDirectCommand")
+
+ cmdOut, err := exec.
+ Command(c.Platform.shell, c.Platform.shellArg, command).
+ CombinedOutput()
+ return sanitisedCommandOutput(cmdOut, err)
+}
+
+func sanitisedCommandOutput(output []byte, err error) (string, error) {
+ outputString := string(output)
+ if outputString == "" && err != nil {
+ return err.Error(), err
+ }
+ return outputString, err
+}
+
+func getPlatform() platform {
+ switch runtime.GOOS {
+ case "windows":
+ return platform{
+ os: "windows",
+ shell: "cmd",
+ shellArg: "/c",
+ escapedQuote: "\\\"",
+ }
+ default:
+ return platform{
+ os: runtime.GOOS,
+ shell: "bash",
+ shellArg: "-c",
+ escapedQuote: "\"",
+ }
+ }
+}
diff --git a/pkg/config/app_config.go b/pkg/config/app_config.go
new file mode 100644
index 000000000..98e56dea2
--- /dev/null
+++ b/pkg/config/app_config.go
@@ -0,0 +1,45 @@
+package config
+
+// AppConfig contains the base configuration fields required for lazygit.
+type AppConfig struct {
+ Debug bool `long:"debug" env:"DEBUG" default:"false"`
+ Version string `long:"version" env:"VERSION" default:"unversioned"`
+ Commit string `long:"commit" env:"COMMIT"`
+ BuildDate string `long:"build-date" env:"BUILD_DATE"`
+ Name string `long:"name" env:"NAME" default:"lazygit"`
+}
+
+// AppConfigurer interface allows individual app config structs to inherit Fields
+// from AppConfig and still be used by lazygit.
+type AppConfigurer interface {
+ GetDebug() bool
+ GetVersion() string
+ GetCommit() string
+ GetBuildDate() string
+ GetName() string
+}
+
+// GetDebug returns debug flag
+func (c *AppConfig) GetDebug() bool {
+ return c.Debug
+}
+
+// GetVersion returns debug flag
+func (c *AppConfig) GetVersion() string {
+ return c.Version
+}
+
+// GetCommit returns debug flag
+func (c *AppConfig) GetCommit() string {
+ return c.Commit
+}
+
+// GetBuildDate returns debug flag
+func (c *AppConfig) GetBuildDate() string {
+ return c.BuildDate
+}
+
+// GetName returns debug flag
+func (c *AppConfig) GetName() string {
+ return c.Name
+}
diff --git a/branch.go b/pkg/git/branch.go
index 78c2e55aa..e0fd75a73 100644
--- a/branch.go
+++ b/pkg/git/branch.go
@@ -1,4 +1,4 @@
-package main
+package git
import (
"strings"
@@ -12,11 +12,13 @@ type Branch struct {
Recency string
}
-func (b *Branch) getDisplayString() string {
- return withPadding(b.Recency, 4) + coloredString(b.Name, b.getColor())
-}
+// GetDisplayString returns the dispaly string of branch
+// func (b *Branch) GetDisplayString() string {
+// return gui.withPadding(b.Recency, 4) + gui.coloredString(b.Name, b.getColor())
+// }
-func (b *Branch) getColor() color.Attribute {
+// GetColor branch color
+func (b *Branch) GetColor() color.Attribute {
switch b.getType() {
case "feature":
return color.FgGreen
diff --git a/branch_list_builder.go b/pkg/git/branch_list_builder.go
index 1d4dc338d..1abf11fcc 100644
--- a/branch_list_builder.go
+++ b/pkg/git/branch_list_builder.go
@@ -1,4 +1,4 @@
-package main
+package git
import (
"regexp"
diff --git a/pkg/git/git_structs.go b/pkg/git/git_structs.go
new file mode 100644
index 000000000..711f25f4b
--- /dev/null
+++ b/pkg/git/git_structs.go
@@ -0,0 +1,28 @@
+package git
+
+// File : A staged/unstaged file
+// TODO: decide whether to give all of these the Git prefix
+type File struct {
+ Name string
+ HasStagedChanges bool
+ HasUnstagedChanges bool
+ Tracked bool
+ Deleted bool
+ HasMergeConflicts bool
+ DisplayString string
+}
+
+// Commit : A git commit
+type Commit struct {
+ Sha string
+ Name string
+ Pushed bool
+ DisplayString string
+}
+
+// StashEntry : A git stash entry
+type StashEntry struct {
+ Index int
+ Name string
+ DisplayString string
+}
diff --git a/gui.go b/pkg/gui/gui.go
index 589dabea3..f35a4811f 100644
--- a/gui.go
+++ b/pkg/gui/gui.go
@@ -1,4 +1,4 @@
-package main
+package gui
import (
@@ -13,16 +13,17 @@ import (
"github.com/golang-collections/collections/stack"
"github.com/jesseduffield/gocui"
+ "github.com/jesseduffield/lazygit/pkg/git"
)
// OverlappingEdges determines if panel edges overlap
var OverlappingEdges = false
type stateType struct {
- GitFiles []GitFile
- Branches []Branch
- Commits []Commit
- StashEntries []StashEntry
+ GitFiles []git.File
+ Branches []git.Branch
+ Commits []git.Commit
+ StashEntries []git.StashEntry
PreviousView string
HasMergeConflicts bool
ConflictIndex int
diff --git a/keybindings.go b/pkg/gui/keybindings.go
index afaa09527..23f320ceb 100644
--- a/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -1,4 +1,4 @@
-package main
+package gui
import "github.com/jesseduffield/gocui"
diff --git a/branches_panel.go b/pkg/gui/panels/branches_panel.go
index a73d28bb3..a73d28bb3 100644
--- a/branches_panel.go
+++ b/pkg/gui/panels/branches_panel.go
diff --git a/commit_message_panel.go b/pkg/gui/panels/commit_message_panel.go
index baef870cf..baef870cf 100644
--- a/commit_message_panel.go
+++ b/pkg/gui/panels/commit_message_panel.go
diff --git a/commits_panel.go b/pkg/gui/panels/commits_panel.go
index 1a9976ffe..1a9976ffe 100644
--- a/commits_panel.go
+++ b/pkg/gui/panels/commits_panel.go
diff --git a/confirmation_panel.go b/pkg/gui/panels/confirmation_panel.go
index a8719d237..a8719d237 100644
--- a/confirmation_panel.go
+++ b/pkg/gui/panels/confirmation_panel.go
diff --git a/files_panel.go b/pkg/gui/panels/files_panel.go
index 4de8caca7..4de8caca7 100644
--- a/files_panel.go
+++ b/pkg/gui/panels/files_panel.go
diff --git a/merge_panel.go b/pkg/gui/panels/merge_panel.go
index f5ca12a23..f5ca12a23 100644
--- a/merge_panel.go
+++ b/pkg/gui/panels/merge_panel.go
diff --git a/stash_panel.go b/pkg/gui/panels/stash_panel.go
index 33c7e297b..33c7e297b 100644
--- a/stash_panel.go
+++ b/pkg/gui/panels/stash_panel.go
diff --git a/status_panel.go b/pkg/gui/panels/status_panel.go
index f3fcb8078..f3fcb8078 100644
--- a/status_panel.go
+++ b/pkg/gui/panels/status_panel.go
diff --git a/view_helpers.go b/pkg/gui/view_helpers.go
index b28e84efb..fc252a25c 100644
--- a/view_helpers.go
+++ b/pkg/gui/view_helpers.go
@@ -1,4 +1,4 @@
-package main
+package gui
import (
"fmt"
@@ -233,3 +233,7 @@ func getCommitMessageView(g *gocui.Gui) *gocui.View {
v, _ := g.View("commitMessage")
return v
}
+
+func trimmedContent(v *gocui.View) string {
+ return strings.TrimSpace(v.Buffer())
+}
diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go
new file mode 100644
index 000000000..01556ea4f
--- /dev/null
+++ b/pkg/utils/utils.go
@@ -0,0 +1,49 @@
+package utils
+
+import (
+ "fmt"
+ "log"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/fatih/color"
+)
+
+func splitLines(multilineString string) []string {
+ multilineString = strings.Replace(multilineString, "\r", "", -1)
+ if multilineString == "" || multilineString == "\n" {
+ return make([]string, 0)
+ }
+ lines := strings.Split(multilineString, "\n")
+ if lines[len(lines)-1] == "" {
+ return lines[:len(lines)-1]
+ }
+ return lines
+}
+
+func withPadding(str string, padding int) string {
+ if padding-len(str) < 0 {
+ return str
+ }
+ return str + strings.Repeat(" ", padding-len(str))
+}
+
+func coloredString(str string, colorAttribute color.Attribute) string {
+ colour := color.New(colorAttribute)
+ return coloredStringDirect(str, colour)
+}
+
+// used for aggregating a few color attributes rather than just sending a single one
+func coloredStringDirect(str string, colour *color.Color) string {
+ return colour.SprintFunc()(fmt.Sprint(str))
+}
+
+// used to get the project name
+func getCurrentProject() string {
+ pwd, err := os.Getwd()
+ if err != nil {
+ log.Fatalln(err.Error())
+ }
+ return filepath.Base(pwd)
+}
diff --git a/utils.go b/utils.go
index e2de46233..df7d04818 100644
--- a/utils.go
+++ b/utils.go
@@ -8,7 +8,6 @@ import (
"strings"
"github.com/fatih/color"
- "github.com/jesseduffield/gocui"
)
func splitLines(multilineString string) []string {
@@ -23,10 +22,6 @@ func splitLines(multilineString string) []string {
return lines
}
-func trimmedContent(v *gocui.View) string {
- return strings.TrimSpace(v.Buffer())
-}
-
func withPadding(str string, padding int) string {
if padding-len(str) < 0 {
return str