Repository: xanzy/go-gitlab (go)

Issue:
gitlab editing labels UpdateLabel function URL 
```PUT /projects/:id/labels/:label_id```
from the doc https://docs.gitlab.com/ee/api/labels.html#edit-an-existing-label

For the UpdateLabel function https://github.com/xanzy/go-gitlab/blob/098437be4ce2607448e2dfa5aaa8509e4e2ac475/labels.go#L224C2-L224C61
```u := fmt.Sprintf("projects/%s/labels", PathEscape(project))```


Pull request description:
Make the (group)labels methods compatible with old and new API versions 
Fixes #2048

Patch:
diff --git a/group_labels.go b/group_labels.go
index 5a39026..8004bb2 100644
--- a/group_labels.go
+++ b/group_labels.go
@@ -79,12 +79,12 @@ func (s *GroupLabelsService) ListGroupLabels(gid interface{}, opt *ListGroupLabe
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ee/api/group_labels.html#get-a-single-group-label
-func (s *GroupLabelsService) GetGroupLabel(gid interface{}, labelID interface{}, options ...RequestOptionFunc) (*GroupLabel, *Response, error) {
+func (s *GroupLabelsService) GetGroupLabel(gid interface{}, lid interface{}, options ...RequestOptionFunc) (*GroupLabel, *Response, error) {
 	group, err := parseID(gid)
 	if err != nil {
 		return nil, nil, err
 	}
-	label, err := parseID(labelID)
+	label, err := parseID(lid)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -108,7 +108,12 @@ func (s *GroupLabelsService) GetGroupLabel(gid interface{}, labelID interface{},
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ee/api/group_labels.html#create-a-new-group-label
-type CreateGroupLabelOptions CreateLabelOptions
+type CreateGroupLabelOptions struct {
+	Name        *string `url:"name,omitempty" json:"name,omitempty"`
+	Color       *string `url:"color,omitempty" json:"color,omitempty"`
+	Description *string `url:"description,omitempty" json:"description,omitempty"`
+	Priority    *int    `url:"priority,omitempty" json:"priority,omitempty"`
+}
 
 // CreateGroupLabel creates a new label for given group with given name and
 // color.
@@ -140,7 +145,9 @@ func (s *GroupLabelsService) CreateGroupLabel(gid interface{}, opt *CreateGroupL
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ee/api/group_labels.html#delete-a-group-label
-type DeleteGroupLabelOptions DeleteLabelOptions
+type DeleteGroupLabelOptions struct {
+	Name *string `url:"name,omitempty" json:"name,omitempty"`
+}
 
 // DeleteGroupLabel deletes a group label given by its name or ID.
 //
@@ -173,20 +180,34 @@ func (s *GroupLabelsService) DeleteGroupLabel(gid interface{}, lid interface{},
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ee/api/group_labels.html#update-a-group-label
-type UpdateGroupLabelOptions UpdateLabelOptions
+type UpdateGroupLabelOptions struct {
+	Name        *string `url:"name,omitempty" json:"name,omitempty"`
+	NewName     *string `url:"new_name,omitempty" json:"new_name,omitempty"`
+	Color       *string `url:"color,omitempty" json:"color,omitempty"`
+	Description *string `url:"description,omitempty" json:"description,omitempty"`
+	Priority    *int    `url:"priority,omitempty" json:"priority,omitempty"`
+}
 
 // UpdateGroupLabel updates an existing label with new name or now color. At least
 // one parameter is required, to update the label.
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ee/api/group_labels.html#update-a-group-label
-func (s *GroupLabelsService) UpdateGroupLabel(gid interface{}, opt *UpdateGroupLabelOptions, options ...RequestOptionFunc) (*GroupLabel, *Response, error) {
+func (s *GroupLabelsService) UpdateGroupLabel(gid interface{}, lid interface{}, opt *UpdateGroupLabelOptions, options ...RequestOptionFunc) (*GroupLabel, *Response, error) {
 	group, err := parseID(gid)
 	if err != nil {
 		return nil, nil, err
 	}
 	u := fmt.Sprintf("groups/%s/labels", PathEscape(group))
 
+	if lid != nil {
+		label, err := parseID(lid)
+		if err != nil {
+			return nil, nil, err
+		}
+		u = fmt.Sprintf("groups/%s/labels/%s", PathEscape(group), PathEscape(label))
+	}
+
 	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
 	if err != nil {
 		return nil, nil, err
@@ -207,12 +228,12 @@ func (s *GroupLabelsService) UpdateGroupLabel(gid interface{}, opt *UpdateGroupL
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ee/api/group_labels.html#subscribe-to-a-group-label
-func (s *GroupLabelsService) SubscribeToGroupLabel(gid interface{}, labelID interface{}, options ...RequestOptionFunc) (*GroupLabel, *Response, error) {
+func (s *GroupLabelsService) SubscribeToGroupLabel(gid interface{}, lid interface{}, options ...RequestOptionFunc) (*GroupLabel, *Response, error) {
 	group, err := parseID(gid)
 	if err != nil {
 		return nil, nil, err
 	}
-	label, err := parseID(labelID)
+	label, err := parseID(lid)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -238,12 +259,12 @@ func (s *GroupLabelsService) SubscribeToGroupLabel(gid interface{}, labelID inte
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ee/api/group_labels.html#unsubscribe-from-a-group-label
-func (s *GroupLabelsService) UnsubscribeFromGroupLabel(gid interface{}, labelID interface{}, options ...RequestOptionFunc) (*Response, error) {
+func (s *GroupLabelsService) UnsubscribeFromGroupLabel(gid interface{}, lid interface{}, options ...RequestOptionFunc) (*Response, error) {
 	group, err := parseID(gid)
 	if err != nil {
 		return nil, err
 	}
-	label, err := parseID(labelID)
+	label, err := parseID(lid)
 	if err != nil {
 		return nil, err
 	}
diff --git a/labels.go b/labels.go
index d36e85b..bc73669 100644
--- a/labels.go
+++ b/labels.go
@@ -108,12 +108,12 @@ func (s *LabelsService) ListLabels(pid interface{}, opt *ListLabelsOptions, opti
 // GetLabel get a single label for a given project.
 //
 // GitLab API docs: https://docs.gitlab.com/ee/api/labels.html#get-a-single-project-label
-func (s *LabelsService) GetLabel(pid interface{}, labelID interface{}, options ...RequestOptionFunc) (*Label, *Response, error) {
+func (s *LabelsService) GetLabel(pid interface{}, lid interface{}, options ...RequestOptionFunc) (*Label, *Response, error) {
 	project, err := parseID(pid)
 	if err != nil {
 		return nil, nil, err
 	}
-	label, err := parseID(labelID)
+	label, err := parseID(lid)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -216,13 +216,21 @@ type UpdateLabelOptions struct {
 // one parameter is required, to update the label.
 //
 // GitLab API docs: https://docs.gitlab.com/ee/api/labels.html#edit-an-existing-label
-func (s *LabelsService) UpdateLabel(pid interface{}, opt *UpdateLabelOptions, options ...RequestOptionFunc) (*Label, *Response, error) {
+func (s *LabelsService) UpdateLabel(pid interface{}, lid interface{}, opt *UpdateLabelOptions, options ...RequestOptionFunc) (*Label, *Response, error) {
 	project, err := parseID(pid)
 	if err != nil {
 		return nil, nil, err
 	}
 	u := fmt.Sprintf("projects/%s/labels", PathEscape(project))
 
+	if lid != nil {
+		label, err := parseID(lid)
+		if err != nil {
+			return nil, nil, err
+		}
+		u = fmt.Sprintf("projects/%s/labels/%s", PathEscape(project), PathEscape(label))
+	}
+
 	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
 	if err != nil {
 		return nil, nil, err
@@ -243,12 +251,12 @@ func (s *LabelsService) UpdateLabel(pid interface{}, opt *UpdateLabelOptions, op
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ee/api/labels.html#subscribe-to-a-label
-func (s *LabelsService) SubscribeToLabel(pid interface{}, labelID interface{}, options ...RequestOptionFunc) (*Label, *Response, error) {
+func (s *LabelsService) SubscribeToLabel(pid interface{}, lid interface{}, options ...RequestOptionFunc) (*Label, *Response, error) {
 	project, err := parseID(pid)
 	if err != nil {
 		return nil, nil, err
 	}
-	label, err := parseID(labelID)
+	label, err := parseID(lid)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -274,12 +282,12 @@ func (s *LabelsService) SubscribeToLabel(pid interface{}, labelID interface{}, o
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ee/api/labels.html#unsubscribe-from-a-label
-func (s *LabelsService) UnsubscribeFromLabel(pid interface{}, labelID interface{}, options ...RequestOptionFunc) (*Response, error) {
+func (s *LabelsService) UnsubscribeFromLabel(pid interface{}, lid interface{}, options ...RequestOptionFunc) (*Response, error) {
 	project, err := parseID(pid)
 	if err != nil {
 		return nil, err
 	}
-	label, err := parseID(labelID)
+	label, err := parseID(lid)
 	if err != nil {
 		return nil, err
 	}
@@ -297,12 +305,12 @@ func (s *LabelsService) UnsubscribeFromLabel(pid interface{}, labelID interface{
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ee/api/labels.html#promote-a-project-label-to-a-group-label
-func (s *LabelsService) PromoteLabel(pid interface{}, labelID interface{}, options ...RequestOptionFunc) (*Response, error) {
+func (s *LabelsService) PromoteLabel(pid interface{}, lid interface{}, options ...RequestOptionFunc) (*Response, error) {
 	project, err := parseID(pid)
 	if err != nil {
 		return nil, err
 	}
-	label, err := parseID(labelID)
+	label, err := parseID(lid)
 	if err != nil {
 		return nil, err
 	}


Test patch:
diff --git a/group_labels_test.go b/group_labels_test.go
index 42c2a32..1fe28e9 100644
--- a/group_labels_test.go
+++ b/group_labels_test.go
@@ -29,18 +29,18 @@ func TestCreateGroupGroupLabel(t *testing.T) {
 
 	mux.HandleFunc("/api/v4/groups/1/labels", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, http.MethodPost)
-		fmt.Fprint(w, `{"id":1, "name": "My / GroupLabel", "color" : "#11FF22"}`)
+		fmt.Fprint(w, `{"id":1, "name": "MyGroupLabel", "color" : "#11FF22"}`)
 	})
 
 	l := &CreateGroupLabelOptions{
-		Name:  Ptr("My / GroupLabel"),
+		Name:  Ptr("MyGroupLabel"),
 		Color: Ptr("#11FF22"),
 	}
 	label, _, err := client.GroupLabels.CreateGroupLabel("1", l)
 	if err != nil {
 		log.Fatal(err)
 	}
-	want := &GroupLabel{ID: 1, Name: "My / GroupLabel", Color: "#11FF22"}
+	want := &GroupLabel{ID: 1, Name: "MyGroupLabel", Color: "#11FF22"}
 	if !reflect.DeepEqual(want, label) {
 		t.Errorf("GroupLabels.CreateGroupLabel returned %+v, want %+v", label, want)
 	}
@@ -62,15 +62,11 @@ func TestDeleteGroupLabelByID(t *testing.T) {
 func TestDeleteGroupLabelByName(t *testing.T) {
 	mux, client := setup(t)
 
-	mux.HandleFunc("/api/v4/groups/1/labels", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/api/v4/groups/1/labels/MyGroupLabel", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, http.MethodDelete)
 	})
 
-	label := &DeleteGroupLabelOptions{
-		Name: Ptr("My / GroupLabel"),
-	}
-
-	_, err := client.GroupLabels.DeleteGroupLabel("1", nil, label)
+	_, err := client.GroupLabels.DeleteGroupLabel("1", "MyGroupLabel", nil)
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -79,19 +75,18 @@ func TestDeleteGroupLabelByName(t *testing.T) {
 func TestUpdateGroupLabel(t *testing.T) {
 	mux, client := setup(t)
 
-	mux.HandleFunc("/api/v4/groups/1/labels", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/api/v4/groups/1/labels/MyGroupLabel", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, http.MethodPut)
-		fmt.Fprint(w, `{"id":1, "name": "New / GroupLabel", "color" : "#11FF23" , "description":"This is updated label"}`)
+		fmt.Fprint(w, `{"id":1, "name": "NewLabel", "color" : "#11FF23" , "description":"This is updated label"}`)
 	})
 
 	l := &UpdateGroupLabelOptions{
-		Name:        Ptr("My / GroupLabel"),
-		NewName:     Ptr("New / GroupLabel"),
+		NewName:     Ptr("NewLabel"),
 		Color:       Ptr("#11FF23"),
 		Description: Ptr("This is updated label"),
 	}
 
-	label, resp, err := client.GroupLabels.UpdateGroupLabel("1", l)
+	label, resp, err := client.GroupLabels.UpdateGroupLabel("1", "MyGroupLabel", l)
 
 	if resp == nil {
 		log.Fatal(err)
@@ -100,7 +95,7 @@ func TestUpdateGroupLabel(t *testing.T) {
 		log.Fatal(err)
 	}
 
-	want := &GroupLabel{ID: 1, Name: "New / GroupLabel", Color: "#11FF23", Description: "This is updated label"}
+	want := &GroupLabel{ID: 1, Name: "NewLabel", Color: "#11FF23", Description: "This is updated label"}
 
 	if !reflect.DeepEqual(want, label) {
 		t.Errorf("GroupLabels.UpdateGroupLabel returned %+v, want %+v", label, want)
diff --git a/labels_test.go b/labels_test.go
index 81260b3..f6a08f1 100644
--- a/labels_test.go
+++ b/labels_test.go
@@ -29,12 +29,12 @@ func TestCreateLabel(t *testing.T) {
 
 	mux.HandleFunc("/api/v4/projects/1/labels", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, http.MethodPost)
-		fmt.Fprint(w, `{"id":1, "name": "My Label", "color" : "#11FF22", "priority": 2}`)
+		fmt.Fprint(w, `{"id":1, "name": "MyLabel", "color" : "#11FF22", "priority": 2}`)
 	})
 
 	// Create new label
 	l := &CreateLabelOptions{
-		Name:     Ptr("My Label"),
+		Name:     Ptr("MyLabel"),
 		Color:    Ptr("#11FF22"),
 		Priority: Ptr(2),
 	}
@@ -42,7 +42,7 @@ func TestCreateLabel(t *testing.T) {
 	if err != nil {
 		log.Fatal(err)
 	}
-	want := &Label{ID: 1, Name: "My Label", Color: "#11FF22", Priority: 2}
+	want := &Label{ID: 1, Name: "MyLabel", Color: "#11FF22", Priority: 2}
 	if !reflect.DeepEqual(want, label) {
 		t.Errorf("Labels.CreateLabel returned %+v, want %+v", label, want)
 	}
@@ -65,16 +65,16 @@ func TestDeleteLabelbyID(t *testing.T) {
 func TestDeleteLabelbyName(t *testing.T) {
 	mux, client := setup(t)
 
-	mux.HandleFunc("/api/v4/projects/1/labels", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/api/v4/projects/1/labels/MyLabel", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, http.MethodDelete)
 	})
 
 	// Delete label
 	label := &DeleteLabelOptions{
-		Name: Ptr("My Label"),
+		Name: Ptr("MyLabel"),
 	}
 
-	_, err := client.Labels.DeleteLabel("1", nil, label)
+	_, err := client.Labels.DeleteLabel("1", "MyLabel", label)
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -83,21 +83,20 @@ func TestDeleteLabelbyName(t *testing.T) {
 func TestUpdateLabel(t *testing.T) {
 	mux, client := setup(t)
 
-	mux.HandleFunc("/api/v4/projects/1/labels", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/api/v4/projects/1/labels/MyLabel", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, http.MethodPut)
 		fmt.Fprint(w, `{"id":1, "name": "New Label", "color" : "#11FF23" , "description":"This is updated label", "priority": 42}`)
 	})
 
 	// Update label
 	l := &UpdateLabelOptions{
-		Name:        Ptr("My Label"),
 		NewName:     Ptr("New Label"),
 		Color:       Ptr("#11FF23"),
 		Description: Ptr("This is updated label"),
 		Priority:    Ptr(42),
 	}
 
-	label, resp, err := client.Labels.UpdateLabel("1", l)
+	label, resp, err := client.Labels.UpdateLabel("1", "MyLabel", l)
 
 	if resp == nil {
 		log.Fatal(err)