Skip to content

Commit 69947c5

Browse files
authored
Merge pull request #1074 from hashicorp/TF-24585-go-tfe-gh-issue-1073-remove-total-count-from-run-list-for-organization-interface
BREAKING: removes TotalCount/TotalPages from ListForOrganization
2 parents e440169 + 8e1f1e6 commit 69947c5

File tree

5 files changed

+63
-20
lines changed

5 files changed

+63
-20
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Unreleased
22

3+
## BREAKING CHANGES
4+
5+
In the last release, Runs interface method `ListForOrganization` included pagination fields `TotalCount` and `TotalPages`, but these are being removed as this feature approaches general availablity by @brandonc [#1074](https://github.com/hashicorp/go-tfe/pull/1074)
6+
37
# v1.76.0
48

59
## Enhancements

mocks/run_mocks.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

run.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ type Runs interface {
2222
List(ctx context.Context, workspaceID string, options *RunListOptions) (*RunList, error)
2323

2424
// List all the runs of the given organization.
25-
ListForOrganization(ctx context.Context, organization string, options *RunListForOrganizationOptions) (*RunList, error)
25+
ListForOrganization(ctx context.Context, organization string, options *RunListForOrganizationOptions) (*OrganizationRunList, error)
2626

2727
// Create a new run with the given options.
2828
Create(ctx context.Context, options RunCreateOptions) (*Run, error)
@@ -120,6 +120,14 @@ type RunList struct {
120120
Items []*Run
121121
}
122122

123+
// OrganizationRunList represents a list of runs across an organization. It
124+
// differs from the RunList in that it does not include a TotalCount of records
125+
// in the pagination details
126+
type OrganizationRunList struct {
127+
*PaginationNextPrev
128+
Items []*Run
129+
}
130+
123131
// Run represents a Terraform Enterprise run.
124132
type Run struct {
125133
ID string `jsonapi:"primary,runs"`
@@ -448,7 +456,7 @@ func (s *runs) List(ctx context.Context, workspaceID string, options *RunListOpt
448456
}
449457

450458
// List all the runs of the given workspace.
451-
func (s *runs) ListForOrganization(ctx context.Context, organization string, options *RunListForOrganizationOptions) (*RunList, error) {
459+
func (s *runs) ListForOrganization(ctx context.Context, organization string, options *RunListForOrganizationOptions) (*OrganizationRunList, error) {
452460
if !validStringID(&organization) {
453461
return nil, ErrInvalidOrg
454462
}
@@ -462,7 +470,7 @@ func (s *runs) ListForOrganization(ctx context.Context, organization string, opt
462470
return nil, err
463471
}
464472

465-
rl := &RunList{}
473+
rl := &OrganizationRunList{}
466474
err = req.Do(ctx, rl)
467475
if err != nil {
468476
return nil, err

run_integration_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -750,7 +750,7 @@ func TestRunsListForOrganization(t *testing.T) {
750750
assert.Contains(t, found, rTest1.ID)
751751
assert.Contains(t, found, rTest2.ID)
752752
assert.Equal(t, 1, rl.CurrentPage)
753-
assert.Equal(t, 2, rl.TotalCount)
753+
assert.Empty(t, rl.NextPage)
754754
})
755755

756756
t.Run("without list options and include as nil", func(t *testing.T) {
@@ -768,7 +768,7 @@ func TestRunsListForOrganization(t *testing.T) {
768768
assert.Contains(t, found, rTest1.ID)
769769
assert.Contains(t, found, rTest2.ID)
770770
assert.Equal(t, 1, rl.CurrentPage)
771-
assert.Equal(t, 2, rl.TotalCount)
771+
assert.Empty(t, rl.NextPage)
772772
})
773773

774774
t.Run("with list options", func(t *testing.T) {
@@ -784,7 +784,7 @@ func TestRunsListForOrganization(t *testing.T) {
784784
require.NoError(t, err)
785785
assert.Empty(t, rl.Items)
786786
assert.Equal(t, 999, rl.CurrentPage)
787-
assert.Equal(t, 2, rl.TotalCount)
787+
assert.Empty(t, rl.NextPage)
788788
})
789789

790790
t.Run("with workspace included", func(t *testing.T) {
@@ -818,7 +818,7 @@ func TestRunsListForOrganization(t *testing.T) {
818818
assert.Contains(t, found, rTest1.ID)
819819
assert.Contains(t, found, rTest2.ID)
820820
assert.Equal(t, 1, rl.CurrentPage)
821-
assert.Equal(t, 2, rl.TotalCount)
821+
assert.Empty(t, rl.NextPage)
822822
})
823823

824824
t.Run("with filter by workspace", func(t *testing.T) {
@@ -840,6 +840,6 @@ func TestRunsListForOrganization(t *testing.T) {
840840
require.NotNil(t, rl.Items[1].Workspace)
841841
assert.NotEmpty(t, rl.Items[1].Workspace.Name)
842842
assert.Equal(t, 1, rl.CurrentPage)
843-
assert.Equal(t, 2, rl.TotalCount)
843+
assert.Empty(t, rl.NextPage)
844844
})
845845
}

tfe.go

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -857,11 +857,10 @@ func unmarshalResponse(responseBody io.Reader, model interface{}) error {
857857

858858
// Try to get the Items and Pagination struct fields.
859859
items := dst.FieldByName("Items")
860-
pagination := dst.FieldByName("Pagination")
861860

862861
// Unmarshal a single value if model does not contain the
863862
// Items and Pagination struct fields.
864-
if !items.IsValid() || !pagination.IsValid() {
863+
if !items.IsValid() {
865864
return jsonapi.UnmarshalPayload(responseBody, model)
866865
}
867866

@@ -892,15 +891,25 @@ func unmarshalResponse(responseBody io.Reader, model interface{}) error {
892891
// Pointer-swap the result.
893892
items.Set(result)
894893

894+
pagination := dst.FieldByName("Pagination")
895+
paginationWithoutTotals := dst.FieldByName("PaginationNextPrev")
896+
895897
// As we are getting a list of values, we need to decode
896898
// the pagination details out of the response body.
897-
p, err := parsePagination(body)
898-
if err != nil {
899-
return err
900-
}
901-
902899
// Pointer-swap the decoded pagination details.
903-
pagination.Set(reflect.ValueOf(p))
900+
if paginationWithoutTotals.IsValid() {
901+
p, err := parsePaginationWithoutTotal(body)
902+
if err != nil {
903+
return err
904+
}
905+
paginationWithoutTotals.Set(reflect.ValueOf(p))
906+
} else if pagination.IsValid() {
907+
p, err := parsePagination(body)
908+
if err != nil {
909+
return err
910+
}
911+
pagination.Set(reflect.ValueOf(p))
912+
}
904913

905914
return nil
906915
}
@@ -915,13 +924,35 @@ type ListOptions struct {
915924
PageSize int `url:"page[size],omitempty"`
916925
}
917926

918-
// Pagination is used to return the pagination details of an API request.
927+
// PaginationNextPrev is used to return the pagination details of an API request.
928+
type PaginationNextPrev struct {
929+
CurrentPage int `json:"current-page"`
930+
PreviousPage int `json:"prev-page"`
931+
NextPage int `json:"next-page"`
932+
}
933+
934+
// Pagination is used to return the pagination details of an API request including TotalCount.
919935
type Pagination struct {
920936
CurrentPage int `json:"current-page"`
921937
PreviousPage int `json:"prev-page"`
922938
NextPage int `json:"next-page"`
923-
TotalPages int `json:"total-pages"`
924939
TotalCount int `json:"total-count"`
940+
TotalPages int `json:"total-pages"`
941+
}
942+
943+
func parsePaginationWithoutTotal(body io.Reader) (*PaginationNextPrev, error) {
944+
var raw struct {
945+
Meta struct {
946+
Pagination PaginationNextPrev `jsonapi:"pagination"`
947+
} `jsonapi:"meta"`
948+
}
949+
950+
// JSON decode the raw response.
951+
if err := json.NewDecoder(body).Decode(&raw); err != nil {
952+
return &PaginationNextPrev{}, err
953+
}
954+
955+
return &raw.Meta.Pagination, nil
925956
}
926957

927958
func parsePagination(body io.Reader) (*Pagination, error) {

0 commit comments

Comments
 (0)