mirror of https://github.com/cheat/cheat.git
commit
573d43a7e6
|
@ -0,0 +1,55 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/cheat/cheat/internal/config"
|
||||||
|
"github.com/cheat/cheat/internal/sheets"
|
||||||
|
)
|
||||||
|
|
||||||
|
// cmdRemove opens a cheatsheet for editing (or creates it if it doesn't exist).
|
||||||
|
func cmdRemove(opts map[string]interface{}, conf config.Config) {
|
||||||
|
|
||||||
|
cheatsheet := opts["--rm"].(string)
|
||||||
|
|
||||||
|
// load the cheatsheets
|
||||||
|
cheatsheets, err := sheets.Load(conf.Cheatpaths)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, fmt.Sprintf("failed to list cheatsheets: %v", err))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// filter cheatcheats by tag if --tag was provided
|
||||||
|
if opts["--tag"] != nil {
|
||||||
|
cheatsheets = sheets.Filter(
|
||||||
|
cheatsheets,
|
||||||
|
strings.Split(opts["--tag"].(string), ","),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// consolidate the cheatsheets found on all paths into a single map of
|
||||||
|
// `title` => `sheet` (ie, allow more local cheatsheets to override less
|
||||||
|
// local cheatsheets)
|
||||||
|
consolidated := sheets.Consolidate(cheatsheets)
|
||||||
|
|
||||||
|
// fail early if the requested cheatsheet does not exist
|
||||||
|
sheet, ok := consolidated[cheatsheet]
|
||||||
|
if !ok {
|
||||||
|
fmt.Fprintln(os.Stderr, fmt.Sprintf("no cheatsheet found for '%s'.\n", cheatsheet))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// fail early if the sheet is read-only
|
||||||
|
if sheet.ReadOnly {
|
||||||
|
fmt.Fprintln(os.Stderr, fmt.Sprintf("cheatsheet '%s' is read-only.", cheatsheet))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise, attempt to delete the sheet
|
||||||
|
if err := os.Remove(sheet.Path); err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, fmt.Sprintf("failed to delete sheet: %s, %v", sheet.Title, err))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
|
@ -55,7 +55,7 @@ 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.Errorf("failed to compile regexp: %s, %v", pattern, err)
|
fmt.Fprintln(os.Stderr, fmt.Sprintf("failed to compile regexp: %s, %v", pattern, err))
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/cheat/cheat/internal/config"
|
||||||
|
"github.com/cheat/cheat/internal/sheets"
|
||||||
|
)
|
||||||
|
|
||||||
|
// cmdTags lists all tags in use.
|
||||||
|
func cmdTags(opts map[string]interface{}, conf config.Config) {
|
||||||
|
|
||||||
|
// load the cheatsheets
|
||||||
|
cheatsheets, err := sheets.Load(conf.Cheatpaths)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, fmt.Sprintf("failed to list cheatsheets: %v", err))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// write sheet tags to stdout
|
||||||
|
for _, tag := range sheets.Tags(cheatsheets) {
|
||||||
|
fmt.Println(tag)
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,13 +5,15 @@ Options:
|
||||||
--init Write a default config file to stdout
|
--init Write a default config file to stdout
|
||||||
-c --colorize Colorize output
|
-c --colorize Colorize output
|
||||||
-d --directories List cheatsheet directories
|
-d --directories List cheatsheet directories
|
||||||
-e --edit=<sheet> Edit cheatsheet
|
-e --edit=<sheet> Edit <sheet>
|
||||||
-l --list List cheatsheets
|
-l --list List cheatsheets
|
||||||
-p --path=<name> Return only sheets found on path <name>
|
-p --path=<name> Return only sheets found on path <name>
|
||||||
-r --regex Treat search <phrase> as a regex
|
-r --regex Treat search <phrase> as a regex
|
||||||
-s --search=<phrase> Search cheatsheets for <phrase>
|
-s --search=<phrase> Search cheatsheets for <phrase>
|
||||||
-t --tag=<tag> Return only sheets matching <tag>
|
-t --tag=<tag> Return only sheets matching <tag>
|
||||||
|
-T --tags List all tags in use
|
||||||
-v --version Print the version number
|
-v --version Print the version number
|
||||||
|
--rm=<sheet> Remove (delete) <sheet>
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
|
@ -33,6 +35,9 @@ Examples:
|
||||||
To list all available cheatsheets:
|
To list all available cheatsheets:
|
||||||
cheat -l
|
cheat -l
|
||||||
|
|
||||||
|
To list all tags in use:
|
||||||
|
cheat -T
|
||||||
|
|
||||||
To list available cheatsheets that are tagged as "personal":
|
To list available cheatsheets that are tagged as "personal":
|
||||||
cheat -l -t personal
|
cheat -l -t personal
|
||||||
|
|
||||||
|
@ -41,3 +46,6 @@ Examples:
|
||||||
|
|
||||||
To search (by regex) for cheatsheets that contain an IP address:
|
To search (by regex) for cheatsheets that contain an IP address:
|
||||||
cheat -c -r -s '(?:[0-9]{1,3}\.){3}[0-9]{1,3}'
|
cheat -c -r -s '(?:[0-9]{1,3}\.){3}[0-9]{1,3}'
|
||||||
|
|
||||||
|
To remove (delete) the foo/bar cheatsheet:
|
||||||
|
cheat --rm foo/bar
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
"github.com/cheat/cheat/internal/config"
|
"github.com/cheat/cheat/internal/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
const version = "3.0.7"
|
const version = "3.1.0"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
|
@ -76,9 +76,15 @@ func main() {
|
||||||
case opts["--list"].(bool):
|
case opts["--list"].(bool):
|
||||||
cmd = cmdList
|
cmd = cmdList
|
||||||
|
|
||||||
|
case opts["--tags"].(bool):
|
||||||
|
cmd = cmdTags
|
||||||
|
|
||||||
case opts["--search"] != nil:
|
case opts["--search"] != nil:
|
||||||
cmd = cmdSearch
|
cmd = cmdSearch
|
||||||
|
|
||||||
|
case opts["--rm"] != nil:
|
||||||
|
cmd = cmdRemove
|
||||||
|
|
||||||
case opts["<cheatsheet>"] != nil:
|
case opts["<cheatsheet>"] != nil:
|
||||||
cmd = cmdView
|
cmd = cmdView
|
||||||
|
|
||||||
|
|
|
@ -14,13 +14,15 @@ Options:
|
||||||
--init Write a default config file to stdout
|
--init Write a default config file to stdout
|
||||||
-c --colorize Colorize output
|
-c --colorize Colorize output
|
||||||
-d --directories List cheatsheet directories
|
-d --directories List cheatsheet directories
|
||||||
-e --edit=<sheet> Edit cheatsheet
|
-e --edit=<sheet> Edit <sheet>
|
||||||
-l --list List cheatsheets
|
-l --list List cheatsheets
|
||||||
-p --path=<name> Return only sheets found on path <name>
|
-p --path=<name> Return only sheets found on path <name>
|
||||||
-r --regex Treat search <phrase> as a regex
|
-r --regex Treat search <phrase> as a regex
|
||||||
-s --search=<phrase> Search cheatsheets for <phrase>
|
-s --search=<phrase> Search cheatsheets for <phrase>
|
||||||
-t --tag=<tag> Return only sheets matching <tag>
|
-t --tag=<tag> Return only sheets matching <tag>
|
||||||
|
-T --tags List all tags in use
|
||||||
-v --version Print the version number
|
-v --version Print the version number
|
||||||
|
--rm=<sheet> Remove (delete) <sheet>
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
|
@ -42,6 +44,9 @@ Examples:
|
||||||
To list all available cheatsheets:
|
To list all available cheatsheets:
|
||||||
cheat -l
|
cheat -l
|
||||||
|
|
||||||
|
To list all tags in use:
|
||||||
|
cheat -T
|
||||||
|
|
||||||
To list available cheatsheets that are tagged as "personal":
|
To list available cheatsheets that are tagged as "personal":
|
||||||
cheat -l -t personal
|
cheat -l -t personal
|
||||||
|
|
||||||
|
@ -50,5 +55,8 @@ Examples:
|
||||||
|
|
||||||
To search (by regex) for cheatsheets that contain an IP address:
|
To search (by regex) for cheatsheets that contain an IP address:
|
||||||
cheat -c -r -s '(?:[0-9]{1,3}\.){3}[0-9]{1,3}'
|
cheat -c -r -s '(?:[0-9]{1,3}\.){3}[0-9]{1,3}'
|
||||||
|
|
||||||
|
To remove (delete) the foo/bar cheatsheet:
|
||||||
|
cheat --rm foo/bar
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package sheets
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/cheat/cheat/internal/sheet"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Tags returns a slice of all tags in use in any sheet
|
||||||
|
func Tags(cheatpaths []map[string]sheet.Sheet) []string {
|
||||||
|
|
||||||
|
// create a map of all tags in use in any sheet
|
||||||
|
tags := make(map[string]bool)
|
||||||
|
|
||||||
|
// iterate over all tags on all sheets on all cheatpaths
|
||||||
|
for _, path := range cheatpaths {
|
||||||
|
for _, sheet := range path {
|
||||||
|
for _, tag := range sheet.Tags {
|
||||||
|
tags[tag] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// restructure the map into a slice
|
||||||
|
sorted := []string{}
|
||||||
|
for tag := range tags {
|
||||||
|
sorted = append(sorted, tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort the slice
|
||||||
|
sort.Slice(sorted, func(i, j int) bool {
|
||||||
|
return sorted[i] < sorted[j]
|
||||||
|
})
|
||||||
|
|
||||||
|
return sorted
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package sheets
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
|
||||||
|
"github.com/cheat/cheat/internal/sheet"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestTags asserts that cheetsheet tags are properly returned
|
||||||
|
func TestTags(t *testing.T) {
|
||||||
|
|
||||||
|
// mock cheatsheets available on multiple cheatpaths
|
||||||
|
cheatpaths := []map[string]sheet.Sheet{
|
||||||
|
|
||||||
|
// mock community cheatsheets
|
||||||
|
map[string]sheet.Sheet{
|
||||||
|
"foo": sheet.Sheet{Title: "foo", Tags: []string{"alpha"}},
|
||||||
|
"bar": sheet.Sheet{Title: "bar", Tags: []string{"alpha", "bravo"}},
|
||||||
|
},
|
||||||
|
|
||||||
|
// mock local cheatsheets
|
||||||
|
map[string]sheet.Sheet{
|
||||||
|
"bar": sheet.Sheet{Title: "bar", Tags: []string{"bravo", "charlie"}},
|
||||||
|
"baz": sheet.Sheet{Title: "baz", Tags: []string{"delta"}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// consolidate the cheatsheets
|
||||||
|
tags := Tags(cheatpaths)
|
||||||
|
|
||||||
|
// specify the expected output
|
||||||
|
want := []string{
|
||||||
|
"alpha",
|
||||||
|
"bravo",
|
||||||
|
"charlie",
|
||||||
|
"delta",
|
||||||
|
}
|
||||||
|
|
||||||
|
// assert that the cheatsheets properly consolidated
|
||||||
|
if !reflect.DeepEqual(tags, want) {
|
||||||
|
t.Errorf(
|
||||||
|
"failed to return tags: want:\n%s, got:\n%s",
|
||||||
|
spew.Sdump(want),
|
||||||
|
spew.Sdump(tags),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue