first bit of advanced query support

This commit is contained in:
David Dworken 2022-04-07 22:53:39 -07:00
parent 475497d7b7
commit 6d84402bce
4 changed files with 77 additions and 30 deletions

View File

@ -4,6 +4,9 @@ test:
build-binary: build-binary:
go build -trimpath -o web/landing/www/binaries/hishtory-linux -ldflags "-X main.GitCommit=`git rev-list -1 HEAD`" client/client.go go build -trimpath -o web/landing/www/binaries/hishtory-linux -ldflags "-X main.GitCommit=`git rev-list -1 HEAD`" client/client.go
install: build-binary
web/landing/www/binaries/hishtory-linux install
build-static: build-binary build-static: build-binary
docker build -t gcr.io/dworken-k8s/hishtory-static -f web/caddy/Dockerfile . docker build -t gcr.io/dworken-k8s/hishtory-static -f web/caddy/Dockerfile .
@ -19,3 +22,4 @@ deploy-api: build-api
kubectl patch deployment hishtory-api -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"ts\":\"`date|sed -e 's/ /_/g'|sed -e 's/:/-/g'`\"}}}}}}" kubectl patch deployment hishtory-api -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"ts\":\"`date|sed -e 's/ /_/g'|sed -e 's/:/-/g'`\"}}}}}}"
deploy: deploy-static deploy-api deploy: deploy-static deploy-api

View File

