Repository: xanzy/go-gitlab
Pull request #1604 (2022-12-22 12:17:08)

Fix .gitignore template and GitLab CI YAML template list items
The two API endpoints for listing `.gitignore` templates and GitLab CI YAML templates used the same `struct` as the corresponding endpoint to retrieve a single template.
However, the two response types are not identical and the `Content` field was always empty when querying the entire list.
I added a new type that properly represents the response of a list item and is different from the type returned by a single template request.


Patch:
diff --git a/ci_yml_templates.go b/ci_yml_templates.go
index fb4e22b..eead0a4 100644
--- a/ci_yml_templates.go
+++ b/ci_yml_templates.go
@@ -39,6 +39,15 @@ type CIYMLTemplate struct {
 	Content string `json:"content"`
 }
 
+// CIYMLTemplateListItem represents a GitLab CI YML template from the list.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ce/api/templates/gitlab_ci_ymls.html
+type CIYMLTemplateListItem struct {
+	Key  string `json:"key"`
+	Name string `json:"name"`
+}
+
 // ListCIYMLTemplatesOptions represents the available ListAllTemplates() options.
 //
 // GitLab API docs:
@@ -49,13 +58,13 @@ type ListCIYMLTemplatesOptions ListOptions
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ce/api/templates/gitlab_ci_ymls.html#list-gitlab-ci-yml-templates
-func (s *CIYMLTemplatesService) ListAllTemplates(opt *ListCIYMLTemplatesOptions, options ...RequestOptionFunc) ([]*CIYMLTemplate, *Response, error) {
+func (s *CIYMLTemplatesService) ListAllTemplates(opt *ListCIYMLTemplatesOptions, options ...RequestOptionFunc) ([]*CIYMLTemplateListItem, *Response, error) {
 	req, err := s.client.NewRequest(http.MethodGet, "templates/gitlab_ci_ymls", opt, options)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var cts []*CIYMLTemplate
+	var cts []*CIYMLTemplateListItem
 	resp, err := s.client.Do(req, &cts)
 	if err != nil {
 		return nil, resp, err
diff --git a/gitignore_templates.go b/gitignore_templates.go
index 6597d44..b2b6be4 100644
--- a/gitignore_templates.go
+++ b/gitignore_templates.go
@@ -38,6 +38,14 @@ type GitIgnoreTemplate struct {
 	Content string `json:"content"`
 }
 
+// GitIgnoreTemplateListItem represents a GitLab gitignore template from the list.
+//
+// GitLab API docs: https://docs.gitlab.com/ce/api/templates/gitignores.html
+type GitIgnoreTemplateListItem struct {
+	Key  string `json:"key"`
+	Name string `json:"name"`
+}
+
 // ListTemplatesOptions represents the available ListAllTemplates() options.
 //
 // GitLab API docs:
@@ -48,13 +56,13 @@ type ListTemplatesOptions ListOptions
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ce/api/templates/gitignores.html#list-gitignore-templates
-func (s *GitIgnoreTemplatesService) ListTemplates(opt *ListTemplatesOptions, options ...RequestOptionFunc) ([]*GitIgnoreTemplate, *Response, error) {
+func (s *GitIgnoreTemplatesService) ListTemplates(opt *ListTemplatesOptions, options ...RequestOptionFunc) ([]*GitIgnoreTemplateListItem, *Response, error) {
 	req, err := s.client.NewRequest(http.MethodGet, "templates/gitignores", opt, options)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var gs []*GitIgnoreTemplate
+	var gs []*GitIgnoreTemplateListItem
 	resp, err := s.client.Do(req, &gs)
 	if err != nil {
 		return nil, resp, err


Test patch:
diff --git a/ci_yml_templates_test.go b/ci_yml_templates_test.go
index 1b890c4..35052cd 100644
--- a/ci_yml_templates_test.go
+++ b/ci_yml_templates_test.go
@@ -30,19 +30,19 @@ func TestListAllTemplates(t *testing.T) {
 		testMethod(t, r, http.MethodGet)
 		fmt.Fprintf(w, `[
 			{
-			   "content":"5-Minute-Production-App",
+			   "key":"5-Minute-Production-App",
 			   "name":"5-Minute-Production-App"
 			},
 			{
-			   "content":"Android",
+			   "key":"Android",
 			   "name":"Android"
 			},
 			{
-			   "content":"Android-Fastlane",
+			   "key":"Android-Fastlane",
 			   "name":"Android-Fastlane"
 			},
 			{
-			   "content":"Auto-DevOps",
+			   "key":"Auto-DevOps",
 			   "name":"Auto-DevOps"
 			}
 		 ]`)
@@ -53,20 +53,22 @@ func TestListAllTemplates(t *testing.T) {
 		t.Errorf("CIYMLTemplates.ListAllTemplates returned error: %v", err)
 	}
 
-	want := []*CIYMLTemplate{
+	want := []*CIYMLTemplateListItem{
 		{
-			Name:    "5-Minute-Production-App",
-			Content: "5-Minute-Production-App",
+			Key:  "5-Minute-Production-App",
+			Name: "5-Minute-Production-App",
 		},
 		{
-			Name:    "Android",
-			Content: "Android"},
+			Key:  "Android",
+			Name: "Android",
+		},
 		{
-			Name:    "Android-Fastlane",
-			Content: "Android-Fastlane"},
+			Key:  "Android-Fastlane",
+			Name: "Android-Fastlane",
+		},
 		{
-			Name:    "Auto-DevOps",
-			Content: "Auto-DevOps",
+			Key:  "Auto-DevOps",
+			Name: "Auto-DevOps",
 		},
 	}
 	if !reflect.DeepEqual(want, templates) {
diff --git a/gitignore_templates_test.go b/gitignore_templates_test.go
index c222a8c..be4069c 100644
--- a/gitignore_templates_test.go
+++ b/gitignore_templates_test.go
@@ -30,83 +30,83 @@ func TestListTemplates(t *testing.T) {
 		testMethod(t, r, http.MethodGet)
 		fmt.Fprintf(w, `[
 			{
-			  "content": "Actionscript",
+			  "key": "Actionscript",
 			  "name": "Actionscript"
 			},
 			{
-			  "content": "Ada",
+			  "key": "Ada",
 			  "name": "Ada"
 			},
 			{
-			  "content": "Agda",
+			  "key": "Agda",
 			  "name": "Agda"
 			},
 			{
-			  "content": "Android",
+			  "key": "Android",
 			  "name": "Android"
 			},
 			{
-			  "content": "AppEngine",
+			  "key": "AppEngine",
 			  "name": "AppEngine"
 			},
 			{
-			  "content": "AppceleratorTitanium",
+			  "key": "AppceleratorTitanium",
 			  "name": "AppceleratorTitanium"
 			},
 			{
-			  "content": "ArchLinuxPackages",
+			  "key": "ArchLinuxPackages",
 			  "name": "ArchLinuxPackages"
 			},
 			{
-			  "content": "Autotools",
+			  "key": "Autotools",
 			  "name": "Autotools"
 			},
 			{
-			  "content": "C",
+			  "key": "C",
 			  "name": "C"
 			},
 			{
-			  "content": "C++",
+			  "key": "C++",
 			  "name": "C++"
 			},
 			{
-			  "content": "CFWheels",
+			  "key": "CFWheels",
 			  "name": "CFWheels"
 			},
 			{
-			  "content": "CMake",
+			  "key": "CMake",
 			  "name": "CMake"
 			},
 			{
-			  "content": "CUDA",
+			  "key": "CUDA",
 			  "name": "CUDA"
 			},
 			{
-			  "content": "CakePHP",
+			  "key": "CakePHP",
 			  "name": "CakePHP"
 			},
 			{
-			  "content": "ChefCookbook",
+			  "key": "ChefCookbook",
 			  "name": "ChefCookbook"
 			},
 			{
-			  "content": "Clojure",
+			  "key": "Clojure",
 			  "name": "Clojure"
 			},
 			{
-			  "content": "CodeIgniter",
+			  "key": "CodeIgniter",
 			  "name": "CodeIgniter"
 			},
 			{
-			  "content": "CommonLisp",
+			  "key": "CommonLisp",
 			  "name": "CommonLisp"
 			},
 			{
-			  "content": "Composer",
+			  "key": "Composer",
 			  "name": "Composer"
 			},
 			{
-			  "content": "Concrete5",
+			  "key": "Concrete5",
 			  "name": "Concrete5"
 			}
 		  ]`)
@@ -117,86 +117,86 @@ func TestListTemplates(t *testing.T) {
 		t.Errorf("GitIgnoreTemplates.ListTemplates returned error: %v", err)
 	}
 
-	want := []*GitIgnoreTemplate{
+	want := []*GitIgnoreTemplateListItem{
 		{
-			Name:    "Actionscript",
-			Content: "Actionscript",
+			Key:  "Actionscript",
+			Name: "Actionscript",
 		},
 		{
-			Name:    "Ada",
-			Content: "Ada",
+			Key:  "Ada",
+			Name: "Ada",
 		},
 		{
-			Name:    "Agda",
-			Content: "Agda",
+			Key:  "Agda",
+			Name: "Agda",
 		},
 		{
-			Name:    "Android",
-			Content: "Android",
+			Key:  "Android",
+			Name: "Android",
 		},
 		{
-			Name:    "AppEngine",
-			Content: "AppEngine",
+			Key:  "AppEngine",
+			Name: "AppEngine",
 		},
 		{
-			Name:    "AppceleratorTitanium",
-			Content: "AppceleratorTitanium",
+			Key:  "AppceleratorTitanium",
+			Name: "AppceleratorTitanium",
 		},
 		{
-			Name:    "ArchLinuxPackages",
-			Content: "ArchLinuxPackages",
+			Key:  "ArchLinuxPackages",
+			Name: "ArchLinuxPackages",
 		},
 		{
-			Name:    "Autotools",
-			Content: "Autotools",
+			Key:  "Autotools",
+			Name: "Autotools",
 		},
 		{
-			Name:    "C",
-			Content: "C",
+			Key:  "C",
+			Name: "C",
 		},
 		{
-			Name:    "C++",
-			Content: "C++",
+			Key:  "C++",
+			Name: "C++",
 		},
 		{
-			Name:    "CFWheels",
-			Content: "CFWheels",
+			Key:  "CFWheels",
+			Name: "CFWheels",
 		},
 		{
-			Name:    "CMake",
-			Content: "CMake",
+			Key:  "CMake",
+			Name: "CMake",
 		},
 		{
-			Name:    "CUDA",
-			Content: "CUDA",
+			Key:  "CUDA",
+			Name: "CUDA",
 		},
 		{
-			Name:    "CakePHP",
-			Content: "CakePHP",
+			Key:  "CakePHP",
+			Name: "CakePHP",
 		},
 		{
-			Name:    "ChefCookbook",
-			Content: "ChefCookbook",
+			Key:  "ChefCookbook",
+			Name: "ChefCookbook",
 		},
 		{
-			Name:    "Clojure",
-			Content: "Clojure",
+			Key:  "Clojure",
+			Name: "Clojure",
 		},
 		{
-			Name:    "CodeIgniter",
-			Content: "CodeIgniter",
+			Key:  "CodeIgniter",
+			Name: "CodeIgniter",
 		},
 		{
-			Name:    "CommonLisp",
-			Content: "CommonLisp",
+			Key:  "CommonLisp",
+			Name: "CommonLisp",
 		},
 		{
-			Name:    "Composer",
-			Content: "Composer",
+			Key:  "Composer",
+			Name: "Composer",
 		},
 		{
-			Name:    "Concrete5",
-			Content: "Concrete5",
+			Key:  "Concrete5",
+			Name: "Concrete5",
 		},
 	}
 	if !reflect.DeepEqual(want, templates) {