mirror of
https://github.com/cheat/cheat.git
synced 2026-03-07 03:03:32 +01:00
Merge branch 'brief-list-flag'
This commit is contained in:
@@ -70,6 +70,12 @@ To list all available cheatsheets:
|
|||||||
cheat -l
|
cheat -l
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To briefly list all cheatsheets (names and tags only):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cheat -b
|
||||||
|
```
|
||||||
|
|
||||||
To list all cheatsheets that are tagged with "networking":
|
To list all cheatsheets that are tagged with "networking":
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
|||||||
128
cmd/cheat/brief_integration_test.go
Normal file
128
cmd/cheat/brief_integration_test.go
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestBriefFlagIntegration exercises the -b/--brief flag end-to-end.
|
||||||
|
func TestBriefFlagIntegration(t *testing.T) {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
t.Skip("integration test uses Unix-specific env vars")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the cheat binary once for all sub-tests.
|
||||||
|
binPath := filepath.Join(t.TempDir(), "cheat_test")
|
||||||
|
build := exec.Command("go", "build", "-o", binPath, ".")
|
||||||
|
if output, err := build.CombinedOutput(); err != nil {
|
||||||
|
t.Fatalf("failed to build cheat: %v\nOutput: %s", err, output)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up a temp environment with some cheatsheets.
|
||||||
|
root := t.TempDir()
|
||||||
|
sheetsDir := filepath.Join(root, "sheets")
|
||||||
|
os.MkdirAll(sheetsDir, 0755)
|
||||||
|
|
||||||
|
os.WriteFile(
|
||||||
|
filepath.Join(sheetsDir, "tar"),
|
||||||
|
[]byte("---\nsyntax: bash\ntags: [ compression ]\n---\ntar xf archive.tar\n"),
|
||||||
|
0644,
|
||||||
|
)
|
||||||
|
os.WriteFile(
|
||||||
|
filepath.Join(sheetsDir, "curl"),
|
||||||
|
[]byte("---\nsyntax: bash\ntags: [ networking, http ]\n---\ncurl https://example.com\n"),
|
||||||
|
0644,
|
||||||
|
)
|
||||||
|
|
||||||
|
confPath := filepath.Join(root, "conf.yml")
|
||||||
|
conf := fmt.Sprintf("---\neditor: vi\ncolorize: false\ncheatpaths:\n - name: test\n path: %s\n readonly: true\n", sheetsDir)
|
||||||
|
os.WriteFile(confPath, []byte(conf), 0644)
|
||||||
|
|
||||||
|
env := []string{
|
||||||
|
"CHEAT_CONFIG_PATH=" + confPath,
|
||||||
|
"HOME=" + root,
|
||||||
|
"PATH=" + os.Getenv("PATH"),
|
||||||
|
"EDITOR=vi",
|
||||||
|
}
|
||||||
|
|
||||||
|
run := func(t *testing.T, args ...string) string {
|
||||||
|
t.Helper()
|
||||||
|
cmd := exec.Command(binPath, args...)
|
||||||
|
cmd.Dir = root
|
||||||
|
cmd.Env = env
|
||||||
|
output, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("cheat %v failed: %v\nOutput: %s", args, err, output)
|
||||||
|
}
|
||||||
|
return string(output)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("brief output omits file path column", func(t *testing.T) {
|
||||||
|
output := run(t, "-b")
|
||||||
|
lines := strings.Split(strings.TrimSpace(output), "\n")
|
||||||
|
|
||||||
|
// Header should have title and tags but not file
|
||||||
|
if !strings.Contains(lines[0], "title:") {
|
||||||
|
t.Errorf("expected title: in header, got: %s", lines[0])
|
||||||
|
}
|
||||||
|
if !strings.Contains(lines[0], "tags:") {
|
||||||
|
t.Errorf("expected tags: in header, got: %s", lines[0])
|
||||||
|
}
|
||||||
|
if strings.Contains(lines[0], "file:") {
|
||||||
|
t.Errorf("brief output should not contain file: column, got: %s", lines[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Data lines should not contain the sheets directory path
|
||||||
|
for _, line := range lines[1:] {
|
||||||
|
if strings.Contains(line, sheetsDir) {
|
||||||
|
t.Errorf("brief output should not contain file paths, got: %s", line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("list output still includes file path column", func(t *testing.T) {
|
||||||
|
output := run(t, "-l")
|
||||||
|
lines := strings.Split(strings.TrimSpace(output), "\n")
|
||||||
|
|
||||||
|
if !strings.Contains(lines[0], "file:") {
|
||||||
|
t.Errorf("list output should contain file: column, got: %s", lines[0])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("brief with filter works", func(t *testing.T) {
|
||||||
|
output := run(t, "-b", "tar")
|
||||||
|
if !strings.Contains(output, "tar") {
|
||||||
|
t.Errorf("expected tar in output, got: %s", output)
|
||||||
|
}
|
||||||
|
if strings.Contains(output, "curl") {
|
||||||
|
t.Errorf("filter should exclude curl, got: %s", output)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("combined -lb works identically to -b", func(t *testing.T) {
|
||||||
|
briefOnly := run(t, "-b", "tar")
|
||||||
|
combined := run(t, "-lb", "tar")
|
||||||
|
if briefOnly != combined {
|
||||||
|
t.Errorf("-b and -lb should produce identical output\n-b:\n%s\n-lb:\n%s", briefOnly, combined)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("brief with tag filter works", func(t *testing.T) {
|
||||||
|
output := run(t, "-b", "-t", "networking")
|
||||||
|
if !strings.Contains(output, "curl") {
|
||||||
|
t.Errorf("expected curl in tag-filtered output, got: %s", output)
|
||||||
|
}
|
||||||
|
if strings.Contains(output, "tar") {
|
||||||
|
// tar is tagged "compression", not "networking"
|
||||||
|
t.Errorf("tag filter should exclude tar, got: %s", output)
|
||||||
|
}
|
||||||
|
if strings.Contains(output, "file:") {
|
||||||
|
t.Errorf("brief output should not contain file: column, got: %s", output)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -87,13 +87,18 @@ func cmdList(opts map[string]interface{}, conf config.Config) {
|
|||||||
var out bytes.Buffer
|
var out bytes.Buffer
|
||||||
w := tabwriter.NewWriter(&out, 0, 0, 1, ' ', 0)
|
w := tabwriter.NewWriter(&out, 0, 0, 1, ' ', 0)
|
||||||
|
|
||||||
// write a header row
|
|
||||||
fmt.Fprintln(w, "title:\tfile:\ttags:")
|
|
||||||
|
|
||||||
// generate sorted, columnized output
|
// generate sorted, columnized output
|
||||||
|
if opts["--brief"].(bool) {
|
||||||
|
fmt.Fprintln(w, "title:\ttags:")
|
||||||
|
for _, sheet := range flattened {
|
||||||
|
fmt.Fprintf(w, "%s\t%s\n", sheet.Title, strings.Join(sheet.Tags, ","))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Fprintln(w, "title:\tfile:\ttags:")
|
||||||
for _, sheet := range flattened {
|
for _, sheet := range flattened {
|
||||||
fmt.Fprintf(w, "%s\t%s\t%s\n", sheet.Title, sheet.Path, strings.Join(sheet.Tags, ","))
|
fmt.Fprintf(w, "%s\t%s\t%s\n", sheet.Title, sheet.Path, strings.Join(sheet.Tags, ","))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// write columnized output to stdout
|
// write columnized output to stdout
|
||||||
w.Flush()
|
w.Flush()
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ func main() {
|
|||||||
case opts["--edit"] != nil:
|
case opts["--edit"] != nil:
|
||||||
cmd = cmdEdit
|
cmd = cmdEdit
|
||||||
|
|
||||||
case opts["--list"].(bool):
|
case opts["--list"].(bool), opts["--brief"].(bool):
|
||||||
cmd = cmdList
|
cmd = cmdList
|
||||||
|
|
||||||
case opts["--tags"].(bool):
|
case opts["--tags"].(bool):
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ func usage() string {
|
|||||||
Options:
|
Options:
|
||||||
--init Write a default config file to stdout
|
--init Write a default config file to stdout
|
||||||
-a --all Search among all cheatpaths
|
-a --all Search among all cheatpaths
|
||||||
|
-b --brief List cheatsheets without file paths
|
||||||
-c --colorize Colorize output
|
-c --colorize Colorize output
|
||||||
-d --directories List cheatsheet directories
|
-d --directories List cheatsheet directories
|
||||||
-e --edit=<cheatsheet> Edit <cheatsheet>
|
-e --edit=<cheatsheet> Edit <cheatsheet>
|
||||||
@@ -41,8 +42,8 @@ Examples:
|
|||||||
To list all available cheatsheets:
|
To list all available cheatsheets:
|
||||||
cheat -l
|
cheat -l
|
||||||
|
|
||||||
To list all cheatsheets whose titles match "apt":
|
To briefly list all cheatsheets whose titles match "apt":
|
||||||
cheat -l apt
|
cheat -b apt
|
||||||
|
|
||||||
To list all tags in use:
|
To list all tags in use:
|
||||||
cheat -T
|
cheat -T
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ Display the config file path.
|
|||||||
\-a, \[en]all
|
\-a, \[en]all
|
||||||
Search among all cheatpaths.
|
Search among all cheatpaths.
|
||||||
.TP
|
.TP
|
||||||
|
\-b, \[en]brief
|
||||||
|
List cheatsheets without file paths.
|
||||||
|
.TP
|
||||||
\-c, \[en]colorize
|
\-c, \[en]colorize
|
||||||
Colorize output.
|
Colorize output.
|
||||||
.TP
|
.TP
|
||||||
@@ -72,8 +75,8 @@ cheat \-d
|
|||||||
To list all available cheatsheets:
|
To list all available cheatsheets:
|
||||||
cheat \-l
|
cheat \-l
|
||||||
.TP
|
.TP
|
||||||
To list all cheatsheets whose titles match `apt':
|
To briefly list all cheatsheets whose titles match `apt':
|
||||||
cheat \-l \f[I]apt\f[R]
|
cheat \-b \f[I]apt\f[R]
|
||||||
.TP
|
.TP
|
||||||
To list all tags in use:
|
To list all tags in use:
|
||||||
cheat \-T
|
cheat \-T
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ OPTIONS
|
|||||||
-a, --all
|
-a, --all
|
||||||
: Search among all cheatpaths.
|
: Search among all cheatpaths.
|
||||||
|
|
||||||
|
-b, --brief
|
||||||
|
: List cheatsheets without file paths.
|
||||||
|
|
||||||
-c, --colorize
|
-c, --colorize
|
||||||
: Colorize output.
|
: Colorize output.
|
||||||
|
|
||||||
@@ -81,8 +84,8 @@ To view all cheatsheet directories:
|
|||||||
To list all available cheatsheets:
|
To list all available cheatsheets:
|
||||||
: cheat -l
|
: cheat -l
|
||||||
|
|
||||||
To list all cheatsheets whose titles match 'apt':
|
To briefly list all cheatsheets whose titles match 'apt':
|
||||||
: cheat -l _apt_
|
: cheat -b _apt_
|
||||||
|
|
||||||
To list all tags in use:
|
To list all tags in use:
|
||||||
: cheat -T
|
: cheat -T
|
||||||
|
|||||||
Reference in New Issue
Block a user