Skip to content

Commit

Permalink
Add complete Tags support
Browse files Browse the repository at this point in the history
  • Loading branch information
janos committed Mar 11, 2022
1 parent 56fd851 commit 384a8be
Show file tree
Hide file tree
Showing 10 changed files with 288 additions and 15 deletions.
14 changes: 6 additions & 8 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.15
go-version: 1.17

- name: Checkout
uses: actions/checkout@v1
Expand All @@ -31,13 +31,11 @@ jobs:
${{ runner.OS }}-build-
${{ runner.OS }}-
- name: Set up GolangCI-Lint
if: matrix.os == 'ubuntu-latest'
run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.34.1

- name: GolangCI-Lint
if: matrix.os == 'ubuntu-latest'
run: golangci-lint run
- name: Lint
uses: golangci/golangci-lint-action@v2
with:
version: v1.43.0
args: --timeout 10m

- name: Vet
if: matrix.os == 'ubuntu-latest'
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ This client implements all NewReleases API features.
- Get added Mattermost webhooks
- Get added Rocket.Chat webhooks
- Get added custom Webhooks
- List tags
- Get tag
- Add tag
- Update tag
- Delete tag
- Get auth keys

## Examples
Expand Down
2 changes: 2 additions & 0 deletions export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@
package newreleases

const UserAgent = userAgent

type TagOptionsRequest = tagOptionsRequest
6 changes: 6 additions & 0 deletions newreleases.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type Client struct {
MattermostWebhooks *MattermostWebhooksService
RocketchatWebhooks *RocketchatWebhooksService
Webhooks *WebhooksService
Tags *TagsService
}

// ClientOptions holds optional parameters for the Client.
Expand Down Expand Up @@ -96,6 +97,7 @@ func newClient(httpClient *http.Client) (c *Client) {
c.MattermostWebhooks = (*MattermostWebhooksService)(&c.service)
c.RocketchatWebhooks = (*RocketchatWebhooksService)(&c.service)
c.Webhooks = (*WebhooksService)(&c.service)
c.Tags = (*TagsService)(&c.service)
return c
}

Expand Down Expand Up @@ -252,6 +254,10 @@ type service struct {
// returns a pointer to it.
func Bool(v bool) (p *bool) { return &v }

// String is a helper routine that allocates a new string value to store v and
// returns a pointer to it.
func String(v string) (p *string) { return &v }

// roundTripperFunc type is an adapter to allow the use of ordinary functions as
// http.RoundTripper interfaces. If f is a function with the appropriate
// signature, roundTripperFunc(f) is a http.RoundTripper that calls f.
Expand Down
2 changes: 1 addition & 1 deletion newreleases_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func newStaticHandler(body string) http.HandlerFunc {
}
}

