diff --git a/Makefile b/Makefile index 18923b90..f2163c30 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,10 @@ help: ## Show this help. @fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//' +fmt: + gofumpt -l -w -extra . + gci write --custom-order -s standard -s 'Prefix(github.com/ddworken/hishtory)' -s default . + local-install: ## Build and install hishtory locally from the current directory go build; ./hishtory install @@ -9,7 +13,7 @@ forcetest: ## Force running all tests without a test cache make test test: ## Run all tests - TZ='America/Los_Angeles' HISHTORY_TEST=1 HISHTORY_SKIP_INIT_IMPORT=1 gotestsum --packages ./... --rerun-fails=10 --rerun-fails-max-failures=30 --format testname --jsonfile /tmp/testrun.json --post-run-command "go run client/posttest/main.go export" -- -p 1 -timeout 90m + TZ='America/Los_Angeles' HISHTORY_TEST=1 HISHTORY_SKIP_INIT_IMPORT=1 gotestsum --packages ./... --rerun-fails=10 --rerun-fails-max-failures=30 --format testname --jsonfile /tmp/testrun.json --post-run-command "go run client/posttest/main.go export" -- -p 1 -timeout 90m ftest: ## Run a specific test specified via `make ftest FILTER=TestParam/testTui/color` go clean -testcache @@ -23,26 +27,26 @@ release: ## [ddworken only] Release the latest version on Github expr `cat VERSION` + 1 > VERSION git add VERSION git commit -m "Release v0.`cat VERSION`" --no-verify - git push + git push gh release create v0.`cat VERSION` --generate-notes git push && git push --tags -build-static: ## [ddworken only] Build the server for hishtory.dev +build-static: ## [ddworken only] Build the server for hishtory.dev ssh server "cd ~/code/hishtory/; git pull; docker build --build-arg GOARCH=amd64 --tag gcr.io/dworken-k8s/hishtory-static --file backend/web/caddy/Dockerfile ." -build-api: ## [ddworken only] Build the API for api.hishtory.dev +build-api: ## [ddworken only] Build the API for api.hishtory.dev rm hishtory server || true docker build --build-arg GOARCH=amd64 --tag gcr.io/dworken-k8s/hishtory-api --file backend/server/Dockerfile . -deploy-static: ## [ddworken only] Build and deploy the server for hishtory.dev +deploy-static: ## [ddworken only] Build and deploy the server for hishtory.dev deploy-static: build-static ssh server "docker push gcr.io/dworken-k8s/hishtory-static" ssh monoserver "cd ~/infra/ && docker compose pull hishtory-static && docker compose rm -svf hishtory-static && docker compose up -d hishtory-static" -deploy-api: ## [ddworken only] Build and deploy the API server for api.hishtory.dev +deploy-api: ## [ddworken only] Build and deploy the API server for api.hishtory.dev deploy-api: build-api docker push gcr.io/dworken-k8s/hishtory-api ssh monoserver "cd ~/infra/ && docker compose pull hishtory-api && docker compose up -d --no-deps hishtory-api" -deploy: ## [ddworken only] Build and deploy all backend services +deploy: ## [ddworken only] Build and deploy all backend services deploy: release deploy-static deploy-api diff --git a/backend/server/internal/database/db.go b/backend/server/internal/database/db.go index 308836c3..b66e57cc 100644 --- a/backend/server/internal/database/db.go +++ b/backend/server/internal/database/db.go @@ -8,6 +8,7 @@ import ( "time" "github.com/ddworken/hishtory/shared" + "github.com/jackc/pgx/v4/stdlib" _ "github.com/lib/pq" sqltrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/database/sql" diff --git a/backend/server/internal/database/historyentries.go b/backend/server/internal/database/historyentries.go index b7d5eef0..2fd42c21 100644 --- a/backend/server/internal/database/historyentries.go +++ b/backend/server/internal/database/historyentries.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/ddworken/hishtory/shared" + "gorm.io/gorm" ) diff --git a/backend/server/internal/database/usagedata.go b/backend/server/internal/database/usagedata.go index 0a270675..e5c303f0 100644 --- a/backend/server/internal/database/usagedata.go +++ b/backend/server/internal/database/usagedata.go @@ -65,7 +65,7 @@ func (db *DB) UpdateUsageDataForNumEntriesHandled(ctx context.Context, userId, d return nil } -func (db *DB) UpdateUsageDataClientVersion(ctx context.Context, userID, deviceID string, version string) error { +func (db *DB) UpdateUsageDataClientVersion(ctx context.Context, userID, deviceID, version string) error { tx := db.DB.WithContext(ctx).Exec("UPDATE usage_data SET version = ? WHERE user_id = ? AND device_id = ?", version, userID, deviceID) if tx.Error != nil { diff --git a/backend/server/internal/release/release_test.go b/backend/server/internal/release/release_test.go index 57b602db..5d2d0820 100644 --- a/backend/server/internal/release/release_test.go +++ b/backend/server/internal/release/release_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/ddworken/hishtory/shared/testutils" + "github.com/stretchr/testify/require" ) diff --git a/backend/server/internal/server/api_handlers.go b/backend/server/internal/server/api_handlers.go index d815e57d..5f873017 100644 --- a/backend/server/internal/server/api_handlers.go +++ b/backend/server/internal/server/api_handlers.go @@ -12,6 +12,7 @@ import ( "github.com/ddworken/hishtory/backend/server/internal/database" "github.com/ddworken/hishtory/shared" "github.com/ddworken/hishtory/shared/ai" + "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" ) @@ -195,7 +196,6 @@ func (s *Server) apiGetPendingDumpRequestsHandler(w http.ResponseWriter, r *http func (s *Server) apiDownloadHandler(w http.ResponseWriter, r *http.Request) { err := json.NewEncoder(w).Encode(s.updateInfo) - if err != nil { panic(fmt.Errorf("failed to JSON marshall the update info: %w", err)) } diff --git a/backend/server/internal/server/server_test.go b/backend/server/internal/server/server_test.go index 6d87ef58..f775a256 100644 --- a/backend/server/internal/server/server_test.go +++ b/backend/server/internal/server/server_test.go @@ -14,15 +14,15 @@ import ( "time" "github.com/ddworken/hishtory/backend/server/internal/database" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "gorm.io/gorm" - "github.com/ddworken/hishtory/client/data" "github.com/ddworken/hishtory/shared" "github.com/ddworken/hishtory/shared/testutils" + "github.com/go-test/deep" "github.com/google/uuid" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gorm.io/gorm" ) var DB *database.DB diff --git a/backend/server/internal/server/srv.go b/backend/server/internal/server/srv.go index 5e2bcbc3..19bdc5a2 100644 --- a/backend/server/internal/server/srv.go +++ b/backend/server/internal/server/srv.go @@ -9,9 +9,10 @@ import ( "strings" "time" - "github.com/DataDog/datadog-go/statsd" "github.com/ddworken/hishtory/backend/server/internal/database" "github.com/ddworken/hishtory/shared" + + "github.com/DataDog/datadog-go/statsd" httptrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/net/http" ) @@ -27,8 +28,10 @@ type Server struct { updateInfo shared.UpdateInfo } -type CronFn func(ctx context.Context, db *database.DB, stats *statsd.Client) error -type Option func(*Server) +type ( + CronFn func(ctx context.Context, db *database.DB, stats *statsd.Client) error + Option func(*Server) +) func WithStatsd(statsd *statsd.Client) Option { return func(s *Server) { @@ -154,7 +157,7 @@ func (s *Server) handleNonCriticalError(err error) { } } -func (s *Server) updateUsageData(ctx context.Context, version string, remoteAddr string, userId, deviceId string, numEntriesHandled int, isQuery bool) error { +func (s *Server) updateUsageData(ctx context.Context, version, remoteAddr, userId, deviceId string, numEntriesHandled int, isQuery bool) error { if !s.trackUsageData { return nil } diff --git a/backend/server/server.go b/backend/server/server.go index 4bcf1ce5..4df83eca 100644 --- a/backend/server/server.go +++ b/backend/server/server.go @@ -7,10 +7,11 @@ import ( "os" "time" - "github.com/DataDog/datadog-go/statsd" "github.com/ddworken/hishtory/backend/server/internal/database" "github.com/ddworken/hishtory/backend/server/internal/release" "github.com/ddworken/hishtory/backend/server/internal/server" + + "github.com/DataDog/datadog-go/statsd" _ "github.com/lib/pq" "gorm.io/gorm" "gorm.io/gorm/logger" @@ -21,10 +22,8 @@ const ( StatsdSocket = "unix:///var/run/datadog/dsd.socket" ) -var ( - // Filled in via ldflags with the latest released version as of the server getting built - ReleaseVersion string -) +// Filled in via ldflags with the latest released version as of the server getting built +var ReleaseVersion string func isTestEnvironment() bool { return os.Getenv("HISHTORY_TEST") != "" @@ -104,8 +103,10 @@ func OpenDB() (*database.DB, error) { return db, nil } -var LAST_USER_STATS_RUN = time.Unix(0, 0) -var LAST_DEEP_CLEAN = time.Unix(0, 0) +var ( + LAST_USER_STATS_RUN = time.Unix(0, 0) + LAST_DEEP_CLEAN = time.Unix(0, 0) +) func cron(ctx context.Context, db *database.DB, stats *statsd.Client) error { // Determine the latest released version of hishtory to serve via the /api/v1/download diff --git a/client/client_test.go b/client/client_test.go index 60467810..3143357c 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -16,10 +16,6 @@ import ( "testing" "time" - "github.com/google/go-cmp/cmp" - "github.com/google/uuid" - "gorm.io/gorm" - "github.com/ddworken/hishtory/client/cmd" "github.com/ddworken/hishtory/client/data" "github.com/ddworken/hishtory/client/hctx" @@ -27,7 +23,11 @@ import ( "github.com/ddworken/hishtory/shared" "github.com/ddworken/hishtory/shared/ai" "github.com/ddworken/hishtory/shared/testutils" + + "github.com/google/go-cmp/cmp" + "github.com/google/uuid" "github.com/stretchr/testify/require" + "gorm.io/gorm" ) func skipSlowTests() bool { @@ -1244,7 +1244,7 @@ func TestStripBashTimePrefix(t *testing.T) { homedir, err := os.UserHomeDir() require.NoError(t, err) f, err := os.OpenFile(path.Join(homedir, data.GetHishtoryPath(), "config.sh"), - os.O_APPEND|os.O_WRONLY, 0644) + os.O_APPEND|os.O_WRONLY, 0o644) require.NoError(t, err) defer f.Close() _, err = f.WriteString("\nexport HISTTIMEFORMAT='%F %T '\n") @@ -1263,7 +1263,7 @@ func TestStripBashTimePrefix(t *testing.T) { homedir, err = os.UserHomeDir() require.NoError(t, err) f, err = os.OpenFile(path.Join(homedir, data.GetHishtoryPath(), "config.sh"), - os.O_APPEND|os.O_WRONLY, 0644) + os.O_APPEND|os.O_WRONLY, 0o644) require.NoError(t, err) defer f.Close() _, err = f.WriteString("\nexport HISTTIMEFORMAT='[%c] '\n") @@ -2983,7 +2983,7 @@ func testMultipleUsers(t *testing.T, tester shellTester) { func createSyntheticImportEntries(t testing.TB, numSyntheticEntries int) { homedir, err := os.UserHomeDir() require.NoError(t, err) - f, err := os.OpenFile(path.Join(homedir, ".bash_history"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + f, err := os.OpenFile(path.Join(homedir, ".bash_history"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644) require.NoError(t, err) defer f.Close() for i := 1; i <= numSyntheticEntries; i++ { diff --git a/client/cmd/configAdd.go b/client/cmd/configAdd.go index 45a951dd..9cd94c31 100644 --- a/client/cmd/configAdd.go +++ b/client/cmd/configAdd.go @@ -7,6 +7,7 @@ import ( "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/client/lib" + "github.com/spf13/cobra" ) diff --git a/client/cmd/configDelete.go b/client/cmd/configDelete.go index 0af8aeb8..6df4c8d8 100644 --- a/client/cmd/configDelete.go +++ b/client/cmd/configDelete.go @@ -6,6 +6,7 @@ import ( "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/client/lib" + "github.com/spf13/cobra" ) @@ -57,6 +58,7 @@ var deleteCustomColumnsCmd = &cobra.Command{ lib.CheckFatalError(hctx.SetConfig(config)) }, } + var deleteDisplayedColumnCommand = &cobra.Command{ Use: "displayed-columns", Aliases: []string{"displayed-column"}, diff --git a/client/cmd/configGet.go b/client/cmd/configGet.go index 8a08b14d..fe854229 100644 --- a/client/cmd/configGet.go +++ b/client/cmd/configGet.go @@ -7,6 +7,7 @@ import ( "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/client/lib" + "github.com/spf13/cobra" ) @@ -41,6 +42,7 @@ var getHighlightMatchesCmd = &cobra.Command{ fmt.Println(config.HighlightMatches) }, } + var getDefaultFilterCmd = &cobra.Command{ Use: "default-filter", Short: "The default filter that is applied to all search queries", diff --git a/client/cmd/configKeyBindings.go b/client/cmd/configKeyBindings.go index dec7d4e9..fd0cf7e7 100644 --- a/client/cmd/configKeyBindings.go +++ b/client/cmd/configKeyBindings.go @@ -6,6 +6,7 @@ import ( "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/client/lib" + "github.com/spf13/cobra" ) diff --git a/client/cmd/configSet.go b/client/cmd/configSet.go index 03cc9af3..cae53685 100644 --- a/client/cmd/configSet.go +++ b/client/cmd/configSet.go @@ -8,6 +8,7 @@ import ( "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/client/lib" + "github.com/spf13/cobra" ) @@ -102,6 +103,7 @@ var setEnableAiCompletionCmd = &cobra.Command{ lib.CheckFatalError(hctx.SetConfig(config)) }, } + var setPresavingCmd = &cobra.Command{ Use: "presaving", Short: "Enable 'presaving' of shell entries that never finish running", diff --git a/client/cmd/enableDisable.go b/client/cmd/enableDisable.go index 5f8224b4..fbc9c4c6 100644 --- a/client/cmd/enableDisable.go +++ b/client/cmd/enableDisable.go @@ -5,6 +5,7 @@ import ( "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/client/lib" + "github.com/spf13/cobra" ) diff --git a/client/cmd/import.go b/client/cmd/import.go index 18d120a0..74385331 100644 --- a/client/cmd/import.go +++ b/client/cmd/import.go @@ -5,6 +5,7 @@ import ( "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/client/lib" + "github.com/spf13/cobra" ) diff --git a/client/cmd/install.go b/client/cmd/install.go index d481c37e..cb1afa43 100644 --- a/client/cmd/install.go +++ b/client/cmd/install.go @@ -19,15 +19,18 @@ import ( "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/client/lib" "github.com/ddworken/hishtory/shared" + "github.com/google/uuid" "github.com/spf13/cobra" "gorm.io/gorm" ) -var offlineInit *bool -var forceInit *bool -var offlineInstall *bool -var skipConfigModification *bool +var ( + offlineInit *bool + forceInit *bool + offlineInstall *bool + skipConfigModification *bool +) var installCmd = &cobra.Command{ Use: "install", @@ -581,7 +584,7 @@ func stripLines(filePath, lines string) error { ret += "\n" } } - return os.WriteFile(filePath, []byte(ret), 0644) + return os.WriteFile(filePath, []byte(ret), 0o644) } func setup(userSecret string, isOffline bool) error { diff --git a/client/cmd/install_test.go b/client/cmd/install_test.go index e8fe6b21..0a435102 100644 --- a/client/cmd/install_test.go +++ b/client/cmd/install_test.go @@ -8,6 +8,7 @@ import ( "github.com/ddworken/hishtory/client/data" "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/shared/testutils" + "github.com/stretchr/testify/require" ) diff --git a/client/cmd/query.go b/client/cmd/query.go index c56bf3e3..1dc4e616 100644 --- a/client/cmd/query.go +++ b/client/cmd/query.go @@ -11,6 +11,7 @@ import ( "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/client/lib" "github.com/ddworken/hishtory/client/tui" + "github.com/fatih/color" "github.com/muesli/termenv" "github.com/rodaine/table" @@ -171,7 +172,7 @@ func DisplayResults(ctx context.Context, results []*data.HistoryEntry, numResult numRows := 0 - var seenCommands = make(map[string]bool) + seenCommands := make(map[string]bool) for _, entry := range results { if config.FilterDuplicateCommands && entry != nil { diff --git a/client/cmd/redact.go b/client/cmd/redact.go index a2e9dbff..1ecc3397 100644 --- a/client/cmd/redact.go +++ b/client/cmd/redact.go @@ -12,6 +12,7 @@ import ( "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/client/lib" "github.com/ddworken/hishtory/shared" + "github.com/spf13/cobra" ) diff --git a/client/cmd/reupload.go b/client/cmd/reupload.go index 88af658c..ccb85a30 100644 --- a/client/cmd/reupload.go +++ b/client/cmd/reupload.go @@ -3,6 +3,7 @@ package cmd import ( "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/client/lib" + "github.com/spf13/cobra" ) diff --git a/client/cmd/root.go b/client/cmd/root.go index 38e1c440..54222cf3 100644 --- a/client/cmd/root.go +++ b/client/cmd/root.go @@ -7,6 +7,7 @@ import ( "os" "github.com/ddworken/hishtory/client/lib" + "github.com/spf13/cobra" ) diff --git a/client/cmd/saveHistoryEntry.go b/client/cmd/saveHistoryEntry.go index 45676cb2..4b70301a 100644 --- a/client/cmd/saveHistoryEntry.go +++ b/client/cmd/saveHistoryEntry.go @@ -19,6 +19,7 @@ import ( "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/client/lib" "github.com/ddworken/hishtory/shared" + "github.com/google/uuid" "github.com/spf13/cobra" "gorm.io/gorm" @@ -441,7 +442,6 @@ func extractCommandFromArg(ctx context.Context, shell, arg string, isPresave boo } else { return "", fmt.Errorf("tried to save a hishtory entry from an unsupported shell=%#v", shell) } - } func trimTrailingWhitespace(s string) string { @@ -582,7 +582,6 @@ func parseCrossPlatformTime(data string) time.Time { } else { return time.Unix(startTime, 0).UTC() } - } func getLastCommand(history string) (string, error) { diff --git a/client/cmd/saveHistoryEntry_test.go b/client/cmd/saveHistoryEntry_test.go index dc7825c1..aedf7929 100644 --- a/client/cmd/saveHistoryEntry_test.go +++ b/client/cmd/saveHistoryEntry_test.go @@ -9,6 +9,7 @@ import ( "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/shared/testutils" + "github.com/stretchr/testify/require" ) @@ -167,6 +168,7 @@ func TestBuildRegexFromTimeFormat(t *testing.T) { } } } + func TestGetLastCommand(t *testing.T) { testcases := []struct { input, expectedOutput string diff --git a/client/cmd/status.go b/client/cmd/status.go index ce3541d7..14e38e71 100644 --- a/client/cmd/status.go +++ b/client/cmd/status.go @@ -6,6 +6,7 @@ import ( "github.com/ddworken/hishtory/client/data" "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/client/lib" + "github.com/spf13/cobra" ) diff --git a/client/cmd/syncing.go b/client/cmd/syncing.go index 5c45a61e..bf90ff5e 100644 --- a/client/cmd/syncing.go +++ b/client/cmd/syncing.go @@ -7,6 +7,7 @@ import ( "github.com/ddworken/hishtory/client/data" "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/client/lib" + "github.com/spf13/cobra" ) diff --git a/client/cmd/update.go b/client/cmd/update.go index 68646db1..ccb12492 100644 --- a/client/cmd/update.go +++ b/client/cmd/update.go @@ -18,6 +18,7 @@ import ( "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/client/lib" "github.com/ddworken/hishtory/shared" + "github.com/spf13/cobra" ) diff --git a/client/cmd/webui.go b/client/cmd/webui.go index 46e2be22..42e60ea6 100644 --- a/client/cmd/webui.go +++ b/client/cmd/webui.go @@ -8,12 +8,15 @@ import ( "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/client/lib" "github.com/ddworken/hishtory/client/webui" + "github.com/spf13/cobra" ) -var disableAuth *bool -var forceCreds *string -var port *int +var ( + disableAuth *bool + forceCreds *string + port *int +) var webUiCmd = &cobra.Command{ Use: "start-web-ui", diff --git a/client/data/data_test.go b/client/data/data_test.go index 268f12f7..28bcf960 100644 --- a/client/data/data_test.go +++ b/client/data/data_test.go @@ -57,5 +57,4 @@ func TestCustomColumnSerialization(t *testing.T) { if val != "[{\"name\":\"name1\",\"value\":\"val1\"},{\"name\":\"name2\",\"value\":\"val2\"}]" { t.Fatalf("unexpected val for empty CustomColumns: %#v", val) } - } diff --git a/client/fuzz_test.go b/client/fuzz_test.go index ab1b59ee..263f5c4a 100644 --- a/client/fuzz_test.go +++ b/client/fuzz_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/ddworken/hishtory/shared/testutils" + "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/require" ) @@ -18,8 +19,10 @@ type operation struct { redactQuery string } -var tmp int = 0 -var runCounter *int = &tmp +var ( + tmp int = 0 + runCounter *int = &tmp +) func fuzzTest(t *testing.T, tester shellTester, input string) { testutils.TestLog(t, fmt.Sprintf("Starting fuzz test for input=%#v", input)) diff --git a/client/hctx/hctx.go b/client/hctx/hctx.go index 1e9ab7af..9c2c778c 100644 --- a/client/hctx/hctx.go +++ b/client/hctx/hctx.go @@ -13,14 +13,14 @@ import ( "github.com/ddworken/hishtory/client/data" "github.com/ddworken/hishtory/client/tui/keybindings" "github.com/ddworken/hishtory/shared" + + // Needed to use sqlite without CGO + "github.com/glebarez/sqlite" "github.com/google/uuid" "github.com/sirupsen/logrus" "gopkg.in/natefinch/lumberjack.v2" "gorm.io/gorm" "gorm.io/gorm/logger" - - // Needed to use sqlite without CGO - "github.com/glebarez/sqlite" ) var ( diff --git a/client/lib/lib.go b/client/lib/lib.go index c90e0ed5..231ae3e4 100644 --- a/client/lib/lib.go +++ b/client/lib/lib.go @@ -5,6 +5,7 @@ import ( "bytes" "context" "database/sql" + _ "embed" // for embedding config.sh "encoding/json" "errors" "fmt" @@ -21,18 +22,15 @@ import ( "strings" "time" - _ "embed" // for embedding config.sh - - "golang.org/x/exp/slices" - "gorm.io/gorm" + "github.com/ddworken/hishtory/client/data" + "github.com/ddworken/hishtory/client/hctx" + "github.com/ddworken/hishtory/shared" "github.com/araddon/dateparse" "github.com/google/uuid" "github.com/schollz/progressbar/v3" - - "github.com/ddworken/hishtory/client/data" - "github.com/ddworken/hishtory/client/hctx" - "github.com/ddworken/hishtory/shared" + "golang.org/x/exp/slices" + "gorm.io/gorm" ) //go:embed config.sh @@ -44,8 +42,10 @@ var ConfigZshContents string //go:embed config.fish var ConfigFishContents string -var Version string = "Unknown" -var GitCommit string = "Unknown" +var ( + Version string = "Unknown" + GitCommit string = "Unknown" +) // 512KB ought to be enough for any reasonable cmd // Funnily enough, 256KB actually wasn't enough. See https://github.com/ddworken/hishtory/issues/93 @@ -732,7 +732,7 @@ func parseTimeGenerously(input string) (time.Time, error) { } // A wrapper around tx.Where(...) that filters out nil-values -func where(tx *gorm.DB, s string, v1 any, v2 any) *gorm.DB { +func where(tx *gorm.DB, s string, v1, v2 any) *gorm.DB { if v1 == nil && v2 == nil { return tx.Where(s) } @@ -791,7 +791,7 @@ func Search(ctx context.Context, db *gorm.DB, query string, limit int) ([]*data. const SEARCH_RETRY_COUNT = 3 -func retryingSearch(ctx context.Context, db *gorm.DB, query string, limit int, currentRetryNum int) ([]*data.HistoryEntry, error) { +func retryingSearch(ctx context.Context, db *gorm.DB, query string, limit, currentRetryNum int) ([]*data.HistoryEntry, error) { if ctx == nil && query != "" { return nil, fmt.Errorf("lib.Search called with a nil context and a non-empty query (this should never happen)") } @@ -986,7 +986,7 @@ func heuristicIgnoreUnclosedQuote(isCurrentlyInQuotedString bool, quoteType rune return true } -func containsUnescaped(query string, token string) bool { +func containsUnescaped(query, token string) bool { runeQuery := []rune(query) for i := 0; i < len(runeQuery); i++ { if runeQuery[i] == '\\' && i+1 < len(runeQuery) { diff --git a/client/lib/lib_test.go b/client/lib/lib_test.go index 68f91e33..2d3ad93b 100644 --- a/client/lib/lib_test.go +++ b/client/lib/lib_test.go @@ -10,6 +10,7 @@ import ( "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/shared" "github.com/ddworken/hishtory/shared/testutils" + "github.com/stretchr/testify/require" ) @@ -142,6 +143,7 @@ func TestChunks(t *testing.T) { } } } + func TestZshWeirdness(t *testing.T) { testcases := []struct { input string diff --git a/client/lib/slsa.go b/client/lib/slsa.go index 2d0bdb65..37b54c73 100644 --- a/client/lib/slsa.go +++ b/client/lib/slsa.go @@ -13,6 +13,7 @@ import ( "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/shared" + "github.com/slsa-framework/slsa-verifier/options" "github.com/slsa-framework/slsa-verifier/verifiers" ) diff --git a/client/posttest/main.go b/client/posttest/main.go index a118e681..c24e05d5 100644 --- a/client/posttest/main.go +++ b/client/posttest/main.go @@ -20,8 +20,10 @@ var GLOBAL_STATSD *statsd.Client = nil var NUM_TEST_RETRIES map[string]int -var UNUSED_GOLDENS []string = []string{"testCustomColumns-query-isAction=false", "testCustomColumns-tquery-bash", - "testCustomColumns-tquery-zsh"} +var UNUSED_GOLDENS []string = []string{ + "testCustomColumns-query-isAction=false", "testCustomColumns-tquery-bash", + "testCustomColumns-tquery-zsh", +} func main() { if os.Args[1] == "export" { @@ -90,7 +92,6 @@ func checkGoldensUsed() { } } fmt.Println("Validated that all goldens in testdata/ were referenced!") - } func exportMetrics() { diff --git a/client/table/table.go b/client/table/table.go index 955e247d..b39aee87 100644 --- a/client/table/table.go +++ b/client/table/table.go @@ -469,7 +469,7 @@ func (m *Model) FromValues(value, separator string) { } func (m Model) headersView() string { - var s = make([]string, 0, len(m.cols)) + s := make([]string, 0, len(m.cols)) for _, col := range m.cols { style := lipgloss.NewStyle().Width(col.Width).MaxWidth(col.Width).Inline(true) renderedCell := style.Render(runewidth.Truncate(col.Title, col.Width, "…")) @@ -491,7 +491,7 @@ func (m *Model) columnNeedsScrolling(columnIdxToCheck int) bool { func (m *Model) renderRow(rowID int) string { isRowSelected := rowID == m.cursor - var s = make([]string, 0, len(m.cols)) + s := make([]string, 0, len(m.cols)) for i, value := range m.rows[rowID] { style := lipgloss.NewStyle().Width(m.cols[i].Width).MaxWidth(m.cols[i].Width).Inline(true) diff --git a/client/testutils.go b/client/testutils.go index 50164171..39bbf49d 100644 --- a/client/testutils.go +++ b/client/testutils.go @@ -21,6 +21,7 @@ import ( "github.com/ddworken/hishtory/client/lib" "github.com/ddworken/hishtory/shared" "github.com/ddworken/hishtory/shared/testutils" + "github.com/stretchr/testify/require" ) diff --git a/client/tui/tui.go b/client/tui/tui.go index d362f4ad..07271fe3 100644 --- a/client/tui/tui.go +++ b/client/tui/tui.go @@ -2,6 +2,7 @@ package tui import ( "context" + _ "embed" // for embedding config.sh "fmt" "os" "path/filepath" @@ -10,14 +11,6 @@ import ( "strings" "time" - _ "embed" // for embedding config.sh - - "github.com/charmbracelet/bubbles/help" - "github.com/charmbracelet/bubbles/key" - "github.com/charmbracelet/bubbles/spinner" - "github.com/charmbracelet/bubbles/textinput" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" "github.com/ddworken/hishtory/client/ai" "github.com/ddworken/hishtory/client/data" "github.com/ddworken/hishtory/client/hctx" @@ -25,23 +18,36 @@ import ( "github.com/ddworken/hishtory/client/table" "github.com/ddworken/hishtory/client/tui/keybindings" "github.com/ddworken/hishtory/shared" + + "github.com/charmbracelet/bubbles/help" + "github.com/charmbracelet/bubbles/key" + "github.com/charmbracelet/bubbles/spinner" + "github.com/charmbracelet/bubbles/textinput" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" "github.com/muesli/termenv" "golang.org/x/term" ) -const TABLE_HEIGHT = 20 -const PADDED_NUM_ENTRIES = TABLE_HEIGHT * 5 +const ( + TABLE_HEIGHT = 20 + PADDED_NUM_ENTRIES = TABLE_HEIGHT * 5 +) -var CURRENT_QUERY_FOR_HIGHLIGHTING string = "" -var SELECTED_COMMAND string = "" +var ( + CURRENT_QUERY_FOR_HIGHLIGHTING string = "" + SELECTED_COMMAND string = "" +) // Globally shared monotonically increasing IDs used to prevent race conditions in handling async queries. // If the user types 'l' and then 's', two queries will be dispatched: One for 'l' and one for 'ls'. These // counters are used to ensure that we don't process the query results for 'ls' and then promptly overwrite // them with the results for 'l'. -var LAST_DISPATCHED_QUERY_ID = 0 -var LAST_DISPATCHED_QUERY_TIMESTAMP time.Time -var LAST_PROCESSED_QUERY_ID = -1 +var ( + LAST_DISPATCHED_QUERY_ID = 0 + LAST_DISPATCHED_QUERY_TIMESTAMP time.Time + LAST_PROCESSED_QUERY_ID = -1 +) type SelectStatus int64 @@ -96,11 +102,14 @@ type model struct { shellName string } -type doneDownloadingMsg struct{} -type offlineMsg struct{} -type bannerMsg struct { - banner string -} +type ( + doneDownloadingMsg struct{} + offlineMsg struct{} + bannerMsg struct { + banner string + } +) + type asyncQueryFinishedMsg struct { // The query ID finished running. Used to ensure that we only process this message if it is the latest query to finish. queryId int @@ -492,7 +501,7 @@ func getRows(ctx context.Context, columnNames []string, shellName, defaultFilter } var rows []table.Row var filteredData []*data.HistoryEntry - var seenCommands = make(map[string]bool) + seenCommands := make(map[string]bool) for i := 0; i < numEntries; i++ { if i < len(searchResults) { @@ -626,6 +635,7 @@ func max(a, b int) int { } return b } + func min(a, b int) int { if a < b { return a diff --git a/client/webui/webui.go b/client/webui/webui.go index a702f710..b5af8ddf 100644 --- a/client/webui/webui.go +++ b/client/webui/webui.go @@ -5,15 +5,15 @@ import ( "crypto/subtle" "embed" "fmt" + "html/template" "net" "net/http" "net/url" - "html/template" - "github.com/ddworken/hishtory/client/data" "github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/client/lib" + "github.com/google/uuid" ) @@ -92,7 +92,6 @@ func webuiHandler(w http.ResponseWriter, r *http.Request) { func getTemplates() *template.Template { return template.Must(template.ParseFS(templateFiles, "templates/*")) - } func buildTableRows(ctx context.Context, entries []*data.HistoryEntry) ([][]string, error) { diff --git a/shared/ai/ai.go b/shared/ai/ai.go index 926b311c..1d01a0e0 100644 --- a/shared/ai/ai.go +++ b/shared/ai/ai.go @@ -9,6 +9,7 @@ import ( "os" "github.com/ddworken/hishtory/client/hctx" + "golang.org/x/exp/slices" ) diff --git a/shared/testutils/testutils.go b/shared/testutils/testutils.go index a5a61dba..44e96b36 100644 --- a/shared/testutils/testutils.go +++ b/shared/testutils/testutils.go @@ -16,6 +16,7 @@ import ( "time" "github.com/ddworken/hishtory/client/data" + "github.com/google/go-cmp/cmp" "github.com/google/uuid" "github.com/stretchr/testify/require" @@ -154,7 +155,7 @@ setopt SHARE_HISTORY if strings.Contains(string(dat), zshrcHistConfig) { return } - f, err := os.OpenFile(path.Join(homedir, ".zshrc"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + f, err := os.OpenFile(path.Join(homedir, ".zshrc"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644) checkError(err) defer f.Close() _, err = f.WriteString(zshrcHistConfig) @@ -290,7 +291,7 @@ func RunTestServer() func() { panic(fmt.Sprintf("server experienced an error\n\n\nstderr=\n%s\n\n\nstdout=%s", stderr.String(), stdout.String())) } // Persist test server logs for debugging - f, err := os.OpenFile("/tmp/hishtory-server.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + f, err := os.OpenFile("/tmp/hishtory-server.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644) checkError(err) defer f.Close() _, err = f.Write([]byte(stdout.String() + "\n")) @@ -332,7 +333,7 @@ func IsGithubAction() bool { } func TestLog(t testing.TB, line string) { - f, err := os.OpenFile("/tmp/test.log", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644) + f, err := os.OpenFile("/tmp/test.log", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0o644) if err != nil { require.NoError(t, err) } @@ -351,7 +352,7 @@ func persistLog() { if err != nil { return } - f, err := os.OpenFile("/tmp/hishtory.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + f, err := os.OpenFile("/tmp/hishtory.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644) checkError(err) defer f.Close() _, err = f.Write(log) @@ -362,7 +363,7 @@ func persistLog() { func recordUsingGolden(t testing.TB, goldenName string) { f, err := os.OpenFile("/tmp/goldens-used.txt", - os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644) if err != nil { t.Fatalf("failed to open file to record using golden: %v", err) } @@ -389,12 +390,12 @@ func CompareGoldens(t testing.TB, out, goldenName string) { if err := os.Mkdir("/tmp/test-goldens", os.ModePerm); err != nil && !os.IsExist(err) { log.Fatal(err) } - require.NoError(t, os.WriteFile(path.Join("/tmp/test-goldens", goldenName), []byte(out), 0644)) + require.NoError(t, os.WriteFile(path.Join("/tmp/test-goldens", goldenName), []byte(out), 0o644)) if os.Getenv("HISHTORY_UPDATE_GOLDENS") == "" { _, filename, line, _ := runtime.Caller(1) t.Fatalf("hishtory golden mismatch for %s at %s:%d (-expected +got):\n%s\nactual=\n%s", goldenName, filename, line, diff, out) } else { - require.NoError(t, os.WriteFile(goldenPath, []byte(out), 0644)) + require.NoError(t, os.WriteFile(goldenPath, []byte(out), 0o644)) } } }