mirror of https://github.com/cheat/cheat.git
Merge pull request #531 from chrisallenlane/auto-config
feat(configs): config auto-generation
This commit is contained in:
commit
d4c6200702
16
Makefile
16
Makefile
|
@ -33,7 +33,7 @@ releases := \
|
||||||
|
|
||||||
## build: builds an executable for your architecture
|
## build: builds an executable for your architecture
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
build: $(dist_dir)
|
build: $(dist_dir) clean generate
|
||||||
$(GO) build $(BUILD_FLAGS) -o $(dist_dir)/cheat $(cmd_dir)
|
$(GO) build $(BUILD_FLAGS) -o $(dist_dir)/cheat $(cmd_dir)
|
||||||
|
|
||||||
## build-release: builds release executables
|
## build-release: builds release executables
|
||||||
|
@ -47,27 +47,27 @@ ci: | setup prepare build
|
||||||
# cheat-darwin-amd64
|
# cheat-darwin-amd64
|
||||||
$(dist_dir)/cheat-darwin-amd64: prepare
|
$(dist_dir)/cheat-darwin-amd64: prepare
|
||||||
GOARCH=amd64 GOOS=darwin \
|
GOARCH=amd64 GOOS=darwin \
|
||||||
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@
|
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@ && chmod -x $@.gz
|
||||||
|
|
||||||
# cheat-linux-amd64
|
# cheat-linux-amd64
|
||||||
$(dist_dir)/cheat-linux-amd64: prepare
|
$(dist_dir)/cheat-linux-amd64: prepare
|
||||||
GOARCH=amd64 GOOS=linux \
|
GOARCH=amd64 GOOS=linux \
|
||||||
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@
|
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@ && chmod -x $@.gz
|
||||||
|
|
||||||
# cheat-linux-arm5
|
# cheat-linux-arm5
|
||||||
$(dist_dir)/cheat-linux-arm5: prepare
|
$(dist_dir)/cheat-linux-arm5: prepare
|
||||||
GOARCH=arm GOOS=linux GOARM=5 \
|
GOARCH=arm GOOS=linux GOARM=5 \
|
||||||
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@
|
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@ && chmod -x $@.gz
|
||||||
|
|
||||||
# cheat-linux-arm6
|
# cheat-linux-arm6
|
||||||
$(dist_dir)/cheat-linux-arm6: prepare
|
$(dist_dir)/cheat-linux-arm6: prepare
|
||||||
GOARCH=arm GOOS=linux GOARM=6 \
|
GOARCH=arm GOOS=linux GOARM=6 \
|
||||||
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@
|
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@ && chmod -x $@.gz
|
||||||
|
|
||||||
# cheat-linux-arm7
|
# cheat-linux-arm7
|
||||||
$(dist_dir)/cheat-linux-arm7: prepare
|
$(dist_dir)/cheat-linux-arm7: prepare
|
||||||
GOARCH=arm GOOS=linux GOARM=7 \
|
GOARCH=arm GOOS=linux GOARM=7 \
|
||||||
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@
|
$(GO) build $(BUILD_FLAGS) -o $@ $(cmd_dir) && $(GZIP) $@ && chmod -x $@.gz
|
||||||
|
|
||||||
# cheat-windows-amd64
|
# cheat-windows-amd64
|
||||||
$(dist_dir)/cheat-windows-amd64.exe: prepare
|
$(dist_dir)/cheat-windows-amd64.exe: prepare
|
||||||
|
@ -95,7 +95,7 @@ clean: $(dist_dir)
|
||||||
## distclean: removes the tags file
|
## distclean: removes the tags file
|
||||||
.PHONY: distclean
|
.PHONY: distclean
|
||||||
distclean:
|
distclean:
|
||||||
$(RM) tags
|
$(RM) -f tags
|
||||||
|
|
||||||
## setup: installs revive (linter) and scc (sloc tool)
|
## setup: installs revive (linter) and scc (sloc tool)
|
||||||
.PHONY: setup
|
.PHONY: setup
|
||||||
|
@ -110,7 +110,7 @@ sloc:
|
||||||
## tags: builds a tags file
|
## tags: builds a tags file
|
||||||
.PHONY: tags
|
.PHONY: tags
|
||||||
tags:
|
tags:
|
||||||
$(CTAGS) -R . --exclude=vendor
|
$(CTAGS) -R --exclude=vendor --languages=go
|
||||||
|
|
||||||
## vendor: downloads, tidies, and verifies dependencies
|
## vendor: downloads, tidies, and verifies dependencies
|
||||||
.PHONY: vendor
|
.PHONY: vendor
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
"github.com/cheat/cheat/internal/config"
|
"github.com/cheat/cheat/internal/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
const version = "3.3.2"
|
const version = "3.4.0"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
|
@ -31,13 +31,35 @@ func main() {
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// load the config file
|
// load the os-specifc paths at which the config file may be located
|
||||||
confpath, err := config.Path(runtime.GOOS)
|
confpaths, err := config.Paths(runtime.GOOS)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "could not locate config file")
|
fmt.Fprintf(os.Stderr, "failed to load config: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// search for the config file in the above paths
|
||||||
|
confpath, err := config.Path(confpaths)
|
||||||
|
if err != nil {
|
||||||
|
|
||||||
|
// the config file does not exist, so we'll try to create one
|
||||||
|
if err = config.Init(confpaths[0], configs()); err != nil {
|
||||||
|
fmt.Fprintf(
|
||||||
|
os.Stderr,
|
||||||
|
"failed to create config file: %s: %v\n",
|
||||||
|
confpaths[0],
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
confpath = confpaths[0]
|
||||||
|
|
||||||
|
fmt.Printf("Created config file: %s\n", confpath)
|
||||||
|
fmt.Println("Please edit this file now to configure cheat.")
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
// initialize the configs
|
// initialize the configs
|
||||||
conf, err := config.New(opts, confpath, true)
|
conf, err := config.New(opts, confpath, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -43,22 +43,23 @@ cheatpaths:
|
||||||
#
|
#
|
||||||
# Note that the paths and tags listed below are just examples. You may freely
|
# Note that the paths and tags listed below are just examples. You may freely
|
||||||
# change them to suit your needs.
|
# change them to suit your needs.
|
||||||
|
#
|
||||||
|
# TODO: regarding community cheatsheets: these must be installed separately.
|
||||||
|
# You may download them here:
|
||||||
|
#
|
||||||
|
# https://github.com/cheat/cheatsheets
|
||||||
|
#
|
||||||
|
# Once downloaded, ensure that 'path' below points to the location at which
|
||||||
|
# you downloaded the community cheatsheets.
|
||||||
- name: community
|
- name: community
|
||||||
path: ~/.dotfiles/cheat/community
|
path: ~/cheat/cheatsheets/community
|
||||||
tags: [ community ]
|
tags: [ community ]
|
||||||
readonly: true
|
readonly: true
|
||||||
|
|
||||||
# Maybe your company or department maintains a repository of cheatsheets as
|
|
||||||
# well. It's probably sensible to list those second.
|
|
||||||
- name: work
|
|
||||||
path: ~/.dotfiles/cheat/work
|
|
||||||
tags: [ work ]
|
|
||||||
readonly: false
|
|
||||||
|
|
||||||
# If you have personalized cheatsheets, list them last. They will take
|
# If you have personalized cheatsheets, list them last. They will take
|
||||||
# precedence over the more global cheatsheets.
|
# precedence over the more global cheatsheets.
|
||||||
- name: personal
|
- name: personal
|
||||||
path: ~/.dotfiles/cheat/personal
|
path: ~/cheat/cheatsheets/personal
|
||||||
tags: [ personal ]
|
tags: [ personal ]
|
||||||
readonly: false
|
readonly: false
|
||||||
|
|
||||||
|
|
|
@ -34,22 +34,23 @@ cheatpaths:
|
||||||
#
|
#
|
||||||
# Note that the paths and tags listed below are just examples. You may freely
|
# Note that the paths and tags listed below are just examples. You may freely
|
||||||
# change them to suit your needs.
|
# change them to suit your needs.
|
||||||
|
#
|
||||||
|
# TODO: regarding community cheatsheets: these must be installed separately.
|
||||||
|
# You may download them here:
|
||||||
|
#
|
||||||
|
# https://github.com/cheat/cheatsheets
|
||||||
|
#
|
||||||
|
# Once downloaded, ensure that 'path' below points to the location at which
|
||||||
|
# you downloaded the community cheatsheets.
|
||||||
- name: community
|
- name: community
|
||||||
path: ~/.dotfiles/cheat/community
|
path: ~/cheat/cheatsheets/community
|
||||||
tags: [ community ]
|
tags: [ community ]
|
||||||
readonly: true
|
readonly: true
|
||||||
|
|
||||||
# Maybe your company or department maintains a repository of cheatsheets as
|
|
||||||
# well. It's probably sensible to list those second.
|
|
||||||
- name: work
|
|
||||||
path: ~/.dotfiles/cheat/work
|
|
||||||
tags: [ work ]
|
|
||||||
readonly: false
|
|
||||||
|
|
||||||
# If you have personalized cheatsheets, list them last. They will take
|
# If you have personalized cheatsheets, list them last. They will take
|
||||||
# precedence over the more global cheatsheets.
|
# precedence over the more global cheatsheets.
|
||||||
- name: personal
|
- name: personal
|
||||||
path: ~/.dotfiles/cheat/personal
|
path: ~/cheat/cheatsheets/personal
|
||||||
tags: [ personal ]
|
tags: [ personal ]
|
||||||
readonly: false
|
readonly: false
|
||||||
|
|
||||||
|
|
|
@ -75,14 +75,16 @@ func New(opts map[string]interface{}, confPath string, resolve bool) (Config, er
|
||||||
// `resolve` is a switch that allows us to turn off symlink resolution when
|
// `resolve` is a switch that allows us to turn off symlink resolution when
|
||||||
// running the config tests.
|
// running the config tests.
|
||||||
if resolve {
|
if resolve {
|
||||||
expanded, err = filepath.EvalSymlinks(expanded)
|
evaled, err := filepath.EvalSymlinks(expanded)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Config{}, fmt.Errorf(
|
return Config{}, fmt.Errorf(
|
||||||
"failed to resolve symlink: %s, %v",
|
"failed to resolve symlink: %s: %v",
|
||||||
expanded,
|
expanded,
|
||||||
err,
|
err,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expanded = evaled
|
||||||
}
|
}
|
||||||
|
|
||||||
conf.Cheatpaths[i].Path = expanded
|
conf.Cheatpaths[i].Path = expanded
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Init initializes a config file
|
||||||
|
func Init(confpath string, configs string) error {
|
||||||
|
|
||||||
|
// assert that the config directory exists
|
||||||
|
if err := os.MkdirAll(filepath.Dir(confpath), 0755); err != nil {
|
||||||
|
return fmt.Errorf("failed to create directory: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the config file
|
||||||
|
if err := ioutil.WriteFile(confpath, []byte(configs), 0644); err != nil {
|
||||||
|
return fmt.Errorf("failed to create file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -3,43 +3,10 @@ package config
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
|
||||||
|
|
||||||
"github.com/mitchellh/go-homedir"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Path returns the config file path
|
// Path returns the config file path
|
||||||
func Path(sys string) (string, error) {
|
func Path(paths []string) (string, error) {
|
||||||
|
|
||||||
var paths []string
|
|
||||||
|
|
||||||
// if CHEAT_CONFIG_PATH is set, return it
|
|
||||||
if os.Getenv("CHEAT_CONFIG_PATH") != "" {
|
|
||||||
|
|
||||||
// expand ~
|
|
||||||
expanded, err := homedir.Expand(os.Getenv("CHEAT_CONFIG_PATH"))
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to expand ~: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return expanded, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
switch sys {
|
|
||||||
case "darwin", "linux", "freebsd":
|
|
||||||
paths = []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"),
|
|
||||||
}
|
|
||||||
case "windows":
|
|
||||||
paths = []string{
|
|
||||||
fmt.Sprintf("%s/cheat/conf.yml", os.Getenv("APPDATA")),
|
|
||||||
fmt.Sprintf("%s/cheat/conf.yml", os.Getenv("PROGRAMDATA")),
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return "", fmt.Errorf("unsupported os: %s", sys)
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if the config file exists on any paths
|
// check if the config file exists on any paths
|
||||||
for _, p := range paths {
|
for _, p := range paths {
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
|
||||||
|
"github.com/mitchellh/go-homedir"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Paths returns config file paths that are appropriate for the operating
|
||||||
|
// system
|
||||||
|
func Paths(sys string) ([]string, error) {
|
||||||
|
|
||||||
|
// if CHEAT_CONFIG_PATH is set, return it
|
||||||
|
if os.Getenv("CHEAT_CONFIG_PATH") != "" {
|
||||||
|
|
||||||
|
// expand ~
|
||||||
|
expanded, err := homedir.Expand(os.Getenv("CHEAT_CONFIG_PATH"))
|
||||||
|
if err != nil {
|
||||||
|
return []string{}, fmt.Errorf("failed to expand ~: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return []string{expanded}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
case "windows":
|
||||||
|
return []string{
|
||||||
|
fmt.Sprintf("%s/cheat/conf.yml", os.Getenv("APPDATA")),
|
||||||
|
fmt.Sprintf("%s/cheat/conf.yml", os.Getenv("PROGRAMDATA")),
|
||||||
|
}, nil
|
||||||
|
default:
|
||||||
|
return []string{}, fmt.Errorf("unsupported os: %s", sys)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue