Skip to content

Commit

Permalink
Merge pull request #1159 from wakatime/develop
Browse files Browse the repository at this point in the history
Release v1.112.1
  • Loading branch information
gandarez authored Jan 16, 2025
2 parents 1edc457 + a33e838 commit eb8d10d
Show file tree
Hide file tree
Showing 25 changed files with 1,026 additions and 364 deletions.
10 changes: 6 additions & 4 deletions USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ api_key_vault_cmd = command arg arg ... (space-separated, no shell syntax)
api_url = https://api.wakatime.com/api/v1
hide_file_names = false
hide_project_names = false
hide_branch_names =
hide_branch_names = false
hide_dependencies = false
hide_project_folder = false
exclude =
^COMMIT_EDITMSG$
Expand Down Expand Up @@ -95,6 +96,7 @@ some/submodule/name = new project name
| hide_file_names | Obfuscate filenames. Will not send file names to api. | _bool_;_list_ | `false` |
| hide_project_names | Obfuscate project names. When a project folder is detected instead of using the folder name as the project, a `.wakatime-project file` is created with a random project name. | _bool_;_list_ | `false` |
| hide_branch_names | Obfuscate branch names. Will not send revision control branch names to api. | _bool_;_list_ | `false` |
| hide_dependencies | Prevent sending imports/libraries/dependencies used in currently focused file to the api. | _bool_;_list_ | `false` |
| hide_project_folder | When set, send the file's path relative to the project folder. For ex: `/User/me/projects/bar/src/file.ts` is sent as `src/file.ts` so the server never sees the full path. When the project folder cannot be detected, only the file name is sent. For ex: `file.ts`. | _bool_ | `false` |
| exclude | Filename patterns to exclude from logging. POSIX regex syntax. | _bool_;_list_ | |
| include | Filename patterns to log. When used in combination with `exclude`, files matching `include` will still be logged. POSIX regex syntax | _bool_;_list_ | |
Expand Down Expand Up @@ -142,9 +144,9 @@ However, if an api key exists in your `~/.wakatime.cfg` file then it takes prece

### Git Section

| option | description | type | default value |
| --- | --- | --- | --- |
| submodules_disabled | It will be matched against the submodule path and if matching, will skip it. | _bool_;_list_ | false |
| option | description | type | default value |
| --- | --- | --- | --- |
| submodules_disabled | It will be matched against the submodule path and if matching, will skip it. | _bool_;_list_ | false |

### Git Submodule Project Map Section

