Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/entries/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ func EditCmd() *cobra.Command {
os.Exit(1)
}

descriptionInput = strings.TrimSpace(descriptionInput)
descriptionInput = ui.SanitizeSingleLine(descriptionInput)
if descriptionInput == "" {
descriptionInput = currentDescription
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/entries/manual.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func ManualCmd() *cobra.Command {
os.Exit(1)
}

projectInput = strings.TrimSpace(projectInput)
projectInput = ui.SanitizeSingleLine(projectInput)
if projectInput == "" {
projectName = projectHint
} else {
Expand Down Expand Up @@ -249,7 +249,7 @@ func ManualCmd() *cobra.Command {
os.Exit(1)
}

descVal = strings.TrimSpace(descVal)
descVal = ui.SanitizeSingleLine(descVal)
if descVal != "" {
description = descVal
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/milestones/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func StartCmd() *cobra.Command {
os.Exit(1)
}

milestoneName := args[0]
milestoneName := ui.SanitizeSingleLine(args[0])

// Check if there's already an active milestone
activeMilestone, err := db.GetActiveMilestoneForProject(projectName)
Expand Down
2 changes: 1 addition & 1 deletion cmd/tracking/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func StartCmd() *cobra.Command {

description := ""
if len(args) > 0 {
description = args[0]
description = ui.SanitizeSingleLine(args[0])
}

var hourlyRate *float64
Expand Down
8 changes: 8 additions & 0 deletions internal/ui/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ui
import (
"fmt"
"os"
"strings"
"time"

"github.com/DylanDevelops/tmpo/internal/shell"
Expand Down Expand Up @@ -159,6 +160,13 @@ func FormatFileSize(bytes int64) string {
return fmt.Sprintf("%.1f MB", float64(bytes)/(1024*1024))
}

func SanitizeSingleLine(s string) string {
s = strings.ReplaceAll(s, "\r\n", " ")
s = strings.ReplaceAll(s, "\r", " ")
s = strings.ReplaceAll(s, "\n", " ")
return strings.TrimSpace(s)
}

func FormatDuration(d time.Duration) string {
totalSeconds := int(d.Seconds())
days := totalSeconds / 86400
Expand Down
71 changes: 71 additions & 0 deletions internal/ui/ui_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,77 @@ func TestFormatFileSize(t *testing.T) {
}
}

func TestSanitizeSingleLine(t *testing.T) {
tests := []struct {
name string
input string
expected string
}{
{
name: "plain string unchanged",
input: "hello world",
expected: "hello world",
},
{
name: "trims leading and trailing whitespace",
input: " hello world ",
expected: "hello world",
},
{
name: "replaces newline with space",
input: "hello\nworld",
expected: "hello world",
},
{
name: "replaces carriage return with space",
input: "hello\rworld",
expected: "hello world",
},
{
name: "replaces CRLF with space",
input: "hello\r\nworld",
expected: "hello world",
},
{
name: "replaces multiple newlines",
input: "hello\n\nworld",
expected: "hello world",
},
{
name: "trims trailing newline",
input: "hello\n",
expected: "hello",
},
{
name: "trims leading newline",
input: "\nhello",
expected: "hello",
},
{
name: "empty string stays empty",
input: "",
expected: "",
},
{
name: "only whitespace becomes empty",
input: " \n\t ",
expected: "",
},
{
name: "mixed newlines and spaces",
input: " something blah blah blah \n ",
expected: "something blah blah blah",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := SanitizeSingleLine(tt.input)
assert.Equal(t, tt.expected, result)
})
}
}

func TestFormatDuration(t *testing.T) {
tests := []struct {
name string
Expand Down
Loading