mirror of
https://github.com/ddworken/hishtory.git
synced 2024-11-22 08:14:02 +01:00
Add custom timestamp format as requested in the original HN thread
This commit is contained in:
parent
6f53fdd41e
commit
e72ef668ea
@ -114,6 +114,11 @@ But if you'd like to self-host the hishtory backend, you can! The backend is a s
|
||||
hiSHtory imports your existing shell history by default. If for some reason this didn't work (e.g. you had your shell history in a non-standard file), you can import it by piping it into `hishtory import` (e.g. `cat ~/.my_history | hishtory import`).
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Custom timestamp formats</summary>
|
||||
You can configure a custom timestamp format for hiSHtory via `hishtory config-set timestamp-format '2006/Jan/2 15:04'`. The timestamp format string should be in [the format used by Go's `time.Format(...)`](https://pkg.go.dev/time#Time.Format).
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Uninstalling</summary>
|
||||
If you'd like to uninstall hishtory, just run `hishtory uninstall`. Note that this deletes the SQLite DB storing your history, so consider running a `hishtory export` first.
|
||||
|
@ -2098,6 +2098,39 @@ echo bar`)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimestampFormat(t *testing.T) {
|
||||
// Setup
|
||||
tester := zshTester{}
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
userSecret := installHishtory(t, tester, "")
|
||||
|
||||
// Add some entries with fixed timestamps
|
||||
tmz, err := time.LoadLocation("America/Los_Angeles")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load timezone: %v", err)
|
||||
}
|
||||
entry1 := testutils.MakeFakeHistoryEntry("table_cmd1")
|
||||
entry1.StartTime = time.Unix(1650096186, 0).In(tmz)
|
||||
entry1.EndTime = time.Unix(1650096190, 0).In(tmz)
|
||||
manuallySubmitHistoryEntry(t, userSecret, entry1)
|
||||
entry2 := testutils.MakeFakeHistoryEntry("table_cmd2")
|
||||
entry2.StartTime = time.Unix(1650096196, 0).In(tmz)
|
||||
entry2.EndTime = time.Unix(1650096220, 0).In(tmz)
|
||||
entry2.CurrentWorkingDirectory = "~/foo/"
|
||||
entry2.ExitCode = 3
|
||||
manuallySubmitHistoryEntry(t, userSecret, entry2)
|
||||
|
||||
// Set a custom timestamp format
|
||||
tester.RunInteractiveShell(t, ` hishtory config-set timestamp-format '2006/Jan/2 15:04'`)
|
||||
|
||||
// And check that it is displayed in both the tui and the classic view
|
||||
out := hishtoryQuery(t, tester, "-pipefail")
|
||||
compareGoldens(t, out, "TestTimestampFormat-query")
|
||||
out = captureTerminalOutput(t, tester, []string{"hishtory SPACE tquery SPACE -pipefail ENTER"})
|
||||
out = strings.TrimSpace(strings.Split(out, "hishtory tquery")[1])
|
||||
compareGoldens(t, out, "TestTimestampFormat-tquery")
|
||||
}
|
||||
|
||||
func TestRemoveDuplicateRows(t *testing.T) {
|
||||
// Setup
|
||||
tester := zshTester{}
|
||||
|
@ -174,6 +174,8 @@ type ClientConfig struct {
|
||||
IsOffline bool `json:"is_offline"`
|
||||
// Whether duplicate commands should be displayed
|
||||
FilterDuplicateCommands bool `json:"filter_duplicate_commands"`
|
||||
// A format string for the timestamp
|
||||
TimestampFormat string `json:"timestamp_format"`
|
||||
}
|
||||
|
||||
type CustomColumnDefinition struct {
|
||||
@ -215,6 +217,9 @@ func GetConfig() (ClientConfig, error) {
|
||||
if config.DisplayedColumns == nil || len(config.DisplayedColumns) == 0 {
|
||||
config.DisplayedColumns = []string{"Hostname", "CWD", "Timestamp", "Runtime", "Exit Code", "Command"}
|
||||
}
|
||||
if config.TimestampFormat == "" {
|
||||
config.TimestampFormat = "Jan 2 2006 15:04:05 MST"
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
|
||||
|
3
client/lib/goldens/TestTimestampFormat-query
Normal file
3
client/lib/goldens/TestTimestampFormat-query
Normal file
@ -0,0 +1,3 @@
|
||||
Hostname CWD Timestamp Runtime Exit Code Command
|
||||
localhost ~/foo/ 2022/Apr/16 01:03 24s 3 table_cmd2
|
||||
localhost /tmp/ 2022/Apr/16 01:03 4s 2 table_cmd1
|
30
client/lib/goldens/TestTimestampFormat-tquery
Normal file
30
client/lib/goldens/TestTimestampFormat-tquery
Normal file
@ -0,0 +1,30 @@
|
||||
-pipefail
|
||||
|
||||
|
||||
|
||||
Search Query: > -pipefail
|
||||
|
||||
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Hostname CWD Timestamp Runtime Exit Code Command │
|
||||
│───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────│
|
||||
│ localhost ~/foo/ 2022/Apr/16 01:03 24s 3 table_cmd2 │
|
||||
│ localhost /tmp/ 2022/Apr/16 01:03 4s 2 table_cmd1 │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
@ -435,7 +435,7 @@ func buildTableRow(ctx *context.Context, columnNames []string, entry data.Histor
|
||||
case "CWD":
|
||||
row = append(row, entry.CurrentWorkingDirectory)
|
||||
case "Timestamp":
|
||||
row = append(row, entry.StartTime.Format("Jan 2 2006 15:04:05 MST"))
|
||||
row = append(row, entry.StartTime.Format(hctx.GetConf(ctx).TimestampFormat))
|
||||
case "Runtime":
|
||||
row = append(row, entry.EndTime.Sub(entry.StartTime).Round(time.Millisecond).String())
|
||||
case "Exit Code":
|
||||
|
@ -184,6 +184,10 @@ func main() {
|
||||
vals := os.Args[3:]
|
||||
config.DisplayedColumns = vals
|
||||
lib.CheckFatalError(hctx.SetConfig(config))
|
||||
case "timestamp-format":
|
||||
val := os.Args[3]
|
||||
config.TimestampFormat = val
|
||||
lib.CheckFatalError(hctx.SetConfig(config))
|
||||
case "custom-columns":
|
||||
log.Fatalf("Please use config-add and config-delete to interact with custom-columns")
|
||||
default:
|
||||
@ -257,7 +261,6 @@ func main() {
|
||||
default:
|
||||
log.Fatalf("Unrecognized config key: %s", key)
|
||||
}
|
||||
|
||||
case "reupload":
|
||||
// Purposefully undocumented since this command is generally not necessary to run
|
||||
lib.CheckFatalError(lib.Reupload(hctx.MakeContext()))
|
||||
@ -476,6 +479,3 @@ func export(ctx *context.Context, query string) {
|
||||
}
|
||||
|
||||
// TODO(feature): Add a session_id column that corresponds to the shell session the command was run in
|
||||
|
||||
// TODO: add a config option for timestamp formatting
|
||||
// TODO: handle control-c in the TUI
|
||||
|
Loading…
Reference in New Issue
Block a user