mirror of
				https://github.com/cheat/cheat.git
				synced 2025-11-04 07:45:28 +01:00 
			
		
		
		
	Merge pull request #532 from chrisallenlane/auto-config-bugfix
fix(config generation): issue #501
This commit is contained in:
		@@ -3,6 +3,10 @@ language: go
 | 
			
		||||
go:
 | 
			
		||||
  - 1.13.x
 | 
			
		||||
 | 
			
		||||
os:
 | 
			
		||||
  - linux
 | 
			
		||||
  - osx
 | 
			
		||||
 | 
			
		||||
env:
 | 
			
		||||
  - GO111MODULE=on
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/docopt/docopt-go"
 | 
			
		||||
 | 
			
		||||
@@ -13,7 +14,7 @@ import (
 | 
			
		||||
	"github.com/cheat/cheat/internal/config"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const version = "3.4.0"
 | 
			
		||||
const version = "3.4.1"
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
 | 
			
		||||
@@ -31,8 +32,15 @@ func main() {
 | 
			
		||||
		os.Exit(0)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// read the envvars into a map of strings
 | 
			
		||||
	envvars := map[string]string{}
 | 
			
		||||
	for _, e := range os.Environ() {
 | 
			
		||||
		pair := strings.SplitN(e, "=", 2)
 | 
			
		||||
		envvars[pair[0]] = pair[1]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// load the os-specifc paths at which the config file may be located
 | 
			
		||||
	confpaths, err := config.Paths(runtime.GOOS)
 | 
			
		||||
	confpaths, err := config.Paths(runtime.GOOS, envvars)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		fmt.Fprintf(os.Stderr, "failed to load config: %v\n", err)
 | 
			
		||||
		os.Exit(1)
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@ package config
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
 | 
			
		||||
	"github.com/mitchellh/go-homedir"
 | 
			
		||||
@@ -10,13 +9,13 @@ import (
 | 
			
		||||
 | 
			
		||||
// Paths returns config file paths that are appropriate for the operating
 | 
			
		||||
// system
 | 
			
		||||
func Paths(sys string) ([]string, error) {
 | 
			
		||||
func Paths(sys string, envvars map[string]string) ([]string, error) {
 | 
			
		||||
 | 
			
		||||
	// if CHEAT_CONFIG_PATH is set, return it
 | 
			
		||||
	if os.Getenv("CHEAT_CONFIG_PATH") != "" {
 | 
			
		||||
	// if `CHEAT_CONFIG_PATH` is set, expand ~ and return it
 | 
			
		||||
	if confpath, ok := envvars["CHEAT_CONFIG_PATH"]; ok {
 | 
			
		||||
 | 
			
		||||
		// expand ~
 | 
			
		||||
		expanded, err := homedir.Expand(os.Getenv("CHEAT_CONFIG_PATH"))
 | 
			
		||||
		expanded, err := homedir.Expand(confpath)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return []string{}, fmt.Errorf("failed to expand ~: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
@@ -26,15 +25,24 @@ func Paths(sys string) ([]string, error) {
 | 
			
		||||
 | 
			
		||||
	switch sys {
 | 
			
		||||
	case "darwin", "linux", "freebsd":
 | 
			
		||||
		return []string{
 | 
			
		||||
			path.Join(os.Getenv("XDG_CONFIG_HOME"), "/cheat/conf.yml"),
 | 
			
		||||
			path.Join(os.Getenv("HOME"), ".config/cheat/conf.yml"),
 | 
			
		||||
			path.Join(os.Getenv("HOME"), ".cheat/conf.yml"),
 | 
			
		||||
		}, nil
 | 
			
		||||
		paths := []string{}
 | 
			
		||||
 | 
			
		||||
		// don't include the `XDG_CONFIG_HOME` path if that envvar is not set
 | 
			
		||||
		if xdgpath, ok := envvars["XDG_CONFIG_HOME"]; ok {
 | 
			
		||||
			paths = append(paths, path.Join(xdgpath, "/cheat/conf.yml"))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// `HOME` will always be set on a POSIX-compliant system, though
 | 
			
		||||
		paths = append(paths, []string{
 | 
			
		||||
			path.Join(envvars["HOME"], ".config/cheat/conf.yml"),
 | 
			
		||||
			path.Join(envvars["HOME"], ".cheat/conf.yml"),
 | 
			
		||||
		}...)
 | 
			
		||||
 | 
			
		||||
		return paths, nil
 | 
			
		||||
	case "windows":
 | 
			
		||||
		return []string{
 | 
			
		||||
			fmt.Sprintf("%s/cheat/conf.yml", os.Getenv("APPDATA")),
 | 
			
		||||
			fmt.Sprintf("%s/cheat/conf.yml", os.Getenv("PROGRAMDATA")),
 | 
			
		||||
			path.Join(envvars["APPDATA"], "/cheat/conf.yml"),
 | 
			
		||||
			path.Join(envvars["PROGRAMDATA"], "/cheat/conf.yml"),
 | 
			
		||||
		}, nil
 | 
			
		||||
	default:
 | 
			
		||||
		return []string{}, fmt.Errorf("unsupported os: %s", sys)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										165
									
								
								internal/config/paths_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								internal/config/paths_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,165 @@
 | 
			
		||||
package config
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"github.com/davecgh/go-spew/spew"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// TestValidatePathsNix asserts that the proper config paths are returned on
 | 
			
		||||
// *nix platforms
 | 
			
		||||
func TestValidatePathsNix(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
	// mock some envvars
 | 
			
		||||
	envvars := map[string]string{
 | 
			
		||||
		"HOME":            "/home/foo",
 | 
			
		||||
		"XDG_CONFIG_HOME": "/home/bar",
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// specify the platforms to test
 | 
			
		||||
	oses := []string{
 | 
			
		||||
		"darwin",
 | 
			
		||||
		"freebsd",
 | 
			
		||||
		"linux",
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// test each *nix os
 | 
			
		||||
	for _, os := range oses {
 | 
			
		||||
		// get the paths for the platform
 | 
			
		||||
		paths, err := Paths(os, envvars)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			t.Errorf("paths returned an error: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// specify the expected output
 | 
			
		||||
		want := []string{
 | 
			
		||||
			"/home/bar/cheat/conf.yml",
 | 
			
		||||
			"/home/foo/.config/cheat/conf.yml",
 | 
			
		||||
			"/home/foo/.cheat/conf.yml",
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// assert that output matches expectations
 | 
			
		||||
		if !reflect.DeepEqual(paths, want) {
 | 
			
		||||
			t.Errorf(
 | 
			
		||||
				"failed to return expected paths: want:\n%s, got:\n%s",
 | 
			
		||||
				spew.Sdump(want),
 | 
			
		||||
				spew.Sdump(paths),
 | 
			
		||||
			)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TestValidatePathsNixNoXDG asserts that the proper config paths are returned
 | 
			
		||||
// on *nix platforms when `XDG_CONFIG_HOME is not set
 | 
			
		||||
func TestValidatePathsNixNoXDG(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
	// mock some envvars
 | 
			
		||||
	envvars := map[string]string{
 | 
			
		||||
		"HOME": "/home/foo",
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// specify the platforms to test
 | 
			
		||||
	oses := []string{
 | 
			
		||||
		"darwin",
 | 
			
		||||
		"freebsd",
 | 
			
		||||
		"linux",
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// test each *nix os
 | 
			
		||||
	for _, os := range oses {
 | 
			
		||||
		// get the paths for the platform
 | 
			
		||||
		paths, err := Paths(os, envvars)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			t.Errorf("paths returned an error: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// specify the expected output
 | 
			
		||||
		want := []string{
 | 
			
		||||
			"/home/foo/.config/cheat/conf.yml",
 | 
			
		||||
			"/home/foo/.cheat/conf.yml",
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// assert that output matches expectations
 | 
			
		||||
		if !reflect.DeepEqual(paths, want) {
 | 
			
		||||
			t.Errorf(
 | 
			
		||||
				"failed to return expected paths: want:\n%s, got:\n%s",
 | 
			
		||||
				spew.Sdump(want),
 | 
			
		||||
				spew.Sdump(paths),
 | 
			
		||||
			)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TestValidatePathsWindows asserts that the proper config paths are returned
 | 
			
		||||
// on Windows platforms
 | 
			
		||||
func TestValidatePathsWindows(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
	// mock some envvars
 | 
			
		||||
	envvars := map[string]string{
 | 
			
		||||
		"APPDATA":     "/apps",
 | 
			
		||||
		"PROGRAMDATA": "/programs",
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// get the paths for the platform
 | 
			
		||||
	paths, err := Paths("windows", envvars)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Errorf("paths returned an error: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// specify the expected output
 | 
			
		||||
	want := []string{
 | 
			
		||||
		"/apps/cheat/conf.yml",
 | 
			
		||||
		"/programs/cheat/conf.yml",
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// assert that output matches expectations
 | 
			
		||||
	if !reflect.DeepEqual(paths, want) {
 | 
			
		||||
		t.Errorf(
 | 
			
		||||
			"failed to return expected paths: want:\n%s, got:\n%s",
 | 
			
		||||
			spew.Sdump(want),
 | 
			
		||||
			spew.Sdump(paths),
 | 
			
		||||
		)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TestValidatePathsUnsupported asserts that an error is returned on
 | 
			
		||||
// unsupported platforms
 | 
			
		||||
func TestValidatePathsUnsupported(t *testing.T) {
 | 
			
		||||
	_, err := Paths("unsupported", map[string]string{})
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		t.Errorf("failed to return error on unsupported platform")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TestValidatePathsCheatConfigPath asserts that the proper config path is
 | 
			
		||||
// returned when `CHEAT_CONFIG_PATH` is explicitly specified.
 | 
			
		||||
func TestValidatePathsCheatConfigPath(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
	// mock some envvars
 | 
			
		||||
	envvars := map[string]string{
 | 
			
		||||
		"HOME":              "/home/foo",
 | 
			
		||||
		"XDG_CONFIG_HOME":   "/home/bar",
 | 
			
		||||
		"CHEAT_CONFIG_PATH": "/home/baz/conf.yml",
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// get the paths for the platform
 | 
			
		||||
	paths, err := Paths("linux", envvars)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Errorf("paths returned an error: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// specify the expected output
 | 
			
		||||
	want := []string{
 | 
			
		||||
		"/home/baz/conf.yml",
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// assert that output matches expectations
 | 
			
		||||
	if !reflect.DeepEqual(paths, want) {
 | 
			
		||||
		t.Errorf(
 | 
			
		||||
			"failed to return expected paths: want:\n%s, got:\n%s",
 | 
			
		||||
			spew.Sdump(want),
 | 
			
		||||
			spew.Sdump(paths),
 | 
			
		||||
		)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user