Skip to content

Commit be1f86b

Browse files
authored
Merge pull request #1219 from wakatime/bugfix/line-changes-negative
Line changes can be negative, and must parse from extra heartbeats json too
2 parents 7f38194 + 472b48d commit be1f86b

File tree

4 files changed

+46
-45
lines changed

4 files changed

+46
-45
lines changed

pkg/params/params.go

Lines changed: 41 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -467,9 +467,7 @@ func loadAPIKey(ctx context.Context, v *viper.Viper, order FlagReadOrder) (strin
467467
func LoadHeartbeatParams(ctx context.Context, v *viper.Viper, order FlagReadOrder) (Heartbeat, error) {
468468
var aiLineChanges *int
469469
if num := v.GetInt("ai-line-changes"); v.IsSet("ai-line-changes") {
470-
if num > 0 {
471-
aiLineChanges = heartbeat.PointerTo(num)
472-
}
470+
aiLineChanges = heartbeat.PointerTo(num)
473471
}
474472

475473
var category heartbeat.Category
@@ -522,9 +520,7 @@ func LoadHeartbeatParams(ctx context.Context, v *viper.Viper, order FlagReadOrde
522520

523521
var humanLineChanges *int
524522
if num := v.GetInt("human-line-changes"); v.IsSet("human-line-changes") {
525-
if num > 0 {
526-
humanLineChanges = heartbeat.PointerTo(num)
527-
}
523+
humanLineChanges = heartbeat.PointerTo(num)
528524
}
529525

530526
var lineNumber *int
@@ -962,18 +958,9 @@ func parseExtraHeartbeat(h ExtraHeartbeat) (*heartbeat.Heartbeat, error) {
962958
}
963959
}
964960

965-
var cursorPosition *int
966-
967-
switch cursorPositionVal := h.CursorPosition.(type) {
968-
case float64:
969-
cursorPosition = heartbeat.PointerTo(int(cursorPositionVal))
970-
case string:
971-
val, err := strconv.Atoi(cursorPositionVal)
972-
if err != nil {
973-
return nil, fmt.Errorf("failed to convert cursor position to int: %s", err)
974-
}
975-
976-
cursorPosition = heartbeat.PointerTo(val)
961+
cursorPosition, err := parseIntegerNumber(h.CursorPosition)
962+
if err != nil {
963+
return nil, fmt.Errorf("failed to convert cursorpos to int: %s", err)
977964
}
978965

979966
var isWrite *bool
@@ -990,32 +977,14 @@ func parseExtraHeartbeat(h ExtraHeartbeat) (*heartbeat.Heartbeat, error) {
990977
isWrite = heartbeat.PointerTo(val)
991978
}
992979

993-
var lineNumber *int
994-
995-
switch lineNumberVal := h.LineNumber.(type) {
996-
case float64:
997-
lineNumber = heartbeat.PointerTo(int(lineNumberVal))
998-
case string:
999-
val, err := strconv.Atoi(lineNumberVal)
1000-
if err != nil {
1001-
return nil, fmt.Errorf("failed to convert line number to int: %s", err)
1002-
}
1003-
1004-
lineNumber = heartbeat.PointerTo(val)
980+
lineNumber, err := parseIntegerNumber(h.LineNumber)
981+
if err != nil {
982+
return nil, fmt.Errorf("failed to convert lineno to int: %s", err)
1005983
}
1006984

1007-
var lines *int
1008-
1009-
switch linesVal := h.Lines.(type) {
1010-
case float64:
1011-
lines = heartbeat.PointerTo(int(linesVal))
1012-
case string:
1013-
val, err := strconv.Atoi(linesVal)
1014-
if err != nil {
1015-
return nil, fmt.Errorf("failed to convert lines to int: %s", err)
1016-
}
1017-
1018-
lines = heartbeat.PointerTo(val)
985+
lines, err := parseIntegerNumber(h.Lines)
986+
if err != nil {
987+
return nil, fmt.Errorf("failed to convert lines to int: %s", err)
1019988
}
1020989

1021990
var time float64
@@ -1071,12 +1040,24 @@ func parseExtraHeartbeat(h ExtraHeartbeat) (*heartbeat.Heartbeat, error) {
10711040
isUnsavedEntity = val
10721041
}
10731042

1043+
aiLineChanges, err := parseIntegerNumber(h.AILineChanges)
1044+
if err != nil {
1045+
return nil, fmt.Errorf("failed to convert ai_line_changes to int: %s", err)
1046+
}
1047+
1048+
humanLineChanges, err := parseIntegerNumber(h.HumanLineChanges)
1049+
if err != nil {
1050+
return nil, fmt.Errorf("failed to convert human_line_changes to int: %s", err)
1051+
}
1052+
10741053
return &heartbeat.Heartbeat{
1054+
AILineChanges: aiLineChanges,
10751055
BranchAlternate: h.BranchAlternate,
10761056
Category: category,
10771057
CursorPosition: cursorPosition,
10781058
Entity: h.Entity,
10791059
EntityType: entityType,
1060+
HumanLineChanges: humanLineChanges,
10801061
IsUnsavedEntity: isUnsavedEntity,
10811062
IsWrite: isWrite,
10821063
Language: h.Language,
@@ -1325,6 +1306,24 @@ func parseBoolOrRegexList(ctx context.Context, s string) ([]regex.Regex, error)
13251306
return patterns, nil
13261307
}
13271308

1309+
func parseIntegerNumber(inp any) (*int, error) {
1310+
var result *int
1311+
1312+
switch val := inp.(type) {
1313+
case float64:
1314+
result = heartbeat.PointerTo(int(val))
1315+
case string:
1316+
v, err := strconv.Atoi(val)
1317+
if err != nil {
1318+
return nil, err
1319+
}
1320+
1321+
result = &v
1322+
}
1323+
1324+
return result, nil
1325+
}
1326+
13281327
// firstNonEmptyString accepts multiple values and return the first non empty string value.
13291328
func firstNonEmptyString(values ...string) string {
13301329
for _, v := range values {

pkg/params/params_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func TestLoadHeartbeatParams_AILineChangesNegative(t *testing.T) {
118118
params, err := paramspkg.LoadHeartbeatParams(t.Context(), v, paramspkg.FlagReadOrderFlagPrecedence)
119119
require.NoError(t, err)
120120

121-
assert.Nil(t, params.AILineChanges)
121+
assert.Equal(t, -789, *params.AILineChanges)
122122
}
123123

124124
func TestLoadHeartbeatParams_AlternateProject(t *testing.T) {
@@ -643,7 +643,7 @@ func TestLoadHeartbeatParams_HumanAdditionsNegative(t *testing.T) {
643643
params, err := paramspkg.LoadHeartbeatParams(t.Context(), v, paramspkg.FlagReadOrderFlagPrecedence)
644644
require.NoError(t, err)
645645

646-
assert.Nil(t, params.HumanLineChanges)
646+
assert.Equal(t, -456, *params.HumanLineChanges)
647647
}
648648

649649
func TestLoadHeartbeatParams_IsUnsavedEntity(t *testing.T) {

testdata/api_heartbeats_request_extra_heartbeats_extra_template.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
"language": "Go",
1010
"lineno": 42,
1111
"lines": 45,
12+
"ai_line_changes": -123,
13+
"human_line_changes": 456,
1214
"project": "wakatime-cli",
1315
"project_root_count": %d,
1416
"type": "file",

testdata/extra_heartbeats.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
[{ "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 1, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "line_additions": 123, "line_deletions": 456, "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598201 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 2, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598202 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 3, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598203 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 4, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598204 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 5, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598205 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 6, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598206 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 7, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598207 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 8, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598208 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 9, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598209 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 10, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598210 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 11, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598211 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 12, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598212 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 13, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598213 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 14, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598214 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 15, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598215 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 16, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598216 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 17, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598217 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 18, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598218 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 19, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598219 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 20, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598220 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 21, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598221 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 22, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598222 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 23, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598223 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "debugging", "cursorpos": 24, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598224 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 25, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598225 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 26, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598226 }]
1+
[{ "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 1, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "line_additions": 123, "line_deletions": 456, "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598201 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 2, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598202 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 3, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598203 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 4, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598204 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 5, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598205 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 6, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598206 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 7, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598207 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 8, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598208 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 9, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598209 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 10, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598210 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 11, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598211 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 12, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598212 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 13, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598213 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 14, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598214 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 15, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598215 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 16, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598216 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 17, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598217 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 18, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598218 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 19, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598219 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 20, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598220 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 21, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598221 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 22, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598222 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 23, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598223 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "debugging", "cursorpos": 24, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598224 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 25, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598225, "ai_line_changes": -123, "human_line_changes": 456 }, { "alternate_language": "Golang", "alternate_project": "billing", "category": "coding", "cursorpos": 26, "entity": "testdata/main.go", "entity_type": "file", "is_write": true, "language": "Go", "lineno": 42, "lines": 45, "project": "wakatime-cli", "time": 1585598226 }]

0 commit comments

Comments
 (0)