Repository: rancher/fleet
Pull request #1649 (2023-07-12 14:04:08)

Prevent non-hex chars in release name hash
When a release name must be truncated to comply with Helm's maximum release name length, Fleet truncates the name and builds a new release name as `<name>-<hash>`.

In cases where the last character of `<name>` is a dash, a previous commit would include the character immediately following the dash and place it before the hash, which might cause confusion.

Instead, this commit does not include that character in such cases and increases the hash length by 1, so that characters after the last dash in the release name remain hexadecimal.

Refers to #1511

## Test

```shell
go test ./internal/name/...
```


Patch:
diff --git a/internal/name/name.go b/internal/name/name.go
index ea49a468..15b4db6e 100644
--- a/internal/name/name.go
+++ b/internal/name/name.go
@@ -20,8 +20,12 @@ var (
 )
 
 // Limit the length of a string to count characters. If the string's length is
-// greater than count, it will be truncated and a hash will be appended to the
-// end.
+// greater than count, it will be truncated and a separator will be appended to
+// the end, followed by a hash.
+// If the last character of the truncated string is the separator, then the
+// separator itself is omitted. This prevents the result from containing two
+// consecutive separators. In such a case, the result will be [count -1]
+// characters long.
 // If count is too small to include the shortened hash the string is simply
 // truncated.
 func Limit(s string, count int) string {
@@ -29,20 +33,21 @@ func Limit(s string, count int) string {
 		return s
 	}
 
-	if count <= 6 {
+	const hexLen int = 5
+	separator := "-"
+
+	if count <= hexLen+len(separator) {
 		return s[:count]
 	}
 
-	separator := "-"
-	nbCharsBeforeTrim := count - 6
+	nbCharsBeforeTrim := count - hexLen - len(separator)
 
 	// If the last character of the truncated string is the separator, include it instead of the separator.
 	if string(s[nbCharsBeforeTrim-1]) == separator {
 		separator = ""
-		nbCharsBeforeTrim++
 	}
 
-	return fmt.Sprintf("%s%s%s", s[:nbCharsBeforeTrim], separator, Hex(s, 5))
+	return fmt.Sprintf("%s%s%s", s[:nbCharsBeforeTrim], separator, Hex(s, hexLen))
 }
 
 // Hex returns a hex-encoded hash of the string and truncates it to length.


Test patch:
diff --git a/internal/name/name_test.go b/internal/name/name_test.go
index 38b35abf..c6b1dcab 100644
--- a/internal/name/name_test.go
+++ b/internal/name/name_test.go
@@ -31,7 +31,7 @@ var _ = Describe("Name", func() {
 			{arg: "12345678", n: 8, result: "12345678"},
 			{arg: "12345678", n: 7, result: "1-25d55"},
 			{arg: "123456789", n: 8, result: "12-25f9e"},
-			{arg: "1-3456789", n: 8, result: "1-39b657"}, // no double dash in the result
+			{arg: "1-3456789", n: 8, result: "1-9b657"}, // no double dash in the result
 		}
 
 		It("matches expected results", func() {
@@ -53,7 +53,7 @@ var _ = Describe("Name", func() {
 			{arg: "long-name-test--App_-_12.factor", result: "long-name-test-app-12-factor-0efbac37"},
 			{arg: "bundle.name.example.com", result: "bundle-name-example-com-645ef821"},
 			// no double dash in the result
-			{arg: str53[0:46] + "-1234567", result: "1234567890123456789012345678901234567890123456-1d0bce"},
+			{arg: str53[0:46] + "-1234567", result: "1234567890123456789012345678901234567890123456-d0bce"},
 		}
 
 		It("matches expected results", func() {