mirror of
				https://github.com/cheat/cheat.git
				synced 2025-11-04 07:45:28 +01:00 
			
		
		
		
	Merge pull request #673 from chrisallenlane/win-compat
fix: Windows compatibility
This commit is contained in:
		
							
								
								
									
										7
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								Makefile
									
									
									
									
									
								
							@@ -86,7 +86,7 @@ $(dist_dir)/cheat-linux-arm64: prepare
 | 
			
		||||
# cheat-windows-amd64
 | 
			
		||||
$(dist_dir)/cheat-windows-amd64.exe: prepare
 | 
			
		||||
	GOARCH=amd64 GOOS=windows \
 | 
			
		||||
	$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(ZIP) $@.zip $@
 | 
			
		||||
	$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(ZIP) $@.zip $@ -j
 | 
			
		||||
 | 
			
		||||
# ./dist
 | 
			
		||||
$(dist_dir):
 | 
			
		||||
@@ -180,6 +180,11 @@ prepare: | $(dist_dir) clean generate vendor fmt lint vet test
 | 
			
		||||
docker-setup:
 | 
			
		||||
	$(DOCKER) build  -t $(docker_image) -f Dockerfile .
 | 
			
		||||
 | 
			
		||||
## docker-run: shell into the development docker container
 | 
			
		||||
.PHONY: docker-run
 | 
			
		||||
docker-run:
 | 
			
		||||
	$(DOCKER) run -v `pwd`:/app -ti $(docker_image) sh
 | 
			
		||||
 | 
			
		||||
## docker-sh: shell into the docker development container
 | 
			
		||||
.PHONY: docker-sh
 | 
			
		||||
docker-sh:
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/exec"
 | 
			
		||||
	"path"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/cheat/cheat/internal/cheatpath"
 | 
			
		||||
