Repository: xanzy/go-gitlab
Pull request #1060 (2021-02-08 13:23:39)

Added support for group share with group api
This PR adds support to share a group with another group.  Its the equivalent of `Projects.ShareProjectWithGroup` and `Projects.DeleteSharedProjectFromGroup` for groups.

API: https://docs.gitlab.com/ee/api/groups.html#create-a-link-to-share-a-group-with-another-group


Patch:
diff --git a/groups.go b/groups.go
index 3c547aa..6aab94c 100644
--- a/groups.go
+++ b/groups.go
@@ -531,6 +531,60 @@ func (s *GroupsService) DeleteGroupLDAPLinkForProvider(gid interface{}, provider
 	return s.client.Do(req, nil)
 }
 
+// ShareGroupWithGroupOptions represents the available ShareGroupWithGroup() options.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/groups.html#share-groups-with-groups
+type ShareGroupWithGroupOptions struct {
+	GroupID     *int              `url:"group_id,omitempty" json:"group_id,omitempty"`
+	GroupAccess *AccessLevelValue `url:"group_access,omitempty" json:"group_access,omitempty"`
+	ExpiresAt   *ISOTime          `url:"expires_at,omitempty" json:"expires_at,omitempty"`
+}
+
+// ShareGroupWithGroup shares a group with another group.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/groups.html#create-a-link-to-share-a-group-with-another-group
+func (s *GroupsService) ShareGroupWithGroup(gid interface{}, opt *ShareGroupWithGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) {
+	group, err := parseID(gid)
+	if err != nil {
+		return nil, nil, err
+	}
+	u := fmt.Sprintf("groups/%s/share", pathEscape(group))
+
+	req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	g := new(Group)
+	resp, err := s.client.Do(req, g)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return g, resp, err
+}
+
+// UnshareGroupFromGroup unshares a group from another group.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/groups.html#delete-link-sharing-group-with-another-group
+func (s *GroupsService) UnshareGroupFromGroup(gid interface{}, groupID int, options ...RequestOptionFunc) (*Response, error) {
+	group, err := parseID(gid)
+	if err != nil {
+		return nil, err
+	}
+	u := fmt.Sprintf("groups/%s/share/%d", pathEscape(group), groupID)
+
+	req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(req, nil)
+}
+
 // GroupPushRules represents a group push rule.
 //
 // GitLab API docs:


Test patch:
diff --git a/groups_test.go b/groups_test.go
index 991e11a..a2d0adf 100644
--- a/groups_test.go
+++ b/groups_test.go
@@ -300,3 +300,43 @@ func TestRestoreGroup(t *testing.T) {
 		t.Errorf("Groups.RestoreGroup returned %+v, want %+v", group, want)
 	}
 }
+
+func TestShareGroupWithGroup(t *testing.T) {
+	mux, server, client := setup(t)
+	defer teardown(server)
+	mux.HandleFunc("/api/v4/groups/1/share",
+		func(w http.ResponseWriter, r *http.Request) {
+			testMethod(t, r, http.MethodPost)
+			fmt.Fprint(w, `{"id": 1, "name": "g"}`)
+		})
+
+	group, _, err := client.Groups.ShareGroupWithGroup(1, &ShareGroupWithGroupOptions{
+		GroupID:     Int(1),
+		GroupAccess: AccessLevel(DeveloperPermissions),
+	})
+	if err != nil {
+		t.Errorf("Groups.ShareGroupWithGroup returned error: %v", err)
+	}
+	want := &Group{ID: 1, Name: "g"}
+	if !reflect.DeepEqual(want, group) {
+		t.Errorf("Groups.ShareGroupWithGroup returned %+v, want %+v", group, want)
+	}
+}
+
+func TestUnshareGroupFromGroup(t *testing.T) {
+	mux, server, client := setup(t)
+	defer teardown(server)
+	mux.HandleFunc("/api/v4/groups/1/share/2",
+		func(w http.ResponseWriter, r *http.Request) {
+			testMethod(t, r, http.MethodDelete)
+			w.WriteHeader(204)
+		})
+
+	r, err := client.Groups.UnshareGroupFromGroup(1, 2)
+	if err != nil {
+		t.Errorf("Groups.UnshareGroupFromGroup returned error: %v", err)
+	}
+	if r.StatusCode != 204 {
+		t.Errorf("Groups.UnshareGroupFromGroup returned status code %d", r.StatusCode)
+	}
+}