labels.go

  1//
  2// Copyright 2017, Sander van Harmelen
  3//
  4// Licensed under the Apache License, Version 2.0 (the "License");
  5// you may not use this file except in compliance with the License.
  6// You may obtain a copy of the License at
  7//
  8//     http://www.apache.org/licenses/LICENSE-2.0
  9//
 10// Unless required by applicable law or agreed to in writing, software
 11// distributed under the License is distributed on an "AS IS" BASIS,
 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13// See the License for the specific language governing permissions and
 14// limitations under the License.
 15//
 16
 17package gitlab
 18
 19import (
 20	"encoding/json"
 21	"fmt"
 22)
 23
 24// LabelsService handles communication with the label related methods of the
 25// GitLab API.
 26//
 27// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html
 28type LabelsService struct {
 29	client *Client
 30}
 31
 32// Label represents a GitLab label.
 33//
 34// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html
 35type Label struct {
 36	ID                     int    `json:"id"`
 37	Name                   string `json:"name"`
 38	Color                  string `json:"color"`
 39	TextColor              string `json:"text_color"`
 40	Description            string `json:"description"`
 41	OpenIssuesCount        int    `json:"open_issues_count"`
 42	ClosedIssuesCount      int    `json:"closed_issues_count"`
 43	OpenMergeRequestsCount int    `json:"open_merge_requests_count"`
 44	Subscribed             bool   `json:"subscribed"`
 45	Priority               int    `json:"priority"`
 46	IsProjectLabel         bool   `json:"is_project_label"`
 47}
 48
 49// UnmarshalJSON implements the json.Unmarshaler interface.
 50func (l *Label) UnmarshalJSON(data []byte) error {
 51	type alias Label
 52	if err := json.Unmarshal(data, (*alias)(l)); err != nil {
 53		return err
 54	}
 55
 56	if l.Name == "" {
 57		var raw map[string]interface{}
 58		if err := json.Unmarshal(data, &raw); err != nil {
 59			return err
 60		}
 61		if title, ok := raw["title"].(string); ok {
 62			l.Name = title
 63		}
 64	}
 65
 66	return nil
 67}
 68
 69func (l Label) String() string {
 70	return Stringify(l)
 71}
 72
 73// ListLabelsOptions represents the available ListLabels() options.
 74//
 75// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#list-labels
 76type ListLabelsOptions ListOptions
 77
 78// ListLabels gets all labels for given project.
 79//
 80// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#list-labels
 81func (s *LabelsService) ListLabels(pid interface{}, opt *ListLabelsOptions, options ...OptionFunc) ([]*Label, *Response, error) {
 82	project, err := parseID(pid)
 83	if err != nil {
 84		return nil, nil, err
 85	}
 86	u := fmt.Sprintf("projects/%s/labels", pathEscape(project))
 87
 88	req, err := s.client.NewRequest("GET", u, opt, options)
 89	if err != nil {
 90		return nil, nil, err
 91	}
 92
 93	var l []*Label
 94	resp, err := s.client.Do(req, &l)
 95	if err != nil {
 96		return nil, resp, err
 97	}
 98
 99	return l, resp, err
100}
101
102// CreateLabelOptions represents the available CreateLabel() options.
103//
104// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#create-a-new-label
105type CreateLabelOptions struct {
106	Name        *string `url:"name,omitempty" json:"name,omitempty"`
107	Color       *string `url:"color,omitempty" json:"color,omitempty"`
108	Description *string `url:"description,omitempty" json:"description,omitempty"`
109}
110
111// CreateLabel creates a new label for given repository with given name and
112// color.
113//
114// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#create-a-new-label
115func (s *LabelsService) CreateLabel(pid interface{}, opt *CreateLabelOptions, options ...OptionFunc) (*Label, *Response, error) {
116	project, err := parseID(pid)
117	if err != nil {
118		return nil, nil, err
119	}
120	u := fmt.Sprintf("projects/%s/labels", pathEscape(project))
121
122	req, err := s.client.NewRequest("POST", u, opt, options)
123	if err != nil {
124		return nil, nil, err
125	}
126
127	l := new(Label)
128	resp, err := s.client.Do(req, l)
129	if err != nil {
130		return nil, resp, err
131	}
132
133	return l, resp, err
134}
135
136// DeleteLabelOptions represents the available DeleteLabel() options.
137//
138// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#delete-a-label
139type DeleteLabelOptions struct {
140	Name *string `url:"name,omitempty" json:"name,omitempty"`
141}
142
143// DeleteLabel deletes a label given by its name.
144//
145// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#delete-a-label
146func (s *LabelsService) DeleteLabel(pid interface{}, opt *DeleteLabelOptions, options ...OptionFunc) (*Response, error) {
147	project, err := parseID(pid)
148	if err != nil {
149		return nil, err
150	}
151	u := fmt.Sprintf("projects/%s/labels", pathEscape(project))
152
153	req, err := s.client.NewRequest("DELETE", u, opt, options)
154	if err != nil {
155		return nil, err
156	}
157
158	return s.client.Do(req, nil)
159}
160
161// UpdateLabelOptions represents the available UpdateLabel() options.
162//
163// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#delete-a-label
164type UpdateLabelOptions struct {
165	Name        *string `url:"name,omitempty" json:"name,omitempty"`
166	NewName     *string `url:"new_name,omitempty" json:"new_name,omitempty"`
167	Color       *string `url:"color,omitempty" json:"color,omitempty"`
168	Description *string `url:"description,omitempty" json:"description,omitempty"`
169}
170
171// UpdateLabel updates an existing label with new name or now color. At least
172// one parameter is required, to update the label.
173//
174// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#edit-an-existing-label
175func (s *LabelsService) UpdateLabel(pid interface{}, opt *UpdateLabelOptions, options ...OptionFunc) (*Label, *Response, error) {
176	project, err := parseID(pid)
177	if err != nil {
178		return nil, nil, err
179	}
180	u := fmt.Sprintf("projects/%s/labels", pathEscape(project))
181
182	req, err := s.client.NewRequest("PUT", u, opt, options)
183	if err != nil {
184		return nil, nil, err
185	}
186
187	l := new(Label)
188	resp, err := s.client.Do(req, l)
189	if err != nil {
190		return nil, resp, err
191	}
192
193	return l, resp, err
194}
195
196// SubscribeToLabel subscribes the authenticated user to a label to receive
197// notifications. If the user is already subscribed to the label, the status
198// code 304 is returned.
199//
200// GitLab API docs:
201// https://docs.gitlab.com/ce/api/labels.html#subscribe-to-a-label
202func (s *LabelsService) SubscribeToLabel(pid interface{}, labelID interface{}, options ...OptionFunc) (*Label, *Response, error) {
203	project, err := parseID(pid)
204	if err != nil {
205		return nil, nil, err
206	}
207	label, err := parseID(labelID)
208	if err != nil {
209		return nil, nil, err
210	}
211	u := fmt.Sprintf("projects/%s/labels/%s/subscribe", pathEscape(project), label)
212
213	req, err := s.client.NewRequest("POST", u, nil, options)
214	if err != nil {
215		return nil, nil, err
216	}
217
218	l := new(Label)
219	resp, err := s.client.Do(req, l)
220	if err != nil {
221		return nil, resp, err
222	}
223
224	return l, resp, err
225}
226
227// UnsubscribeFromLabel unsubscribes the authenticated user from a label to not
228// receive notifications from it. If the user is not subscribed to the label, the
229// status code 304 is returned.
230//
231// GitLab API docs:
232// https://docs.gitlab.com/ce/api/labels.html#unsubscribe-from-a-label
233func (s *LabelsService) UnsubscribeFromLabel(pid interface{}, labelID interface{}, options ...OptionFunc) (*Response, error) {
234	project, err := parseID(pid)
235	if err != nil {
236		return nil, err
237	}
238	label, err := parseID(labelID)
239	if err != nil {
240		return nil, err
241	}
242	u := fmt.Sprintf("projects/%s/labels/%s/unsubscribe", pathEscape(project), label)
243
244	req, err := s.client.NewRequest("POST", u, nil, options)
245	if err != nil {
246		return nil, err
247	}
248
249	return s.client.Do(req, nil)
250}