@ -24,7 +24,7 @@ func RunInteractiveBashCommands(t *testing.T, script string) string {
cmd.Stdout = &out cmd.Stdout = &out
var err bytes.Buffer var err bytes.Buffer
cmd.Stderr = &err cmd.Stderr = &err
shared.CheckWithInfo(t, cmd.Run(), out.String()+err.String()) shared.CheckWithInfo(t, cmd.Run(), fmt.Sprintf("out=%#v, err=%#v", out.String(), err.String()))
outStr := out.String() outStr := out.String()
if strings.Contains(outStr, "hishtory fatal error:") { if strings.Contains(outStr, "hishtory fatal error:") {
t.Fatalf("Ran command, but hishtory had a fatal error! out=%#v", outStr) t.Fatalf("Ran command, but hishtory had a fatal error! out=%#v", outStr)
@ -53,19 +53,10 @@ func TestIntegrationWithNewDevice(t *testing.T) {
shared.ResetLocalState(t) shared.ResetLocalState(t)
// Install it again // Install it again
out := RunInteractiveBashCommands(t, ` installHishtory(t, userSecret)
gvm use go1.17
cd /home/david/code/hishtory/
go build -o /tmp/client client/client.go
/tmp/client install `+userSecret)
match, err := regexp.MatchString(`Setting secret hishtory key to .*`, out)
shared.Check(t, err)
if !match {
t.Fatalf("unexpected output from install: %v", out)
}
// Querying should show the history from the previous run // Querying should show the history from the previous run
out = RunInteractiveBashCommands(t, "hishtory query") out := RunInteractiveBashCommands(t, "hishtory query")
expected := []string{"echo thisisrecorded", "hishtory enable", "echo bar", "echo foo", "ls /foo", "ls /bar", "ls /a"} expected := []string{"echo thisisrecorded", "hishtory enable", "echo bar", "echo foo", "ls /foo", "ls /bar", "ls /a"}
for _, item := range expected { for _, item := range expected {
if !strings.Contains(out, item) { if !strings.Contains(out, item) {
@ -89,16 +80,7 @@ func TestIntegrationWithNewDevice(t *testing.T) {
shared.ResetLocalState(t) shared.ResetLocalState(t)
// Install it a 3rd time // Install it a 3rd time
out = RunInteractiveBashCommands(t, ` installHishtory(t, "adifferentsecret")
gvm use go1.17
cd /home/david/code/hishtory/
go build -o /tmp/client client/client.go
/tmp/client install`)
match, err = regexp.MatchString(`Setting secret hishtory key to .*`, out)
shared.Check(t, err)
if !match {
t.Fatalf("unexpected output from install: %v", out)
}
// Run a command that shouldn't be in the hishtory later on // Run a command that shouldn't be in the hishtory later on
RunInteractiveBashCommands(t, `echo notinthehistory`) RunInteractiveBashCommands(t, `echo notinthehistory`)
@ -163,22 +145,26 @@ func TestIntegrationWithNewDevice(t *testing.T) {
} }
} }
func testIntegration(t *testing.T) string { func installHishtory(t *testing.T, userSecret string) string {
// Test install
out := RunInteractiveBashCommands(t, ` out := RunInteractiveBashCommands(t, `
gvm use go1.17 gvm use go1.17
cd /home/david/code/hishtory cd /home/david/code/hishtory
go build -o /tmp/client client/client.go go build -o /tmp/client client/client.go
/tmp/client install`) /tmp/client install `+userSecret)
r := regexp.MustCompile(`Setting secret hishtory key to (.*)`) r := regexp.MustCompile(`Setting secret hishtory key to (.*)`)
matches := r.FindStringSubmatch(out) matches := r.FindStringSubmatch(out)
if len(matches) != 2 { if len(matches) != 2 {
t.Fatalf("Failed to extract userSecret from output: matches=%#v", matches) t.Fatalf("Failed to extract userSecret from output: matches=%#v", matches)
} }
userSecret := matches[1] return matches[1]
}
func testIntegration(t *testing.T) string {
// Test install
userSecret := installHishtory(t, "")
// Test the status subcommand // Test the status subcommand
out = RunInteractiveBashCommands(t, ` out := RunInteractiveBashCommands(t, `
hishtory status hishtory status
`) `)
if out != fmt.Sprintf("Hishtory: e2e sync\nEnabled: true\nSecret Key: %s\nCommit Hash: Unknown\n", userSecret) { if out != fmt.Sprintf("Hishtory: e2e sync\nEnabled: true\nSecret Key: %s\nCommit Hash: Unknown\n", userSecret) {
@ -243,3 +229,45 @@ func testIntegration(t *testing.T) string {
return userSecret return userSecret
} }
func TestAdvancedQuery(t *testing.T) {
// Set up
defer shared.BackupAndRestore(t)()
defer shared.RunTestServer(t)()
// Install hishtory
installHishtory(t, "")
// Run some commands we can query for
RunInteractiveBashCommands(t, `
echo nevershouldappear
cd /tmp/
echo querybydir
`)
// Query based on cwd
out := RunInteractiveBashCommands(t, `hishtory query cwd:/tmp`)
if !strings.Contains(out, "echo querybydir") {
t.Fatalf("hishtory query doesn't contain result matching cwd:/tmp, out=%#v", out)
}
if strings.Contains(out, "nevershouldappear") {
t.Fatalf("hishtory query contains unexpected entry, out=%#v", out)
}
if strings.Count(out, "\n") != 3 {
t.Fatalf("hishtory query has the wrong number of lines=%d, out=%#v", strings.Count(out, "\n"), out)
}
// Query based on cwd and another term
out = RunInteractiveBashCommands(t, `hishtory query cwd:/tmp querybydir`)
if !strings.Contains(out, "echo querybydir") {
t.Fatalf("hishtory query doesn't contain result matching cwd:/tmp, out=%#v", out)
}
if strings.Contains(out, "nevershouldappear") {
t.Fatalf("hishtory query contains unexpected entry, out=%#v", out)
}
if strings.Count(out, "\n") != 2 {
t.Fatalf("hishtory query has the wrong number of lines=%d, out=%#v", strings.Count(out, "\n"), out)
}
// TODO: more tests for advanced queries
}

View File

@ -136,8 +136,22 @@ func Search(db *gorm.DB, query string, limit int) ([]*HistoryEntry, error) {
splitToken := strings.SplitN(token, ":", 2) splitToken := strings.SplitN(token, ":", 2)
field := splitToken[0] field := splitToken[0]
val := splitToken[1] val := splitToken[1]
// tx = tx.Where() switch field {
panic("TODO(ddworken): Implement better searching using " + field + val) case "username":
tx = tx.Where("local_username = ?", val)
case "hostname":
tx = tx.Where("hostname = ?", val)
case "cwd":
tx = tx.Where("instr(current_working_directory, ?) > 0", val)
case "exit_code":
tx = tx.Where("exit_code = ?", val)
case "before":
panic("TODO(ddworken): Implement before")
case "after":
panic("TODO(ddworken): Implement after")
default:
panic("TODO: probably return an error?")
}
} else if strings.HasPrefix(token, "-") { } else if strings.HasPrefix(token, "-") {
panic("TODO(ddworken): Implement -foo as filtering out foo") panic("TODO(ddworken): Implement -foo as filtering out foo")
} else { } else {

View File

@ -14,6 +14,7 @@ trap "PreCommand" DEBUG
HISHTORY_FIRST_PROMPT=1 HISHTORY_FIRST_PROMPT=1
function PostCommand() { function PostCommand() {
EXIT_CODE=$?
HISHTORY_AT_PROMPT=1 HISHTORY_AT_PROMPT=1
if [ -n "$HISHTORY_FIRST_PROMPT" ]; then if [ -n "$HISHTORY_FIRST_PROMPT" ]; then
@ -22,6 +23,6 @@ function PostCommand() {
fi fi
# Run after every prompt # Run after every prompt
(hishtory saveHistoryEntry $? "`history 1`" $HISHTORY_START_TIME &) (hishtory saveHistoryEntry $EXIT_CODE "`history 1`" $HISHTORY_START_TIME &)
} }
PROMPT_COMMAND="PostCommand" PROMPT_COMMAND="PostCommand"