Expand Down
9 changes: 5 additions & 4 deletions cmd/fileexperts/fileexperts.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,11 @@ func initHandleOptions(params paramscmd.Params) []heartbeat.HandleOption {
ExcludeUnknownProject: params.Heartbeat.Filter.ExcludeUnknownProject,
}),
heartbeat.WithSanitization(heartbeat.SanitizeConfig{
BranchPatterns: params.Heartbeat.Sanitize.HideBranchNames,
FilePatterns: params.Heartbeat.Sanitize.HideFileNames,
HideProjectFolder: params.Heartbeat.Sanitize.HideProjectFolder,
ProjectPatterns: params.Heartbeat.Sanitize.HideProjectNames,
BranchPatterns: params.Heartbeat.Sanitize.HideBranchNames,
DependencyPatterns: params.Heartbeat.Sanitize.HideDependencies,
FilePatterns: params.Heartbeat.Sanitize.HideFileNames,
HideProjectFolder: params.Heartbeat.Sanitize.HideProjectFolder,
ProjectPatterns: params.Heartbeat.Sanitize.HideProjectNames,
}),
fileexperts.WithValidation(),
filter.WithLengthValidator(),
Expand Down
14 changes: 7 additions & 7 deletions cmd/heartbeat/heartbeat.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,8 @@ func Run(ctx context.Context, v *viper.Viper) (int, error) {
if err != nil {
var errauth api.ErrAuth

// api.ErrAuth represents an error when parsing api key.
// Save heartbeats to offline db even when api key invalid.
// It avoids losing heartbeats when api key is invalid.
// api.ErrAuth represents an error when parsing api key or timeout.
// Save heartbeats to offline db when api.ErrAuth as it avoids losing heartbeats.
if errors.As(err, &errauth) {
if err := offlinecmd.SaveHeartbeats(ctx, v, nil, queueFilepath); err != nil {
logger.Errorf("failed to save heartbeats to offline queue: %s", err)
Expand Down Expand Up @@ -327,10 +326,11 @@ func initHandleOptions(params paramscmd.Params) []heartbeat.HandleOption {
ExcludeUnknownProject: params.Heartbeat.Filter.ExcludeUnknownProject,
}),
heartbeat.WithSanitization(heartbeat.SanitizeConfig{
BranchPatterns: params.Heartbeat.Sanitize.HideBranchNames,
FilePatterns: params.Heartbeat.Sanitize.HideFileNames,
HideProjectFolder: params.Heartbeat.Sanitize.HideProjectFolder,
ProjectPatterns: params.Heartbeat.Sanitize.HideProjectNames,
BranchPatterns: params.Heartbeat.Sanitize.HideBranchNames,
DependencyPatterns: params.Heartbeat.Sanitize.HideDependencies,
FilePatterns: params.Heartbeat.Sanitize.HideFileNames,
HideProjectFolder: params.Heartbeat.Sanitize.HideProjectFolder,
ProjectPatterns: params.Heartbeat.Sanitize.HideProjectNames,
}),
remote.WithCleanup(),
filter.WithLengthValidator(),
Expand Down
14 changes: 9 additions & 5 deletions cmd/heartbeat/heartbeat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ func TestSendHeartbeats_NonExistingEntity(t *testing.T) {
assert.Contains(t, string(output), "skipping because of non-existing file")
}

func TestSendHeartbeats_IsUnsavedEntity(t *testing.T) {
func TestSendHeartbeats_ExtraHeartbeatsIsUnsavedEntity(t *testing.T) {
resetSingleton(t)

testServerURL, router, tearDown := setupTestServer()
Expand Down Expand Up @@ -639,8 +639,8 @@ func TestSendHeartbeats_IsUnsavedEntity(t *testing.T) {

expectedBodyStr := fmt.Sprintf(
string(expectedBody),
entities[0].Entity, userAgent,
entities[1].Entity, userAgent,
entities[0].Entity, subfolders, userAgent,
entities[1].Entity, subfolders, userAgent,
entities[2].Entity, subfolders, userAgent,
)

Expand Down Expand Up @@ -707,7 +707,6 @@ func TestSendHeartbeats_IsUnsavedEntity(t *testing.T) {
v.Set("lines-in-file", 91)
v.Set("plugin", plugin)
v.Set("time", 1585598051)
v.Set("timeout", 5)
v.Set("extra-heartbeats", true)
v.Set("log-file", logFile.Name())
v.Set("verbose", true)
Expand Down Expand Up @@ -1062,7 +1061,12 @@ func TestSendHeartbeats_ObfuscateProject(t *testing.T) {
lines, err := project.ReadFile(ctx, filepath.Join(fp, "wakatime-cli", ".wakatime-project"), 1)
require.NoError(t, err)

expectedBodyStr := fmt.Sprintf(string(expectedBody), entity.Entity, lines[0], heartbeat.UserAgent(ctx, plugin))
expectedBodyStr := fmt.Sprintf(
string(expectedBody),
entity.Entity,
lines[0],
heartbeat.UserAgent(ctx, plugin),
)

assert.True(t, strings.HasSuffix(entity.Entity, "src/pkg/file.go"))
assert.JSONEq(t, expectedBodyStr, string(body))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"lineno": 11,
"lines": 91,
"project": "wakatime-cli",
"project_root_count": %d,
"type": "file",
"time": 1585598051,
"user_agent": "%s"
Expand All @@ -20,6 +21,7 @@
"lineno": 42,
"lines": 45,
"project": "wakatime-cli",
"project_root_count": %d,
"type": "file",
"time": 1585598052,
"user_agent": "%s"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[
{
"branch": "master",
"category": "debugging",
"entity": "%s",
"is_write": true,
Expand Down
242 changes: 130 additions & 112 deletions cmd/logfile/logfile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,125 +19,143 @@ func TestLoadParams(t *testing.T) {

defer tmpFile.Close()

ctx := context.Background()

v := viper.New()
v.Set("log-file", tmpFile.Name())
v.Set("log-to-stdout", true)
v.Set("metrics", true)
v.Set("verbose", true)
v.Set("send-diagnostics-on-errors", true)

params, err := logfile.LoadParams(ctx, v)
require.NoError(t, err)

assert.True(t, params.Verbose)
assert.True(t, params.Metrics)
assert.True(t, params.ToStdout)
assert.True(t, params.SendDiagsOnErrors)
assert.Equal(t, tmpFile.Name(), params.File)
}

func TestLoadParams_LogFile_FlagDeprecated(t *testing.T) {
tmpFile, err := os.CreateTemp(t.TempDir(), "")
require.NoError(t, err)

defer tmpFile.Close()

ctx := context.Background()

v := viper.New()
v.Set("logfile", tmpFile.Name())

params, err := logfile.LoadParams(ctx, v)
require.NoError(t, err)

assert.Equal(t, tmpFile.Name(), params.File)
}

func TestLoadParams_LogFile_FromConfig(t *testing.T) {
tmpFile, err := os.CreateTemp(t.TempDir(), "")
require.NoError(t, err)

defer tmpFile.Close()

ctx := context.Background()

v := viper.New()
v.Set("settings.log_file", tmpFile.Name())

params, err := logfile.LoadParams(ctx, v)
require.NoError(t, err)

assert.Equal(t, tmpFile.Name(), params.File)
}

func TestLoadParams_LogFile_FromEnvVar(t *testing.T) {
tmpFile, err := os.CreateTemp(t.TempDir(), "")
require.NoError(t, err)

defer tmpFile.Close()

dir, _ := filepath.Split(tmpFile.Name())

logFile, err := os.Create(filepath.Join(dir, "wakatime.log"))
ctx := context.Background()

v := viper.New()

t.Setenv("WAKATIME_HOME", dir)

params, err := logfile.LoadParams(ctx, v)
require.NoError(t, err)

defer logFile.Close()
assert.Equal(t, filepath.Join(dir, "wakatime.log"), params.File)
}

home, err := os.UserHomeDir()
func TestLoadParams_LogFile_FlagTakesPrecedence(t *testing.T) {
tmpFile, err := os.CreateTemp(t.TempDir(), "")
require.NoError(t, err)

defer tmpFile.Close()

ctx := context.Background()

tests := map[string]struct {
EnvVar string
ViperDebug bool
ViperDebugConfig bool
ViperLogFile string
ViperLogFileConfig string
ViperLogFileOld string
ViperMetrics bool
ViperMetricsConfig bool
ViperToStdout bool
Expected logfile.Params
}{
"verbose set": {
ViperDebug: true,
Expected: logfile.Params{
File: filepath.Join(home, ".wakatime", "wakatime.log"),
Verbose: true,
},
},
"verbose from config": {
ViperDebugConfig: true,
Expected: logfile.Params{
File: filepath.Join(home, ".wakatime", "wakatime.log"),
Verbose: true,
},
},
"log file flag takes precedence": {
ViperLogFile: tmpFile.Name(),
ViperLogFileConfig: "otherfolder/wakatime.config.log",
ViperLogFileOld: "otherfolder/wakatime.old.log",
Expected: logfile.Params{
File: tmpFile.Name(),
},
},
"log file deprecated flag takes precedence": {
ViperLogFileConfig: "otherfolder/wakatime.config.log",
ViperLogFileOld: tmpFile.Name(),
Expected: logfile.Params{
File: tmpFile.Name(),
},
},
"log file from config": {
ViperLogFileConfig: tmpFile.Name(),
Expected: logfile.Params{
File: tmpFile.Name(),
},
},
"log file from WAKATIME_HOME": {
EnvVar: dir,
Expected: logfile.Params{
File: filepath.Join(dir, "wakatime.log"),
},
},
"log file from home dir": {
Expected: logfile.Params{
File: filepath.Join(home, ".wakatime", "wakatime.log"),
},
},
"metrics set": {
ViperMetrics: true,
Expected: logfile.Params{
File: filepath.Join(home, ".wakatime", "wakatime.log"),
Metrics: true,
},
},
"metrics from config": {
ViperMetricsConfig: true,
Expected: logfile.Params{
File: filepath.Join(home, ".wakatime", "wakatime.log"),
Metrics: true,
},
},
"metrics flag takes precedence": {
ViperMetrics: true,
ViperMetricsConfig: false,
Expected: logfile.Params{
File: filepath.Join(home, ".wakatime", "wakatime.log"),
Metrics: true,
},
},
"log to stdout": {
ViperToStdout: true,
Expected: logfile.Params{
File: filepath.Join(home, ".wakatime", "wakatime.log"),
ToStdout: true,
},
},
}

for name, test := range tests {
t.Run(name, func(t *testing.T) {
v := viper.New()
v.Set("log-file", test.ViperLogFile)
v.Set("logfile", test.ViperLogFileOld)
v.Set("log-to-stdout", test.ViperToStdout)
v.Set("metrics", test.ViperMetrics)
v.Set("settings.metrics", test.ViperMetricsConfig)
v.Set("settings.log_file", test.ViperLogFileConfig)
v.Set("settings.debug", test.ViperDebug)
v.Set("verbose", test.ViperDebugConfig)

t.Setenv("WAKATIME_HOME", test.EnvVar)

params, err := logfile.LoadParams(ctx, v)
require.NoError(t, err)

assert.Equal(t, test.Expected, params)
})
}
v := viper.New()
v.Set("log-file", tmpFile.Name())
v.Set("settings.log_file", "otherfolder/wakatime.config.log")

params, err := logfile.LoadParams(ctx, v)
require.NoError(t, err)

assert.Equal(t, tmpFile.Name(), params.File)
}

func TestLoadParams_Metrics_FromConfig(t *testing.T) {
ctx := context.Background()

v := viper.New()
v.Set("settings.metrics", true)

params, err := logfile.LoadParams(ctx, v)
require.NoError(t, err)

assert.True(t, params.Metrics)
}

func TestLoadParams_Metrics_FlagTakesPrecedence(t *testing.T) {
ctx := context.Background()

v := viper.New()
v.Set("metrics", false)
v.Set("settings.metrics", true)

params, err := logfile.LoadParams(ctx, v)
require.NoError(t, err)

assert.False(t, params.Metrics)
}

func TestLoadParams_Verbose_FromConfig(t *testing.T) {
ctx := context.Background()

v := viper.New()
v.Set("settings.debug", true)

params, err := logfile.LoadParams(ctx, v)
require.NoError(t, err)

assert.True(t, params.Verbose)
}

func TestLoadParams_Verbose_FlagTakesPrecedence(t *testing.T) {
ctx := context.Background()

v := viper.New()
v.Set("verbose", false)
v.Set("settings.debug", true)

params, err := logfile.LoadParams(ctx, v)
require.NoError(t, err)

assert.False(t, params.Verbose)
}
Loading

0 comments on commit eb8d10d

Please sign in to comment.