1
0
mirror of https://github.com/ddworken/hishtory.git synced 2025-03-29 09:08:28 +01:00

Add basic support for stripping out HISTTIMEFORMAT prefixes

This commit is contained in:
David Dworken 2022-06-12 21:28:19 -07:00
parent 3f32891469
commit e8f001c78b
4 changed files with 119 additions and 1 deletions

View File

@ -125,6 +125,7 @@ func TestParameterized(t *testing.T) {
t.Run("testInstallViaPythonScript/"+tester.ShellName(), func(t *testing.T) { testInstallViaPythonScript(t, tester) })
t.Run("testExportWithQuery/"+tester.ShellName(), func(t *testing.T) { testExportWithQuery(t, tester) })
t.Run("testHelpCommand/"+tester.ShellName(), func(t *testing.T) { testHelpCommand(t, tester) })
t.Run("testStripBashTimePrefix/"+tester.ShellName(), func(t *testing.T) { testStripBashTimePrefix(t, tester) })
}
}
@ -1142,4 +1143,64 @@ func testHelpCommand(t *testing.T, tester shellTester) {
}
}
func testStripBashTimePrefix(t *testing.T, tester shellTester) {
if tester.ShellName() != "bash" {
t.Skip()
}
// Setup
defer shared.BackupAndRestore(t)()
installHishtory(t, tester, "")
// Add a HISTTIMEFORMAT to the bashrc
homedir, err := os.UserHomeDir()
if err != nil {
t.Fatal(err)
}
f, err := os.OpenFile(path.Join(homedir, ".hishtory", "config.sh"),
os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
t.Fatal(err)
}
defer f.Close()
_, err = f.WriteString("\nexport HISTTIMEFORMAT='%F %T '\n")
if err != nil {
t.Fatal(err)
}
// Record a command
tester.RunInteractiveShell(t, `ls -Slah`)
// Check it shows up correctly
out := tester.RunInteractiveShell(t, "hishtory export ls")
if out != "ls -Slah\n" {
t.Fatalf("hishtory had unexpected output=%#v", out)
}
// Update it to another complex one
homedir, err = os.UserHomeDir()
if err != nil {
t.Fatal(err)
}
f, err = os.OpenFile(path.Join(homedir, ".hishtory", "config.sh"),
os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
t.Fatal(err)
}
defer f.Close()
_, err = f.WriteString("\nexport HISTTIMEFORMAT='[%c] '\n")
if err != nil {
t.Fatal(err)
}
// Record a command
tester.RunInteractiveShell(t, `echo foo`)
// Check it shows up correctly
out = tester.RunInteractiveShell(t, "hishtory export echo")
if out != "echo foo\n" {
t.Fatalf("hishtory had unexpected output=%#v", out)
}
}
// TODO: write a test that runs hishtroy export | grep -v pipefail and then see if that shows up in query/export, I think there is weird behavior here

View File

@ -121,7 +121,7 @@ func BuildHistoryEntry(args []string) (*data.HistoryEntry, error) {
// Don't save commands that start with a space
return nil, nil
}
entry.Command = cmd
entry.Command = maybeSkipBashHistTimePrefix(cmd)
} else if shell == "zsh" {
cmd := strings.TrimSuffix(strings.TrimSuffix(args[4], "\n"), " ")
if strings.HasPrefix(cmd, " ") {
@ -150,6 +150,23 @@ func BuildHistoryEntry(args []string) (*data.HistoryEntry, error) {
return &entry, nil
}
func maybeSkipBashHistTimePrefix(cmdLine string) string {
format := os.Getenv("HISTTIMEFORMAT")
if format == "" {
return cmdLine
}
if !strings.HasSuffix(format, " ") {
GetLogger().Printf("bash has HISTTIMEFORMAT set, but it doesn't end in a space so we can't strip the timestamp")
return cmdLine
}
// TODO: could we handle things like `export HISTTIMEFORMAT='%c:'`?
numSpaces := strings.Count(format, " ")
numC := strings.Count(format, "%c")
numSpaces += (4 * numC)
split := strings.SplitN(cmdLine, " ", numSpaces+1)
return split[len(split)-1]
}
func parseCrossPlatformInt(data string) (int64, error) {
data = strings.TrimSuffix(data, "N")
return strconv.ParseInt(data, 10, 64)

View File

@ -190,3 +190,36 @@ func TestParseCrossPlatformInt(t *testing.T) {
t.Fatalf("failed to parse cross platform int %d", res)
}
}
func TestMaybeSkipBashHistTimePrefix(t *testing.T) {
defer shared.BackupAndRestoreEnv("HISTTIMEFORMAT")()
testcases := []struct {
env, cmdLine, expected string
}{
{"%F %T ", "2019-07-12 13:02:31 sudo apt update", "sudo apt update"},
{"%F %T ", "2019-07-12 13:02:31 ls a b", "ls a b"},
{"%F %T ", "2019-07-12 13:02:31 ls a ", "ls a "},
{"%F %T ", "2019-07-12 13:02:31 ls a", "ls a"},
{"%F %T ", "2019-07-12 13:02:31 ls", "ls"},
{"%F %T ", "2019-07-12 13:02:31 ls -Slah", "ls -Slah"},
{"%F ", "2019-07-12 ls -Slah", "ls -Slah"},
{"%F ", "2019-07-12 ls -Slah", "ls -Slah"},
{"", "ls -Slah", "ls -Slah"},
{"[%F %T] ", "[2019-07-12 13:02:31] sudo apt update", "sudo apt update"},
{"[%F a %T] ", "[2019-07-12 a 13:02:31] sudo apt update", "sudo apt update"},
{"aaa ", "aaa sudo apt update", "sudo apt update"},
{"%c ", "Sun Aug 19 02:56:02 2012 sudo apt update", "sudo apt update"},
{"%c ", "Sun Aug 19 02:56:02 2012 ls", "ls"},
{"[%c] ", "[Sun Aug 19 02:56:02 2012] ls", "ls"},
{"[%c %t] ", "[Sun Aug 19 02:56:02 2012 aaaa] ls", "ls"},
{"[%c %t] ", "[Sun Aug 19 02:56:02 2012 aaaa] ls -Slah", "ls -Slah"},
}
for _, tc := range testcases {
os.Setenv("HISTTIMEFORMAT", tc.env)
if stripped := maybeSkipBashHistTimePrefix(tc.cmdLine); stripped != tc.expected {
t.Fatalf("skipping the time prefix returned %#v (expected=%#v for %#v)", stripped, tc.expected, tc.cmdLine)
}
}
}

View File

@ -61,6 +61,13 @@ func BackupAndRestoreWithId(t *testing.T, id string) func() {
}
}
func BackupAndRestoreEnv(k string) func() {
origValue := os.Getenv(k)
return func() {
os.Setenv(k, origValue)
}
}
func checkError(err error) {
if err != nil && os.Getenv("GITHUB_ACTION") == "" {
_, filename, line, _ := runtime.Caller(1)