mirror of
				https://github.com/cheat/cheat.git
				synced 2025-11-04 07:45:28 +01:00 
			
		
		
		
	feat: implements --tags
Implements `--tags`, which lists all tags in use.
This commit is contained in:
		
							
								
								
									
										25
									
								
								cmd/cheat/cmd_tags.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								cmd/cheat/cmd_tags.go
									
									
									
									
									
										Normal file
									
								
							@@ -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)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -11,6 +11,7 @@ Options:
 | 
			
		||||
  -r --regex            Treat search <phrase> as a regex
 | 
			
		||||
  -s --search=<phrase>  Search cheatsheets for <phrase>
 | 
			
		||||
  -t --tag=<tag>        Return only sheets matching <tag>
 | 
			
		||||
  -T --tags             List all tags in use
 | 
			
		||||
  -v --version          Print the version number
 | 
			
		||||
 | 
			
		||||
Examples:
 | 
			
		||||
@@ -33,6 +34,9 @@ Examples:
 | 
			
		||||
  To list all available cheatsheets:
 | 
			
		||||
    cheat -l
 | 
			
		||||
 | 
			
		||||
  To list all tags in use:
 | 
			
		||||
    cheat -T
 | 
			
		||||
 | 
			
		||||
  To list available cheatsheets that are tagged as "personal":
 | 
			
		||||
    cheat -l -t personal
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -76,6 +76,9 @@ func main() {
 | 
			
		||||
	case opts["--list"].(bool):
 | 
			
		||||
		cmd = cmdList
 | 
			
		||||
 | 
			
		||||
	case opts["--tags"].(bool):
 | 
			
		||||
		cmd = cmdTags
 | 
			
		||||
 | 
			
		||||
	case opts["--search"] != nil:
 | 
			
		||||
		cmd = cmdSearch
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@ Options:
 | 
			
		||||
  -r --regex            Treat search <phrase> as a regex
 | 
			
		||||
  -s --search=<phrase>  Search cheatsheets for <phrase>
 | 
			
		||||
  -t --tag=<tag>        Return only sheets matching <tag>
 | 
			
		||||
  -T --tags             List all tags in use
 | 
			
		||||
  -v --version          Print the version number
 | 
			
		||||
 | 
			
		||||
Examples:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								internal/sheets/tags.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								internal/sheets/tags.go
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										51
									
								
								internal/sheets/tags_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								internal/sheets/tags_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -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),
 | 
			
		||||
		)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user