mirror of https://github.com/cheat/cheat.git
commit
73f80bde48
|
@ -9,13 +9,13 @@ On Unix-like systems, you may simply paste the following snippet into your termi
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd /tmp \
|
cd /tmp \
|
||||||
&& wget https://github.com/cheat/cheat/releases/download/4.2.5/cheat-linux-amd64.gz \
|
&& wget https://github.com/cheat/cheat/releases/download/4.2.7/cheat-linux-amd64.gz \
|
||||||
&& gunzip cheat-linux-amd64.gz \
|
&& gunzip cheat-linux-amd64.gz \
|
||||||
&& chmod +x cheat-linux-amd64 \
|
&& chmod +x cheat-linux-amd64 \
|
||||||
&& sudo mv cheat-linux-amd64 /usr/local/bin/cheat
|
&& sudo mv cheat-linux-amd64 /usr/local/bin/cheat
|
||||||
```
|
```
|
||||||
|
|
||||||
You may need to need to change the version number (`4.2.5`) and the archive
|
You may need to need to change the version number (`4.2.7`) and the archive
|
||||||
(`cheat-linux-amd64.gz`) depending on your platform.
|
(`cheat-linux-amd64.gz`) depending on your platform.
|
||||||
|
|
||||||
See the [releases page][releases] for a list of supported platforms.
|
See the [releases page][releases] for a list of supported platforms.
|
||||||
|
|
|
@ -18,11 +18,7 @@ func cmdDirectories(opts map[string]interface{}, conf config.Config) {
|
||||||
|
|
||||||
// generate sorted, columnized output
|
// generate sorted, columnized output
|
||||||
for _, path := range conf.Cheatpaths {
|
for _, path := range conf.Cheatpaths {
|
||||||
fmt.Fprintln(w, fmt.Sprintf(
|
fmt.Fprintf(w, "%s:\t%s\n", path.Name, path.Path)
|
||||||
"%s:\t%s",
|
|
||||||
path.Name,
|
|
||||||
path.Path,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// write columnized output to stdout
|
// write columnized output to stdout
|
||||||
|
|
|
@ -20,7 +20,7 @@ func cmdEdit(opts map[string]interface{}, conf config.Config) {
|
||||||
// load the cheatsheets
|
// load the cheatsheets
|
||||||
cheatsheets, err := sheets.Load(conf.Cheatpaths)
|
cheatsheets, err := sheets.Load(conf.Cheatpaths)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, fmt.Sprintf("failed to list cheatsheets: %v", err))
|
fmt.Fprintf(os.Stderr, "failed to list cheatsheets: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ func cmdList(opts map[string]interface{}, conf config.Config) {
|
||||||
// load the cheatsheets
|
// load the cheatsheets
|
||||||
cheatsheets, err := sheets.Load(conf.Cheatpaths)
|
cheatsheets, err := sheets.Load(conf.Cheatpaths)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, fmt.Sprintf("failed to list cheatsheets: %v", err))
|
fmt.Fprintf(os.Stderr, "failed to list cheatsheets: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,10 +63,7 @@ func cmdList(opts map[string]interface{}, conf config.Config) {
|
||||||
// compile the regex
|
// compile the regex
|
||||||
reg, err := regexp.Compile(pattern)
|
reg, err := regexp.Compile(pattern)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(
|
fmt.Fprintf(os.Stderr, "failed to compile regexp: %s, %v\n", pattern, err)
|
||||||
os.Stderr,
|
|
||||||
fmt.Sprintf("failed to compile regexp: %s, %v", pattern, err),
|
|
||||||
)
|
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,12 +92,7 @@ func cmdList(opts map[string]interface{}, conf config.Config) {
|
||||||
|
|
||||||
// generate sorted, columnized output
|
// generate sorted, columnized output
|
||||||
for _, sheet := range flattened {
|
for _, sheet := range flattened {
|
||||||
fmt.Fprintln(w, fmt.Sprintf(
|
fmt.Fprintf(w, "%s\t%s\t%s\n", sheet.Title, sheet.Path, strings.Join(sheet.Tags, ","))
|
||||||
"%s\t%s\t%s",
|
|
||||||
sheet.Title,
|
|
||||||
sheet.Path,
|
|
||||||
strings.Join(sheet.Tags, ","),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// write columnized output to stdout
|
// write columnized output to stdout
|
||||||
|
|
|
@ -17,7 +17,7 @@ func cmdRemove(opts map[string]interface{}, conf config.Config) {
|
||||||
// load the cheatsheets
|
// load the cheatsheets
|
||||||
cheatsheets, err := sheets.Load(conf.Cheatpaths)
|
cheatsheets, err := sheets.Load(conf.Cheatpaths)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, fmt.Sprintf("failed to list cheatsheets: %v", err))
|
fmt.Fprintf(os.Stderr, "failed to list cheatsheets: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,19 +37,19 @@ func cmdRemove(opts map[string]interface{}, conf config.Config) {
|
||||||
// fail early if the requested cheatsheet does not exist
|
// fail early if the requested cheatsheet does not exist
|
||||||
sheet, ok := consolidated[cheatsheet]
|
sheet, ok := consolidated[cheatsheet]
|
||||||
if !ok {
|
if !ok {
|
||||||
fmt.Fprintln(os.Stderr, fmt.Sprintf("No cheatsheet found for '%s'.\n", cheatsheet))
|
fmt.Fprintf(os.Stderr, "No cheatsheet found for '%s'.\n", cheatsheet)
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fail early if the sheet is read-only
|
// fail early if the sheet is read-only
|
||||||
if sheet.ReadOnly {
|
if sheet.ReadOnly {
|
||||||
fmt.Fprintln(os.Stderr, fmt.Sprintf("cheatsheet '%s' is read-only.", cheatsheet))
|
fmt.Fprintf(os.Stderr, "cheatsheet '%s' is read-only.\n", cheatsheet)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, attempt to delete the sheet
|
// otherwise, attempt to delete the sheet
|
||||||
if err := os.Remove(sheet.Path); err != nil {
|
if err := os.Remove(sheet.Path); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, fmt.Sprintf("failed to delete sheet: %s, %v", sheet.Title, err))
|
fmt.Fprintf(os.Stderr, "failed to delete sheet: %s, %v\n", sheet.Title, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ func cmdSearch(opts map[string]interface{}, conf config.Config) {
|
||||||
// load the cheatsheets
|
// load the cheatsheets
|
||||||
cheatsheets, err := sheets.Load(conf.Cheatpaths)
|
cheatsheets, err := sheets.Load(conf.Cheatpaths)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, fmt.Sprintf("failed to list cheatsheets: %v", err))
|
fmt.Fprintf(os.Stderr, "failed to list cheatsheets: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,13 +55,13 @@ func cmdSearch(opts map[string]interface{}, conf config.Config) {
|
||||||
// compile the regex
|
// compile the regex
|
||||||
reg, err := regexp.Compile(pattern)
|
reg, err := regexp.Compile(pattern)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, fmt.Sprintf("failed to compile regexp: %s, %v", pattern, err))
|
fmt.Fprintf(os.Stderr, "failed to compile regexp: %s, %v\n", pattern, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// `Search` will return text entries that match the search terms. We're
|
// `Search` will return text entries that match the search terms.
|
||||||
// using it here to overwrite the prior cheatsheet Text, filtering it to
|
// We're using it here to overwrite the prior cheatsheet Text,
|
||||||
// only what is relevant
|
// filtering it to only what is relevant.
|
||||||
sheet.Text = sheet.Search(reg)
|
sheet.Text = sheet.Search(reg)
|
||||||
|
|
||||||
// if the sheet did not match the search, ignore it and move on
|
// if the sheet did not match the search, ignore it and move on
|
||||||
|
@ -74,14 +74,16 @@ func cmdSearch(opts map[string]interface{}, conf config.Config) {
|
||||||
sheet.Colorize(conf)
|
sheet.Colorize(conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// display the cheatsheet title and path
|
// display the cheatsheet body
|
||||||
out += fmt.Sprintf("%s %s\n",
|
out += fmt.Sprintf(
|
||||||
display.Underline(sheet.Title),
|
"%s %s\n%s\n",
|
||||||
|
// append the cheatsheet title
|
||||||
|
sheet.Title,
|
||||||
|
// append the cheatsheet path
|
||||||
display.Faint(fmt.Sprintf("(%s)", sheet.CheatPath), conf),
|
display.Faint(fmt.Sprintf("(%s)", sheet.CheatPath), conf),
|
||||||
|
// indent each line of content
|
||||||
|
display.Indent(sheet.Text),
|
||||||
)
|
)
|
||||||
|
|
||||||
// indent each line of content
|
|
||||||
out += display.Indent(sheet.Text) + "\n"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +91,7 @@ func cmdSearch(opts map[string]interface{}, conf config.Config) {
|
||||||
out = strings.TrimSpace(out)
|
out = strings.TrimSpace(out)
|
||||||
|
|
||||||
// display the output
|
// display the output
|
||||||
// NB: resist the temptation to call `display.Display` multiple times in
|
// NB: resist the temptation to call `display.Write` multiple times in the
|
||||||
// the loop above. That will not play nicely with the paginator.
|
// loop above. That will not play nicely with the paginator.
|
||||||
display.Write(out, conf)
|
display.Write(out, conf)
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ func cmdTags(opts map[string]interface{}, conf config.Config) {
|
||||||
// load the cheatsheets
|
// load the cheatsheets
|
||||||
cheatsheets, err := sheets.Load(conf.Cheatpaths)
|
cheatsheets, err := sheets.Load(conf.Cheatpaths)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, fmt.Sprintf("failed to list cheatsheets: %v", err))
|
fmt.Fprintf(os.Stderr, "failed to list cheatsheets: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ func cmdView(opts map[string]interface{}, conf config.Config) {
|
||||||
// load the cheatsheets
|
// load the cheatsheets
|
||||||
cheatsheets, err := sheets.Load(conf.Cheatpaths)
|
cheatsheets, err := sheets.Load(conf.Cheatpaths)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, fmt.Sprintf("failed to list cheatsheets: %v", err))
|
fmt.Fprintf(os.Stderr, "failed to list cheatsheets: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ func cmdView(opts map[string]interface{}, conf config.Config) {
|
||||||
|
|
||||||
// identify the matching cheatsheet
|
// identify the matching cheatsheet
|
||||||
out += fmt.Sprintf("%s %s\n",
|
out += fmt.Sprintf("%s %s\n",
|
||||||
display.Underline(sheet.Title),
|
sheet.Title,
|
||||||
display.Faint(fmt.Sprintf("(%s)", sheet.CheatPath), conf),
|
display.Faint(fmt.Sprintf("(%s)", sheet.CheatPath), conf),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
"github.com/cheat/cheat/internal/installer"
|
"github.com/cheat/cheat/internal/installer"
|
||||||
)
|
)
|
||||||
|
|
||||||
const version = "4.2.6"
|
const version = "4.2.7"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ func TestFilterFailure(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// filter the paths
|
// filter the paths
|
||||||
paths, err := Filter(paths, "qux")
|
_, err := Filter(paths, "qux")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("failed to return an error on non-existent cheatpath")
|
t.Errorf("failed to return an error on non-existent cheatpath")
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,12 +11,10 @@ func Writeable(cheatpaths []Cheatpath) (Cheatpath, error) {
|
||||||
// NB: we're going backwards because we assume that the most "local"
|
// NB: we're going backwards because we assume that the most "local"
|
||||||
// cheatpath will be specified last in the configs
|
// cheatpath will be specified last in the configs
|
||||||
for i := len(cheatpaths) - 1; i >= 0; i-- {
|
for i := len(cheatpaths) - 1; i >= 0; i-- {
|
||||||
|
|
||||||
// if the cheatpath is not read-only, it is writeable, and thus returned
|
// if the cheatpath is not read-only, it is writeable, and thus returned
|
||||||
if cheatpaths[i].ReadOnly == false {
|
if !cheatpaths[i].ReadOnly {
|
||||||
return cheatpaths[i], nil
|
return cheatpaths[i], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, return an error
|
// otherwise, return an error
|
||||||
|
|
|
@ -2,7 +2,6 @@ package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -29,7 +28,7 @@ type Config struct {
|
||||||
func New(opts map[string]interface{}, confPath string, resolve bool) (Config, error) {
|
func New(opts map[string]interface{}, confPath string, resolve bool) (Config, error) {
|
||||||
|
|
||||||
// read the config file
|
// read the config file
|
||||||
buf, err := ioutil.ReadFile(confPath)
|
buf, err := os.ReadFile(confPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Config{}, fmt.Errorf("could not read config file: %v", err)
|
return Config{}, fmt.Errorf("could not read config file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
@ -16,7 +15,7 @@ func Init(confpath string, configs string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// write the config file
|
// write the config file
|
||||||
if err := ioutil.WriteFile(confpath, []byte(configs), 0644); err != nil {
|
if err := os.WriteFile(confpath, []byte(configs), 0644); err != nil {
|
||||||
return fmt.Errorf("failed to create file: %v", err)
|
return fmt.Errorf("failed to create file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
@ -10,7 +9,7 @@ import (
|
||||||
func TestInit(t *testing.T) {
|
func TestInit(t *testing.T) {
|
||||||
|
|
||||||
// initialize a temporary config file
|
// initialize a temporary config file
|
||||||
confFile, err := ioutil.TempFile("", "cheat-test")
|
confFile, err := os.CreateTemp("", "cheat-test")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to create temp file: %v", err)
|
t.Errorf("failed to create temp file: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -25,7 +24,7 @@ func TestInit(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// read back the config file contents
|
// read back the config file contents
|
||||||
bytes, err := ioutil.ReadFile(confFile.Name())
|
bytes, err := os.ReadFile(confFile.Name())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to read config file: %v", err)
|
t.Errorf("failed to read config file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
@ -24,7 +23,7 @@ func TestPathConfigNotExists(t *testing.T) {
|
||||||
func TestPathConfigExists(t *testing.T) {
|
func TestPathConfigExists(t *testing.T) {
|
||||||
|
|
||||||
// initialize a temporary config file
|
// initialize a temporary config file
|
||||||
confFile, err := ioutil.TempFile("", "cheat-test")
|
confFile, err := os.CreateTemp("", "cheat-test")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to create temp file: %v", err)
|
t.Errorf("failed to create temp file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
func Faint(str string, conf config.Config) string {
|
func Faint(str string, conf config.Config) string {
|
||||||
// make `str` faint only if colorization has been requested
|
// make `str` faint only if colorization has been requested
|
||||||
if conf.Colorize {
|
if conf.Colorize {
|
||||||
return fmt.Sprintf(fmt.Sprintf("\033[2m%s\033[0m", str))
|
return fmt.Sprintf("\033[2m%s\033[0m", str)
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, return the string unmodified
|
// otherwise, return the string unmodified
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
package display
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
// Underline returns an underlined string
|
|
||||||
func Underline(str string) string {
|
|
||||||
return fmt.Sprintf(fmt.Sprintf("\033[4m%s\033[0m", str))
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
package display
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TestUnderline asserts that Underline applies underline formatting
|
|
||||||
func TestUnderline(t *testing.T) {
|
|
||||||
want := "\033[4mfoo\033[0m"
|
|
||||||
got := Underline("foo")
|
|
||||||
if want != got {
|
|
||||||
t.Errorf("failed to underline: want: %s, got: %s", want, got)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -23,15 +23,14 @@ func Write(out string, conf config.Config) {
|
||||||
pager := parts[0]
|
pager := parts[0]
|
||||||
args := parts[1:]
|
args := parts[1:]
|
||||||
|
|
||||||
// run the pager
|
// configure the pager
|
||||||
cmd := exec.Command(pager, args...)
|
cmd := exec.Command(pager, args...)
|
||||||
cmd.Stdin = strings.NewReader(out)
|
cmd.Stdin = strings.NewReader(out)
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
|
|
||||||
// handle errors
|
// run the pager and handle errors
|
||||||
err := cmd.Run()
|
if err := cmd.Run(); err != nil {
|
||||||
if err != nil {
|
fmt.Fprintf(os.Stderr, "failed to write to pager: %v\n", err)
|
||||||
fmt.Fprintln(os.Stderr, fmt.Sprintf("failed to write to pager: %v", err))
|
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ func Prompt(prompt string, def bool) (bool, error) {
|
||||||
reader := bufio.NewReader(os.Stdin)
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
|
||||||
// display the prompt
|
// display the prompt
|
||||||
fmt.Print(fmt.Sprintf("%s: ", prompt))
|
fmt.Printf("%s: ", prompt)
|
||||||
|
|
||||||
// read the answer
|
// read the answer
|
||||||
ans, err := reader.ReadString('\n')
|
ans, err := reader.ReadString('\n')
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package sheet
|
package sheet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -13,7 +12,7 @@ func TestCopyFlat(t *testing.T) {
|
||||||
|
|
||||||
// mock a cheatsheet file
|
// mock a cheatsheet file
|
||||||
text := "this is the cheatsheet text"
|
text := "this is the cheatsheet text"
|
||||||
src, err := ioutil.TempFile("", "foo-src")
|
src, err := os.CreateTemp("", "foo-src")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to mock cheatsheet: %v", err)
|
t.Errorf("failed to mock cheatsheet: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -41,7 +40,7 @@ func TestCopyFlat(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// assert that the destination file contains the correct text
|
// assert that the destination file contains the correct text
|
||||||
got, err := ioutil.ReadFile(outpath)
|
got, err := os.ReadFile(outpath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to read destination file: %v", err)
|
t.Errorf("failed to read destination file: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -60,7 +59,7 @@ func TestCopyDeep(t *testing.T) {
|
||||||
|
|
||||||
// mock a cheatsheet file
|
// mock a cheatsheet file
|
||||||
text := "this is the cheatsheet text"
|
text := "this is the cheatsheet text"
|
||||||
src, err := ioutil.TempFile("", "foo-src")
|
src, err := os.CreateTemp("", "foo-src")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to mock cheatsheet: %v", err)
|
t.Errorf("failed to mock cheatsheet: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -94,7 +93,7 @@ func TestCopyDeep(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// assert that the destination file contains the correct text
|
// assert that the destination file contains the correct text
|
||||||
got, err := ioutil.ReadFile(outpath)
|
got, err := os.ReadFile(outpath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to read destination file: %v", err)
|
t.Errorf("failed to read destination file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package sheet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/cheat/cheat/internal/frontmatter"
|
"github.com/cheat/cheat/internal/frontmatter"
|
||||||
|
@ -29,7 +29,7 @@ func New(
|
||||||
) (Sheet, error) {
|
) (Sheet, error) {
|
||||||
|
|
||||||
// read the cheatsheet file
|
// read the cheatsheet file
|
||||||
markdown, err := ioutil.ReadFile(path)
|
markdown, err := os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Sheet{}, fmt.Errorf("failed to read file: %s, %v", path, err)
|
return Sheet{}, fmt.Errorf("failed to read file: %s, %v", path, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package sheets
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -55,7 +56,11 @@ func Load(cheatpaths []cp.Cheatpath) ([]map[string]sheet.Sheet, error) {
|
||||||
// contained within hidden directories in the middle of a path, though
|
// contained within hidden directories in the middle of a path, though
|
||||||
// that should not realistically occur.
|
// that should not realistically occur.
|
||||||
if strings.HasPrefix(title, ".") || strings.HasPrefix(info.Name(), ".") {
|
if strings.HasPrefix(title, ".") || strings.HasPrefix(info.Name(), ".") {
|
||||||
return nil
|
// Do not walk hidden directories. This is important,
|
||||||
|
// because it's common for cheatsheets to be stored in
|
||||||
|
// version-control, and a `.git` directory can easily
|
||||||
|
// contain thousands of files.
|
||||||
|
return fs.SkipDir
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse the cheatsheet file into a `sheet` struct
|
// parse the cheatsheet file into a `sheet` struct
|
||||||
|
|
Loading…
Reference in New Issue