Skip to content

Commit 3c3e71b

Browse files
authored
[cloud] improve mutagen session name sanitization (#451)
## Summary Sanitizes the mutagen session name to match the validation done in mutagen's code. Specifically: 1. ensure the first char is a letter 2. ensure only numbers, letters and dash characters are used ## How was it tested? 1. added test 2. copied `rust-stable` example project into folder: `/var/folders/79/1yc1ywp10w9f2xnr_rpp_ff00000gn/T/tmp.XshVTWYu`.Then started `devbox cloud shell` and saw it sync files successfully.
1 parent e5dc817 commit 3c3e71b

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package mutagen
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestSanitizeSessionName(t *testing.T) {
10+
11+
testCases := []struct {
12+
input string
13+
sanitized string
14+
}{
15+
{"7foo", "a7foo"},
16+
{"foo", "foo"},
17+
{"foo/bar", "foo-bar"},
18+
{"foo/bar/baz", "foo-bar-baz"},
19+
{"foo.bar", "foo-bar"},
20+
{"foo_bar", "foo-bar"},
21+
}
22+
23+
for _, testCase := range testCases {
24+
t.Run(testCase.input, func(t *testing.T) {
25+
assert := assert.New(t)
26+
result := SanitizeSessionName(testCase.input)
27+
assert.Equal(testCase.sanitized, result)
28+
})
29+
}
30+
}

internal/cloud/mutagen/types.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ package mutagen
22

33
import (
44
"errors"
5-
"strings"
5+
"unicode"
6+
"unicode/utf8"
67
)
78

89
type SessionIgnore struct {
@@ -33,10 +34,29 @@ func (s *SessionSpec) Validate() error {
3334
return nil
3435
}
3536

37+
// SanitizeSessionName ensures the input string contains letter, number or dash
38+
// runes. This matches the implementation in mutagen's codebase:
39+
// https://github.com/mutagen-io/mutagen/blob/master/pkg/selection/names.go
40+
//
3641
// TODO savil. Refactor SessionSpec so that this is always applied.
3742
// We can make it a struct that uses a constructor, and make Sync a method on the struct.
3843
func SanitizeSessionName(input string) string {
39-
return strings.ReplaceAll(input, ".", "-")
44+
result := make([]byte, 0, len(input))
45+
46+
// note that for-range over a string extracts characters of type rune
47+
for index, char := range input {
48+
// the first character must be a letter
49+
if index == 0 && !unicode.IsLetter(char) {
50+
result = utf8.AppendRune(result, 'a')
51+
}
52+
53+
if unicode.IsLetter(char) || unicode.IsNumber(char) || char == '-' {
54+
result = utf8.AppendRune(result, char)
55+
} else {
56+
result = utf8.AppendRune(result, '-')
57+
}
58+
}
59+
return string(result)
4060
}
4161

4262
// Based on the structs available at: https://github.com/mutagen-io/mutagen/blob/master/pkg/api/models/synchronization/session.go

0 commit comments

Comments
 (0)