From 694c2e26795f4d3a2b31e5a1fde2573ebe3405c1 Mon Sep 17 00:00:00 2001 From: David Dworken Date: Tue, 20 Sep 2022 22:28:40 -0700 Subject: [PATCH] Untested: ctx wired through --- client/client_test.go | 7 +- client/{ctx/ctx.go => hctx/hctx.go} | 19 ++-- client/lib/lib.go | 111 ++++++++--------------- client/lib/lib_test.go | 38 ++------ hishtory.go | 135 +++++++++++----------------- 5 files changed, 115 insertions(+), 195 deletions(-) rename client/{ctx/ctx.go => hctx/hctx.go} (92%) diff --git a/client/client_test.go b/client/client_test.go index 008f59f..e3cb306 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -18,8 +18,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/uuid" - "github.com/ddworken/hishtory/client/ctx" "github.com/ddworken/hishtory/client/data" + "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/client/lib" "github.com/ddworken/hishtory/shared" ) @@ -959,10 +959,7 @@ func testRequestAndReceiveDbDump(t *testing.T, tester shellTester) { secretKey := installHishtory(t, tester, "") // Confirm there are no pending dump requests - config, err := ctx.GetConfig() - if err != nil { - t.Fatal(err) - } + config := hctx.GetConf(hctx.MakeContext()) deviceId1 := config.DeviceId resp, err := lib.ApiGet("/api/v1/get-dump-requests?user_id=" + data.UserId(secretKey) + "&device_id=" + deviceId1) if err != nil { diff --git a/client/ctx/ctx.go b/client/hctx/hctx.go similarity index 92% rename from client/ctx/ctx.go rename to client/hctx/hctx.go index 584083b..33ae4ff 100644 --- a/client/ctx/ctx.go +++ b/client/hctx/hctx.go @@ -1,4 +1,4 @@ -package ctx +package hctx import ( "context" @@ -77,7 +77,7 @@ func OpenLocalSqliteDb() (*gorm.DB, error) { type hishtoryContextKey string -func MakeContext() context.Context { +func MakeContext() *context.Context { ctx := context.Background() config, err := GetConfig() if err != nil { @@ -89,11 +89,20 @@ func MakeContext() context.Context { GetLogger().Fatalf("failed to open local DB: %v", err) } ctx = context.WithValue(ctx, hishtoryContextKey("db"), db) - return ctx + return &ctx } -func GetDbFromContext(ctx context.Context) *gorm.DB { - v := ctx.Value(hishtoryContextKey("db")) +func GetConf(ctx *context.Context) ClientConfig { + v := (*ctx).Value(hishtoryContextKey("config")) + if v != nil { + return v.(ClientConfig) + } + GetLogger().Fatalf("failed to find config in ctx") + return ClientConfig{} +} + +func GetDb(ctx *context.Context) *gorm.DB { + v := (*ctx).Value(hishtoryContextKey("db")) if v != nil { return v.(*gorm.DB) } diff --git a/client/lib/lib.go b/client/lib/lib.go index e6f5976..1373afb 100644 --- a/client/lib/lib.go +++ b/client/lib/lib.go @@ -3,6 +3,7 @@ package lib import ( "bufio" "bytes" + "context" "encoding/json" "errors" "fmt" @@ -32,8 +33,8 @@ import ( "github.com/google/uuid" "github.com/rodaine/table" - "github.com/ddworken/hishtory/client/ctx" "github.com/ddworken/hishtory/client/data" + "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/shared" ) @@ -72,9 +73,9 @@ func getCwd() (string, string, error) { return cwd, homedir, nil } -func BuildHistoryEntry(args []string) (*data.HistoryEntry, error) { +func BuildHistoryEntry(ctx *context.Context, args []string) (*data.HistoryEntry, error) { if len(args) < 6 { - ctx.GetLogger().Printf("BuildHistoryEntry called with args=%#v, which has too few entries! This can happen in specific edge cases for newly opened terminals and is likely not a problem.", args) + hctx.GetLogger().Printf("BuildHistoryEntry called with args=%#v, which has too few entries! This can happen in specific edge cases for newly opened terminals and is likely not a problem.", args) return nil, nil } shell := args[2] @@ -119,7 +120,7 @@ func BuildHistoryEntry(args []string) (*data.HistoryEntry, error) { if err != nil { return nil, fmt.Errorf("failed to build history entry: %v", err) } - shouldBeSkipped, err := shouldSkipHiddenCommand(args[4]) + shouldBeSkipped, err := shouldSkipHiddenCommand(ctx, args[4]) if err != nil { return nil, fmt.Errorf("failed to check if command was hidden: %v", err) } @@ -151,10 +152,7 @@ func BuildHistoryEntry(args []string) (*data.HistoryEntry, error) { entry.Hostname = hostname // device ID - config, err := ctx.GetConfig() - if err != nil { - return nil, fmt.Errorf("failed to get device ID when building history entry: %v", err) - } + config := hctx.GetConf(ctx) entry.DeviceId = config.DeviceId return &entry, nil @@ -263,31 +261,20 @@ func getLastCommand(history string) (string, error) { return strings.SplitN(strings.SplitN(strings.TrimSpace(history), " ", 2)[1], " ", 2)[1], nil } -func shouldSkipHiddenCommand(historyLine string) (bool, error) { - config, err := ctx.GetConfig() - if err != nil { - return false, err - } +func shouldSkipHiddenCommand(ctx *context.Context, historyLine string) (bool, error) { + config := hctx.GetConf(ctx) if config.LastSavedHistoryLine == historyLine { return true, nil } config.LastSavedHistoryLine = historyLine - err = ctx.SetConfig(config) + err := hctx.SetConfig(config) if err != nil { return false, err } return false, nil } -func GetUserSecret() (string, error) { - config, err := ctx.GetConfig() - if err != nil { - return "", err - } - return config.UserSecret, nil -} - -func Setup(args []string) error { +func Setup(ctx *context.Context, args []string) error { userSecret := uuid.Must(uuid.NewRandom()).String() if len(args) > 2 && args[2] != "" { userSecret = args[2] @@ -295,20 +282,17 @@ func Setup(args []string) error { fmt.Println("Setting secret hishtory key to " + string(userSecret)) // Create and set the config - var config ctx.ClientConfig + var config hctx.ClientConfig config.UserSecret = userSecret config.IsEnabled = true config.DeviceId = uuid.Must(uuid.NewRandom()).String() - err := ctx.SetConfig(config) + err := hctx.SetConfig(config) if err != nil { return fmt.Errorf("failed to persist config to disk: %v", err) } // Drop all existing data - db, err := ctx.OpenLocalSqliteDb() - if err != nil { - return fmt.Errorf("failed to open DB: %v", err) - } + db := hctx.GetDb(ctx) db.Exec("DELETE FROM history_entries") // Bootstrap from remote date @@ -367,30 +351,20 @@ func DisplayResults(results []*data.HistoryEntry) { tbl.Print() } -func IsEnabled() (bool, error) { - config, err := ctx.GetConfig() - if err != nil { - return false, err - } - return config.IsEnabled, nil +func IsEnabled(ctx *context.Context) (bool, error) { + return hctx.GetConf(ctx).IsEnabled, nil } -func Enable() error { - config, err := ctx.GetConfig() - if err != nil { - return err - } +func Enable(ctx *context.Context) error { + config := hctx.GetConf(ctx) config.IsEnabled = true - return ctx.SetConfig(config) + return hctx.SetConfig(config) } -func Disable() error { - config, err := ctx.GetConfig() - if err != nil { - return err - } +func Disable(ctx *context.Context) error { + config := hctx.GetConf(ctx) config.IsEnabled = false - return ctx.SetConfig(config) + return hctx.SetConfig(config) } func CheckFatalError(err error) { @@ -400,11 +374,8 @@ func CheckFatalError(err error) { } } -func ImportHistory() (int, error) { - config, err := ctx.GetConfig() - if err != nil { - return 0, err - } +func ImportHistory(ctx *context.Context) (int, error) { + config := hctx.GetConf(ctx) if config.HaveCompletedInitialImport { // Don't run an import if we already have run one. This avoids importing the same entry multiple times. return 0, nil @@ -422,10 +393,7 @@ func ImportHistory() (int, error) { return 0, fmt.Errorf("failed to parse zsh history: %v", err) } historyEntries = append(historyEntries, extraEntries...) - db, err := ctx.OpenLocalSqliteDb() - if err != nil { - return 0, nil - } + db := hctx.GetDb(ctx) currentUser, err := user.Current() if err != nil { return 0, err @@ -453,7 +421,7 @@ func ImportHistory() (int, error) { } } config.HaveCompletedInitialImport = true - err = ctx.SetConfig(config) + err = hctx.SetConfig(config) if err != nil { return 0, fmt.Errorf("failed to mark initial import as completed, this may lead to duplicate history entries: %v", err) } @@ -497,7 +465,7 @@ func parseZshHistory(homedir string) ([]string, error) { return readFileToArray(histfile) } -func Install() error { +func Install(ctx *context.Context) error { homedir, err := os.UserHomeDir() if err != nil { return fmt.Errorf("failed to get user's home directory: %v", err) @@ -519,10 +487,10 @@ func Install() error { if err != nil { return err } - _, err = ctx.GetConfig() + _, err = hctx.GetConfig() if err != nil { // No config, so set up a new installation - return Setup(os.Args) + return Setup(ctx, os.Args) } return nil } @@ -798,7 +766,7 @@ func assertIdenticalBinaries(bin1Path, bin2Path string) error { differences = append(differences, fmt.Sprintf("diff at index %d: %s[%d]=%x, %s[%d]=%x", i, bin1Path, i, b1, bin2Path, i, b2)) } } - logger := ctx.GetLogger() + logger := hctx.GetLogger() for _, d := range differences { logger.Printf("comparing binaries: %#v\n", d) } @@ -907,7 +875,7 @@ func ApiGet(path string) ([]byte, error) { return nil, fmt.Errorf("failed to read response body from GET %s%s: %v", getServerHostname(), path, err) } duration := time.Since(start) - ctx.GetLogger().Printf("ApiGet(%#v): %s\n", path, duration.String()) + hctx.GetLogger().Printf("ApiGet(%#v): %s\n", path, duration.String()) return respBody, nil } @@ -929,7 +897,7 @@ func ApiPost(path, contentType string, data []byte) ([]byte, error) { return nil, fmt.Errorf("failed to read response body from POST %s: %v", path, err) } duration := time.Since(start) - ctx.GetLogger().Printf("ApiPost(%#v): %s\n", path, duration.String()) + hctx.GetLogger().Printf("ApiPost(%#v): %s\n", path, duration.String()) return respBody, nil } @@ -968,7 +936,7 @@ func ReliableDbCreate(db *gorm.DB, entry interface{}) error { return fmt.Errorf("failed to create DB entry even with %d retries: %v", i, err) } -func EncryptAndMarshal(config ctx.ClientConfig, entry *data.HistoryEntry) ([]byte, error) { +func EncryptAndMarshal(config hctx.ClientConfig, entry *data.HistoryEntry) ([]byte, error) { encEntry, err := data.EncryptHistoryEntry(config.UserSecret, *entry) if err != nil { return nil, fmt.Errorf("failed to encrypt history entry") @@ -981,8 +949,8 @@ func EncryptAndMarshal(config ctx.ClientConfig, entry *data.HistoryEntry) ([]byt return jsonValue, nil } -func Redact(db *gorm.DB, query string, force bool) error { - tx, err := data.MakeWhereQueryFromSearch(db, query) +func Redact(ctx *context.Context, query string, force bool) error { + tx, err := data.MakeWhereQueryFromSearch(hctx.GetDb(ctx), query) if err != nil { return err } @@ -1006,7 +974,7 @@ func Redact(db *gorm.DB, query string, force bool) error { return nil } } - tx, err = data.MakeWhereQueryFromSearch(db, query) + tx, err = data.MakeWhereQueryFromSearch(hctx.GetDb(ctx), query) if err != nil { return err } @@ -1017,18 +985,15 @@ func Redact(db *gorm.DB, query string, force bool) error { if res.RowsAffected != int64(len(historyEntries)) { return fmt.Errorf("DB deleted %d rows, when we only expected to delete %d rows, something may have gone wrong", res.RowsAffected, len(historyEntries)) } - err = deleteOnRemoteInstances(historyEntries) + err = deleteOnRemoteInstances(ctx, historyEntries) if err != nil { return err } return nil } -func deleteOnRemoteInstances(historyEntries []*data.HistoryEntry) error { - config, err := ctx.GetConfig() - if err != nil { - return err - } +func deleteOnRemoteInstances(ctx *context.Context, historyEntries []*data.HistoryEntry) error { + config := hctx.GetConf(ctx) var deletionRequest shared.DeletionRequest deletionRequest.SendTime = time.Now() diff --git a/client/lib/lib_test.go b/client/lib/lib_test.go index c526cae..cfa4b65 100644 --- a/client/lib/lib_test.go +++ b/client/lib/lib_test.go @@ -8,8 +8,8 @@ import ( "testing" "time" - "github.com/ddworken/hishtory/client/ctx" "github.com/ddworken/hishtory/client/data" + "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/shared" ) @@ -21,7 +21,7 @@ func TestSetup(t *testing.T) { if _, err := os.Stat(path.Join(homedir, shared.HISHTORY_PATH, shared.CONFIG_PATH)); err == nil { t.Fatalf("hishtory secret file already exists!") } - shared.Check(t, Setup([]string{})) + shared.Check(t, Setup(hctx.MakeContext(), []string{})) if _, err := os.Stat(path.Join(homedir, shared.HISHTORY_PATH, shared.CONFIG_PATH)); err != nil { t.Fatalf("hishtory secret file does not exist after Setup()!") } @@ -35,10 +35,10 @@ func TestSetup(t *testing.T) { func TestBuildHistoryEntry(t *testing.T) { defer shared.BackupAndRestore(t)() defer shared.RunTestServer()() - shared.Check(t, Setup([]string{})) + shared.Check(t, Setup(hctx.MakeContext(), []string{})) // Test building an actual entry for bash - entry, err := BuildHistoryEntry([]string{"unused", "saveHistoryEntry", "bash", "120", " 123 ls /foo ", "1641774958"}) + entry, err := BuildHistoryEntry(hctx.MakeContext(), []string{"unused", "saveHistoryEntry", "bash", "120", " 123 ls /foo ", "1641774958"}) shared.Check(t, err) if entry.ExitCode != 120 { t.Fatalf("history entry has unexpected exit code: %v", entry.ExitCode) @@ -67,7 +67,7 @@ func TestBuildHistoryEntry(t *testing.T) { } // Test building an entry for zsh - entry, err = BuildHistoryEntry([]string{"unused", "saveHistoryEntry", "zsh", "120", "ls /foo\n", "1641774958"}) + entry, err = BuildHistoryEntry(hctx.MakeContext(), []string{"unused", "saveHistoryEntry", "zsh", "120", "ls /foo\n", "1641774958"}) shared.Check(t, err) if entry.ExitCode != 120 { t.Fatalf("history entry has unexpected exit code: %v", entry.ExitCode) @@ -92,29 +92,9 @@ func TestBuildHistoryEntry(t *testing.T) { } } -func TestGetUserSecret(t *testing.T) { - defer shared.BackupAndRestore(t)() - defer shared.RunTestServer()() - shared.Check(t, Setup([]string{})) - secret1, err := GetUserSecret() - shared.Check(t, err) - if len(secret1) < 10 || strings.Contains(secret1, " ") || strings.Contains(secret1, "\n") { - t.Fatalf("unexpected secret: %v", secret1) - } - - shared.Check(t, Setup([]string{})) - secret2, err := GetUserSecret() - shared.Check(t, err) - - if secret1 == secret2 { - t.Fatalf("GetUserSecret() returned the same values for different setups! val=%v", secret1) - } -} - func TestPersist(t *testing.T) { defer shared.BackupAndRestore(t)() - db, err := ctx.OpenLocalSqliteDb() - shared.Check(t, err) + db := hctx.GetDb(hctx.MakeContext()) entry := data.MakeFakeHistoryEntry("ls ~/") db.Create(entry) @@ -132,8 +112,7 @@ func TestPersist(t *testing.T) { func TestSearch(t *testing.T) { defer shared.BackupAndRestore(t)() - db, err := ctx.OpenLocalSqliteDb() - shared.Check(t, err) + db := hctx.GetDb(hctx.MakeContext()) // Insert data entry1 := data.MakeFakeHistoryEntry("ls /foo") @@ -158,8 +137,7 @@ func TestSearch(t *testing.T) { func TestAddToDbIfNew(t *testing.T) { // Set up defer shared.BackupAndRestore(t)() - db, err := ctx.OpenLocalSqliteDb() - shared.Check(t, err) + db := hctx.GetDb(hctx.MakeContext()) // Add duplicate entries entry1 := data.MakeFakeHistoryEntry("ls /foo") diff --git a/hishtory.go b/hishtory.go index e95805c..a717a74 100644 --- a/hishtory.go +++ b/hishtory.go @@ -1,15 +1,15 @@ package main import ( + "context" "encoding/json" "fmt" - "log" "os" "strings" "time" - "github.com/ddworken/hishtory/client/ctx" "github.com/ddworken/hishtory/client/data" + "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/client/lib" "github.com/ddworken/hishtory/shared" ) @@ -21,37 +21,36 @@ func main() { fmt.Println("Must specify a command! Do you mean `hishtory query`?") return } + ctx := hctx.MakeContext() switch os.Args[1] { case "saveHistoryEntry": - lib.CheckFatalError(maybeUploadSkippedHistoryEntries()) - saveHistoryEntry() - lib.CheckFatalError(processDeletionRequests()) + lib.CheckFatalError(maybeUploadSkippedHistoryEntries(ctx)) + saveHistoryEntry(ctx) + lib.CheckFatalError(processDeletionRequests(ctx)) case "query": - lib.CheckFatalError(processDeletionRequests()) - query(strings.Join(os.Args[2:], " ")) + lib.CheckFatalError(processDeletionRequests(ctx)) + query(ctx, strings.Join(os.Args[2:], " ")) case "export": - lib.CheckFatalError(processDeletionRequests()) - export(strings.Join(os.Args[2:], " ")) + lib.CheckFatalError(processDeletionRequests(ctx)) + export(ctx, strings.Join(os.Args[2:], " ")) case "redact": fallthrough case "delete": - lib.CheckFatalError(retrieveAdditionalEntriesFromRemote()) - lib.CheckFatalError(processDeletionRequests()) - db, err := ctx.OpenLocalSqliteDb() - lib.CheckFatalError(err) + lib.CheckFatalError(retrieveAdditionalEntriesFromRemote(ctx)) + lib.CheckFatalError(processDeletionRequests(ctx)) query := strings.Join(os.Args[2:], " ") force := false if os.Args[2] == "--force" { query = strings.Join(os.Args[3:], " ") force = true } - lib.CheckFatalError(lib.Redact(db, query, force)) + lib.CheckFatalError(lib.Redact(ctx, query, force)) case "init": - lib.CheckFatalError(lib.Setup(os.Args)) + lib.CheckFatalError(lib.Setup(ctx, os.Args)) case "install": - lib.CheckFatalError(lib.Install()) + lib.CheckFatalError(lib.Install(ctx)) if os.Getenv("HISHTORY_TEST") == "" { - numImported, err := lib.ImportHistory() + numImported, err := lib.ImportHistory(ctx) lib.CheckFatalError(err) if numImported > 0 { fmt.Printf("Imported %v history entries from your existing shell history", numImported) @@ -61,20 +60,19 @@ func main() { if os.Getenv("HISHTORY_TEST") == "" { lib.CheckFatalError(fmt.Errorf("the hishtory import command is only meant to be for testing purposes")) } - numImported, err := lib.ImportHistory() + numImported, err := lib.ImportHistory(ctx) lib.CheckFatalError(err) if numImported > 0 { fmt.Printf("Imported %v history entries from your existing shell history", numImported) } case "enable": - lib.CheckFatalError(lib.Enable()) + lib.CheckFatalError(lib.Enable(ctx)) case "disable": - lib.CheckFatalError(lib.Disable()) + lib.CheckFatalError(lib.Disable(ctx)) case "version": fallthrough case "status": - config, err := ctx.GetConfig() - lib.CheckFatalError(err) + config := hctx.GetConf(ctx) fmt.Printf("Hishtory: v0.%s\nEnabled: %v\n", lib.Version, config.IsEnabled) fmt.Printf("Secret Key: %s\n", config.UserSecret) if len(os.Args) == 3 && os.Args[2] == "-v" { @@ -117,7 +115,7 @@ Supported commands: } } -func printDumpStatus(config ctx.ClientConfig) { +func printDumpStatus(config hctx.ClientConfig) { dumpRequests, err := getDumpRequests(config) lib.CheckFatalError(err) fmt.Printf("Dump Requests: ") @@ -127,7 +125,7 @@ func printDumpStatus(config ctx.ClientConfig) { fmt.Print("\n") } -func getDumpRequests(config ctx.ClientConfig) ([]*shared.DumpRequest, error) { +func getDumpRequests(config hctx.ClientConfig) ([]*shared.DumpRequest, error) { resp, err := lib.ApiGet("/api/v1/get-dump-requests?user_id=" + data.UserId(config.UserSecret) + "&device_id=" + config.DeviceId) if lib.IsOfflineError(err) { return []*shared.DumpRequest{}, nil @@ -140,11 +138,8 @@ func getDumpRequests(config ctx.ClientConfig) ([]*shared.DumpRequest, error) { return dumpRequests, err } -func processDeletionRequests() error { - config, err := ctx.GetConfig() - if err != nil { - return err - } +func processDeletionRequests(ctx *context.Context) error { + config := hctx.GetConf(ctx) resp, err := lib.ApiGet("/api/v1/get-deletion-requests?user_id=" + data.UserId(config.UserSecret) + "&device_id=" + config.DeviceId) if lib.IsOfflineError(err) { @@ -158,10 +153,7 @@ func processDeletionRequests() error { if err != nil { return err } - db, err := ctx.OpenLocalSqliteDb() - if err != nil { - return err - } + db := hctx.GetDb(ctx) for _, request := range deletionRequests { for _, entry := range request.Messages.Ids { res := db.Where("device_id = ? AND end_time = ?", entry.DeviceId, entry.Date).Delete(&data.HistoryEntry{}) @@ -173,15 +165,9 @@ func processDeletionRequests() error { return nil } -func retrieveAdditionalEntriesFromRemote() error { - db, err := ctx.OpenLocalSqliteDb() - if err != nil { - return err - } - config, err := ctx.GetConfig() - if err != nil { - return err - } +func retrieveAdditionalEntriesFromRemote(ctx *context.Context) error { + db := hctx.GetDb(ctx) + config := hctx.GetConf(ctx) respBody, err := lib.ApiGet("/api/v1/query?device_id=" + config.DeviceId + "&user_id=" + data.UserId(config.UserSecret)) if lib.IsOfflineError(err) { return nil @@ -201,13 +187,12 @@ func retrieveAdditionalEntriesFromRemote() error { } lib.AddToDbIfNew(db, decEntry) } - return processDeletionRequests() + return processDeletionRequests(ctx) } -func query(query string) { - db, err := ctx.OpenLocalSqliteDb() - lib.CheckFatalError(err) - err = retrieveAdditionalEntriesFromRemote() +func query(ctx *context.Context, query string) { + db := hctx.GetDb(ctx) + err := retrieveAdditionalEntriesFromRemote(ctx) if err != nil { if lib.IsOfflineError(err) { fmt.Println("Warning: hishtory is offline so this may be missing recent results from your other machines!") @@ -215,17 +200,14 @@ func query(query string) { lib.CheckFatalError(err) } } - lib.CheckFatalError(displayBannerIfSet()) + lib.CheckFatalError(displayBannerIfSet(ctx)) data, err := data.Search(db, query, 25) lib.CheckFatalError(err) lib.DisplayResults(data) } -func displayBannerIfSet() error { - config, err := ctx.GetConfig() - if err != nil { - return fmt.Errorf("failed to get config: %v", err) - } +func displayBannerIfSet(ctx *context.Context) error { + config := hctx.GetConf(ctx) url := "/api/v1/banner?commit_hash=" + GitCommit + "&user_id=" + data.UserId(config.UserSecret) + "&device_id=" + config.DeviceId + "&version=" + lib.Version + "&forced_banner=" + os.Getenv("FORCED_BANNER") respBody, err := lib.ApiGet(url) if lib.IsOfflineError(err) { @@ -240,26 +222,20 @@ func displayBannerIfSet() error { return nil } -func maybeUploadSkippedHistoryEntries() error { - config, err := ctx.GetConfig() - if err != nil { - return err - } +func maybeUploadSkippedHistoryEntries(ctx *context.Context) error { + config := hctx.GetConf(ctx) if !config.HaveMissedUploads { return nil } // Upload the missing entries - db, err := ctx.OpenLocalSqliteDb() - if err != nil { - return nil - } + db := hctx.GetDb(ctx) query := fmt.Sprintf("after:%s", time.Unix(config.MissedUploadTimestamp, 0).Format("2006-01-02")) entries, err := data.Search(db, query, 0) if err != nil { return fmt.Errorf("failed to retrieve history entries that haven't been uploaded yet: %v", err) } - ctx.GetLogger().Printf("Uploading %d history entries that previously failed to upload (query=%#v)\n", len(entries), query) + hctx.GetLogger().Printf("Uploading %d history entries that previously failed to upload (query=%#v)\n", len(entries), query) for _, entry := range entries { jsonValue, err := lib.EncryptAndMarshal(config, entry) if err != nil { @@ -275,32 +251,28 @@ func maybeUploadSkippedHistoryEntries() error { // Mark down that we persisted it config.HaveMissedUploads = false config.MissedUploadTimestamp = 0 - err = ctx.SetConfig(config) + err = hctx.SetConfig(config) if err != nil { return fmt.Errorf("failed to mark a history entry as uploaded: %v", err) } return nil } -func saveHistoryEntry() { - config, err := ctx.GetConfig() - if err != nil { - log.Fatalf("hishtory cannot save an entry because the hishtory config file does not exist, try running `hishtory init` (err=%v)", err) - } +func saveHistoryEntry(ctx *context.Context) { + config := hctx.GetConf(ctx) if !config.IsEnabled { - ctx.GetLogger().Printf("Skipping saving a history entry because hishtory is disabled\n") + hctx.GetLogger().Printf("Skipping saving a history entry because hishtory is disabled\n") return } - entry, err := lib.BuildHistoryEntry(os.Args) + entry, err := lib.BuildHistoryEntry(ctx, os.Args) lib.CheckFatalError(err) if entry == nil { - ctx.GetLogger().Printf("Skipping saving a history entry because we failed to build a history entry (was the command prefixed with a space?)\n") + hctx.GetLogger().Printf("Skipping saving a history entry because we failed to build a history entry (was the command prefixed with a space?)\n") return } // Persist it locally - db, err := ctx.OpenLocalSqliteDb() - lib.CheckFatalError(err) + db := hctx.GetDb(ctx) err = lib.ReliableDbCreate(db, entry) lib.CheckFatalError(err) @@ -310,11 +282,11 @@ func saveHistoryEntry() { _, err = lib.ApiPost("/api/v1/submit", "application/json", jsonValue) if err != nil { if lib.IsOfflineError(err) { - ctx.GetLogger().Printf("Failed to remotely persist hishtory entry because the device is offline!") + hctx.GetLogger().Printf("Failed to remotely persist hishtory entry because the device is offline!") if !config.HaveMissedUploads { config.HaveMissedUploads = true config.MissedUploadTimestamp = time.Now().Unix() - lib.CheckFatalError(ctx.SetConfig(config)) + lib.CheckFatalError(hctx.SetConfig(config)) } } else { lib.CheckFatalError(err) @@ -327,13 +299,13 @@ func saveHistoryEntry() { if lib.IsOfflineError(err) { // It is fine to just ignore this, the next command will retry the API and eventually we will respond to any pending dump requests dumpRequests = []*shared.DumpRequest{} - ctx.GetLogger().Printf("Failed to check for dump requests because the device is offline!") + hctx.GetLogger().Printf("Failed to check for dump requests because the device is offline!") } else { lib.CheckFatalError(err) } } if len(dumpRequests) > 0 { - lib.CheckFatalError(retrieveAdditionalEntriesFromRemote()) + lib.CheckFatalError(retrieveAdditionalEntriesFromRemote(ctx)) entries, err := data.Search(db, "", 0) lib.CheckFatalError(err) var encEntries []*shared.EncHistoryEntry @@ -351,10 +323,9 @@ func saveHistoryEntry() { } } -func export(query string) { - db, err := ctx.OpenLocalSqliteDb() - lib.CheckFatalError(err) - err = retrieveAdditionalEntriesFromRemote() +func export(ctx *context.Context, query string) { + db := hctx.GetDb(ctx) + err := retrieveAdditionalEntriesFromRemote(ctx) if err != nil { if lib.IsOfflineError(err) { fmt.Println("Warning: hishtory is offline so this may be missing recent results from your other machines!")