Strip history entries with zsh weirdness rather than skip them + ensure the hishtory import command runs a full re-import

This commit is contained in:
David Dworken 2022-11-12 16:30:59 -08:00
parent e6fc09cc5d
commit 15abcd8d13
No known key found for this signature in database
4 changed files with 32 additions and 24 deletions

View File

@ -1474,6 +1474,8 @@ func testHishtoryOffline(t *testing.T, tester shellTester) {
} }
} }
// TODO: tests for hishtory import
func testInitialHistoryImport(t *testing.T, tester shellTester) { func testInitialHistoryImport(t *testing.T, tester shellTester) {
// Setup // Setup
defer testutils.BackupAndRestore(t)() defer testutils.BackupAndRestore(t)()

View File

@ -190,22 +190,27 @@ func buildCustomColumns(ctx *context.Context) (data.CustomColumns, error) {
return ccs, nil return ccs, nil
} }
func isZshWeirdness(cmd string) bool { func stripZshWeirdness(cmd string) string {
// Zsh has this weird behavior where the currently running command is persisted to // Zsh has this weird behavior where sometimes commands are saved in the hishtory file
// the history file with a weird prefix. This only matters to us when running // with a weird prefix. I've never been able to figure out why this happens, but we
// an import, in which case we want to just skip it. // can at least strip it.
// For example, if the running command was echo foo the command would
// show up in the history file as `: 1663823053:0;echo foo`
firstCommandBugRegex := regexp.MustCompile(`: \d+:\d;(.*)`) firstCommandBugRegex := regexp.MustCompile(`: \d+:\d;(.*)`)
matches := firstCommandBugRegex.FindStringSubmatch(cmd) matches := firstCommandBugRegex.FindStringSubmatch(cmd)
return len(matches) == 2 if len(matches) == 2 {
return matches[1]
}
return cmd
} }
func isBashWeirdness(cmd string) bool { func isBashWeirdness(cmd string) bool {
// Bash has this weird behavior where the it has entries like `#1664342754` in the // Bash has this weird behavior where the it has entries like `#1664342754` in the
// history file. We want to skip these. // history file. We want to skip these.
firstCommandBugRegex := regexp.MustCompile(`#\d+`) firstCommandBugRegex := regexp.MustCompile(`^#\d+\s+$`)
return firstCommandBugRegex.MatchString(cmd) result := firstCommandBugRegex.MatchString(cmd)
if result {
fmt.Println("BASH: " + cmd)
}
return result
} }
func buildRegexFromTimeFormat(timeFormat string) string { func buildRegexFromTimeFormat(timeFormat string) string {
@ -517,9 +522,9 @@ func CheckFatalError(err error) {
} }
} }
func ImportHistory(ctx *context.Context, shouldReadStdin bool) (int, error) { func ImportHistory(ctx *context.Context, shouldReadStdin, force bool) (int, error) {
config := hctx.GetConf(ctx) config := hctx.GetConf(ctx)
if config.HaveCompletedInitialImport { if config.HaveCompletedInitialImport && !force {
// Don't run an import if we already have run one. This avoids importing the same entry multiple times. // Don't run an import if we already have run one. This avoids importing the same entry multiple times.
return 0, nil return 0, nil
} }
@ -555,7 +560,8 @@ func ImportHistory(ctx *context.Context, shouldReadStdin bool) (int, error) {
return 0, err return 0, err
} }
for _, cmd := range historyEntries { for _, cmd := range historyEntries {
if isZshWeirdness(cmd) || isBashWeirdness(cmd) || strings.HasPrefix(cmd, " ") { cmd := stripZshWeirdness(cmd)
if isBashWeirdness(cmd) || strings.HasPrefix(cmd, " ") {
// Skip it // Skip it
continue continue
} }

View File

@ -370,17 +370,17 @@ func TestChunks(t *testing.T) {
func TestZshWeirdness(t *testing.T) { func TestZshWeirdness(t *testing.T) {
testcases := []struct { testcases := []struct {
input string input string
isWeird bool output string
}{ }{
{": 1666062975:0;bash", true}, {": 1666062975:0;bash", "bash"},
{": 16660:0;ls", true}, {": 16660:0;ls", "ls"},
{"ls", false}, {"ls", "ls"},
{"0", false}, {"0", "0"},
{"hgffddxsdsrzsz xddfgdxfdv gdfc ghcvhgfcfg vgv", false}, {"hgffddxsdsrzsz xddfgdxfdv gdfc ghcvhgfcfg vgv", "hgffddxsdsrzsz xddfgdxfdv gdfc ghcvhgfcfg vgv"},
} }
for _, tc := range testcases { for _, tc := range testcases {
actual := isZshWeirdness(tc.input) actual := stripZshWeirdness(tc.input)
if !reflect.DeepEqual(actual, tc.isWeird) { if !reflect.DeepEqual(actual, tc.output) {
t.Fatalf("weirdness failure for %#v", tc.input) t.Fatalf("weirdness failure for %#v", tc.input)
} }
} }

View File

@ -71,7 +71,7 @@ func main() {
if os.Getenv("HISHTORY_SKIP_INIT_IMPORT") == "" { if os.Getenv("HISHTORY_SKIP_INIT_IMPORT") == "" {
fmt.Println("Importing existing shell history...") fmt.Println("Importing existing shell history...")
ctx := hctx.MakeContext() ctx := hctx.MakeContext()
numImported, err := lib.ImportHistory(ctx, false) numImported, err := lib.ImportHistory(ctx, false, false)
lib.CheckFatalError(err) lib.CheckFatalError(err)
if numImported > 0 { if numImported > 0 {
fmt.Printf("Imported %v history entries from your existing shell history\n", numImported) fmt.Printf("Imported %v history entries from your existing shell history\n", numImported)
@ -87,7 +87,7 @@ func main() {
if len(data) < 10 { if len(data) < 10 {
fmt.Println("Importing existing shell history...") fmt.Println("Importing existing shell history...")
ctx := hctx.MakeContext() ctx := hctx.MakeContext()
numImported, err := lib.ImportHistory(ctx, false) numImported, err := lib.ImportHistory(ctx, false, false)
lib.CheckFatalError(err) lib.CheckFatalError(err)
if numImported > 0 { if numImported > 0 {
fmt.Printf("Imported %v history entries from your existing shell history\n", numImported) fmt.Printf("Imported %v history entries from your existing shell history\n", numImported)
@ -106,7 +106,7 @@ func main() {
lib.CheckFatalError(lib.Uninstall(hctx.MakeContext())) lib.CheckFatalError(lib.Uninstall(hctx.MakeContext()))
case "import": case "import":
ctx := hctx.MakeContext() ctx := hctx.MakeContext()
numImported, err := lib.ImportHistory(ctx, true) numImported, err := lib.ImportHistory(ctx, true, true)
lib.CheckFatalError(err) lib.CheckFatalError(err)
if numImported > 0 { if numImported > 0 {
fmt.Printf("Imported %v history entries from your existing shell history\n", numImported) fmt.Printf("Imported %v history entries from your existing shell history\n", numImported)