Merge pull request #673 from chrisallenlane/win-compat

fix: Windows compatibility
This commit is contained in:
Chris Allen Lane 2022-07-04 17:03:11 -04:00 committed by GitHub
commit fe8f39013e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 68 additions and 42 deletions

View File

@ -86,7 +86,7 @@ $(dist_dir)/cheat-linux-arm64: prepare
# cheat-windows-amd64 # cheat-windows-amd64
$(dist_dir)/cheat-windows-amd64.exe: prepare $(dist_dir)/cheat-windows-amd64.exe: prepare
GOARCH=amd64 GOOS=windows \ 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
$(dist_dir): $(dist_dir):
@ -180,6 +180,11 @@ prepare: | $(dist_dir) clean generate vendor fmt lint vet test
docker-setup: docker-setup:
$(DOCKER) build -t $(docker_image) -f Dockerfile . $(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 ## docker-sh: shell into the docker development container
.PHONY: docker-sh .PHONY: docker-sh
docker-sh: docker-sh:

View File

@ -4,7 +4,7 @@ import (
"fmt" "fmt"
"os" "os"
"os/exec" "os/exec"
"path" "path/filepath"
"strings" "strings"
"github.com/cheat/cheat/internal/cheatpath" "github.com/cheat/cheat/internal/cheatpath"
@ -58,10 +58,10 @@ func cmdEdit(opts map[string]interface{}, conf config.Config) {
} }
// compute the new edit path // compute the new edit path
editpath = path.Join(writepath.Path, sheet.Title) editpath = filepath.Join(writepath.Path, sheet.Title)
// create any necessary subdirectories // create any necessary subdirectories
dirs := path.Dir(editpath) dirs := filepath.Dir(editpath)
if dirs != "." { if dirs != "." {
if err := os.MkdirAll(dirs, 0755); err != nil { if err := os.MkdirAll(dirs, 0755); err != nil {
fmt.Fprintf(os.Stderr, "failed to create directory: %s, %v\n", dirs, err) 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 // compute the new edit path
editpath = path.Join(writepath.Path, cheatsheet) editpath = filepath.Join(writepath.Path, cheatsheet)
// create any necessary subdirectories // create any necessary subdirectories
dirs := path.Dir(editpath) dirs := filepath.Dir(editpath)
if dirs != "." { if dirs != "." {
if err := os.MkdirAll(dirs, 0755); err != nil { if err := os.MkdirAll(dirs, 0755); err != nil {
fmt.Fprintf(os.Stderr, "failed to create directory: %s, %v\n", dirs, err) fmt.Fprintf(os.Stderr, "failed to create directory: %s, %v\n", dirs, err)

View File

@ -3,7 +3,7 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"path" "path/filepath"
"runtime" "runtime"
"strings" "strings"
@ -42,11 +42,11 @@ func cmdInit() {
// determine the appropriate paths for config data and (optional) community // determine the appropriate paths for config data and (optional) community
// cheatsheets based on the user's platform // cheatsheets based on the user's platform
confpath := confpaths[0] confpath := confpaths[0]
confdir := path.Dir(confpath) confdir := filepath.Dir(confpath)
// create paths for community and personal cheatsheets // create paths for community and personal cheatsheets
community := path.Join(confdir, "/cheatsheets/community") community := filepath.Join(confdir, "cheatsheets", "community")
personal := path.Join(confdir, "/cheatsheets/personal") personal := filepath.Join(confdir, "cheatsheets", "personal")
// template the above paths into the default configs // template the above paths into the default configs
configs = strings.Replace(configs, "COMMUNITY_PATH", community, -1) configs = strings.Replace(configs, "COMMUNITY_PATH", community, -1)

View File

@ -16,7 +16,7 @@ import (
"github.com/cheat/cheat/internal/installer" "github.com/cheat/cheat/internal/installer"
) )
const version = "4.2.3" const version = "4.2.4"
func main() { func main() {

View File

@ -9,22 +9,23 @@ import (
func configs() string { func configs() string {
return strings.TrimSpace(`--- return strings.TrimSpace(`---
# The editor to use with 'cheat -e <sheet>'. Defaults to $EDITOR or $VISUAL. # The editor to use with 'cheat -e <sheet>'. Defaults to $EDITOR or $VISUAL.
editor: vim # editor: vim
# Should 'cheat' always colorize output? # Should 'cheat' always colorize output?
colorize: true colorize: false
# Which 'chroma' colorscheme should be applied to the output? # Which 'chroma' colorscheme should be applied to the output?
# Options are available here: # Options are available here:
# https://github.com/alecthomas/chroma/tree/master/styles # https://github.com/alecthomas/chroma/tree/master/styles
style: monokai # style: monokai
# Which 'chroma' "formatter" should be applied? # Which 'chroma' "formatter" should be applied?
# One of: "terminal", "terminal256", "terminal16m" # One of: "terminal", "terminal256", "terminal16m"
formatter: terminal16m formatter: terminal
# Through which pager should output be piped? (Unset this key for no pager.) # 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 # The paths at which cheatsheets are available. Tags associated with a cheatpath
# are automatically attached to all cheatsheets residing on that path. # are automatically attached to all cheatsheets residing on that path.

View File

@ -1,21 +1,22 @@
--- ---
# The editor to use with 'cheat -e <sheet>'. Defaults to $EDITOR or $VISUAL. # The editor to use with 'cheat -e <sheet>'. Defaults to $EDITOR or $VISUAL.
editor: vim # editor: vim
# Should 'cheat' always colorize output? # Should 'cheat' always colorize output?
colorize: true colorize: false
# Which 'chroma' colorscheme should be applied to the output? # Which 'chroma' colorscheme should be applied to the output?
# Options are available here: # Options are available here:
# https://github.com/alecthomas/chroma/tree/master/styles # https://github.com/alecthomas/chroma/tree/master/styles
style: monokai # style: monokai
# Which 'chroma' "formatter" should be applied? # Which 'chroma' "formatter" should be applied?
# One of: "terminal", "terminal256", "terminal16m" # One of: "terminal", "terminal256", "terminal16m"
formatter: terminal16m formatter: terminal
# Through which pager should output be piped? (Unset this key for no pager.) # 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 # The paths at which cheatsheets are available. Tags associated with a cheatpath
# are automatically attached to all cheatsheets residing on that path. # are automatically attached to all cheatsheets residing on that path.

View File

@ -4,7 +4,9 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"os/exec"
"path/filepath" "path/filepath"
"runtime"
"strings" "strings"
cp "github.com/cheat/cheat/internal/cheatpath" 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") conf.Editor = os.Getenv("VISUAL")
} else if os.Getenv("EDITOR") != "" { } else if os.Getenv("EDITOR") != "" {
conf.Editor = os.Getenv("EDITOR") conf.Editor = os.Getenv("EDITOR")
} else if runtime.GOOS == "windows" {
conf.Editor = "notepad"
} else { } 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 a chroma formatter was not provided, set a default
if conf.Formatter == "" { if conf.Formatter == "" {
conf.Formatter = "terminal16m" conf.Formatter = "terminal"
} }
// if a pager was not provided, set a default // attempt to fall back to `PAGER` if a pager is not specified in configs
if strings.TrimSpace(conf.Pager) == "" { conf.Pager = strings.TrimSpace(conf.Pager)
conf.Pager = "" if conf.Pager == "" && os.Getenv("PAGER") != "" {
conf.Pager = os.Getenv("PAGER")
} }
return conf, nil return conf, nil

View File

@ -39,17 +39,17 @@ func TestConfigSuccessful(t *testing.T) {
// assert that the cheatpaths are correct // assert that the cheatpaths are correct
want := []cheatpath.Cheatpath{ want := []cheatpath.Cheatpath{
cheatpath.Cheatpath{ cheatpath.Cheatpath{
Path: filepath.Join(home, ".dotfiles/cheat/community"), Path: filepath.Join(home, ".dotfiles", "cheat", "community"),
ReadOnly: true, ReadOnly: true,
Tags: []string{"community"}, Tags: []string{"community"},
}, },
cheatpath.Cheatpath{ cheatpath.Cheatpath{
Path: filepath.Join(home, ".dotfiles/cheat/work"), Path: filepath.Join(home, ".dotfiles", "cheat", "work"),
ReadOnly: false, ReadOnly: false,
Tags: []string{"work"}, Tags: []string{"work"},
}, },
cheatpath.Cheatpath{ cheatpath.Cheatpath{
Path: filepath.Join(home, ".dotfiles/cheat/personal"), Path: filepath.Join(home, ".dotfiles", "cheat", "personal"),
ReadOnly: false, ReadOnly: false,
Tags: []string{"personal"}, Tags: []string{"personal"},
}, },
@ -85,8 +85,8 @@ func TestEmptyEditor(t *testing.T) {
// initialize a config // initialize a config
conf, err := New(map[string]interface{}{}, mock.Path("conf/empty.yml"), false) conf, err := New(map[string]interface{}{}, mock.Path("conf/empty.yml"), false)
if err == nil { if err != nil {
t.Errorf("failed to return an error on empty editor") t.Errorf("failed to initialize test: %v", err)
} }
// set editor, and assert that it is respected // set editor, and assert that it is respected

View File

@ -33,20 +33,20 @@ func Paths(
// don't include the `XDG_CONFIG_HOME` path if that envvar is not set // don't include the `XDG_CONFIG_HOME` path if that envvar is not set
if xdgpath, ok := envvars["XDG_CONFIG_HOME"]; ok { 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{ paths = append(paths, []string{
filepath.Join(home, ".config/cheat/conf.yml"), filepath.Join(home, ".config", "cheat", "conf.yml"),
filepath.Join(home, ".cheat/conf.yml"), filepath.Join(home, ".cheat", "conf.yml"),
"/etc/cheat/conf.yml", "/etc/cheat/conf.yml",
}...) }...)
return paths, nil return paths, nil
case "windows": case "windows":
return []string{ return []string{
filepath.Join(envvars["APPDATA"], "/cheat/conf.yml"), filepath.Join(envvars["APPDATA"], "cheat", "conf.yml"),
filepath.Join(envvars["PROGRAMDATA"], "/cheat/conf.yml"), filepath.Join(envvars["PROGRAMDATA"], "cheat", "conf.yml"),
}, nil }, nil
default: default:
return []string{}, fmt.Errorf("unsupported os: %s", sys) return []string{}, fmt.Errorf("unsupported os: %s", sys)

View File

@ -3,7 +3,7 @@ package installer
import ( import (
"fmt" "fmt"
"os" "os"
"path" "path/filepath"
"strings" "strings"
"github.com/cheat/cheat/internal/config" "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 // determine the appropriate paths for config data and (optional) community
// cheatsheets based on the user's platform // cheatsheets based on the user's platform
confdir := path.Dir(confpath) confdir := filepath.Dir(confpath)
// create paths for community and personal cheatsheets // create paths for community and personal cheatsheets
community := path.Join(confdir, "/cheatsheets/community") community := filepath.Join(confdir, "cheatsheets", "community")
personal := path.Join(confdir, "/cheatsheets/personal") personal := filepath.Join(confdir, "cheatsheets", "personal")
// template the above paths into the default configs // template the above paths into the default configs
configs = strings.Replace(configs, "COMMUNITY_PATH", community, -1) 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 // clone the community cheatsheets if so instructed
if yes { if yes {
// clone the community cheatsheets // clone the community cheatsheets
fmt.Printf("Cloning community cheatsheets to %s.\n", community)
if err := clone(community); err != nil { if err := clone(community); err != nil {
return fmt.Errorf("failed to clone cheatsheets: %v", err) return fmt.Errorf("failed to clone cheatsheets: %v", err)
} }
// also create a directory for personal cheatsheets // 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 { if err := os.MkdirAll(personal, os.ModePerm); err != nil {
return fmt.Errorf("failed to create directory: %v", err) return fmt.Errorf("failed to create directory: %v", err)
} }

View File

@ -4,7 +4,7 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"path" "path/filepath"
) )
// Copy copies a cheatsheet to a new location // Copy copies a cheatsheet to a new location
@ -22,7 +22,7 @@ func (s *Sheet) Copy(dest string) error {
defer infile.Close() defer infile.Close()
// create any necessary subdirectories // create any necessary subdirectories
dirs := path.Dir(dest) dirs := filepath.Dir(dest)
if dirs != "." { if dirs != "." {
if err := os.MkdirAll(dirs, 0755); err != nil { if err := os.MkdirAll(dirs, 0755); err != nil {
return fmt.Errorf("failed to create directory: %s, %v", dirs, err) return fmt.Errorf("failed to create directory: %s, %v", dirs, err)