Replace `SplitStringAtByteN` with `EllipsisStringWholeWord`.

This commit is contained in:
KN4CK3R 2024-08-12 20:01:55 +00:00
parent 3862b31abb
commit 53d6f6cdc9
7 changed files with 65 additions and 18 deletions

View File

@ -13,6 +13,7 @@ import (
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/json"
api "code.gitea.io/gitea/modules/structs"
@ -305,7 +306,7 @@ func InsertRun(ctx context.Context, run *ActionRun, jobs []*jobparser.SingleWork
} else {
hasWaiting = true
}
job.Name, _ = util.SplitStringAtByteN(job.Name, 255)
job.Name = base.EllipsisStringWholeWord(job.Name, 255)
runJobs = append(runJobs, &ActionRunJob{
RunID: run.ID,
RepoID: run.RepoID,

View File

@ -12,6 +12,7 @@ import (
auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
@ -298,9 +299,8 @@ func CreateTaskForRunner(ctx context.Context, runner *ActionRunner) (*ActionTask
if len(workflowJob.Steps) > 0 {
steps := make([]*ActionTaskStep, len(workflowJob.Steps))
for i, v := range workflowJob.Steps {
name, _ := util.SplitStringAtByteN(v.String(), 255)
steps[i] = &ActionTaskStep{
Name: name,
Name: base.EllipsisStringWholeWord(v.String(), 255),
TaskID: task.ID,
Index: int64(i),
RepoID: task.RepoID,

View File

@ -19,6 +19,7 @@ import (
"strconv"
"strings"
"time"
"unicode"
"unicode/utf8"
"code.gitea.io/gitea/modules/git"
@ -131,6 +132,28 @@ func EllipsisString(str string, length int) string {
return string([]rune(str)[:length-3]) + "..."
}
// EllipsisStringWholeWord returns a truncated short string with … appended if the input is larger then the limit.
// If the input contains spaces the string is truncated at the last space before reaching the length limit.
// If the input does not contain a space before reaching the length limit, the input is truncated in the middle of a word.
func EllipsisStringWholeWord(str string, maxLength int) string {
lastSpace := -1
length := 0
for i, r := range str {
if unicode.IsSpace(r) {
lastSpace = i
}
length++
if length > maxLength {
if lastSpace != -1 {
return str[:lastSpace] + "…"
}
return str[:i] + "…"
}
}
return str
}
// TruncateString returns a truncated string with given limit,
// it returns input string if length is not reached limit.
func TruncateString(str string, limit int) string {

View File

@ -129,6 +129,38 @@ func TestEllipsisString(t *testing.T) {
assert.Equal(t, "测试文本一二三四", EllipsisString("测试文本一二三四", 10))
}
func TestEllipsisStringWholeWord(t *testing.T) {
assert.Equal(t, "…", EllipsisStringWholeWord("foobar", 0))
assert.Equal(t, "f…", EllipsisStringWholeWord("foobar", 1))
assert.Equal(t, "fo…", EllipsisStringWholeWord("foobar", 2))
assert.Equal(t, "foo…", EllipsisStringWholeWord("foobar", 3))
assert.Equal(t, "foob…", EllipsisStringWholeWord("foobar", 4))
assert.Equal(t, "fooba…", EllipsisStringWholeWord("foobar", 5))
assert.Equal(t, "foobar", EllipsisStringWholeWord("foobar", 6))
assert.Equal(t, "foobar", EllipsisStringWholeWord("foobar", 10))
assert.Equal(t, "…", EllipsisStringWholeWord("foo bar", 0))
assert.Equal(t, "f…", EllipsisStringWholeWord("foo bar", 1))
assert.Equal(t, "fo…", EllipsisStringWholeWord("foo bar", 2))
assert.Equal(t, "foo…", EllipsisStringWholeWord("foo bar", 3))
assert.Equal(t, "foo…", EllipsisStringWholeWord("foo bar", 4))
assert.Equal(t, "foo…", EllipsisStringWholeWord("foo bar", 5))
assert.Equal(t, "foo…", EllipsisStringWholeWord("foo bar", 6))
assert.Equal(t, "foo bar", EllipsisStringWholeWord("foo bar", 7))
assert.Equal(t, "foo bar", EllipsisStringWholeWord("foo bar", 10))
assert.Equal(t, "foo bar…", EllipsisStringWholeWord("foo bar foo", 7))
assert.Equal(t, "foo bar…", EllipsisStringWholeWord("foo bar foo", 8))
assert.Equal(t, "foo bar…", EllipsisStringWholeWord("foo bar foo", 9))
assert.Equal(t, "foo bar…", EllipsisStringWholeWord("foo bar foo", 10))
assert.Equal(t, "foo bar foo", EllipsisStringWholeWord("foo bar foo", 11))
assert.Equal(t, "测试文本…", EllipsisStringWholeWord("测试文本一二三四", 4))
assert.Equal(t, "测试文本…", EllipsisStringWholeWord("测试文本 一二三四", 6)) // contains special unicode space U+2008
assert.Equal(t, "测试文本一二…", EllipsisStringWholeWord("测试文本一二三四", 6))
assert.Equal(t, "测试文本一二三四", EllipsisStringWholeWord("测试文本一二三四", 10))
}
func TestTruncateString(t *testing.T) {
assert.Equal(t, "", TruncateString("foobar", 0))
assert.Equal(t, "f", TruncateString("foobar", 1))

View File

@ -9,11 +9,11 @@ import (
"path"
"strconv"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
"gopkg.in/yaml.v3"
)
@ -109,7 +109,7 @@ func unmarshal(filename string, content []byte) (*api.IssueTemplate, error) {
it.Content = string(content)
it.Name = path.Base(it.FileName) // paths in Git are always '/' separated - do not use filepath!
it.About, _ = util.SplitStringAtByteN(it.Content, 80)
it.About = base.EllipsisStringWholeWord(it.Content, 80)
} else {
it.Content = templateBody
if it.About == "" {

View File

@ -12,8 +12,8 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/actions"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/util"
actions_service "code.gitea.io/gitea/services/actions"
runnerv1 "code.gitea.io/actions-proto-go/runner/v1"
@ -69,10 +69,9 @@ func (s *Service) Register(
labels := req.Msg.Labels
// create new runner
name, _ := util.SplitStringAtByteN(req.Msg.Name, 255)
runner := &actions_model.ActionRunner{
UUID: gouuid.New().String(),
Name: name,
Name: base.EllipsisStringWholeWord(req.Msg.Name, 255),
OwnerID: runnerToken.OwnerID,
RepoID: runnerToken.RepoID,
Version: req.Msg.Version,

View File

@ -13,11 +13,11 @@ import (
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/util"
notify_service "code.gitea.io/gitea/services/notify"
)
@ -109,15 +109,7 @@ func (a *actionNotifier) CreateIssueComment(ctx context.Context, doer *user_mode
IsPrivate: issue.Repo.IsPrivate,
}
truncatedContent, truncatedRight := util.SplitStringAtByteN(comment.Content, 200)
if truncatedRight != "" {
// in case the content is in a Latin family language, we remove the last broken word.
lastSpaceIdx := strings.LastIndex(truncatedContent, " ")
if lastSpaceIdx != -1 && (len(truncatedContent)-lastSpaceIdx < 15) {
truncatedContent = truncatedContent[:lastSpaceIdx] + "…"
}
}
act.Content = fmt.Sprintf("%d|%s", issue.Index, truncatedContent)
act.Content = fmt.Sprintf("%d|%s", issue.Index, base.EllipsisStringWholeWord(comment.Content, 200))
if issue.IsPull {
act.OpType = activities_model.ActionCommentPull