mirror of
https://github.com/ddworken/hishtory.git
synced 2024-11-22 16:24:00 +01:00
wrap errors with %w instead of using %v
This commit is contained in:
parent
efa9ddd6df
commit
83ad8c7b1f
@ -196,7 +196,7 @@ func apiSubmitHandler(ctx context.Context, w http.ResponseWriter, r *http.Reques
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to execute transaction to add entries to DB: %v", err))
|
||||
panic(fmt.Errorf("failed to execute transaction to add entries to DB: %w", err))
|
||||
}
|
||||
if GLOBAL_STATSD != nil {
|
||||
GLOBAL_STATSD.Count("hishtory.submit", int64(len(devices)), []string{}, 1.0)
|
||||
@ -312,7 +312,7 @@ func apiGetPendingDumpRequestsHandler(ctx context.Context, w http.ResponseWriter
|
||||
checkGormResult(GLOBAL_DB.WithContext(ctx).Where("user_id = ? AND requesting_device_id != ?", userId, deviceId).Find(&dumpRequests))
|
||||
respBody, err := json.Marshal(dumpRequests)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to JSON marshall the dump requests: %v", err))
|
||||
panic(fmt.Errorf("failed to JSON marshall the dump requests: %w", err))
|
||||
}
|
||||
w.Write(respBody)
|
||||
}
|
||||
@ -342,7 +342,7 @@ func apiSubmitDumpHandler(ctx context.Context, w http.ResponseWriter, r *http.Re
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to execute transaction to add dumped DB: %v", err))
|
||||
panic(fmt.Errorf("failed to execute transaction to add dumped DB: %w", err))
|
||||
}
|
||||
checkGormResult(GLOBAL_DB.WithContext(ctx).Delete(&shared.DumpRequest{}, "user_id = ? AND requesting_device_id = ?", userId, requestingDeviceId))
|
||||
updateUsageData(ctx, r, userId, srcDeviceId, len(entries), false)
|
||||
@ -372,7 +372,7 @@ func getDeletionRequestsHandler(ctx context.Context, w http.ResponseWriter, r *h
|
||||
checkGormResult(GLOBAL_DB.WithContext(ctx).Where("user_id = ? AND destination_device_id = ?", userId, deviceId).Find(&deletionRequests))
|
||||
respBody, err := json.Marshal(deletionRequests)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to JSON marshall the dump requests: %v", err))
|
||||
panic(fmt.Errorf("failed to JSON marshall the dump requests: %w", err))
|
||||
}
|
||||
w.Write(respBody)
|
||||
}
|
||||
@ -491,11 +491,11 @@ func OpenDB() (*gorm.DB, error) {
|
||||
if isTestEnvironment() {
|
||||
db, err := gorm.Open(sqlite.Open("file::memory:?_journal_mode=WAL&cache=shared"), &gorm.Config{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to connect to the DB: %v", err)
|
||||
return nil, fmt.Errorf("failed to connect to the DB: %w", err)
|
||||
}
|
||||
underlyingDb, err := db.DB()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to access underlying DB: %v", err)
|
||||
return nil, fmt.Errorf("failed to access underlying DB: %w", err)
|
||||
}
|
||||
underlyingDb.SetMaxOpenConns(1)
|
||||
db.Exec("PRAGMA journal_mode = WAL")
|
||||
@ -521,7 +521,7 @@ func OpenDB() (*gorm.DB, error) {
|
||||
var err error
|
||||
db, err = gorm.Open(sqlite.Open(sqliteDb), &gorm.Config{Logger: customLogger})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to connect to the DB: %v", err)
|
||||
return nil, fmt.Errorf("failed to connect to the DB: %w", err)
|
||||
}
|
||||
} else {
|
||||
postgresDb := fmt.Sprintf(PostgresDb, os.Getenv("POSTGRESQL_PASSWORD"))
|
||||
@ -535,7 +535,7 @@ func OpenDB() (*gorm.DB, error) {
|
||||
}
|
||||
db, err = gormtrace.Open(postgres.New(postgres.Config{Conn: sqlDb}), &gorm.Config{Logger: customLogger})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to connect to the DB: %v", err)
|
||||
return nil, fmt.Errorf("failed to connect to the DB: %w", err)
|
||||
}
|
||||
}
|
||||
AddDatabaseTables(db)
|
||||
@ -602,12 +602,12 @@ type releaseInfo struct {
|
||||
func updateReleaseVersion() error {
|
||||
resp, err := http.Get("https://api.github.com/repos/ddworken/hishtory/releases/latest")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get latest release version: %v", err)
|
||||
return fmt.Errorf("failed to get latest release version: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read github API response body: %v", err)
|
||||
return fmt.Errorf("failed to read github API response body: %w", err)
|
||||
}
|
||||
if resp.StatusCode == 403 && strings.Contains(string(respBody), "API rate limit exceeded for ") {
|
||||
return nil
|
||||
@ -618,7 +618,7 @@ func updateReleaseVersion() error {
|
||||
var info releaseInfo
|
||||
err = json.Unmarshal(respBody, &info)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse github API response: %v", err)
|
||||
return fmt.Errorf("failed to parse github API response: %w", err)
|
||||
}
|
||||
latestVersionTag := info.Name
|
||||
ReleaseVersion = decrementVersionIfInvalid(latestVersionTag)
|
||||
@ -654,7 +654,7 @@ func assertValidUpdate(updateInfo shared.UpdateInfo) error {
|
||||
for _, url := range urls {
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to retrieve URL %#v: %v", url, err)
|
||||
return fmt.Errorf("failed to retrieve URL %#v: %w", url, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode == 404 {
|
||||
@ -878,7 +878,7 @@ func deepCleanDatabase(ctx context.Context) {
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to deep clean DB: %v", err))
|
||||
panic(fmt.Errorf("failed to deep clean DB: %w", err))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ func (b bashTester) RunInteractiveShellRelaxed(t testing.TB, script string) (str
|
||||
cmd.Stderr = &stderr
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("unexpected error when running commands, out=%#v, err=%#v: %v", stdout.String(), stderr.String(), err)
|
||||
return "", fmt.Errorf("unexpected error when running commands, out=%#v, err=%#v: %w", stdout.String(), stderr.String(), err)
|
||||
}
|
||||
outStr := stdout.String()
|
||||
require.NotContains(t, outStr, "hishtory fatal error", "Ran command, but hishtory had a fatal error!")
|
||||
@ -105,7 +105,7 @@ func (z zshTester) RunInteractiveShellRelaxed(t testing.TB, script string) (stri
|
||||
cmd.Stderr = &stderr
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return stdout.String(), fmt.Errorf("unexpected error when running command=%#v, out=%#v, err=%#v: %v", script, stdout.String(), stderr.String(), err)
|
||||
return stdout.String(), fmt.Errorf("unexpected error when running command=%#v, out=%#v, err=%#v: %w", script, stdout.String(), stderr.String(), err)
|
||||
}
|
||||
outStr := stdout.String()
|
||||
require.NotContains(t, outStr, "hishtory fatal error")
|
||||
|
@ -129,7 +129,7 @@ func warnIfUnsupportedBashVersion() error {
|
||||
cmd := exec.Command("bash", "--version")
|
||||
bashVersion, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check bash version: %v", err)
|
||||
return fmt.Errorf("failed to check bash version: %w", err)
|
||||
}
|
||||
if strings.Contains(string(bashVersion), "version 3.") {
|
||||
fmt.Printf("Warning: Your current bash version does not support overriding control-r. Please upgrade to at least bash 5 to enable the control-r integration.\n")
|
||||
@ -140,7 +140,7 @@ func warnIfUnsupportedBashVersion() error {
|
||||
func install(secretKey string, offline bool) error {
|
||||
homedir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get user's home directory: %v", err)
|
||||
return fmt.Errorf("failed to get user's home directory: %w", err)
|
||||
}
|
||||
err = hctx.MakeHishtoryDir()
|
||||
if err != nil {
|
||||
@ -201,16 +201,16 @@ func installBinary(homedir string) (string, error) {
|
||||
if _, err := os.Stat(clientPath); err == nil {
|
||||
err = syscall.Unlink(clientPath)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to unlink %s for install: %v", clientPath, err)
|
||||
return "", fmt.Errorf("failed to unlink %s for install: %w", clientPath, err)
|
||||
}
|
||||
}
|
||||
err = copyFile(os.Args[0], clientPath)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to copy hishtory binary to $PATH: %v", err)
|
||||
return "", fmt.Errorf("failed to copy hishtory binary to $PATH: %w", err)
|
||||
}
|
||||
err = os.Chmod(clientPath, 0o700)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to set permissions on hishtory binary: %v", err)
|
||||
return "", fmt.Errorf("failed to set permissions on hishtory binary: %w", err)
|
||||
}
|
||||
return clientPath, nil
|
||||
}
|
||||
@ -236,12 +236,12 @@ func configureFish(homedir, binaryPath string) error {
|
||||
}
|
||||
err = os.WriteFile(getFishConfigPath(homedir), []byte(configContents), 0o644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write config.zsh file: %v", err)
|
||||
return fmt.Errorf("failed to write config.zsh file: %w", err)
|
||||
}
|
||||
// Check if we need to configure the fishrc
|
||||
fishIsConfigured, err := isFishConfigured(homedir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check ~/.config/fish/config.fish: %v", err)
|
||||
return fmt.Errorf("failed to check ~/.config/fish/config.fish: %w", err)
|
||||
}
|
||||
if fishIsConfigured {
|
||||
return nil
|
||||
@ -249,7 +249,7 @@ func configureFish(homedir, binaryPath string) error {
|
||||
// Add to fishrc
|
||||
err = os.MkdirAll(path.Join(homedir, ".config/fish"), 0o744)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create fish config directory: %v", err)
|
||||
return fmt.Errorf("failed to create fish config directory: %w", err)
|
||||
}
|
||||
return addToShellConfig(path.Join(homedir, ".config/fish/config.fish"), getFishConfigFragment(homedir))
|
||||
}
|
||||
@ -265,7 +265,7 @@ func isFishConfigured(homedir string) (bool, error) {
|
||||
}
|
||||
fishConfig, err := os.ReadFile(path.Join(homedir, ".config/fish/config.fish"))
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to read ~/.config/fish/config.fish: %v", err)
|
||||
return false, fmt.Errorf("failed to read ~/.config/fish/config.fish: %w", err)
|
||||
}
|
||||
return strings.Contains(string(fishConfig), getFishConfigFragment(homedir)), nil
|
||||
}
|
||||
@ -286,12 +286,12 @@ func configureZshrc(homedir, binaryPath string) error {
|
||||
}
|
||||
err := os.WriteFile(getZshConfigPath(homedir), []byte(configContents), 0o644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write config.zsh file: %v", err)
|
||||
return fmt.Errorf("failed to write config.zsh file: %w", err)
|
||||
}
|
||||
// Check if we need to configure the zshrc
|
||||
zshIsConfigured, err := isZshConfigured(homedir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check .zshrc: %v", err)
|
||||
return fmt.Errorf("failed to check .zshrc: %w", err)
|
||||
}
|
||||
if zshIsConfigured {
|
||||
return nil
|
||||
@ -318,7 +318,7 @@ func isZshConfigured(homedir string) (bool, error) {
|
||||
}
|
||||
bashrc, err := os.ReadFile(getZshRcPath(homedir))
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to read zshrc: %v", err)
|
||||
return false, fmt.Errorf("failed to read zshrc: %w", err)
|
||||
}
|
||||
return strings.Contains(string(bashrc), getZshConfigFragment(homedir)), nil
|
||||
}
|
||||
@ -339,12 +339,12 @@ func configureBashrc(homedir, binaryPath string) error {
|
||||
}
|
||||
err := os.WriteFile(getBashConfigPath(homedir), []byte(configContents), 0o644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write config.sh file: %v", err)
|
||||
return fmt.Errorf("failed to write config.sh file: %w", err)
|
||||
}
|
||||
// Check if we need to configure the bashrc and configure it if so
|
||||
bashRcIsConfigured, err := isBashRcConfigured(homedir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check ~/.bashrc: %v", err)
|
||||
return fmt.Errorf("failed to check ~/.bashrc: %w", err)
|
||||
}
|
||||
if !bashRcIsConfigured {
|
||||
err = addToShellConfig(path.Join(homedir, ".bashrc"), getBashConfigFragment(homedir))
|
||||
@ -356,7 +356,7 @@ func configureBashrc(homedir, binaryPath string) error {
|
||||
if doesBashProfileNeedConfig(homedir) {
|
||||
bashProfileIsConfigured, err := isBashProfileConfigured(homedir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check ~/.bash_profile: %v", err)
|
||||
return fmt.Errorf("failed to check ~/.bash_profile: %w", err)
|
||||
}
|
||||
if !bashProfileIsConfigured {
|
||||
err = addToShellConfig(path.Join(homedir, ".bash_profile"), getBashConfigFragment(homedir))
|
||||
@ -371,12 +371,12 @@ func configureBashrc(homedir, binaryPath string) error {
|
||||
func addToShellConfig(shellConfigPath, configFragment string) error {
|
||||
f, err := os.OpenFile(shellConfigPath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0o644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to append to %s: %v", shellConfigPath, err)
|
||||
return fmt.Errorf("failed to append to %s: %w", shellConfigPath, err)
|
||||
}
|
||||
defer f.Close()
|
||||
_, err = f.WriteString(configFragment)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to append to %s: %v", shellConfigPath, err)
|
||||
return fmt.Errorf("failed to append to %s: %w", shellConfigPath, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -392,7 +392,7 @@ func isBashRcConfigured(homedir string) (bool, error) {
|
||||
}
|
||||
bashrc, err := os.ReadFile(path.Join(homedir, ".bashrc"))
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to read bashrc: %v", err)
|
||||
return false, fmt.Errorf("failed to read bashrc: %w", err)
|
||||
}
|
||||
return strings.Contains(string(bashrc), getBashConfigFragment(homedir)), nil
|
||||
}
|
||||
@ -418,7 +418,7 @@ func isBashProfileConfigured(homedir string) (bool, error) {
|
||||
}
|
||||
bashrc, err := os.ReadFile(path.Join(homedir, ".bash_profile"))
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to read bash_profile: %v", err)
|
||||
return false, fmt.Errorf("failed to read bash_profile: %w", err)
|
||||
}
|
||||
return strings.Contains(string(bashrc), getBashConfigFragment(homedir)), nil
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ func redact(ctx *context.Context, query string, force bool) error {
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
resp, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read response: %v", err)
|
||||
return fmt.Errorf("failed to read response: %w", err)
|
||||
}
|
||||
if strings.TrimSpace(resp) != "y" {
|
||||
fmt.Printf("Aborting delete per user response of %#v\n", strings.TrimSpace(resp))
|
||||
|
@ -58,7 +58,7 @@ func maybeUploadSkippedHistoryEntries(ctx *context.Context) error {
|
||||
query := fmt.Sprintf("after:%s", time.Unix(config.MissedUploadTimestamp, 0).Format("2006-01-02"))
|
||||
entries, err := lib.Search(ctx, db, query, 0)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to retrieve history entries that haven't been uploaded yet: %v", err)
|
||||
return fmt.Errorf("failed to retrieve history entries that haven't been uploaded yet: %w", err)
|
||||
}
|
||||
hctx.GetLogger().Infof("Uploading %d history entries that previously failed to upload (query=%#v)\n", len(entries), query)
|
||||
jsonValue, err := lib.EncryptAndMarshal(config, entries)
|
||||
@ -76,7 +76,7 @@ func maybeUploadSkippedHistoryEntries(ctx *context.Context) error {
|
||||
config.MissedUploadTimestamp = 0
|
||||
err = hctx.SetConfig(config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to mark a history entry as uploaded: %v", err)
|
||||
return fmt.Errorf("failed to mark a history entry as uploaded: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -140,11 +140,11 @@ func saveHistoryEntry(ctx *context.Context) {
|
||||
if config.BetaMode {
|
||||
tx, err := lib.MakeWhereQueryFromSearch(ctx, db, "cwd:"+entry.CurrentWorkingDirectory+" start_time:"+strconv.FormatInt(entry.StartTime.Unix(), 10))
|
||||
if err != nil {
|
||||
lib.CheckFatalError(fmt.Errorf("failed to query for pre-saved history entries: %s", err))
|
||||
lib.CheckFatalError(fmt.Errorf("failed to query for pre-saved history entries: %w", err))
|
||||
}
|
||||
res := tx.Delete(&data.HistoryEntry{})
|
||||
if res.Error != nil {
|
||||
lib.CheckFatalError(fmt.Errorf("failed to delete pre-saved history entries: %s", res.Error))
|
||||
lib.CheckFatalError(fmt.Errorf("failed to delete pre-saved history entries: %w", res.Error))
|
||||
}
|
||||
if res.RowsAffected > 1 {
|
||||
lib.CheckFatalError(fmt.Errorf("attempted to delete pre-saved entry, but something went wrong since we deleted %d rows", res.RowsAffected))
|
||||
@ -224,14 +224,14 @@ func buildPreArgsHistoryEntry(ctx *context.Context) (*data.HistoryEntry, error)
|
||||
// user
|
||||
user, err := user.Current()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to build history entry: %v", err)
|
||||
return nil, fmt.Errorf("failed to build history entry: %w", err)
|
||||
}
|
||||
entry.LocalUsername = user.Username
|
||||
|
||||
// cwd and homedir
|
||||
cwd, homedir, err := getCwd(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to build history entry: %v", err)
|
||||
return nil, fmt.Errorf("failed to build history entry: %w", err)
|
||||
}
|
||||
entry.CurrentWorkingDirectory = cwd
|
||||
entry.HomeDirectory = homedir
|
||||
@ -239,7 +239,7 @@ func buildPreArgsHistoryEntry(ctx *context.Context) (*data.HistoryEntry, error)
|
||||
// hostname
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to build history entry: %v", err)
|
||||
return nil, fmt.Errorf("failed to build history entry: %w", err)
|
||||
}
|
||||
entry.Hostname = hostname
|
||||
|
||||
@ -272,14 +272,14 @@ func buildHistoryEntry(ctx *context.Context, args []string) (*data.HistoryEntry,
|
||||
// exitCode
|
||||
exitCode, err := strconv.Atoi(args[3])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to build history entry: %v", err)
|
||||
return nil, fmt.Errorf("failed to build history entry: %w", err)
|
||||
}
|
||||
entry.ExitCode = exitCode
|
||||
|
||||
// start time
|
||||
seconds, err := parseCrossPlatformInt(args[5])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse start time %s as int: %v", args[5], err)
|
||||
return nil, fmt.Errorf("failed to parse start time %s as int: %w", args[5], err)
|
||||
}
|
||||
entry.StartTime = time.Unix(seconds, 0)
|
||||
|
||||
@ -290,11 +290,11 @@ func buildHistoryEntry(ctx *context.Context, args []string) (*data.HistoryEntry,
|
||||
if shell == "bash" {
|
||||
cmd, err := getLastCommand(args[4])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to build history entry: %v", err)
|
||||
return nil, fmt.Errorf("failed to build history entry: %w", err)
|
||||
}
|
||||
shouldBeSkipped, err := shouldSkipHiddenCommand(ctx, args[4])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to check if command was hidden: %v", err)
|
||||
return nil, fmt.Errorf("failed to check if command was hidden: %w", err)
|
||||
}
|
||||
if shouldBeSkipped || strings.HasPrefix(cmd, " ") {
|
||||
// Don't save commands that start with a space
|
||||
@ -443,7 +443,7 @@ func maybeSkipBashHistTimePrefix(cmdLine string) (string, error) {
|
||||
}
|
||||
re, err := regexp.Compile("^" + buildRegexFromTimeFormat(format))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to parse regex for HISTTIMEFORMAT variable: %v", err)
|
||||
return "", fmt.Errorf("failed to parse regex for HISTTIMEFORMAT variable: %w", err)
|
||||
}
|
||||
return re.ReplaceAllLiteralString(cmdLine, ""), nil
|
||||
}
|
||||
@ -481,7 +481,7 @@ func shouldSkipHiddenCommand(ctx *context.Context, historyLine string) (bool, er
|
||||
func getCwd(ctx *context.Context) (string, string, error) {
|
||||
cwd, err := getCwdWithoutSubstitution()
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("failed to get cwd for last command: %v", err)
|
||||
return "", "", fmt.Errorf("failed to get cwd for last command: %w", err)
|
||||
}
|
||||
homedir := hctx.GetHome(ctx)
|
||||
if cwd == homedir {
|
||||
|
@ -96,16 +96,16 @@ func makeAead(userSecret string) (cipher.AEAD, error) {
|
||||
func Encrypt(userSecret string, data, additionalData []byte) ([]byte, []byte, error) {
|
||||
aead, err := makeAead(userSecret)
|
||||
if err != nil {
|
||||
return []byte{}, []byte{}, fmt.Errorf("failed to make AEAD: %v", err)
|
||||
return []byte{}, []byte{}, fmt.Errorf("failed to make AEAD: %w", err)
|
||||
}
|
||||
nonce := make([]byte, 12)
|
||||
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
|
||||
return []byte{}, []byte{}, fmt.Errorf("failed to read a nonce: %v", err)
|
||||
return []byte{}, []byte{}, fmt.Errorf("failed to read a nonce: %w", err)
|
||||
}
|
||||
ciphertext := aead.Seal(nil, nonce, data, additionalData)
|
||||
_, err = aead.Open(nil, nonce, ciphertext, additionalData)
|
||||
if err != nil {
|
||||
return []byte{}, []byte{}, fmt.Errorf("failed to open AEAD: %v", err)
|
||||
return []byte{}, []byte{}, fmt.Errorf("failed to open AEAD: %w", err)
|
||||
}
|
||||
return ciphertext, nonce, nil
|
||||
}
|
||||
@ -113,11 +113,11 @@ func Encrypt(userSecret string, data, additionalData []byte) ([]byte, []byte, er
|
||||
func Decrypt(userSecret string, data, additionalData, nonce []byte) ([]byte, error) {
|
||||
aead, err := makeAead(userSecret)
|
||||
if err != nil {
|
||||
return []byte{}, fmt.Errorf("failed to make AEAD: %v", err)
|
||||
return []byte{}, fmt.Errorf("failed to make AEAD: %w", err)
|
||||
}
|
||||
plaintext, err := aead.Open(nil, nonce, data, additionalData)
|
||||
if err != nil {
|
||||
return []byte{}, fmt.Errorf("failed to decrypt: %v", err)
|
||||
return []byte{}, fmt.Errorf("failed to decrypt: %w", err)
|
||||
}
|
||||
return plaintext, nil
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ func GetLogger() *logrus.Logger {
|
||||
getLoggerOnce.Do(func() {
|
||||
homedir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to get user's home directory: %v", err))
|
||||
panic(fmt.Errorf("failed to get user's home directory: %w", err))
|
||||
}
|
||||
err = MakeHishtoryDir()
|
||||
if err != nil {
|
||||
@ -59,11 +59,11 @@ func GetLogger() *logrus.Logger {
|
||||
func MakeHishtoryDir() error {
|
||||
homedir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get user's home directory: %v", err)
|
||||
return fmt.Errorf("failed to get user's home directory: %w", err)
|
||||
}
|
||||
err = os.MkdirAll(path.Join(homedir, data.GetHishtoryPath()), 0o744)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create ~/%s dir: %v", data.GetHishtoryPath(), err)
|
||||
return fmt.Errorf("failed to create ~/%s dir: %w", data.GetHishtoryPath(), err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -71,7 +71,7 @@ func MakeHishtoryDir() error {
|
||||
func OpenLocalSqliteDb() (*gorm.DB, error) {
|
||||
homedir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get user's home directory: %v", err)
|
||||
return nil, fmt.Errorf("failed to get user's home directory: %w", err)
|
||||
}
|
||||
err = MakeHishtoryDir()
|
||||
if err != nil {
|
||||
@ -90,7 +90,7 @@ func OpenLocalSqliteDb() (*gorm.DB, error) {
|
||||
dsn := fmt.Sprintf("file:%s?mode=rwc&_journal_mode=WAL", dbFilePath)
|
||||
db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{SkipDefaultTransaction: true, Logger: newLogger})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to connect to the DB: %v", err)
|
||||
return nil, fmt.Errorf("failed to connect to the DB: %w", err)
|
||||
}
|
||||
tx, err := db.DB()
|
||||
if err != nil {
|
||||
@ -112,17 +112,17 @@ func MakeContext() *context.Context {
|
||||
ctx := context.Background()
|
||||
config, err := GetConfig()
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to retrieve config: %v", err))
|
||||
panic(fmt.Errorf("failed to retrieve config: %w", err))
|
||||
}
|
||||
ctx = context.WithValue(ctx, hishtoryContextKey("config"), config)
|
||||
db, err := OpenLocalSqliteDb()
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to open local DB: %v", err))
|
||||
panic(fmt.Errorf("failed to open local DB: %w", err))
|
||||
}
|
||||
ctx = context.WithValue(ctx, hishtoryContextKey("db"), db)
|
||||
homedir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to get homedir: %v", err))
|
||||
panic(fmt.Errorf("failed to get homedir: %w", err))
|
||||
}
|
||||
ctx = context.WithValue(ctx, hishtoryContextKey("homedir"), homedir)
|
||||
return &ctx
|
||||
@ -191,20 +191,20 @@ type CustomColumnDefinition struct {
|
||||
func GetConfigContents() ([]byte, error) {
|
||||
homedir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to retrieve homedir: %v", err)
|
||||
return nil, fmt.Errorf("failed to retrieve homedir: %w", err)
|
||||
}
|
||||
dat, err := os.ReadFile(path.Join(homedir, data.GetHishtoryPath(), data.CONFIG_PATH))
|
||||
if err != nil {
|
||||
files, err := os.ReadDir(path.Join(homedir, data.GetHishtoryPath()))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read config file (and failed to list too): %v", err)
|
||||
return nil, fmt.Errorf("failed to read config file (and failed to list too): %w", err)
|
||||
}
|
||||
filenames := ""
|
||||
for _, file := range files {
|
||||
filenames += file.Name()
|
||||
filenames += ", "
|
||||
}
|
||||
return nil, fmt.Errorf("failed to read config file (files in HISHTORY_PATH: %s): %v", filenames, err)
|
||||
return nil, fmt.Errorf("failed to read config file (files in HISHTORY_PATH: %s): %w", filenames, err)
|
||||
}
|
||||
return dat, nil
|
||||
}
|
||||
@ -217,7 +217,7 @@ func GetConfig() (ClientConfig, error) {
|
||||
var config ClientConfig
|
||||
err = json.Unmarshal(data, &config)
|
||||
if err != nil {
|
||||
return ClientConfig{}, fmt.Errorf("failed to parse config file: %v", err)
|
||||
return ClientConfig{}, fmt.Errorf("failed to parse config file: %w", err)
|
||||
}
|
||||
if config.DisplayedColumns == nil || len(config.DisplayedColumns) == 0 {
|
||||
config.DisplayedColumns = []string{"Hostname", "CWD", "Timestamp", "Runtime", "Exit Code", "Command"}
|
||||
@ -231,11 +231,11 @@ func GetConfig() (ClientConfig, error) {
|
||||
func SetConfig(config ClientConfig) error {
|
||||
serializedConfig, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to serialize config: %v", err)
|
||||
return fmt.Errorf("failed to serialize config: %w", err)
|
||||
}
|
||||
homedir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to retrieve homedir: %v", err)
|
||||
return fmt.Errorf("failed to retrieve homedir: %w", err)
|
||||
}
|
||||
err = MakeHishtoryDir()
|
||||
if err != nil {
|
||||
@ -245,11 +245,11 @@ func SetConfig(config ClientConfig) error {
|
||||
stagedConfigPath := configPath + ".tmp-" + uuid.Must(uuid.NewRandom()).String()
|
||||
err = os.WriteFile(stagedConfigPath, serializedConfig, 0o644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write config: %v", err)
|
||||
return fmt.Errorf("failed to write config: %w", err)
|
||||
}
|
||||
err = os.Rename(stagedConfigPath, configPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to replace config file with the updated version: %v", err)
|
||||
return fmt.Errorf("failed to replace config file with the updated version: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ func Setup(userSecret string, isOffline bool) error {
|
||||
config.IsOffline = isOffline
|
||||
err := hctx.SetConfig(config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to persist config to disk: %v", err)
|
||||
return fmt.Errorf("failed to persist config to disk: %w", err)
|
||||
}
|
||||
|
||||
// Drop all existing data
|
||||
@ -82,22 +82,22 @@ func Setup(userSecret string, isOffline bool) error {
|
||||
}
|
||||
_, err = ApiGet("/api/v1/register?user_id=" + data.UserId(userSecret) + "&device_id=" + config.DeviceId)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to register device with backend: %v", err)
|
||||
return fmt.Errorf("failed to register device with backend: %w", err)
|
||||
}
|
||||
|
||||
respBody, err := ApiGet("/api/v1/bootstrap?user_id=" + data.UserId(userSecret) + "&device_id=" + config.DeviceId)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to bootstrap device from the backend: %v", err)
|
||||
return fmt.Errorf("failed to bootstrap device from the backend: %w", err)
|
||||
}
|
||||
var retrievedEntries []*shared.EncHistoryEntry
|
||||
err = json.Unmarshal(respBody, &retrievedEntries)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load JSON response: %v", err)
|
||||
return fmt.Errorf("failed to load JSON response: %w", err)
|
||||
}
|
||||
for _, entry := range retrievedEntries {
|
||||
decEntry, err := data.DecryptHistoryEntry(userSecret, *entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to decrypt history entry from server: %v", err)
|
||||
return fmt.Errorf("failed to decrypt history entry from server: %w", err)
|
||||
}
|
||||
AddToDbIfNew(db, decEntry)
|
||||
}
|
||||
@ -252,30 +252,30 @@ func ImportHistory(ctx *context.Context, shouldReadStdin, force bool) (int, erro
|
||||
bashHistPath := filepath.Join(homedir, ".bash_history")
|
||||
historyEntries, err := readFileToArray(bashHistPath)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to parse bash history: %v", err)
|
||||
return 0, fmt.Errorf("failed to parse bash history: %w", err)
|
||||
}
|
||||
zshHistPath := filepath.Join(homedir, ".zsh_history")
|
||||
extraEntries, err := readFileToArray(zshHistPath)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to parse zsh history: %v", err)
|
||||
return 0, fmt.Errorf("failed to parse zsh history: %w", err)
|
||||
}
|
||||
historyEntries = append(historyEntries, extraEntries...)
|
||||
extraEntries, err = parseFishHistory(homedir)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to parse fish history: %v", err)
|
||||
return 0, fmt.Errorf("failed to parse fish history: %w", err)
|
||||
}
|
||||
historyEntries = append(historyEntries, extraEntries...)
|
||||
if histfile := os.Getenv("HISTFILE"); histfile != "" && histfile != zshHistPath && histfile != bashHistPath {
|
||||
extraEntries, err := readFileToArray(histfile)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to parse histfile: %v", err)
|
||||
return 0, fmt.Errorf("failed to parse histfile: %w", err)
|
||||
}
|
||||
historyEntries = append(historyEntries, extraEntries...)
|
||||
}
|
||||
if shouldReadStdin {
|
||||
extraEntries, err = readStdin()
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to read stdin: %v", err)
|
||||
return 0, fmt.Errorf("failed to read stdin: %w", err)
|
||||
}
|
||||
historyEntries = append(historyEntries, extraEntries...)
|
||||
}
|
||||
@ -307,17 +307,17 @@ func ImportHistory(ctx *context.Context, shouldReadStdin, force bool) (int, erro
|
||||
}
|
||||
err = ReliableDbCreate(db, entry)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to insert imported history entry: %v", err)
|
||||
return 0, fmt.Errorf("failed to insert imported history entry: %w", err)
|
||||
}
|
||||
}
|
||||
err = Reupload(ctx)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to upload hishtory import: %v", err)
|
||||
return 0, fmt.Errorf("failed to upload hishtory import: %w", err)
|
||||
}
|
||||
config.HaveCompletedInitialImport = true
|
||||
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)
|
||||
return 0, fmt.Errorf("failed to mark initial import as completed, this may lead to duplicate history entries: %w", err)
|
||||
}
|
||||
// Trigger a checkpoint so that these bulk entries are added from the WAL to the main DB
|
||||
db.Exec("PRAGMA wal_checkpoint")
|
||||
@ -386,12 +386,12 @@ func readFileToArray(path string) ([]string, error) {
|
||||
func GetDownloadData() (shared.UpdateInfo, error) {
|
||||
respBody, err := ApiGet("/api/v1/download")
|
||||
if err != nil {
|
||||
return shared.UpdateInfo{}, fmt.Errorf("failed to download update info: %v", err)
|
||||
return shared.UpdateInfo{}, fmt.Errorf("failed to download update info: %w", err)
|
||||
}
|
||||
var downloadData shared.UpdateInfo
|
||||
err = json.Unmarshal(respBody, &downloadData)
|
||||
if err != nil {
|
||||
return shared.UpdateInfo{}, fmt.Errorf("failed to parse update info: %v", err)
|
||||
return shared.UpdateInfo{}, fmt.Errorf("failed to parse update info: %w", err)
|
||||
}
|
||||
return downloadData, nil
|
||||
}
|
||||
@ -438,7 +438,7 @@ func Update(ctx *context.Context) error {
|
||||
homedir := hctx.GetHome(ctx)
|
||||
err = syscall.Unlink(path.Join(homedir, data.GetHishtoryPath(), "hishtory"))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unlink %s for update: %v", path.Join(homedir, data.GetHishtoryPath(), "hishtory"), err)
|
||||
return fmt.Errorf("failed to unlink %s for update: %w", path.Join(homedir, data.GetHishtoryPath(), "hishtory"), err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -450,7 +450,7 @@ func Update(ctx *context.Context) error {
|
||||
cmd.Stderr = &stderr
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to chmod +x the update (stdout=%#v, stderr=%#v): %v", stdout.String(), stderr.String(), err)
|
||||
return fmt.Errorf("failed to chmod +x the update (stdout=%#v, stderr=%#v): %w", stdout.String(), stderr.String(), err)
|
||||
}
|
||||
cmd = exec.Command(getTmpClientPath(), "install")
|
||||
cmd.Stdout = os.Stdout
|
||||
@ -458,7 +458,7 @@ func Update(ctx *context.Context) error {
|
||||
cmd.Stdin = os.Stdin
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to install update (stderr=%#v), is %s in a noexec directory? (if so, set the TMPDIR environment variable): %v", stderr.String(), getTmpClientPath(), err)
|
||||
return fmt.Errorf("failed to install update (stderr=%#v), is %s in a noexec directory? (if so, set the TMPDIR environment variable): %w", stderr.String(), getTmpClientPath(), err)
|
||||
}
|
||||
fmt.Printf("Successfully updated hishtory from v0.%s to %s\n", Version, downloadData.Version)
|
||||
return nil
|
||||
@ -550,7 +550,7 @@ func stripCodeSignature(inPath, outPath string) error {
|
||||
cmd.Stderr = &stderr
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to use codesign_allocate to strip signatures on binary=%v (stdout=%#v, stderr%#v): %v", inPath, stdout.String(), stderr.String(), err)
|
||||
return fmt.Errorf("failed to use codesign_allocate to strip signatures on binary=%v (stdout=%#v, stderr%#v): %w", inPath, stdout.String(), stderr.String(), err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -591,7 +591,7 @@ func downloadFile(filename, url string) error {
|
||||
// Download the data
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to download file at %s to %s: %v", url, filename, err)
|
||||
return fmt.Errorf("failed to download file at %s to %s: %w", url, filename, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != 200 {
|
||||
@ -609,7 +609,7 @@ func downloadFile(filename, url string) error {
|
||||
// Create the file
|
||||
out, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to save file to %s: %v", filename, err)
|
||||
return fmt.Errorf("failed to save file to %s: %w", filename, err)
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
@ -636,12 +636,12 @@ func ApiGet(path string) ([]byte, error) {
|
||||
start := time.Now()
|
||||
req, err := http.NewRequest("GET", getServerHostname()+path, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create GET: %v", err)
|
||||
return nil, fmt.Errorf("failed to create GET: %w", err)
|
||||
}
|
||||
req.Header.Set("X-Hishtory-Version", "v0."+Version)
|
||||
resp, err := httpClient().Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to GET %s%s: %v", getServerHostname(), path, err)
|
||||
return nil, fmt.Errorf("failed to GET %s%s: %w", getServerHostname(), path, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != 200 {
|
||||
@ -649,7 +649,7 @@ func ApiGet(path string) ([]byte, error) {
|
||||
}
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read response body from GET %s%s: %v", getServerHostname(), path, err)
|
||||
return nil, fmt.Errorf("failed to read response body from GET %s%s: %w", getServerHostname(), path, err)
|
||||
}
|
||||
duration := time.Since(start)
|
||||
hctx.GetLogger().Infof("ApiGet(%#v): %s\n", path, duration.String())
|
||||
@ -663,13 +663,13 @@ func ApiPost(path, contentType string, data []byte) ([]byte, error) {
|
||||
start := time.Now()
|
||||
req, err := http.NewRequest("POST", getServerHostname()+path, bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create POST: %v", err)
|
||||
return nil, fmt.Errorf("failed to create POST: %w", err)
|
||||
}
|
||||
req.Header.Set("Content-Type", contentType)
|
||||
req.Header.Set("X-Hishtory-Version", "v0."+Version)
|
||||
resp, err := httpClient().Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to POST %s: %v", path, err)
|
||||
return nil, fmt.Errorf("failed to POST %s: %w", path, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != 200 {
|
||||
@ -677,7 +677,7 @@ func ApiPost(path, contentType string, data []byte) ([]byte, error) {
|
||||
}
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read response body from POST %s: %v", path, err)
|
||||
return nil, fmt.Errorf("failed to read response body from POST %s: %w", path, err)
|
||||
}
|
||||
duration := time.Since(start)
|
||||
hctx.GetLogger().Infof("ApiPost(%#v): %s\n", path, duration.String())
|
||||
@ -721,13 +721,13 @@ func ReliableDbCreate(db *gorm.DB, entry interface{}) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("unrecoverable sqlite error: %v", err)
|
||||
return fmt.Errorf("unrecoverable sqlite error: %w", err)
|
||||
}
|
||||
if err != nil && err.Error() != "database is locked (5) (SQLITE_BUSY)" {
|
||||
return fmt.Errorf("unrecoverable sqlite error: %v", err)
|
||||
return fmt.Errorf("unrecoverable sqlite error: %w", err)
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("failed to create DB entry even with %d retries: %v", i, err)
|
||||
return fmt.Errorf("failed to create DB entry even with %d retries: %w", i, err)
|
||||
}
|
||||
|
||||
func EncryptAndMarshal(config hctx.ClientConfig, entries []*data.HistoryEntry) ([]byte, error) {
|
||||
@ -742,7 +742,7 @@ func EncryptAndMarshal(config hctx.ClientConfig, entries []*data.HistoryEntry) (
|
||||
}
|
||||
jsonValue, err := json.Marshal(encEntries)
|
||||
if err != nil {
|
||||
return jsonValue, fmt.Errorf("failed to marshal encrypted history entry: %v", err)
|
||||
return jsonValue, fmt.Errorf("failed to marshal encrypted history entry: %w", err)
|
||||
}
|
||||
return jsonValue, nil
|
||||
}
|
||||
@ -754,16 +754,16 @@ func Reupload(ctx *context.Context) error {
|
||||
}
|
||||
entries, err := Search(ctx, hctx.GetDb(ctx), "", 0)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to reupload due to failed search: %v", err)
|
||||
return fmt.Errorf("failed to reupload due to failed search: %w", err)
|
||||
}
|
||||
for _, chunk := range shared.Chunks(entries, 100) {
|
||||
jsonValue, err := EncryptAndMarshal(config, chunk)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to reupload due to failed encryption: %v", err)
|
||||
return fmt.Errorf("failed to reupload due to failed encryption: %w", err)
|
||||
}
|
||||
_, err = ApiPost("/api/v1/submit?source_device_id="+config.DeviceId, "application/json", jsonValue)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to reupload due to failed POST: %v", err)
|
||||
return fmt.Errorf("failed to reupload due to failed POST: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@ -785,12 +785,12 @@ func RetrieveAdditionalEntriesFromRemote(ctx *context.Context) error {
|
||||
var retrievedEntries []*shared.EncHistoryEntry
|
||||
err = json.Unmarshal(respBody, &retrievedEntries)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load JSON response: %v", err)
|
||||
return fmt.Errorf("failed to load JSON response: %w", err)
|
||||
}
|
||||
for _, entry := range retrievedEntries {
|
||||
decEntry, err := data.DecryptHistoryEntry(config.UserSecret, *entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to decrypt history entry from server: %v", err)
|
||||
return fmt.Errorf("failed to decrypt history entry from server: %w", err)
|
||||
}
|
||||
AddToDbIfNew(db, decEntry)
|
||||
}
|
||||
@ -819,7 +819,7 @@ func ProcessDeletionRequests(ctx *context.Context) error {
|
||||
for _, entry := range request.Messages.Ids {
|
||||
res := db.Where("device_id = ? AND end_time = ?", entry.DeviceId, entry.Date).Delete(&data.HistoryEntry{})
|
||||
if res.Error != nil {
|
||||
return fmt.Errorf("DB error: %v", res.Error)
|
||||
return fmt.Errorf("DB error: %w", res.Error)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -843,7 +843,7 @@ func parseTimeGenerously(input string) (time.Time, error) {
|
||||
func MakeWhereQueryFromSearch(ctx *context.Context, db *gorm.DB, query string) (*gorm.DB, error) {
|
||||
tokens, err := tokenize(query)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to tokenize query: %v", err)
|
||||
return nil, fmt.Errorf("failed to tokenize query: %w", err)
|
||||
}
|
||||
tx := db.Model(&data.HistoryEntry{}).Where("true")
|
||||
for _, token := range tokens {
|
||||
@ -903,7 +903,7 @@ func Search(ctx *context.Context, db *gorm.DB, query string, limit int) ([]*data
|
||||
var historyEntries []*data.HistoryEntry
|
||||
result := tx.Find(&historyEntries)
|
||||
if result.Error != nil {
|
||||
return nil, fmt.Errorf("DB query error: %v", result.Error)
|
||||
return nil, fmt.Errorf("DB query error: %w", result.Error)
|
||||
}
|
||||
return historyEntries, nil
|
||||
}
|
||||
@ -931,13 +931,13 @@ func parseAtomizedToken(ctx *context.Context, token string) (string, interface{}
|
||||
case "before":
|
||||
t, err := parseTimeGenerously(val)
|
||||
if err != nil {
|
||||
return "", nil, nil, fmt.Errorf("failed to parse before:%s as a timestamp: %v", val, err)
|
||||
return "", nil, nil, fmt.Errorf("failed to parse before:%s as a timestamp: %w", val, err)
|
||||
}
|
||||
return "(CAST(strftime(\"%s\",start_time) AS INTEGER) < ?)", t.Unix(), nil, nil
|
||||
case "after":
|
||||
t, err := parseTimeGenerously(val)
|
||||
if err != nil {
|
||||
return "", nil, nil, fmt.Errorf("failed to parse after:%s as a timestamp: %v", val, err)
|
||||
return "", nil, nil, fmt.Errorf("failed to parse after:%s as a timestamp: %w", val, err)
|
||||
}
|
||||
return "(CAST(strftime(\"%s\",start_time) AS INTEGER) > ?)", t.Unix(), nil, nil
|
||||
case "start_time":
|
||||
@ -945,7 +945,7 @@ func parseAtomizedToken(ctx *context.Context, token string) (string, interface{}
|
||||
// internally for pre-saving history entries.
|
||||
t, err := parseTimeGenerously(val)
|
||||
if err != nil {
|
||||
return "", nil, nil, fmt.Errorf("failed to parse after:%s as a timestamp: %v", val, err)
|
||||
return "", nil, nil, fmt.Errorf("failed to parse after:%s as a timestamp: %w", val, err)
|
||||
}
|
||||
return "(CAST(strftime(\"%s\",start_time) AS INTEGER) = ?)", t.Unix(), nil, nil
|
||||
case "command":
|
||||
@ -960,7 +960,7 @@ func parseAtomizedToken(ctx *context.Context, token string) (string, interface{}
|
||||
// Also get all ones that are in the DB
|
||||
names, err := getAllCustomColumnNames(ctx)
|
||||
if err != nil {
|
||||
return "", nil, nil, fmt.Errorf("failed to get custom column names from the DB: %v", err)
|
||||
return "", nil, nil, fmt.Errorf("failed to get custom column names from the DB: %w", err)
|
||||
}
|
||||
knownCustomColumns = append(knownCustomColumns, names...)
|
||||
// Check if the atom is for a custom column that exists and if it isn't, return an error
|
||||
@ -1079,7 +1079,7 @@ func SendDeletionRequest(deletionRequest shared.DeletionRequest) error {
|
||||
}
|
||||
_, err = ApiPost("/api/v1/add-deletion-request", "application/json", data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to send deletion request to backend service, this may cause commands to not get deleted on other instances of hishtory: %v", err)
|
||||
return fmt.Errorf("failed to send deletion request to backend service, this may cause commands to not get deleted on other instances of hishtory: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ func verifyBinary(ctx *context.Context, binaryPath, attestationPath, versionTag
|
||||
|
||||
attestation, err := os.ReadFile(attestationPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read attestation file: %v", err)
|
||||
return fmt.Errorf("failed to read attestation file: %w", err)
|
||||
}
|
||||
|
||||
hash, err := getFileHash(binaryPath)
|
||||
@ -75,13 +75,13 @@ func verifyBinary(ctx *context.Context, binaryPath, attestationPath, versionTag
|
||||
func getFileHash(binaryPath string) (string, error) {
|
||||
binaryFile, err := os.Open(binaryPath)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to read binary for verification purposes: %v", err)
|
||||
return "", fmt.Errorf("failed to read binary for verification purposes: %w", err)
|
||||
}
|
||||
defer binaryFile.Close()
|
||||
|
||||
hasher := sha256.New()
|
||||
if _, err := io.Copy(hasher, binaryFile); err != nil {
|
||||
return "", fmt.Errorf("failed to hash binary: %v", err)
|
||||
return "", fmt.Errorf("failed to hash binary: %w", err)
|
||||
}
|
||||
hash := hex.EncodeToString(hasher.Sum(nil))
|
||||
return hash, nil
|
||||
@ -95,5 +95,5 @@ func handleSlsaFailure(srcErr error) error {
|
||||
fmt.Println("Proceeding with update...")
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("failed to verify SLSA provenance of the updated binary, aborting update (to bypass, set `export HISHTORY_DISABLE_SLSA_ATTESTATION=true`): %v", srcErr)
|
||||
return fmt.Errorf("failed to verify SLSA provenance of the updated binary, aborting update (to bypass, set `export HISHTORY_DISABLE_SLSA_ATTESTATION=true`): %w", srcErr)
|
||||
}
|
||||
|
@ -381,7 +381,7 @@ func getRows(ctx *context.Context, columnNames []string, query string, numEntrie
|
||||
entry.Command = strings.ReplaceAll(entry.Command, "\n", "\\n")
|
||||
row, err := buildTableRow(ctx, columnNames, *entry)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to build row for entry=%#v: %v", entry, err)
|
||||
return nil, nil, fmt.Errorf("failed to build row for entry=%#v: %w", entry, err)
|
||||
}
|
||||
rows = append(rows, row)
|
||||
filteredData = append(filteredData, entry)
|
||||
@ -449,7 +449,7 @@ func makeTableColumns(ctx *context.Context, columnNames []string, rows []table.R
|
||||
// Get the actual terminal width. If we're below this, opportunistically add some padding aiming for the maximum column widths
|
||||
terminalWidth, _, err := getTerminalSize()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get terminal size: %v", err)
|
||||
return nil, fmt.Errorf("failed to get terminal size: %w", err)
|
||||
}
|
||||
for totalWidth < (terminalWidth - len(columnNames)) {
|
||||
prevTotalWidth := totalWidth
|
||||
|
Loading…
Reference in New Issue
Block a user