Skip to content
This repository has been archived by the owner on Dec 10, 2024. It is now read-only.

Commit

Permalink
Merge pull request #1381 from timofurrer/feature/topic-avatars
Browse files Browse the repository at this point in the history
Support `avatar` field in create and update method of the topic service
  • Loading branch information
svanharmelen authored Mar 7, 2022
2 parents 4c8a95d + 9c27114 commit ae600d9
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 14 deletions.
69 changes: 69 additions & 0 deletions examples/topics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//
// Copyright 2021, Timo Furrer <tuxtimo@gmail.com>
//
// 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 main

import (
"fmt"
"log"
"os"

"github.com/xanzy/go-gitlab"
)

func topicExample() {
git, err := gitlab.NewClient("yourtokengoeshere")
if err != nil {
log.Fatal(err)
}

// New topic
topic, _, err := git.Topics.CreateTopic(&gitlab.CreateTopicOptions{
Name: gitlab.String("My Topic 2"),
Description: gitlab.String("Some description"),
})
if err != nil {
panic(err)
}

fmt.Printf("Topic: %+v\n", topic)

// Set topic avatar
avatarFile, err := os.Open("5746961_detect_direction_gps_location_map_icon.png")
if err != nil {
panic(err)
}
topic, _, err = git.Topics.UpdateTopic(topic.ID, &gitlab.UpdateTopicOptions{
Avatar: &gitlab.TopicAvatar{
Filename: "5746961_detect_direction_gps_location_map_icon.png",
Image: avatarFile,
},
})
if err != nil {
panic(err)
}
fmt.Printf("Topic with Avatar: %+v\n", topic)

// Remove topic avatar
topic, _, err = git.Topics.UpdateTopic(topic.ID, &gitlab.UpdateTopicOptions{
Avatar: &gitlab.TopicAvatar{},
})
if err != nil {
panic(err)
}

fmt.Printf("Topic without Avatar: %+v\n", topic)
}
68 changes: 60 additions & 8 deletions topics.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@
package gitlab

import (
"encoding/json"
"fmt"
"io"
"net/http"

retryablehttp "github.com/hashicorp/go-retryablehttp"
)

// TopicsService handles communication with the topics related methods
Expand Down Expand Up @@ -96,17 +100,47 @@ func (s *TopicsService) GetTopic(topic int, options ...RequestOptionFunc) (*Topi
// GitLab API docs:
// https://docs.gitlab.com/ee/api/topics.html#create-a-project-topic
type CreateTopicOptions struct {
Name *string `url:"name,omitempty" json:"name,omitempty"`
Description *string `url:"description,omitempty" json:"description,omitempty"`
// Avatar *string `url:"avatar,omitempty" json:"avatar,omitempty"`
Name *string `url:"name,omitempty" json:"name,omitempty"`
Description *string `url:"description,omitempty" json:"description,omitempty"`
Avatar *TopicAvatar `url:"-" json:"-"`
}

// TopicAvatar represents a GitLab topic avatar.
type TopicAvatar struct {
Filename string
Image io.Reader
}

// MarshalJSON implements the json.Marshaler interface.
func (a *TopicAvatar) MarshalJSON() ([]byte, error) {
if a.Filename == "" && a.Image == nil {
return []byte(`""`), nil
}
type alias TopicAvatar
return json.Marshal((*alias)(a))
}

// CreateTopic creates a new project topic.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/topics.html#create-a-project-topic
func (s *TopicsService) CreateTopic(opt *CreateTopicOptions, options ...RequestOptionFunc) (*Topic, *Response, error) {
req, err := s.client.NewRequest(http.MethodPost, "topics", opt, options)
var err error
var req *retryablehttp.Request

if opt.Avatar == nil {
req, err = s.client.NewRequest(http.MethodPost, "topics", opt, options)
} else {
req, err = s.client.UploadRequest(
http.MethodPost,
"topics",
opt.Avatar.Image,
opt.Avatar.Filename,
UploadAvatar,
opt,
options,
)
}
if err != nil {
return nil, nil, err
}
Expand All @@ -125,19 +159,37 @@ func (s *TopicsService) CreateTopic(opt *CreateTopicOptions, options ...RequestO
// GitLab API docs:
// https://docs.gitlab.com/ee/api/topics.html#update-a-project-topic
type UpdateTopicOptions struct {
Name *string `url:"name,omitempty" json:"name,omitempty"`
Description *string `url:"description,omitempty" json:"description,omitempty"`
// Avatar *string `url:"avatar,omitempty" json:"avatar,omitempty"`
Name *string `url:"name,omitempty" json:"name,omitempty"`
Description *string `url:"description,omitempty" json:"description,omitempty"`
Avatar *TopicAvatar `url:"-" json:"avatar,omitempty"`
}

// UpdateTopic updates a project topic. Only available to administrators.
//
// To remove a topic avatar set the TopicAvatar.Filename to an empty string
// and set TopicAvatar.Image to nil.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/topics.html#update-a-project-topic
func (s *TopicsService) UpdateTopic(topic int, opt *UpdateTopicOptions, options ...RequestOptionFunc) (*Topic, *Response, error) {
u := fmt.Sprintf("topics/%d", topic)

req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
var err error
var req *retryablehttp.Request

if opt.Avatar == nil || (opt.Avatar.Filename == "" && opt.Avatar.Image == nil) {
req, err = s.client.NewRequest(http.MethodPut, u, opt, options)
} else {
req, err = s.client.UploadRequest(
http.MethodPut,
u,
opt.Avatar.Image,
opt.Avatar.Filename,
UploadAvatar,
opt,
options,
)
}
if err != nil {
return nil, nil, err
}
Expand Down
12 changes: 6 additions & 6 deletions topics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,19 +123,19 @@ func TestTopicsService_CreateTopic(t *testing.T) {
fmt.Fprint(w, `{
"id": 1,
"name": "topic1",
"description": null,
"description": "description",
"total_projects_count": 0,
"avatar_url": null
}`)
})

opt := &CreateTopicOptions{Name: String("topic1")}
opt := &CreateTopicOptions{Name: String("topic1"), Description: String("description")}
release, _, err := client.Topics.CreateTopic(opt)
if err != nil {
t.Errorf("Topics.CreateTopic returned error: %v", err)
}

want := &Topic{ID: 1, Name: "topic1"}
want := &Topic{ID: 1, Name: "topic1", Description: "description", TotalProjectsCount: 0}
if !reflect.DeepEqual(want, release) {
t.Errorf("Topics.CreateTopic returned %+v, want %+v", release, want)
}
Expand All @@ -150,19 +150,19 @@ func TestTopicsService_UpdateTopic(t *testing.T) {
fmt.Fprint(w, `{
"id": 1,
"name": "topic1",
"description": null,
"description": "description",
"total_projects_count": 0,
"avatar_url": null
}`)
})

opt := &UpdateTopicOptions{Name: String("topic1")}
opt := &UpdateTopicOptions{Name: String("topic1"), Description: String("description")}
release, _, err := client.Topics.UpdateTopic(1, opt)
if err != nil {
t.Errorf("Topics.UpdateTopic returned error: %v", err)
}

want := &Topic{ID: 1, Name: "topic1"}
want := &Topic{ID: 1, Name: "topic1", Description: "description", TotalProjectsCount: 0}
if !reflect.DeepEqual(want, release) {
t.Errorf("Topics.UpdateTopic returned %+v, want %+v", release, want)
}
Expand Down

0 comments on commit ae600d9

Please sign in to comment.