mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 11:01:25 +01:00
feat(label): address labels by name and add import and clone
label edit bug and label delete kind/feature failed with "invalid resource number", and label create took its name as --name and required --color. Like gh, label create takes the name as an argument and picks a random color without -c; label edit and delete take names or IDs (delete several at once, after a confirmation that names them), and -c/-d/-n/-f are the gh short flags. Without a name on a terminal, label create asks for the name, color and description. label list shows ID NAME COLOR DESCRIPTION FLAGS with a colored swatch and exclusive and archived labels flagged. Mutations report ✓ lines. label import reads a label file or stdin (label create --file still works), label clone copies another repository's labels, skipping those that exist unless --force, and label export writes to stdout by default or to -O/--output. Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
10 files changed
+583
-194
No files matched your search
@@ -25,23 +25,41 @@ func (s Labels) finder(byName bool) NameOrID[Label] {
|
||||
return NameOrID[Label]{Kind: "label", Scope: s.Scope(), ID: func(l Label) int64 { return l.ID }, Name: func(l Label) string { return l.Name }, ByName: byName}
|
||||
}
|
||||
|
||||
// Find returns the labels of the scope that raws address, each by ID or name (D10); byName matches
|
||||
// numeric values as names only.
|
||||
func (s Labels) Find(ctx context.Context, raws []string, byName bool) ([]Label, error) {
|
||||
items, err := s.All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := make([]Label, len(raws))
|
||||
for i, raw := range raws {
|
||||
if result[i], err = s.finder(byName).Find(items, raw); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// CreateUnique creates a label unless existing, the labels of the scope, has one with its name,
|
||||
// ignoring case. Then update edits that label with the supplied fields, keeping its name, and
|
||||
// otherwise CreateUnique fails: Gitea would create a second label that name filters cannot tell
|
||||
// apart.
|
||||
func (s Labels) CreateUnique(ctx context.Context, existing []Label, opts LabelOptions, update bool) (Label, error) {
|
||||
// apart. It reports whether it updated a label.
|
||||
func (s Labels) CreateUnique(ctx context.Context, existing []Label, opts LabelOptions, update bool) (Label, bool, error) {
|
||||
current, err := s.finder(true).Find(existing, deref(opts.Name))
|
||||
if errors.As(err, new(*NotFoundError)) {
|
||||
return s.Create(ctx, opts)
|
||||
label, err := s.Create(ctx, opts)
|
||||
return label, false, err
|
||||
}
|
||||
if err != nil {
|
||||
return Label{}, err
|
||||
return Label{}, false, err
|
||||
}
|
||||
if !update {
|
||||
return Label{}, &ConflictError{Reason: ReasonExists, Kind: "label", Key: strconv.Quote(current.Name), Scope: s.Scope(), Hint: "pass --force to update it"}
|
||||
return Label{}, false, &ConflictError{Reason: ReasonExists, Kind: "label", Key: strconv.Quote(current.Name), Scope: s.Scope(), Hint: "pass --force to update it"}
|
||||
}
|
||||
opts.Name = nil
|
||||
return s.Edit(ctx, current.ID, opts)
|
||||
label, err := s.Edit(ctx, current.ID, opts)
|
||||
return label, true, err
|
||||
}
|
||||
|
||||
func selectLabelNames(scope string, names []string, matches map[string][]int64) ([]int64, error) {
|
||||
|
||||
Reference in new issue
Block a user