func newPagedStaticHndler(pages ...string) http.HandlerFunc {
func newPagedStaticHandler(pages ...string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
page := 1
if p := r.URL.Query().Get("page"); p != "" {
Expand Down
12 changes: 10 additions & 2 deletions projects.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ type Project struct {
Exclusions []Exclusion `json:"exclude_version_regexp,omitempty"`
ExcludePrereleases bool `json:"exclude_prereleases,omitempty"`
ExcludeUpdated bool `json:"exclude_updated,omitempty"`
Note string `json:"note,omitempty"`
TagIDs []string `json:"tags,omitempty"`
}

// EmailNotification enumerates available options for email notifications.
Expand Down Expand Up @@ -67,6 +69,7 @@ type ProjectListOptions struct {
Order ProjectListOrder
Reverse bool
Provider string
TagID string
}

// ProjectListOrder enumerates available project list orders.
Expand Down Expand Up @@ -99,6 +102,9 @@ func (s *ProjectsService) List(ctx context.Context, o ProjectListOptions) (proje
if o.Reverse {
q.Set("reverse", "")
}
if o.TagID != "" {
q.Set("tag", string(o.TagID))
}
if query := q.Encode(); query != "" {
query = strings.ReplaceAll(query, "reverse=", "reverse")
path += "?" + query
Expand Down Expand Up @@ -147,8 +153,8 @@ func (s *ProjectsService) get(ctx context.Context, projectRef string) (project *
// If any of the fields have nil value, the option is not set by Add method or
// changed by UpdateByID or UpdateByName methods. When using update methods,
// removing all elements must be done by setting an initialized slice, not a nil
// slice. For boolean pointer methods, there is a convenient function Bool that
// returns boolean pointer by passing a regular bool value.
// slice. For boolean pointer methods, there is a convenient functions Bool and
// String that return boolean pointer by passing a regular value.
type ProjectOptions struct {
EmailNotification *EmailNotification `json:"email_notification"`
SlackIDs []string `json:"slack_channels"`
Expand All @@ -162,6 +168,8 @@ type ProjectOptions struct {
Exclusions []Exclusion `json:"exclude_version_regexp"`
ExcludePrereleases *bool `json:"exclude_prereleases"`
ExcludeUpdated *bool `json:"exclude_updated"`
Note *string `json:"note"`
TagIDs []string `json:"tags"`
}

// Add adds a new project to be tracked.
Expand Down
30 changes: 28 additions & 2 deletions projects_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func TestProjectsService_List(t *testing.T) {
client, mux, _, teardown := newClient(t, "")
defer teardown()

mux.HandleFunc("/v1/projects", requireMethod("GET", newPagedStaticHndler(projectsServiceList...)))
mux.HandleFunc("/v1/projects", requireMethod("GET", newPagedStaticHandler(projectsServiceList...)))

for i, page := range projectsServiceListWant {
name := "page " + strconv.Itoa(i+1)
Expand Down Expand Up @@ -90,7 +90,7 @@ func TestProjectsService_List_provider(t *testing.T) {
client, mux, _, teardown := newClient(t, "")
defer teardown()

mux.HandleFunc("/v1/projects/github", requireMethod("GET", newPagedStaticHndler(projectsServiceList...)))
mux.HandleFunc("/v1/projects/github", requireMethod("GET", newPagedStaticHandler(projectsServiceList...)))

for i, page := range projectsServiceListWant {
name := "page " + strconv.Itoa(i+1)
Expand All @@ -108,6 +108,29 @@ func TestProjectsService_List_provider(t *testing.T) {
}
}

func TestProjectsService_List_tagID(t *testing.T) {
client, mux, _, teardown := newClient(t, "")
defer teardown()

mux.HandleFunc("/v1/projects", requireMethod("GET", func(w http.ResponseWriter, r *http.Request) {
if tagID := r.URL.Query().Get("tag"); tagID != "12345678" {
w.WriteHeader(http.StatusBadRequest)
return
}
w.Header().Set("Content-Type", jsonContentType)
fmt.Fprintln(w, struct{}{})
}))

got, _, err := client.Projects.List(context.Background(), newreleases.ProjectListOptions{
Page: 1,
TagID: "12345678",
})
if err != nil {
t.Fatal(err)
}

assertEqual(t, "", got, []newreleases.Project(nil))
}
func TestProjectsService_List_providerOrder(t *testing.T) {
client, mux, _, teardown := newClient(t, "")
defer teardown()
Expand Down Expand Up @@ -414,6 +437,7 @@ var (
Exclusions: []newreleases.Exclusion{{Value: "^1.9", Inverse: true}},
ExcludePrereleases: true,
ExcludeUpdated: false,
Note: "great stuff",
}
projectOptions = &newreleases.ProjectOptions{
EmailNotification: &newreleases.EmailNotificationHourly,
Expand All @@ -428,6 +452,8 @@ var (
Exclusions: []newreleases.Exclusion{{Value: "^1.9", Inverse: true}},
ExcludePrereleases: newreleases.Bool(true),
ExcludeUpdated: newreleases.Bool(false),
Note: newreleases.String("great stuff"),
TagIDs: []string{"tag1", "tag2"},
}
)

Expand Down
4 changes: 2 additions & 2 deletions releases_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func TestReleasesService_ListByProjectID(t *testing.T) {
client, mux, _, teardown := newClient(t, "")
defer teardown()

mux.HandleFunc("/v1/projects/8wdvh4w9bhsvzclz4ynaqpcpvg/releases", requireMethod("GET", newPagedStaticHndler(releasesServiceList...)))
mux.HandleFunc("/v1/projects/8wdvh4w9bhsvzclz4ynaqpcpvg/releases", requireMethod("GET", newPagedStaticHandler(releasesServiceList...)))

for i, page := range releasesServiceListWant {
name := "page " + strconv.Itoa(i+1)
Expand All @@ -37,7 +37,7 @@ func TestReleasesService_ListByProjectName(t *testing.T) {
client, mux, _, teardown := newClient(t, "")
defer teardown()

mux.HandleFunc("/v1/projects/github/nodejs/node/releases", requireMethod("GET", newPagedStaticHndler(releasesServiceList...)))
mux.HandleFunc("/v1/projects/github/nodejs/node/releases", requireMethod("GET", newPagedStaticHandler(releasesServiceList...)))

for i, page := range releasesServiceListWant {
name := "page " + strconv.Itoa(i+1)
Expand Down
63 changes: 63 additions & 0 deletions tags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright (c) 2022, NewReleases Go client AUTHORS.
// All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package newreleases

import (
"context"
"net/http"
)

// TagsService provides information about project Tags.
type TagsService service

// Tag holds the information about tag ID and its descriptive name.
type Tag struct {
ID string `json:"id"`
Name string `json:"name"`
}

// Get returns the tag by its ID.
func (s *TagsService) Get(ctx context.Context, id string) (tag *Tag, err error) {
err = s.client.request(ctx, http.MethodGet, "v1/tags/"+id, nil, &tag)
return tag, err
}

// List returns all tags.
func (s *TagsService) List(ctx context.Context) (tags []Tag, err error) {

type tagsResponse struct {
Tags []Tag `json:"tags"`
}

var r tagsResponse
err = s.client.request(ctx, http.MethodGet, "v1/tags", nil, &r)
return r.Tags, err
}

type tagOptionsRequest struct {
Name string `json:"name"`
}

// Add adds a new tag.
func (s *TagsService) Add(ctx context.Context, name string) (tag *Tag, err error) {
err = s.client.request(ctx, http.MethodPost, "v1/tags", tagOptionsRequest{
Name: name,
}, &tag)
return tag, err
}

// Update changes the name of the tag referenced by the ID.
func (s *TagsService) Update(ctx context.Context, id, name string) (tag *Tag, err error) {
err = s.client.request(ctx, http.MethodPost, "v1/tags/"+id, tagOptionsRequest{
Name: name,
}, &tag)
return tag, err
}

// Delete removes the tag by its ID.
func (s *TagsService) Delete(ctx context.Context, id string) error {
return s.client.request(ctx, http.MethodDelete, "v1/tags/"+id, nil, nil)
}
Loading

0 comments on commit 384a8be

Please sign in to comment.