Repository: xanzy/go-gitlab
Pull request #1324 (2021-12-16 20:57:25)

Add support for Repository Submodules API
Adds support for GitLab's [Repository Submodules API](https://docs.gitlab.com/ee/api/repository_submodules.html)


Patch:
diff --git a/README.md b/README.md
index acbf747..62d5179 100644
--- a/README.md
+++ b/README.md
@@ -81,6 +81,7 @@ to add new and/or missing endpoints. Currently the following services are suppor
 - [x] Protected Tags
 - [x] Repositories
 - [x] Repository Files
+- [x] Repository Submodules
 - [x] Runners
 - [x] Search
 - [x] Services
diff --git a/gitlab.go b/gitlab.go
index f8b59b1..a5c3f26 100644
--- a/gitlab.go
+++ b/gitlab.go
@@ -177,6 +177,7 @@ type Client struct {
 	Releases              *ReleasesService
 	Repositories          *RepositoriesService
 	RepositoryFiles       *RepositoryFilesService
+	RepositorySubmodules  *RepositorySubmodulesService
 	ResourceLabelEvents   *ResourceLabelEventsService
 	ResourceStateEvents   *ResourceStateEventsService
 	Runners               *RunnersService
@@ -369,6 +370,7 @@ func newClient(options ...ClientOptionFunc) (*Client, error) {
 	c.Releases = &ReleasesService{client: c}
 	c.Repositories = &RepositoriesService{client: c}
 	c.RepositoryFiles = &RepositoryFilesService{client: c}
+	c.RepositorySubmodules = &RepositorySubmodulesService{client: c}
 	c.ResourceLabelEvents = &ResourceLabelEventsService{client: c}
 	c.ResourceStateEvents = &ResourceStateEventsService{client: c}
 	c.Runners = &RunnersService{client: c}
diff --git a/repository_submodules.go b/repository_submodules.go
new file mode 100644
index 0000000..70ac05e
--- /dev/null
+++ b/repository_submodules.go
@@ -0,0 +1,93 @@
+//
+// Copyright 2021, Sander van Harmelen
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package gitlab
+
+import (
+	"fmt"
+	"net/http"
+	"time"
+)
+
+// RepositorySubmodulesService handles communication with the repository
+// submodules related methods of the GitLab API.
+//
+// GitLab API docs: https://docs.gitlab.com/ee/api/repository_submodules.html
+type RepositorySubmodulesService struct {
+	client *Client
+}
+
+// SubmoduleCommit represents a GitLab submodule commit.
+//
+// GitLab API docs: https://docs.gitlab.com/ee/api/repository_submodules.html
+type SubmoduleCommit struct {
+	ID             string           `json:"id"`
+	ShortID        string           `json:"short_id"`
+	Title          string           `json:"title"`
+	AuthorName     string           `json:"author_name"`
+	AuthorEmail    string           `json:"author_email"`
+	CommitterName  string           `json:"committer_name"`
+	CommitterEmail string           `json:"committer_email"`
+	CreatedAt      *time.Time       `json:"created_at"`
+	Message        string           `json:"message"`
+	ParentIDs      []string         `json:"parent_ids"`
+	CommittedDate  *time.Time       `json:"committed_date"`
+	AuthoredDate   *time.Time       `json:"authored_date"`
+	Status         *BuildStateValue `json:"status"`
+}
+
+func (r SubmoduleCommit) String() string {
+	return Stringify(r)
+}
+
+// UpdateSubmoduleOptions represents the available UpdateSubmodule() options.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/repository_submodules.html#update-existing-submodule-reference-in-repository
+type UpdateSubmoduleOptions struct {
+	Branch        *string `url:"branch,omitempty" json:"branch,omitempty"`
+	CommitSHA     *string `url:"commit_sha,omitempty" json:"commit_sha,omitempty"`
+	CommitMessage *string `url:"commit_message,omitempty" json:"commit_message,omitempty"`
+}
+
+// UpdateSubmodule updates an existing submodule reference.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/repository_submodules.html#update-existing-submodule-reference-in-repository
+func (s *RepositorySubmodulesService) UpdateSubmodule(pid interface{}, submodule string, opt *UpdateSubmoduleOptions, options ...RequestOptionFunc) (*SubmoduleCommit, *Response, error) {
+	project, err := parseID(pid)
+	if err != nil {
+		return nil, nil, err
+	}
+	u := fmt.Sprintf(
+		"projects/%s/repository/submodules/%s",
+		PathEscape(project),
+		PathEscape(submodule),
+	)
+
+	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	sc := new(SubmoduleCommit)
+	resp, err := s.client.Do(req, sc)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return sc, resp, err
+}


Test patch:
diff --git a/repository_submodules_test.go b/repository_submodules_test.go
new file mode 100644
index 0000000..2cab147
--- /dev/null
+++ b/repository_submodules_test.go
@@ -0,0 +1,52 @@
+package gitlab
+
+import (
+	"fmt"
+	"net/http"
+	"testing"
+
+	"github.com/stretchr/testify/require"
+)
+
+func TestRepositorySubmodulesService_UpdateSubmodule(t *testing.T) {
+	mux, server, client := setup(t)
+	defer teardown(server)
+
+	mux.HandleFunc("/api/v4/projects/13083/repository/submodules/app%2Fproject", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, http.MethodPut)
+		fmt.Fprintf(w, `
+			{
+			  "id": "6104942438c14ec7bd21c6cd5bd995272b3faff6",
+			  "short_id": "6104942438c",
+			  "title": "Update my submodule",
+			  "author_name": "popdabubbles",
+			  "author_email": "noty@gmail.com",
+			  "committer_name": "Will",
+			  "committer_email": "noty@gmail.com",
+			  "message": "Update my submodule",
+			  "parent_ids": [
+			    "ae1d9fb46aa2b07ee9836d49862ec4e2c46fbbba"
+			  ],
+			  "status": "running"
+			}
+		`)
+	})
+
+	want := &SubmoduleCommit{
+		ID:             "6104942438c14ec7bd21c6cd5bd995272b3faff6",
+		ShortID:        "6104942438c",
+		Title:          "Update my submodule",
+		AuthorName:     "popdabubbles",
+		AuthorEmail:    "noty@gmail.com",
+		CommitterName:  "Will",
+		CommitterEmail: "noty@gmail.com",
+		Message:        "Update my submodule",
+		ParentIDs:      []string{"ae1d9fb46aa2b07ee9836d49862ec4e2c46fbbba"},
+		Status:         BuildState(Running),
+	}
+
+	sc, resp, err := client.RepositorySubmodules.UpdateSubmodule(13083, "app%2Fproject", nil)
+	require.NoError(t, err)
+	require.NotNil(t, resp)
+	require.Equal(t, want, sc)
+}