summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2020-10-04 22:05:39 +1100
committerJesse Duffield <jessedduffield@gmail.com>2020-10-10 00:23:01 +1100
commit485f6d53864845d2e58b63b04dd83e3dcc2b4e6a (patch)
treefa8b56d7bc13c8676bf1ca04c2bdcce77c48367f
parent778ca8e6f9f012de401fef215270670d1e028545 (diff)
support configurable config
-rw-r--r--.gitignore1
-rw-r--r--main.go9
-rw-r--r--pkg/commands/oscommands/copy.go134
-rw-r--r--pkg/config/app_config.go7
-rw-r--r--pkg/gui/gui_test.go79
-rw-r--r--test/default_test_config/config.yml1
-rw-r--r--test/fixtures/manyCommits.sh5
-rw-r--r--test/fixtures/newFile.sh5
-rw-r--r--test/fixtures/updatedFile.sh5
9 files changed, 222 insertions, 24 deletions
diff --git a/.gitignore b/.gitignore
index d6b15ef10..21ec121da 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,3 +27,4 @@ lazygit
test/git_server/data
test/integration_test/
+test/integration_test_config/
diff --git a/main.go b/main.go
index c5cd2f222..131f1e6e3 100644
--- a/main.go
+++ b/main.go
@@ -49,7 +49,10 @@ func main() {
flaggy.Bool(&configFlag, "c", "config", "Print the default config")
configDirFlag := false
- flaggy.Bool(&configDirFlag, "cd", "config-dir", "Print the config directory")
+ flaggy.Bool(&configDirFlag, "cd", "print-config-dir", "Print the config directory")
+
+ useConfigDir := ""
+ flaggy.String(&useConfigDir, "ucd", "use-config-dir", "override default config directory with provided directory")
workTree := ""
flaggy.String(&workTree, "w", "work-tree", "equivalent of the --work-tree git argument")
@@ -68,6 +71,10 @@ func main() {
gitDir = filepath.Join(repoPath, ".git")
}
+ if useConfigDir != "" {
+ os.Setenv("CONFIG_DIR", useConfigDir)
+ }
+
if workTree != "" {
env.SetGitWorkTreeEnv(workTree)
}
diff --git a/pkg/commands/oscommands/copy.go b/pkg/commands/oscommands/copy.go
new file mode 100644
index 000000000..2681441c5
--- /dev/null
+++ b/pkg/commands/oscommands/copy.go
@@ -0,0 +1,134 @@
+package oscommands
+
+import (
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+)
+
+/* MIT License
+ *
+ * Copyright (c) 2017 Roland Singer [roland.singer@desertbit.com]
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+// CopyFile copies the contents of the file named src to the file named
+// by dst. The file will be created if it does not already exist. If the
+// destination file exists, all it's contents will be replaced by the contents
+// of the source file. The file mode will be copied from the source and
+// the copied data is synced/flushed to stable storage.
+func CopyFile(src, dst string) (err error) {
+ in, err := os.Open(src)
+ if err != nil {
+ return
+ }
+ defer in.Close()
+
+ out, err := os.Create(dst)
+ if err != nil {
+ return
+ }
+ defer func() {
+ if e := out.Close(); e != nil {
+ err = e
+ }
+ }()
+
+ _, err = io.Copy(out, in)
+ if err != nil {
+ return
+ }
+
+ err = out.Sync()
+ if err != nil {
+ return
+ }
+
+ si, err := os.Stat(src)
+ if err != nil {
+ return
+ }
+ err = os.Chmod(dst, si.Mode())
+ if err != nil {
+ return
+ }
+
+ return
+}
+
+// CopyDir recursively copies a directory tree, attempting to preserve permissions.
+// Source directory must exist, destination directory must *not* exist.
+// Symlinks are ignored and skipped.
+func CopyDir(src string, dst string) (err error) {
+ src = filepath.Clean(src)
+ dst = filepath.Clean(dst)
+
+ si, err := os.Stat(src)
+ if err != nil {
+ return err
+ }
+ if !si.IsDir() {
+ return fmt.Errorf("source is not a directory")
+ }
+
+ _, err = os.Stat(dst)
+ if err != nil && !os.IsNotExist(err) {
+ return
+ }
+ if err == nil {
+ return fmt.Errorf("destination already exists")
+ }
+
+ err = os.MkdirAll(dst, si.Mode())
+ if err != nil {
+ return
+ }
+
+ entries, err := ioutil.ReadDir(src)
+ if err != nil {
+ return
+ }
+
+ for _, entry := range entries {
+ srcPath := filepath.Join(src, entry.Name())
+ dstPath := filepath.Join(dst, entry.Name())
+
+ if entry.IsDir() {
+ err = CopyDir(srcPath, dstPath)
+ if err != nil {
+ return
+ }
+ } else {
+ // Skip symlinks.
+ if entry.Mode()&os.ModeSymlink != 0 {
+ continue
+ }
+
+ err = CopyFile(srcPath, dstPath)
+ if err != nil {
+ return
+ }
+ }
+ }
+
+ return
+}
diff --git a/pkg/config/app_config.go b/pkg/config/app_config.go
index 95ac99b73..df4707a94 100644
--- a/pkg/config/app_config.go
+++ b/pkg/config/app_config.go
@@ -81,6 +81,11 @@ func NewAppConfig(name, version, commit, date string, buildSource string, debugg
}
func ConfigDir() string {
+ envConfigDir := os.Getenv("CONFIG_DIR")
+ if envConfigDir != "" {
+ return envConfigDir
+ }
+
// chucking my name there is not for vanity purposes, the xdg spec (and that
// function) requires a vendor name. May as well line up with github
configDirs := xdg.New("jesseduffield", "lazygit")
@@ -226,7 +231,7 @@ func loadAppState() (*AppState, error) {
}
appStateBytes, err := ioutil.ReadFile(filepath)
- if err != nil {
+ if err != nil && !os.IsNotExist(err) {
return nil, err
}
diff --git a/pkg/gui/gui_test.go b/pkg/gui/gui_test.go
index 371cf1397..234ec2afb 100644
--- a/pkg/gui/gui_test.go
+++ b/pkg/gui/gui_test.go
@@ -2,12 +2,14 @@ package gui
import (
"fmt"
+ "io"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"testing"
+ "github.com/creack/pty"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/stretchr/testify/assert"
)
@@ -34,6 +36,23 @@ type integrationTest struct {
fixture string
}
+func tests() []integrationTest {
+ return []integrationTest{
+ {
+ name: "commit",
+ fixture: "newFile",
+ },
+ {
+ name: "squash",
+ fixture: "manyCommits",
+ },
+ {
+ name: "patchBuilding",
+ fixture: "updatedFile",
+ },
+ }
+}
+
func generateSnapshot(t *testing.T) string {
osCommand := oscommands.NewDummyOSCommand()
cmd := `sh -c "git status; cat ./*; git log --pretty=%B -p"`
@@ -59,20 +78,7 @@ func findOrCreateDir(path string) {
}
func Test(t *testing.T) {
- tests := []integrationTest{
- {
- name: "commit",
- fixture: "newFile",
- },
- {
- name: "squash",
- fixture: "manyCommits",
- },
- {
- name: "patchBuilding",
- fixture: "updatedFile",
- },
- }
+ tests := tests()
gotoRootDirectory()
@@ -87,7 +93,6 @@ func Test(t *testing.T) {
testPath := filepath.Join(rootDir, "test", "integration", test.name)
findOrCreateDir(testPath)
- replayPath := filepath.Join(testPath, "recording.json")
snapshotPath := filepath.Join(testPath, "snapshot.txt")
err := os.Chdir(rootDir)
@@ -99,7 +104,7 @@ func Test(t *testing.T) {
assert.NoError(t, err)
record := os.Getenv("RECORD_EVENTS") != ""
- runLazygit(t, replayPath, record)
+ runLazygit(t, testPath, rootDir, record)
updateSnapshot := record || os.Getenv("UPDATE_SNAPSHOT") != ""
@@ -148,25 +153,55 @@ func gotoRootDirectory() {
}
}
-func runLazygit(t *testing.T, replayPath string, record bool) {
+func runLazygit(t *testing.T, testPath string, rootDir string, record bool) {
osCommand := oscommands.NewDummyOSCommand()
- var cmd *exec.Cmd
+ replayPath := filepath.Join(testPath, "recording.json")
+ cmdStr := fmt.Sprintf("go run %s", filepath.Join(rootDir, "main.go"))
+ templateConfigDir := filepath.Join(rootDir, "test", "default_test_config")
+
+ exists, err := osCommand.FileExists(filepath.Join(testPath, "config"))
+ assert.NoError(t, err)
+
+ if exists {
+ templateConfigDir = filepath.Join(testPath, "config")
+ }
+
+ configDir := filepath.Join(rootDir, "test", "integration_test_config")
+
+ err = os.RemoveAll(configDir)
+ assert.NoError(t, err)
+ err = oscommands.CopyDir(templateConfigDir, configDir)
+ assert.NoError(t, err)
+
+ cmdStr = fmt.Sprintf("%s --use-config-dir=%s", cmdStr, configDir)
+
+ cmd := osCommand.ExecutableFromString(cmdStr)
if record {
- cmd = osCommand.ExecutableFromString("lazygit")
cmd.Env = append(
cmd.Env,
fmt.Sprintf("RECORD_EVENTS_TO=%s", replayPath),
)
} else {
- cmd = osCommand.ExecutableFromString("lazygit")
cmd.Env = append(
cmd.Env,
fmt.Sprintf("REPLAY_EVENTS_FROM=%s", replayPath),
)
}
- err := osCommand.RunExecutable(cmd)
- assert.NoError(t, err)
+
+ // if we're on CI we'll need to use a PTY. We can work that out by seeing if the 'TERM' env is defined.
+ if os.Getenv("TERM") == "" {
+ cmd.Env = append(cmd.Env, "TERM=xterm")
+
+ f, err := pty.StartWithSize(cmd, &pty.Winsize{Rows: 100, Cols: 100})
+ assert.NoError(t, err)
+
+ _, err = io.Copy(os.Stdout, f)
+ assert.NoError(t, err)
+ } else {
+ err := osCommand.RunExecutable(cmd)
+ assert.NoError(t, err)
+ }
}
func prepareIntegrationTestDir() {
diff --git a/test/default_test_config/config.yml b/test/default_test_config/config.yml
new file mode 100644
index 000000000..dc8bd1faa
--- /dev/null
+++ b/test/default_test_config/config.yml
@@ -0,0 +1 @@
+disableStartupPopups: true
diff --git a/test/fixtures/manyCommits.sh b/test/fixtures/manyCommits.sh
index 8eec5ae57..ae92f3f15 100644
--- a/test/fixtures/manyCommits.sh
+++ b/test/fixtures/manyCommits.sh
@@ -1,5 +1,10 @@
#!/bin/sh
+
git init
+
+git config user.email "CI@example.com"
+git config user.name "CI"
+
echo test1 > myfile1
git add .
git commit -am "myfile1"
diff --git a/test/fixtures/newFile.sh b/test/fixtures/newFile.sh
index f8592c33f..83470bba8 100644
--- a/test/fixtures/newFile.sh
+++ b/test/fixtures/newFile.sh
@@ -1,5 +1,10 @@
#!/bin/sh
+
git init
+
+git config user.email "CI@example.com"
+git config user.name "CI"
+
echo test1 > myfile1
git add .
git commit -am "myfile1"
diff --git a/test/fixtures/updatedFile.sh b/test/fixtures/updatedFile.sh
index 2c42d6282..64e62c8d4 100644
--- a/test/fixtures/updatedFile.sh
+++ b/test/fixtures/updatedFile.sh
@@ -1,5 +1,10 @@
#!/bin/sh
+
git init
+
+git config user.email "CI@example.com"
+git config user.name "CI"
+
echo test1 > myfile1
git add .
git commit -am "myfile1"