@@ -58,10 +58,10 @@ func cmdEdit(opts map[string]interface{}, conf config.Config) {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// compute the new edit path
 | 
			
		||||
		editpath = path.Join(writepath.Path, sheet.Title)
 | 
			
		||||
		editpath = filepath.Join(writepath.Path, sheet.Title)
 | 
			
		||||
 | 
			
		||||
		// create any necessary subdirectories
 | 
			
		||||
		dirs := path.Dir(editpath)
 | 
			
		||||
		dirs := filepath.Dir(editpath)
 | 
			
		||||
		if dirs != "." {
 | 
			
		||||
			if err := os.MkdirAll(dirs, 0755); err != nil {
 | 
			
		||||
				fmt.Fprintf(os.Stderr, "failed to create directory: %s, %v\n", dirs, err)
 | 
			
		||||
@@ -87,10 +87,10 @@ func cmdEdit(opts map[string]interface{}, conf config.Config) {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// compute the new edit path
 | 
			
		||||
		editpath = path.Join(writepath.Path, cheatsheet)
 | 
			
		||||
		editpath = filepath.Join(writepath.Path, cheatsheet)
 | 
			
		||||
 | 
			
		||||
		// create any necessary subdirectories
 | 
			
		||||
		dirs := path.Dir(editpath)
 | 
			
		||||
		dirs := filepath.Dir(editpath)
 | 
			
		||||
		if dirs != "." {
 | 
			
		||||
			if err := os.MkdirAll(dirs, 0755); err != nil {
 | 
			
		||||
				fmt.Fprintf(os.Stderr, "failed to create directory: %s, %v\n", dirs, err)
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@ package main
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
@@ -42,11 +42,11 @@ func cmdInit() {
 | 
			
		||||
	// determine the appropriate paths for config data and (optional) community
 | 
			
		||||
	// cheatsheets based on the user's platform
 | 
			
		||||
	confpath := confpaths[0]
 | 
			
		||||
	confdir := path.Dir(confpath)
 | 
			
		||||
	confdir := filepath.Dir(confpath)
 | 
			
		||||
 | 
			
		||||
	// create paths for community and personal cheatsheets
 | 
			
		||||
	community := path.Join(confdir, "/cheatsheets/community")
 | 
			
		||||
	personal := path.Join(confdir, "/cheatsheets/personal")
 | 
			
		||||
	community := filepath.Join(confdir, "cheatsheets", "community")
 | 
			
		||||
	personal := filepath.Join(confdir, "cheatsheets", "personal")
 | 
			
		||||
 | 
			
		||||
	// template the above paths into the default configs
 | 
			
		||||
	configs = strings.Replace(configs, "COMMUNITY_PATH", community, -1)
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ import (
 | 
			
		||||
	"github.com/cheat/cheat/internal/installer"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const version = "4.2.3"
 | 
			
		||||
const version = "4.2.4"
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -9,22 +9,23 @@ import (
 | 
			
		||||
func configs() string {
 | 
			
		||||
	return strings.TrimSpace(`---
 | 
			
		||||
# The editor to use with 'cheat -e <sheet>'. Defaults to $EDITOR or $VISUAL.
 | 
			
		||||
editor: vim
 | 
			
		||||
# editor: vim
 | 
			
		||||
 | 
			
		||||
# Should 'cheat' always colorize output?
 | 
			
		||||
colorize: true
 | 
			
		||||
colorize: false
 | 
			
		||||
 | 
			
		||||
# Which 'chroma' colorscheme should be applied to the output?
 | 
			
		||||
# Options are available here:
 | 
			
		||||
#   https://github.com/alecthomas/chroma/tree/master/styles
 | 
			
		||||
style: monokai
 | 
			
		||||
# style: monokai
 | 
			
		||||
 | 
			
		||||
# Which 'chroma' "formatter" should be applied?
 | 
			
		||||
# One of: "terminal", "terminal256", "terminal16m"
 | 
			
		||||
formatter: terminal16m
 | 
			
		||||
formatter: terminal
 | 
			
		||||
 | 
			
		||||
# Through which pager should output be piped? (Unset this key for no pager.)
 | 
			
		||||
pager: less -FRX
 | 
			
		||||
pager: more
 | 
			
		||||
# pager: less -FRX # <- recommended where available
 | 
			
		||||
 | 
			
		||||
# The paths at which cheatsheets are available. Tags associated with a cheatpath
 | 
			
		||||
# are automatically attached to all cheatsheets residing on that path.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,21 +1,22 @@
 | 
			
		||||
---
 | 
			
		||||
# The editor to use with 'cheat -e <sheet>'. Defaults to $EDITOR or $VISUAL.
 | 
			
		||||
editor: vim
 | 
			
		||||
# editor: vim
 | 
			
		||||
 | 
			
		||||
# Should 'cheat' always colorize output?
 | 
			
		||||
colorize: true
 | 
			
		||||
colorize: false
 | 
			
		||||
 | 
			
		||||
# Which 'chroma' colorscheme should be applied to the output?
 | 
			
		||||
# Options are available here:
 | 
			
		||||
#   https://github.com/alecthomas/chroma/tree/master/styles
 | 
			
		||||
style: monokai
 | 
			
		||||
# style: monokai
 | 
			
		||||
 | 
			
		||||
# Which 'chroma' "formatter" should be applied?
 | 
			
		||||
# One of: "terminal", "terminal256", "terminal16m"
 | 
			
		||||
formatter: terminal16m
 | 
			
		||||
formatter: terminal
 | 
			
		||||
 | 
			
		||||
# Through which pager should output be piped? (Unset this key for no pager.)
 | 
			
		||||
pager: less -FRX
 | 
			
		||||
pager: more
 | 
			
		||||
# pager: less -FRX # <- recommended where available
 | 
			
		||||
 | 
			
		||||
# The paths at which cheatsheets are available. Tags associated with a cheatpath
 | 
			
		||||
# are automatically attached to all cheatsheets residing on that path.
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,9 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/exec"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	cp "github.com/cheat/cheat/internal/cheatpath"
 | 
			
		||||
@@ -98,8 +100,22 @@ func New(opts map[string]interface{}, confPath string, resolve bool) (Config, er
 | 
			
		||||
			conf.Editor = os.Getenv("VISUAL")
 | 
			
		||||
		} else if os.Getenv("EDITOR") != "" {
 | 
			
		||||
			conf.Editor = os.Getenv("EDITOR")
 | 
			
		||||
		} else if runtime.GOOS == "windows" {
 | 
			
		||||
			conf.Editor = "notepad"
 | 
			
		||||
		} else {
 | 
			
		||||
			return Config{}, fmt.Errorf("no editor set")
 | 
			
		||||
			// try to fall back to `nano`
 | 
			
		||||
			path, err := exec.LookPath("nano")
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return Config{}, fmt.Errorf("failed to locate nano: %s", err)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// use `nano` if we found it
 | 
			
		||||
			if path != "" {
 | 
			
		||||
				conf.Editor = "nano"
 | 
			
		||||
				// otherwise, give up
 | 
			
		||||
			} else {
 | 
			
		||||
				return Config{}, fmt.Errorf("no editor set")
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -110,12 +126,13 @@ func New(opts map[string]interface{}, confPath string, resolve bool) (Config, er
 | 
			
		||||
 | 
			
		||||
	// if a chroma formatter was not provided, set a default
 | 
			
		||||
	if conf.Formatter == "" {
 | 
			
		||||
		conf.Formatter = "terminal16m"
 | 
			
		||||
		conf.Formatter = "terminal"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// if a pager was not provided, set a default
 | 
			
		||||
	if strings.TrimSpace(conf.Pager) == "" {
 | 
			
		||||
		conf.Pager = ""
 | 
			
		||||
	// attempt to fall back to `PAGER` if a pager is not specified in configs
 | 
			
		||||
	conf.Pager = strings.TrimSpace(conf.Pager)
 | 
			
		||||
	if conf.Pager == "" && os.Getenv("PAGER") != "" {
 | 
			
		||||
		conf.Pager = os.Getenv("PAGER")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return conf, nil
 | 
			
		||||
 
 | 
			
		||||
@@ -39,17 +39,17 @@ func TestConfigSuccessful(t *testing.T) {
 | 
			
		||||
	// assert that the cheatpaths are correct
 | 
			
		||||
	want := []cheatpath.Cheatpath{
 | 
			
		||||
		cheatpath.Cheatpath{
 | 
			
		||||
			Path:     filepath.Join(home, ".dotfiles/cheat/community"),
 | 
			
		||||
			Path:     filepath.Join(home, ".dotfiles", "cheat", "community"),
 | 
			
		||||
			ReadOnly: true,
 | 
			
		||||
			Tags:     []string{"community"},
 | 
			
		||||
		},
 | 
			
		||||
		cheatpath.Cheatpath{
 | 
			
		||||
			Path:     filepath.Join(home, ".dotfiles/cheat/work"),
 | 
			
		||||
			Path:     filepath.Join(home, ".dotfiles", "cheat", "work"),
 | 
			
		||||
			ReadOnly: false,
 | 
			
		||||
			Tags:     []string{"work"},
 | 
			
		||||
		},
 | 
			
		||||
		cheatpath.Cheatpath{
 | 
			
		||||
			Path:     filepath.Join(home, ".dotfiles/cheat/personal"),
 | 
			
		||||
			Path:     filepath.Join(home, ".dotfiles", "cheat", "personal"),
 | 
			
		||||
			ReadOnly: false,
 | 
			
		||||
			Tags:     []string{"personal"},
 | 
			
		||||
		},
 | 
			
		||||
@@ -85,8 +85,8 @@ func TestEmptyEditor(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
	// initialize a config
 | 
			
		||||
	conf, err := New(map[string]interface{}{}, mock.Path("conf/empty.yml"), false)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		t.Errorf("failed to return an error on empty editor")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Errorf("failed to initialize test: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// set editor, and assert that it is respected
 | 
			
		||||
 
 | 
			
		||||
@@ -33,20 +33,20 @@ func Paths(
 | 
			
		||||
 | 
			
		||||
		// 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, filepath.Join(xdgpath, "/cheat/conf.yml"))
 | 
			
		||||
			paths = append(paths, filepath.Join(xdgpath, "cheat", "conf.yml"))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		paths = append(paths, []string{
 | 
			
		||||
			filepath.Join(home, ".config/cheat/conf.yml"),
 | 
			
		||||
			filepath.Join(home, ".cheat/conf.yml"),
 | 
			
		||||
			filepath.Join(home, ".config", "cheat", "conf.yml"),
 | 
			
		||||
			filepath.Join(home, ".cheat", "conf.yml"),
 | 
			
		||||
			"/etc/cheat/conf.yml",
 | 
			
		||||
		}...)
 | 
			
		||||
 | 
			
		||||
		return paths, nil
 | 
			
		||||
	case "windows":
 | 
			
		||||
		return []string{
 | 
			
		||||
			filepath.Join(envvars["APPDATA"], "/cheat/conf.yml"),
 | 
			
		||||
			filepath.Join(envvars["PROGRAMDATA"], "/cheat/conf.yml"),
 | 
			
		||||
			filepath.Join(envvars["APPDATA"], "cheat", "conf.yml"),
 | 
			
		||||
			filepath.Join(envvars["PROGRAMDATA"], "cheat", "conf.yml"),
 | 
			
		||||
		}, nil
 | 
			
		||||
	default:
 | 
			
		||||
		return []string{}, fmt.Errorf("unsupported os: %s", sys)
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@ package installer
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/cheat/cheat/internal/config"
 | 
			
		||||
@@ -14,11 +14,11 @@ func Run(configs string, confpath string) error {
 | 
			
		||||
 | 
			
		||||
	// determine the appropriate paths for config data and (optional) community
 | 
			
		||||
	// cheatsheets based on the user's platform
 | 
			
		||||
	confdir := path.Dir(confpath)
 | 
			
		||||
	confdir := filepath.Dir(confpath)
 | 
			
		||||
 | 
			
		||||
	// create paths for community and personal cheatsheets
 | 
			
		||||
	community := path.Join(confdir, "/cheatsheets/community")
 | 
			
		||||
	personal := path.Join(confdir, "/cheatsheets/personal")
 | 
			
		||||
	community := filepath.Join(confdir, "cheatsheets", "community")
 | 
			
		||||
	personal := filepath.Join(confdir, "cheatsheets", "personal")
 | 
			
		||||
 | 
			
		||||
	// template the above paths into the default configs
 | 
			
		||||
	configs = strings.Replace(configs, "COMMUNITY_PATH", community, -1)
 | 
			
		||||
@@ -36,11 +36,13 @@ func Run(configs string, confpath string) error {
 | 
			
		||||
	// clone the community cheatsheets if so instructed
 | 
			
		||||
	if yes {
 | 
			
		||||
		// clone the community cheatsheets
 | 
			
		||||
		fmt.Printf("Cloning community cheatsheets to %s.\n", community)
 | 
			
		||||
		if err := clone(community); err != nil {
 | 
			
		||||
			return fmt.Errorf("failed to clone cheatsheets: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// also create a directory for personal cheatsheets
 | 
			
		||||
		fmt.Printf("Cloning personal cheatsheets to %s.\n", personal)
 | 
			
		||||
		if err := os.MkdirAll(personal, os.ModePerm); err != nil {
 | 
			
		||||
			return fmt.Errorf("failed to create directory: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Copy copies a cheatsheet to a new location
 | 
			
		||||
@@ -22,7 +22,7 @@ func (s *Sheet) Copy(dest string) error {
 | 
			
		||||
	defer infile.Close()
 | 
			
		||||
 | 
			
		||||
	// create any necessary subdirectories
 | 
			
		||||
	dirs := path.Dir(dest)
 | 
			
		||||
	dirs := filepath.Dir(dest)
 | 
			
		||||
	if dirs != "." {
 | 
			
		||||
		if err := os.MkdirAll(dirs, 0755); err != nil {
 | 
			
		||||
			return fmt.Errorf("failed to create directory: %s, %v", dirs, err)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user