diff --git a/github/github-iterators.go b/github/github-iterators.go index cdc88d681b2..8d4cced8c6c 100644 --- a/github/github-iterators.go +++ b/github/github-iterators.go @@ -7172,6 +7172,37 @@ func (s *UsersService) ListKeysIter(ctx context.Context, user string, opts *List } } +// ListPackageVersionsIter returns an iterator that paginates through all results of ListPackageVersions. +func (s *UsersService) ListPackageVersionsIter(ctx context.Context, packageType string, packageName string, opts *ListPackageVersionsOptions) iter.Seq2[*PackageVersion, error] { + return func(yield func(*PackageVersion, error) bool) { + // Create a copy of opts to avoid mutating the caller's struct + if opts == nil { + opts = &ListPackageVersionsOptions{} + } else { + opts = Ptr(*opts) + } + + for { + results, resp, err := s.ListPackageVersions(ctx, packageType, packageName, opts) + if err != nil { + yield(nil, err) + return + } + + for _, item := range results { + if !yield(item, nil) { + return + } + } + + if resp.NextPage == 0 { + break + } + opts.ListOptions.Page = resp.NextPage + } + } +} + // ListPackagesIter returns an iterator that paginates through all results of ListPackages. func (s *UsersService) ListPackagesIter(ctx context.Context, user string, opts *PackageListOptions) iter.Seq2[*Package, error] { return func(yield func(*Package, error) bool) { diff --git a/github/github-iterators_test.go b/github/github-iterators_test.go index 055d4966413..9a074b5e814 100644 --- a/github/github-iterators_test.go +++ b/github/github-iterators_test.go @@ -15999,6 +15999,78 @@ func TestUsersService_ListKeysIter(t *testing.T) { } } +func TestUsersService_ListPackageVersionsIter(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + var callNum int + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + callNum++ + switch callNum { + case 1: + w.Header().Set("Link", `; rel="next"`) + fmt.Fprint(w, `[{},{},{}]`) + case 2: + fmt.Fprint(w, `[{},{},{},{}]`) + case 3: + fmt.Fprint(w, `[{},{}]`) + case 4: + w.WriteHeader(http.StatusNotFound) + case 5: + fmt.Fprint(w, `[{},{}]`) + } + }) + + iter := client.Users.ListPackageVersionsIter(t.Context(), "", "", nil) + var gotItems int + for _, err := range iter { + gotItems++ + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + } + if want := 7; gotItems != want { + t.Errorf("client.Users.ListPackageVersionsIter call 1 got %v items; want %v", gotItems, want) + } + + opts := &ListPackageVersionsOptions{} + iter = client.Users.ListPackageVersionsIter(t.Context(), "", "", opts) + gotItems = 0 + for _, err := range iter { + gotItems++ + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + } + if want := 2; gotItems != want { + t.Errorf("client.Users.ListPackageVersionsIter call 2 got %v items; want %v", gotItems, want) + } + + iter = client.Users.ListPackageVersionsIter(t.Context(), "", "", nil) + gotItems = 0 + for _, err := range iter { + gotItems++ + if err == nil { + t.Error("expected error; got nil") + } + } + if gotItems != 1 { + t.Errorf("client.Users.ListPackageVersionsIter call 3 got %v items; want 1 (an error)", gotItems) + } + + iter = client.Users.ListPackageVersionsIter(t.Context(), "", "", nil) + gotItems = 0 + iter(func(item *PackageVersion, err error) bool { + gotItems++ + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + return false + }) + if gotItems != 1 { + t.Errorf("client.Users.ListPackageVersionsIter call 4 got %v items; want 1 (an error)", gotItems) + } +} + func TestUsersService_ListPackagesIter(t *testing.T) { t.Parallel() client, mux, _ := setup(t) diff --git a/github/users_packages.go b/github/users_packages.go index fa6cd9157c1..f0c152dd545 100644 --- a/github/users_packages.go +++ b/github/users_packages.go @@ -127,22 +127,21 @@ func (s *UsersService) RestorePackage(ctx context.Context, user, packageType, pa return s.client.Do(ctx, req, nil) } -// PackageGetAllVersions gets all versions of a package for a user. Passing the empty string for "user" will -// get versions for the authenticated user. -// -// GitHub API docs: https://docs.github.com/rest/packages/packages#list-package-versions-for-a-package-owned-by-a-user +// ListPackageVersionsOptions specifies the optional parameters to the UsersService.ListPackageVersions. +type ListPackageVersionsOptions struct { + // State of package either "active" or "deleted". + State string `url:"state,omitempty"` + + ListOptions +} + +// ListPackageVersions gets all versions of a package for the authenticated user. // // GitHub API docs: https://docs.github.com/rest/packages/packages#list-package-versions-for-a-package-owned-by-the-authenticated-user // //meta:operation GET /user/packages/{package_type}/{package_name}/versions -//meta:operation GET /users/{username}/packages/{package_type}/{package_name}/versions -func (s *UsersService) PackageGetAllVersions(ctx context.Context, user, packageType, packageName string, opts *PackageListOptions) ([]*PackageVersion, *Response, error) { - var u string - if user != "" { - u = fmt.Sprintf("users/%v/packages/%v/%v/versions", user, packageType, packageName) - } else { - u = fmt.Sprintf("user/packages/%v/%v/versions", packageType, packageName) - } +func (s *UsersService) ListPackageVersions(ctx context.Context, packageType, packageName string, opts *ListPackageVersionsOptions) ([]*PackageVersion, *Response, error) { + u := fmt.Sprintf("user/packages/%v/%v/versions", packageType, packageName) u, err := addOptions(u, opts) if err != nil { return nil, nil, err @@ -162,6 +161,28 @@ func (s *UsersService) PackageGetAllVersions(ctx context.Context, user, packageT return versions, resp, nil } +// ListUserPackageVersions returns package versions for a public package owned by a specified user. +// +// GitHub API docs: https://docs.github.com/rest/packages/packages#list-package-versions-for-a-package-owned-by-a-user +// +//meta:operation GET /users/{username}/packages/{package_type}/{package_name}/versions +func (s *UsersService) ListUserPackageVersions(ctx context.Context, user, packageType, packageName string) ([]*PackageVersion, *Response, error) { + u := fmt.Sprintf("users/%v/packages/%v/%v/versions", user, packageType, packageName) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var versions []*PackageVersion + resp, err := s.client.Do(ctx, req, &versions) + if err != nil { + return nil, resp, err + } + + return versions, resp, nil +} + // PackageGetVersion gets a specific version of a package for a user. Passing the empty string for "user" will // get the version for the authenticated user. // diff --git a/github/users_packages_test.go b/github/users_packages_test.go index e8d6af02243..939344fd93d 100644 --- a/github/users_packages_test.go +++ b/github/users_packages_test.go @@ -339,7 +339,7 @@ func TestUsersService_specifiedUser_RestorePackage(t *testing.T) { }) } -func TestUsersService_Authenticated_ListPackagesVersions(t *testing.T) { +func TestUsersService_ListPackageVersions(t *testing.T) { t.Parallel() client, mux, _ := setup(t) @@ -368,12 +368,12 @@ func TestUsersService_Authenticated_ListPackagesVersions(t *testing.T) { }) ctx := t.Context() - opts := &PackageListOptions{ - Ptr("internal"), Ptr("container"), Ptr("deleted"), ListOptions{Page: 1, PerPage: 2}, + opts := &ListPackageVersionsOptions{ + ListOptions: ListOptions{Page: 1, PerPage: 2}, } - packages, _, err := client.Users.PackageGetAllVersions(ctx, "", "container", "hello_docker", opts) + packages, _, err := client.Users.ListPackageVersions(ctx, "container", "hello_docker", opts) if err != nil { - t.Errorf("Users.Authenticated_PackageGetAllVersions returned error: %v", err) + t.Errorf("Users.ListPackageVersions returned error: %v", err) } want := []*PackageVersion{{ @@ -387,17 +387,17 @@ func TestUsersService_Authenticated_ListPackagesVersions(t *testing.T) { Metadata: json.RawMessage(m), }} if !cmp.Equal(packages, want) { - t.Errorf("Users.PackageGetAllVersions returned %+v, want %+v", packages, want) + t.Errorf("Users.ListPackageVersions returned %+v, want %+v", packages, want) } - const methodName = "PackageGetAllVersions" + const methodName = "ListPackageVersions" testBadOptions(t, methodName, func() (err error) { - _, _, err = client.Users.PackageGetAllVersions(ctx, "\n", "", "", &PackageListOptions{}) + _, _, err = client.Users.ListPackageVersions(ctx, "\n", "\n", &ListPackageVersionsOptions{}) return err }) testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Users.PackageGetAllVersions(ctx, "", "", "", &PackageListOptions{}) + got, resp, err := client.Users.ListPackageVersions(ctx, "", "", &ListPackageVersionsOptions{}) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -405,7 +405,7 @@ func TestUsersService_Authenticated_ListPackagesVersions(t *testing.T) { }) } -func TestUsersService_specifiedUser_ListPackagesVersions(t *testing.T) { +func TestUsersService_ListUserPackageVersions(t *testing.T) { t.Parallel() client, mux, _ := setup(t) @@ -434,12 +434,9 @@ func TestUsersService_specifiedUser_ListPackagesVersions(t *testing.T) { }) ctx := t.Context() - opts := &PackageListOptions{ - Ptr("internal"), Ptr("container"), Ptr("deleted"), ListOptions{Page: 1, PerPage: 2}, - } - packages, _, err := client.Users.PackageGetAllVersions(ctx, "u", "container", "hello_docker", opts) + packages, _, err := client.Users.ListUserPackageVersions(ctx, "u", "container", "hello_docker") if err != nil { - t.Errorf("Users.specifiedUser_PackageGetAllVersions returned error: %v", err) + t.Errorf("Users.ListUserPackageVersions returned error: %v", err) } want := []*PackageVersion{{ @@ -453,17 +450,17 @@ func TestUsersService_specifiedUser_ListPackagesVersions(t *testing.T) { Metadata: json.RawMessage(m), }} if !cmp.Equal(packages, want) { - t.Errorf("Users.specifiedUser_PackageGetAllVersions returned %+v, want %+v", packages, want) + t.Errorf("Users.ListUserPackageVersions returned %+v, want %+v", packages, want) } - const methodName = "PackageGetAllVersions" + const methodName = "ListUserPackageVersions" testBadOptions(t, methodName, func() (err error) { - _, _, err = client.Users.PackageGetAllVersions(ctx, "\n", "", "", &PackageListOptions{}) + _, _, err = client.Users.ListUserPackageVersions(ctx, "\n", "\n", "\n") return err }) testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Users.PackageGetAllVersions(ctx, "", "", "", &PackageListOptions{}) + got, resp, err := client.Users.ListUserPackageVersions(ctx, "", "", "") if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) }