mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 11:01:25 +01:00
fix: address verified review findings (issues-1)
Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
16 files changed
+225
-27
No files matched your search
@@ -388,8 +388,12 @@ func (s Issues) applyChanges(ctx context.Context, n int64, opts IssueEdit) (Issu
|
||||
return opts, err
|
||||
}
|
||||
if len(changes.AddLabels)+len(changes.RemoveLabels) > 0 {
|
||||
ids := make([]int64, len(current.Labels))
|
||||
for i, label := range current.Labels {
|
||||
kept, err := s.withoutReplacedExclusive(ctx, current.Labels, changes.AddLabels)
|
||||
if err != nil {
|
||||
return opts, err
|
||||
}
|
||||
ids := make([]int64, len(kept))
|
||||
for i, label := range kept {
|
||||
ids[i] = label.ID
|
||||
}
|
||||
ids = mergeUnique(ids, changes.AddLabels, changes.RemoveLabels, func(a, b int64) bool { return a == b })
|
||||
@@ -402,6 +406,44 @@ func (s Issues) applyChanges(ctx context.Context, n int64, opts IssueEdit) (Issu
|
||||
return opts, nil
|
||||
}
|
||||
|
||||
// withoutReplacedExclusive drops the current labels that an added label of the same exclusive
|
||||
// scope replaces. Gitea keeps one label per scope but picks it by name, not by recency, so
|
||||
// sending both would keep whichever sorts last.
|
||||
func (s Issues) withoutReplacedExclusive(ctx context.Context, current []Label, add []int64) ([]Label, error) {
|
||||
if len(add) == 0 || !slices.ContainsFunc(current, func(l Label) bool { return l.Exclusive }) {
|
||||
return current, nil
|
||||
}
|
||||
all, err := (Labels{Client: s.Client, Repository: s.Repository}).All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
owner, _, _ := strings.Cut(s.Repository, "/")
|
||||
if _, isOrg, err := organization(ctx, s.Client, owner); err != nil {
|
||||
return nil, err
|
||||
} else if isOrg {
|
||||
shared, err := (Labels{Client: s.Client, Organization: owner}).All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
all = append(all, shared...)
|
||||
}
|
||||
replaced := map[string]bool{}
|
||||
for _, label := range all {
|
||||
if scope := exclusiveScope(label); scope != "" && slices.Contains(add, label.ID) {
|
||||
replaced[scope] = true
|
||||
}
|
||||
}
|
||||
return slices.DeleteFunc(slices.Clone(current), func(l Label) bool { return replaced[exclusiveScope(l)] }), nil
|
||||
}
|
||||
|
||||
// exclusiveScope is the name of an exclusive label up to its last slash, or "" for any other label.
|
||||
func exclusiveScope(label Label) string {
|
||||
if i := strings.LastIndex(label.Name, "/"); label.Exclusive && i > 0 {
|
||||
return label.Name[:i]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// mergeUnique applies additions and removals to current values, preserving order.
|
||||
func mergeUnique[T any](current, add, remove []T, equal func(T, T) bool) []T {
|
||||
result := []T{}
|
||||
|
||||
Reference in new issue
Block a user