Skip to content

Commit

Permalink
feat: upgrade go version (#264)
Browse files Browse the repository at this point in the history
* feat: update go version

* chg: paginate with generics

* feat: changelog

* fix: netlify build

* fix: 1.17 => 1.22

* fix: netlify goes to 1.19

* fix: goreleaser fix deprecation

* fix: nil slice

* fix: cobra deprecation

* chore: prevent time variation

* fix: unused parameter

* feat: test fail to parse

* feat: test tag queries

* feat: changelog
  • Loading branch information
lucassabreu authored May 25, 2024
1 parent 79fc6ce commit 91ff819
Show file tree
Hide file tree
Showing 14 changed files with 160 additions and 997 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: 1.17
go-version: 1.19
cache: false
- name: golangci-lint
uses: golangci/golangci-lint-action@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
- name: go-setup
uses: actions/setup-go@v5
with:
go-version: 1.17
go-version: 1.19
- name: install snapcraft
run: |
sudo apt-get update
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-unit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:

- uses: actions/setup-go@v5
with:
go-version: 1.17
go-version: 1.19

- name: Get dependencies
run: |
Expand Down
2 changes: 1 addition & 1 deletion .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ brews:
- repository:
owner: lucassabreu
name: homebrew-tap
folder: Formula
directory: Formula
homepage: https://github.com/lucassabreu/clockify-cli
description: Helps to interact with Clockfy's API
test: |
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added
- more unit tests

### Changed

- using throttle/ticket providing system to limit requests per second to the clockify's api to prevent the
error message: `Too Many Requests (code: 429)`
- upgrade go version to 1.19

## [v0.49.0] - 2024-03-29

Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ size/complexity of it.
## Building the project

Prerequisites:
- Go 1.17+
- Go 1.19+

Run `make deps-install` to install the packages used by the project.

Expand Down
142 changes: 34 additions & 108 deletions api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"fmt"
"net/http"
"net/url"
"reflect"
"regexp"
"strings"
"time"
Expand Down Expand Up @@ -347,27 +346,18 @@ func (c *client) WorkspaceUsers(p WorkspaceUsersParam) (users []dto.User, err er
return users, err
}

err = c.paginate(
users, err = paginate[dto.User](
c,
"GET",
fmt.Sprintf("v1/workspaces/%s/users", p.Workspace),
p.PaginationParam,
dto.WorkspaceUsersRequest{
Email: p.Email,
},
&users,
func(res interface{}) (int, error) {
if res == nil {
return 0, nil
}
ls := *res.(*[]dto.User)

users = append(users, ls...)
return len(ls), nil
},
"WorkspaceUsers",
)

return users, err
return
}

// PaginationParam parameters about pagination
Expand Down Expand Up @@ -449,36 +439,13 @@ type GetUserTimeEntriesParam struct {

// GetUserTimeEntries will list the time entries of a user on a workspace, can be paginated
func (c *client) GetUserTimeEntries(p GetUserTimeEntriesParam) ([]dto.TimeEntryImpl, error) {
var timeEntries []dto.TimeEntryImpl
var tes []dto.TimeEntryImpl
return getUserTimeEntriesImpl[dto.TimeEntryImpl](c, p, false)

err := c.getUserTimeEntriesImpl(p, false, &tes, func(res interface{}) (int, error) {
if res == nil {
return 0, nil
}

tes := res.(*[]dto.TimeEntryImpl)
timeEntries = append(timeEntries, *tes...)
return len(*tes), nil
})

return timeEntries, err
}

// GetUsersHydratedTimeEntries will list hydrated time entries of a user on a workspace, can be paginated
func (c *client) GetUsersHydratedTimeEntries(p GetUserTimeEntriesParam) ([]dto.TimeEntry, error) {
var timeEntries []dto.TimeEntry
var tes []dto.TimeEntry

err := c.getUserTimeEntriesImpl(p, true, &tes, func(res interface{}) (int, error) {
if res == nil {
return 0, nil
}

tes := res.(*[]dto.TimeEntry)
timeEntries = append(timeEntries, *tes...)
return len(*tes), nil
})
timeEntries, err := getUserTimeEntriesImpl[dto.TimeEntry](c, p, true)

if err != nil {
return timeEntries, err
Expand All @@ -496,12 +463,11 @@ func (c *client) GetUsersHydratedTimeEntries(p GetUserTimeEntriesParam) ([]dto.T
return timeEntries, err
}

func (c *client) getUserTimeEntriesImpl(
func getUserTimeEntriesImpl[K dto.TimeEntry | dto.TimeEntryImpl](
c *client,
p GetUserTimeEntriesParam,
hydrated bool,
tmpl interface{},
reducer func(interface{}) (int, error),
) (err error) {
) (tes []K, err error) {
defer wrapError(&err, "get time entries from user \"%s\"", p.UserID)

ids := map[field]string{
Expand All @@ -510,11 +476,11 @@ func (c *client) getUserTimeEntriesImpl(
}

if err := required(ids); err != nil {
return err
return tes, err
}

if err := checkIDs(ids); err != nil {
return err
return tes, err
}

inProgressFilter := "nil"
Expand Down Expand Up @@ -552,7 +518,8 @@ func (c *client) getUserTimeEntriesImpl(
r.End = &dto.DateTime{Time: *p.End}
}

err = c.paginate(
tes, err = paginate[K](
c,
"GET",
fmt.Sprintf(
"v1/workspaces/%s/user/%s/time-entries",
Expand All @@ -561,22 +528,19 @@ func (c *client) getUserTimeEntriesImpl(
),
p.PaginationParam,
r,
tmpl,
reducer,
"GetUserTimeEntries",
)

return err
return
}

func (c *client) paginate(
func paginate[K any](
c *client,
method, uri string,
p PaginationParam,
request dto.PaginatedRequest,
bodyTempl interface{},
reducer func(interface{}) (int, error),
name string,
) error {
) ([]K, error) {
page := p.Page
if p.AllPages {
page = 1
Expand All @@ -586,6 +550,7 @@ func (c *client) paginate(
p.PageSize = 50
}

var ls []K
stop := false
for !stop {
r, err := c.NewRequest(
Expand All @@ -594,24 +559,24 @@ func (c *client) paginate(
request.WithPagination(page, p.PageSize),
)
if err != nil {
return err
return ls, err
}

response := reflect.New(reflect.TypeOf(bodyTempl).Elem()).Interface()
var response []K
_, err = c.Do(r, &response, name)
if err != nil {
return err
return ls, err
}

count, err := reducer(response)
if err != nil {
return err
count := len(response)
if count > 0 {
ls = append(ls, response...)
}

stop = count < p.PageSize || !p.AllPages
page++
}
return nil
return ls, nil
}

// GetTimeEntryInProgressParam params to query entries
Expand Down Expand Up @@ -878,8 +843,6 @@ type GetTasksParam struct {

// GetTasks get tasks of a project
func (c *client) GetTasks(p GetTasksParam) (ps []dto.Task, err error) {
var tmpl []dto.Task

defer wrapError(&err, "get tasks from project \"%s\"", p.ProjectID)

ids := map[field]string{
Expand All @@ -895,7 +858,8 @@ func (c *client) GetTasks(p GetTasksParam) (ps []dto.Task, err error) {
return ps, err
}

err = c.paginate(
ps, err = paginate[dto.Task](
c,
"GET",
fmt.Sprintf(
"v1/workspaces/%s/projects/%s/tasks",
Expand All @@ -907,16 +871,6 @@ func (c *client) GetTasks(p GetTasksParam) (ps []dto.Task, err error) {
Name: p.Name,
Active: p.Active,
},
&tmpl,
func(res interface{}) (int, error) {
if res == nil {
return 0, nil
}
ls := *res.(*[]dto.Task)

ps = append(ps, ls...)
return len(ls), nil
},
"GetTasks",
)
return ps, err
Expand Down Expand Up @@ -1210,12 +1164,12 @@ type GetTagsParam struct {
// GetTags get all tags of a workspace
func (c *client) GetTags(p GetTagsParam) (ps []dto.Tag, err error) {
defer wrapError(&err, "get tags")
var tmpl []dto.Tag
if err = checkWorkspace(p.Workspace); err != nil {
return ps, err
}

err = c.paginate(
ps, err = paginate[dto.Tag](
c,
"GET",
fmt.Sprintf(
"v1/workspaces/%s/tags",
Expand All @@ -1226,16 +1180,6 @@ func (c *client) GetTags(p GetTagsParam) (ps []dto.Tag, err error) {
Name: p.Name,
Archived: p.Archived,
},
&tmpl,
func(res interface{}) (int, error) {
if res == nil {
return 0, nil
}
ls := *res.(*[]dto.Tag)

ps = append(ps, ls...)
return len(ls), nil
},
"GetTags",
)
return ps, err
Expand All @@ -1255,12 +1199,12 @@ func (c *client) GetClients(p GetClientsParam) (
clients []dto.Client, err error) {
defer wrapError(&err, "get clients")

var tmpl []dto.Client
if err = checkWorkspace(p.Workspace); err != nil {
return clients, err
}

err = c.paginate(
clients, err = paginate[dto.Client](
c,
"GET",
fmt.Sprintf(
"v1/workspaces/%s/clients",
Expand All @@ -1271,19 +1215,11 @@ func (c *client) GetClients(p GetClientsParam) (
Name: p.Name,
Archived: p.Archived,
},
&tmpl,
func(res interface{}) (int, error) {
if res == nil {
return 0, nil
}
ls := *res.(*[]dto.Client)

clients = append(clients, ls...)
return len(ls), nil
},
"GetClients",
)
return clients, err

return
}

type AddClientParam struct {
Expand Down Expand Up @@ -1342,12 +1278,12 @@ type GetProjectsParam struct {
func (c *client) GetProjects(p GetProjectsParam) (ps []dto.Project, err error) {
defer wrapError(&err, "get projects")

var tmpl []dto.Project
if err = checkWorkspace(p.Workspace); err != nil {
return ps, err
}

err = c.paginate(
ps, err = paginate[dto.Project](
c,
"GET",
fmt.Sprintf(
"v1/workspaces/%s/projects",
Expand All @@ -1360,16 +1296,6 @@ func (c *client) GetProjects(p GetProjectsParam) (ps []dto.Project, err error) {
Clients: p.Clients,
Hydrated: p.Hydrate,
},
&tmpl,
func(res interface{}) (int, error) {
if res == nil {
return 0, nil
}
ls := *res.(*[]dto.Project)

ps = append(ps, ls...)
return len(ls), nil
},
"GetProjects",
)

Expand Down
5 changes: 4 additions & 1 deletion api/dto/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,10 @@ func (r GetTagsRequest) AppendToQuery(u *url.URL) *url.URL {
u = r.pagination.AppendToQuery(u)

v := u.Query()
v.Add("name", r.Name)
if r.Name != "" {
v.Add("name", r.Name)
}

if r.Archived != nil {
v.Add("archived", boolString[*r.Archived])
}
Expand Down
Loading

0 comments on commit 91ff819

Please sign in to comment.