diff --git a/.golangci.yml b/.golangci.yml index adbb8a0c4d6..51d47ebb474 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -231,38 +231,27 @@ linters: - WeeklyStats.Deletions - WeeklyStats.Week allowed-tag-types: - - ActivityListStarredOptions.Direction # TODO: Activities - - ActivityListStarredOptions.Sort # TODO: Activities - - AddProjectItemOptions.ID # TODO: Projects - - AddProjectItemOptions.Type # TODO: Projects - - AlertInstancesListOptions.Ref # TODO: CodeScanning - - AlertListOptions.Direction # TODO: CodeScanning - - AlertListOptions.Ref # TODO: CodeScanning - - AlertListOptions.Severity # TODO: CodeScanning - - AlertListOptions.Sort # TODO: CodeScanning - - AlertListOptions.State # TODO: CodeScanning - - AlertListOptions.ToolGUID # TODO: CodeScanning - - AlertListOptions.ToolName # TODO: CodeScanning - APIMetaArtifactAttestations.TrustDomain # TODO: Meta - - CommitsListOptions.Author # TODO: Repositories - - CommitsListOptions.Path # TODO: Repositories - - CommitsListOptions.SHA # TODO: Repositories + - ActionsCacheListOptions.Direction + - ActionsCacheListOptions.Key + - ActionsCacheListOptions.Ref + - ActionsCacheListOptions.Sort + - ActiveCommittersListOptions.AdvancedSecurityProduct + - AnalysesListOptions.Ref + - AnalysesListOptions.SarifID + - BranchListOptions.Protected + - CodespaceGetDefaultAttributesOptions.ClientIP + - CodespaceGetDefaultAttributesOptions.Ref - CommitsListOptions.Since # TODO: Repositories - CommitsListOptions.Until # TODO: Repositories + - ConfigApplyEventsOptions.LastRequestID - CreateTag.Message # TODO: Git - CreateTag.Object # TODO: Git - CreateTag.Tag # TODO: Git - CreateTag.Type # TODO: Git - - CredentialAuthorizationsListOptions.Login # TODO: Organizations - DependabotEncryptedSecret.SelectedRepositoryIDs # TODO: Dependabot - DependabotEncryptedSecret.Visibility # TODO: Dependabot - DeploymentRequest.RequiredContexts # TODO: Deployments - - DeploymentsListOptions.Environment # TODO: Repositories - - DeploymentsListOptions.Ref # TODO: Repositories - - DeploymentsListOptions.SHA # TODO: Repositories - - DeploymentsListOptions.Task # TODO: Repositories - - DiscussionCommentListOptions.Direction # TODO: Teams - - DiscussionListOptions.Direction # TODO: Teams - DismissalRestrictionsRequest.Apps # TODO: Repositories - DismissalRestrictionsRequest.Teams # TODO: Repositories - DismissalRestrictionsRequest.Users # TODO: Repositories @@ -270,154 +259,97 @@ linters: - EncryptedSecret.Visibility # TODO: Actions - ErrorBlock.Reason # TODO: Common - ErrorResponse.DocumentationURL # TODO: Common - - GetCodeownersErrorsOptions.Ref # TODO: Repositories + - GetAuditLogOptions.Include + - GetAuditLogOptions.Order + - GetAuditLogOptions.Phrase + - GetProvisionedSCIMGroupEnterpriseOptions.ExcludedAttributes - GistListOptions.Since # TODO: Gists - IssueEvent.Action # TODO: Issues - - IssueListByRepoOptions.Assignee # TODO: Issues - - IssueListByRepoOptions.Assignee # TODO: Issues - - IssueListByRepoOptions.Creator # TODO: Issues - - IssueListByRepoOptions.Creator # TODO: Issues - - IssueListByRepoOptions.Direction # TODO: Issues - - IssueListByRepoOptions.Direction # TODO: Issues - - IssueListByRepoOptions.Mentioned # TODO: Issues - - IssueListByRepoOptions.Mentioned # TODO: Issues - - IssueListByRepoOptions.Milestone # TODO: Issues - IssueListByRepoOptions.Since # TODO: Issues - - IssueListByRepoOptions.Since # TODO: Issues - - IssueListByRepoOptions.Sort # TODO: Issues - - IssueListByRepoOptions.Sort # TODO: Issues - - IssueListByRepoOptions.State # TODO: Issues - - IssueListOptions.Direction # TODO: Issues - - IssueListOptions.Filter # TODO: Issues + - IssueListCommentsOptions.Direction + - IssueListCommentsOptions.Sort - IssueListOptions.Since # TODO: Issues - - IssueListOptions.Sort # TODO: Issues - - IssueListOptions.State # TODO: Issues - IssueRequest.Assignees # TODO: Issues - IssueRequest.Labels # TODO: Issues - License.Conditions # TODO: Licenses - License.Limitations # TODO: Licenses - License.Permissions # TODO: Licenses - - ListCodespacesOptions.RepositoryID # TODO: Codespaces - - ListCollaboratorsOptions.Affiliation # TODO: Repositories - - ListCollaboratorsOptions.Permission # TODO: Repositories - - ListContributorsOptions.Anon # TODO: Repositories - - ListCursorOptions.After # TODO: Common - - ListCursorOptions.Before # TODO: Common - - ListCursorOptions.Cursor # TODO: Common - - ListCursorOptions.First # TODO: Common - - ListCursorOptions.Last # TODO: Common - - ListCursorOptions.Page # TODO: Common - - ListCursorOptions.PerPage # TODO: Common - - ListCustomPropertyValuesOptions.RepositoryQuery # TODO: Organizations - - ListEnterpriseRunnerGroupOptions.VisibleToOrganization # TODO: Enterprise - - ListFineGrainedPATOptions.Direction # TODO: Organizations - - ListFineGrainedPATOptions.LastUsedAfter # TODO: Organizations - - ListFineGrainedPATOptions.LastUsedBefore # TODO: Organizations - - ListFineGrainedPATOptions.Permission # TODO: Organizations - - ListFineGrainedPATOptions.Repository # TODO: Organizations - - ListFineGrainedPATOptions.Sort # TODO: Organizations - - ListIDPGroupsOptions.Query # TODO: Teams - - ListMembersOptions.Filter # TODO: Organizations - - ListMembersOptions.Role # TODO: Organizations - - ListOptions.Page # TODO: Common - - ListOptions.PerPage # TODO: Common - - ListOrgMembershipsOptions.State # TODO: Organizations - - ListOrgRunnerGroupOptions.VisibleToRepository # TODO: Actions - - ListOutsideCollaboratorsOptions.Filter # TODO: Organizations + - ListAlertsOptions.Direction + - ListAlertsOptions.Ecosystem + - ListAlertsOptions.Package + - ListAlertsOptions.Scope + - ListAlertsOptions.Severity + - ListAlertsOptions.Sort + - ListAlertsOptions.State + - ListArtifactsOptions.Name + - ListCheckRunsOptions.AppID + - ListCheckRunsOptions.CheckName + - ListCheckRunsOptions.Filter + - ListCheckRunsOptions.Status + - ListCheckSuiteOptions.AppID + - ListCheckSuiteOptions.CheckName + - ListCostCenterOptions.State + - ListExternalGroupsOptions.DisplayName + - ListGlobalSecurityAdvisoriesOptions.Affects + - ListGlobalSecurityAdvisoriesOptions.CVEID + - ListGlobalSecurityAdvisoriesOptions.Ecosystem + - ListGlobalSecurityAdvisoriesOptions.GHSAID + - ListGlobalSecurityAdvisoriesOptions.IsWithdrawn + - ListGlobalSecurityAdvisoriesOptions.Modified + - ListGlobalSecurityAdvisoriesOptions.Published + - ListGlobalSecurityAdvisoriesOptions.Severity + - ListGlobalSecurityAdvisoriesOptions.Type + - ListGlobalSecurityAdvisoriesOptions.Updated + - ListLicensesOptions.Featured - ListProvisionedSCIMGroupsEnterpriseOptions.Count # TODO: Enterprise - ListProvisionedSCIMGroupsEnterpriseOptions.ExcludedAttributes # TODO: Enterprise - ListProvisionedSCIMGroupsEnterpriseOptions.Filter # TODO: Enterprise - ListProvisionedSCIMGroupsEnterpriseOptions.StartIndex # TODO: Enterprise - - ListReactionOptions.Content # TODO: Reactions - - ListRepositoryActivityOptions.ActivityType # TODO: Repositories - - ListRepositoryActivityOptions.Actor # TODO: Repositories - - ListRepositoryActivityOptions.After # TODO: Repositories - - ListRepositoryActivityOptions.Before # TODO: Repositories - - ListRepositoryActivityOptions.Direction # TODO: Repositories - - ListRepositoryActivityOptions.PerPage # TODO: Repositories - - ListRepositoryActivityOptions.Ref # TODO: Repositories - - ListRepositoryActivityOptions.TimePeriod # TODO: Repositories - - ListRepositorySecurityAdvisoriesOptions.Direction # TODO: SecurityAdvisories - - ListRepositorySecurityAdvisoriesOptions.Direction # TODO: SecurityAdvisories - - ListRepositorySecurityAdvisoriesOptions.Sort # TODO: SecurityAdvisories - - ListRepositorySecurityAdvisoriesOptions.Sort # TODO: SecurityAdvisories - - ListRepositorySecurityAdvisoriesOptions.State # TODO: SecurityAdvisories - - ListRepositorySecurityAdvisoriesOptions.State # TODO: SecurityAdvisories - - ListWorkflowJobsOptions.Filter # TODO: Actions - - ListWorkflowRunsOptions.Actor # TODO: Actions - - ListWorkflowRunsOptions.Branch # TODO: Actions - - ListWorkflowRunsOptions.CheckSuiteID # TODO: Actions - - ListWorkflowRunsOptions.Created # TODO: Actions - - ListWorkflowRunsOptions.Event # TODO: Actions - - ListWorkflowRunsOptions.ExcludePullRequests # TODO: Actions - - ListWorkflowRunsOptions.HeadSHA # TODO: Actions - - ListWorkflowRunsOptions.Status # TODO: Actions + - ListProvisionedSCIMUsersEnterpriseOptions.Count + - ListProvisionedSCIMUsersEnterpriseOptions.Filter + - ListProvisionedSCIMUsersEnterpriseOptions.StartIndex + - ListRepoMachineTypesOptions.ClientIP + - ListRepoMachineTypesOptions.Location + - ListRepoMachineTypesOptions.Ref + - ListRunnersOptions.Name + - ListSCIMProvisionedIdentitiesOptions.Count + - ListSCIMProvisionedIdentitiesOptions.Filter + - ListSCIMProvisionedIdentitiesOptions.StartIndex - LockIssueOptions.LockReason # TODO: Issues - MarketplacePlan.Bullets # TODO: Marketplaces - - MilestoneListOptions.Direction # TODO: Issues - - MilestoneListOptions.Sort # TODO: Issues - - MilestoneListOptions.State # TODO: Issues - - NotificationListOptions.All # TODO: Activities + - NodeQueryOptions.ClusterRoles + - NodeQueryOptions.UUID - NotificationListOptions.Before # TODO: Activities - - NotificationListOptions.Participating # TODO: Activities - NotificationListOptions.Since # TODO: Activities - - OrganizationsListOptions.Since # TODO: Organizations - - OrganizationsListOptions.PerPage # TODO: Organizations - - ProjectV2ItemFieldValue.DataType # TODO: Projects - - ProjectV2ItemFieldValue.Name # TODO: Projects - - PullRequestListCommentsOptions.Direction # TODO: PullRequests + - PackageListOptions.PackageType + - PackageListOptions.State + - PackageListOptions.Visibility + - PremiumRequestUsageReportOptions.Day + - PremiumRequestUsageReportOptions.Model + - PremiumRequestUsageReportOptions.Month + - PremiumRequestUsageReportOptions.Product + - PremiumRequestUsageReportOptions.User + - PremiumRequestUsageReportOptions.Year - PullRequestListCommentsOptions.Since # TODO: PullRequests - - PullRequestListCommentsOptions.Sort # TODO: PullRequests - - PullRequestListOptions.Base # TODO: PullRequests - - PullRequestListOptions.Direction # TODO: PullRequests - - PullRequestListOptions.Head # TODO: PullRequests - - PullRequestListOptions.Sort # TODO: PullRequests - - PullRequestListOptions.State # TODO: PullRequests - Rate.Resource # TODO: Common - RepositoryAddCollaboratorOptions.Permission # TODO: Repositories - - RepositoryContentGetOptions.Ref # TODO: Repositories - RepositoryCreateForkOptions.DefaultBranchOnly # TODO: Repositories - RepositoryCreateForkOptions.Name # TODO: Repositories - RepositoryCreateForkOptions.Organization # TODO: Repositories - - RepositoryListAllOptions.Since # TODO: Repositories - - RepositoryListByAuthenticatedUserOptions.Affiliation # TODO: Repositories - - RepositoryListByAuthenticatedUserOptions.Direction # TODO: Repositories - - RepositoryListByAuthenticatedUserOptions.Sort # TODO: Repositories - - RepositoryListByAuthenticatedUserOptions.Type # TODO: Repositories - - RepositoryListByAuthenticatedUserOptions.Visibility # TODO: Repositories - - RepositoryListByOrgOptions.Direction # TODO: Repositories - - RepositoryListByOrgOptions.Sort # TODO: Repositories - - RepositoryListByOrgOptions.Type # TODO: Repositories - - RepositoryListByUserOptions.Direction # TODO: Repositories - - RepositoryListByUserOptions.Sort # TODO: Repositories - - RepositoryListByUserOptions.Type # TODO: Repositories - - RepositoryListForksOptions.Sort # TODO: Repositories - - RepositoryListOptions.Affiliation # TODO: Repositories - - RepositoryListOptions.Direction # TODO: Repositories - - RepositoryListOptions.Sort # TODO: Repositories - - RepositoryListOptions.Type # TODO: Repositories - - RepositoryListOptions.Visibility # TODO: Repositories + - RepositoryListRulesetsOptions.IncludesParents - RequiredStatusChecks.Checks # TODO: Repositories - RequiredStatusChecks.Contexts # TODO: Repositories - - SearchOptions.Order # TODO: Search - - SearchOptions.Sort # TODO: Search + - SearchOptions.AdvancedSearch - Secret.SelectedRepositoriesURL # TODO: Actions - Secret.Visibility # TODO: Actions - - SecretScanningAlertListOptions.Direction # TODO: SecretScanning - - SecretScanningAlertListOptions.IsMultiRepo # TODO: SecretScanning - - SecretScanningAlertListOptions.IsPubliclyLeaked # TODO: SecretScanning - - SecretScanningAlertListOptions.Resolution # TODO: SecretScanning - - SecretScanningAlertListOptions.SecretType # TODO: SecretScanning - - SecretScanningAlertListOptions.Sort # TODO: SecretScanning - - SecretScanningAlertListOptions.State # TODO: SecretScanning - - SecretScanningAlertListOptions.Validity # TODO: SecretScanning - TeamAddTeamMembershipOptions.Role # TODO: Teams - TeamAddTeamRepoOptions.Permission # TODO: Teams - - TeamListTeamMembersOptions.Role # TODO: Teams - - TrafficBreakdownOptions.Per # TODO: Repositories - UpdateRuleParameters.UpdateAllowsFetchAndMerge # TODO: Rules - - UploadOptions.Label # TODO: Repositories - - UploadOptions.Name # TODO: Repositories + - UsageReportOptions.Day + - UsageReportOptions.Hour + - UsageReportOptions.Month + - UsageReportOptions.Year + - WorkflowRunAttemptOptions.ExcludePullRequests exclusions: rules: - linters: diff --git a/github/enterprise_codesecurity_configurations.go b/github/enterprise_codesecurity_configurations.go index 687873dec42..978a32ad8b7 100644 --- a/github/enterprise_codesecurity_configurations.go +++ b/github/enterprise_codesecurity_configurations.go @@ -21,13 +21,13 @@ import ( // per page (max 100 per GitHub API docs). type ListEnterpriseCodeSecurityConfigurationOptions struct { // A cursor, as given in the Link header. If specified, the query only searches for security configurations before this cursor. - Before *string `url:"before,omitempty"` + Before string `url:"before,omitempty"` // A cursor, as given in the Link header. If specified, the query only searches for security configurations after this cursor. - After *string `url:"after,omitempty"` + After string `url:"after,omitempty"` // For paginated result sets, the number of results to include per page. - PerPage *int `url:"per_page,omitempty"` + PerPage int `url:"per_page,omitempty"` } // ListCodeSecurityConfigurations lists all code security configurations available in an enterprise. diff --git a/github/enterprise_codesecurity_configurations_test.go b/github/enterprise_codesecurity_configurations_test.go index 02d2d1fc612..5a807f158d5 100644 --- a/github/enterprise_codesecurity_configurations_test.go +++ b/github/enterprise_codesecurity_configurations_test.go @@ -16,7 +16,7 @@ import ( func TestEnterpriseService_ListCodeSecurityConfigurations(t *testing.T) { t.Parallel() - opts := &ListEnterpriseCodeSecurityConfigurationOptions{Before: Ptr("1"), After: Ptr("2"), PerPage: Ptr(30)} + opts := &ListEnterpriseCodeSecurityConfigurationOptions{Before: "1", After: "2", PerPage: 30} ctx := t.Context() client, mux, _ := setup(t) @@ -391,7 +391,7 @@ func TestEnterpriseService_SetDefaultCodeSecurityConfiguration(t *testing.T) { func TestEnterpriseService_ListCodeSecurityConfigurationRepositories(t *testing.T) { t.Parallel() - opts := &ListCodeSecurityConfigurationRepositoriesOptions{Before: Ptr("1"), After: Ptr("2"), PerPage: Ptr(30), Status: Ptr("attached")} + opts := &ListCodeSecurityConfigurationRepositoriesOptions{Before: "1", After: "2", PerPage: 30, Status: "attached"} ctx := t.Context() client, mux, _ := setup(t) diff --git a/github/examples_test.go b/github/examples_test.go index 989ba8ef86a..96cec48d49e 100644 --- a/github/examples_test.go +++ b/github/examples_test.go @@ -105,7 +105,7 @@ func ExampleUsersService_ListAll() { if len(users) == 0 { break } - opts.Since = users[len(users)-1].ID + opts.Since = users[len(users)-1].GetID() // Process users... } } diff --git a/github/github-accessors.go b/github/github-accessors.go index 1d79e676c4d..ec77299f2fe 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -14734,38 +14734,6 @@ func (l *ListCheckSuiteResults) GetTotal() int { return *l.Total } -// GetAfter returns the After field if it's non-nil, zero value otherwise. -func (l *ListCodeSecurityConfigurationRepositoriesOptions) GetAfter() string { - if l == nil || l.After == nil { - return "" - } - return *l.After -} - -// GetBefore returns the Before field if it's non-nil, zero value otherwise. -func (l *ListCodeSecurityConfigurationRepositoriesOptions) GetBefore() string { - if l == nil || l.Before == nil { - return "" - } - return *l.Before -} - -// GetPerPage returns the PerPage field if it's non-nil, zero value otherwise. -func (l *ListCodeSecurityConfigurationRepositoriesOptions) GetPerPage() int { - if l == nil || l.PerPage == nil { - return 0 - } - return *l.PerPage -} - -// GetStatus returns the Status field if it's non-nil, zero value otherwise. -func (l *ListCodeSecurityConfigurationRepositoriesOptions) GetStatus() string { - if l == nil || l.Status == nil { - return "" - } - return *l.Status -} - // GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise. func (l *ListCodespaces) GetTotalCount() int { if l == nil || l.TotalCount == nil { @@ -14798,30 +14766,6 @@ func (l *ListDeploymentProtectionRuleResponse) GetTotalCount() int { return *l.TotalCount } -// GetAfter returns the After field if it's non-nil, zero value otherwise. -func (l *ListEnterpriseCodeSecurityConfigurationOptions) GetAfter() string { - if l == nil || l.After == nil { - return "" - } - return *l.After -} - -// GetBefore returns the Before field if it's non-nil, zero value otherwise. -func (l *ListEnterpriseCodeSecurityConfigurationOptions) GetBefore() string { - if l == nil || l.Before == nil { - return "" - } - return *l.Before -} - -// GetPerPage returns the PerPage field if it's non-nil, zero value otherwise. -func (l *ListEnterpriseCodeSecurityConfigurationOptions) GetPerPage() int { - if l == nil || l.PerPage == nil { - return 0 - } - return *l.PerPage -} - // GetDisplayName returns the DisplayName field if it's non-nil, zero value otherwise. func (l *ListExternalGroupsOptions) GetDisplayName() string { if l == nil || l.DisplayName == nil { @@ -14926,70 +14870,6 @@ func (l *ListOrganizations) GetTotalCount() int { return *l.TotalCount } -// GetAfter returns the After field if it's non-nil, zero value otherwise. -func (l *ListOrgCodeSecurityConfigurationOptions) GetAfter() string { - if l == nil || l.After == nil { - return "" - } - return *l.After -} - -// GetBefore returns the Before field if it's non-nil, zero value otherwise. -func (l *ListOrgCodeSecurityConfigurationOptions) GetBefore() string { - if l == nil || l.Before == nil { - return "" - } - return *l.Before -} - -// GetPerPage returns the PerPage field if it's non-nil, zero value otherwise. -func (l *ListOrgCodeSecurityConfigurationOptions) GetPerPage() int { - if l == nil || l.PerPage == nil { - return 0 - } - return *l.PerPage -} - -// GetTargetType returns the TargetType field if it's non-nil, zero value otherwise. -func (l *ListOrgCodeSecurityConfigurationOptions) GetTargetType() string { - if l == nil || l.TargetType == nil { - return "" - } - return *l.TargetType -} - -// GetQuery returns the Query field if it's non-nil, zero value otherwise. -func (l *ListProjectsOptions) GetQuery() string { - if l == nil || l.Query == nil { - return "" - } - return *l.Query -} - -// GetAfter returns the After field if it's non-nil, zero value otherwise. -func (l *ListProjectsPaginationOptions) GetAfter() string { - if l == nil || l.After == nil { - return "" - } - return *l.After -} - -// GetBefore returns the Before field if it's non-nil, zero value otherwise. -func (l *ListProjectsPaginationOptions) GetBefore() string { - if l == nil || l.Before == nil { - return "" - } - return *l.Before -} - -// GetPerPage returns the PerPage field if it's non-nil, zero value otherwise. -func (l *ListProjectsPaginationOptions) GetPerPage() int { - if l == nil || l.PerPage == nil { - return 0 - } - return *l.PerPage -} - // GetCount returns the Count field if it's non-nil, zero value otherwise. func (l *ListProvisionedSCIMGroupsEnterpriseOptions) GetCount() int { if l == nil || l.Count == nil { @@ -31454,22 +31334,6 @@ func (u *UserLDAPMapping) GetURL() string { return *u.URL } -// GetPerPage returns the PerPage field if it's non-nil, zero value otherwise. -func (u *UserListOptions) GetPerPage() int { - if u == nil || u.PerPage == nil { - return 0 - } - return *u.PerPage -} - -// GetSince returns the Since field if it's non-nil, zero value otherwise. -func (u *UserListOptions) GetSince() int64 { - if u == nil || u.Since == nil { - return 0 - } - return *u.Since -} - // GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. func (u *UserMigration) GetCreatedAt() string { if u == nil || u.CreatedAt == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 49296912c7c..08332e3776d 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -19169,50 +19169,6 @@ func TestListCheckSuiteResults_GetTotal(tt *testing.T) { l.GetTotal() } -func TestListCodeSecurityConfigurationRepositoriesOptions_GetAfter(tt *testing.T) { - tt.Parallel() - var zeroValue string - l := &ListCodeSecurityConfigurationRepositoriesOptions{After: &zeroValue} - l.GetAfter() - l = &ListCodeSecurityConfigurationRepositoriesOptions{} - l.GetAfter() - l = nil - l.GetAfter() -} - -func TestListCodeSecurityConfigurationRepositoriesOptions_GetBefore(tt *testing.T) { - tt.Parallel() - var zeroValue string - l := &ListCodeSecurityConfigurationRepositoriesOptions{Before: &zeroValue} - l.GetBefore() - l = &ListCodeSecurityConfigurationRepositoriesOptions{} - l.GetBefore() - l = nil - l.GetBefore() -} - -func TestListCodeSecurityConfigurationRepositoriesOptions_GetPerPage(tt *testing.T) { - tt.Parallel() - var zeroValue int - l := &ListCodeSecurityConfigurationRepositoriesOptions{PerPage: &zeroValue} - l.GetPerPage() - l = &ListCodeSecurityConfigurationRepositoriesOptions{} - l.GetPerPage() - l = nil - l.GetPerPage() -} - -func TestListCodeSecurityConfigurationRepositoriesOptions_GetStatus(tt *testing.T) { - tt.Parallel() - var zeroValue string - l := &ListCodeSecurityConfigurationRepositoriesOptions{Status: &zeroValue} - l.GetStatus() - l = &ListCodeSecurityConfigurationRepositoriesOptions{} - l.GetStatus() - l = nil - l.GetStatus() -} - func TestListCodespaces_GetTotalCount(tt *testing.T) { tt.Parallel() var zeroValue int @@ -19257,39 +19213,6 @@ func TestListDeploymentProtectionRuleResponse_GetTotalCount(tt *testing.T) { l.GetTotalCount() } -func TestListEnterpriseCodeSecurityConfigurationOptions_GetAfter(tt *testing.T) { - tt.Parallel() - var zeroValue string - l := &ListEnterpriseCodeSecurityConfigurationOptions{After: &zeroValue} - l.GetAfter() - l = &ListEnterpriseCodeSecurityConfigurationOptions{} - l.GetAfter() - l = nil - l.GetAfter() -} - -func TestListEnterpriseCodeSecurityConfigurationOptions_GetBefore(tt *testing.T) { - tt.Parallel() - var zeroValue string - l := &ListEnterpriseCodeSecurityConfigurationOptions{Before: &zeroValue} - l.GetBefore() - l = &ListEnterpriseCodeSecurityConfigurationOptions{} - l.GetBefore() - l = nil - l.GetBefore() -} - -func TestListEnterpriseCodeSecurityConfigurationOptions_GetPerPage(tt *testing.T) { - tt.Parallel() - var zeroValue int - l := &ListEnterpriseCodeSecurityConfigurationOptions{PerPage: &zeroValue} - l.GetPerPage() - l = &ListEnterpriseCodeSecurityConfigurationOptions{} - l.GetPerPage() - l = nil - l.GetPerPage() -} - func TestListExternalGroupsOptions_GetDisplayName(tt *testing.T) { tt.Parallel() var zeroValue string @@ -19433,94 +19356,6 @@ func TestListOrganizations_GetTotalCount(tt *testing.T) { l.GetTotalCount() } -func TestListOrgCodeSecurityConfigurationOptions_GetAfter(tt *testing.T) { - tt.Parallel() - var zeroValue string - l := &ListOrgCodeSecurityConfigurationOptions{After: &zeroValue} - l.GetAfter() - l = &ListOrgCodeSecurityConfigurationOptions{} - l.GetAfter() - l = nil - l.GetAfter() -} - -func TestListOrgCodeSecurityConfigurationOptions_GetBefore(tt *testing.T) { - tt.Parallel() - var zeroValue string - l := &ListOrgCodeSecurityConfigurationOptions{Before: &zeroValue} - l.GetBefore() - l = &ListOrgCodeSecurityConfigurationOptions{} - l.GetBefore() - l = nil - l.GetBefore() -} - -func TestListOrgCodeSecurityConfigurationOptions_GetPerPage(tt *testing.T) { - tt.Parallel() - var zeroValue int - l := &ListOrgCodeSecurityConfigurationOptions{PerPage: &zeroValue} - l.GetPerPage() - l = &ListOrgCodeSecurityConfigurationOptions{} - l.GetPerPage() - l = nil - l.GetPerPage() -} - -func TestListOrgCodeSecurityConfigurationOptions_GetTargetType(tt *testing.T) { - tt.Parallel() - var zeroValue string - l := &ListOrgCodeSecurityConfigurationOptions{TargetType: &zeroValue} - l.GetTargetType() - l = &ListOrgCodeSecurityConfigurationOptions{} - l.GetTargetType() - l = nil - l.GetTargetType() -} - -func TestListProjectsOptions_GetQuery(tt *testing.T) { - tt.Parallel() - var zeroValue string - l := &ListProjectsOptions{Query: &zeroValue} - l.GetQuery() - l = &ListProjectsOptions{} - l.GetQuery() - l = nil - l.GetQuery() -} - -func TestListProjectsPaginationOptions_GetAfter(tt *testing.T) { - tt.Parallel() - var zeroValue string - l := &ListProjectsPaginationOptions{After: &zeroValue} - l.GetAfter() - l = &ListProjectsPaginationOptions{} - l.GetAfter() - l = nil - l.GetAfter() -} - -func TestListProjectsPaginationOptions_GetBefore(tt *testing.T) { - tt.Parallel() - var zeroValue string - l := &ListProjectsPaginationOptions{Before: &zeroValue} - l.GetBefore() - l = &ListProjectsPaginationOptions{} - l.GetBefore() - l = nil - l.GetBefore() -} - -func TestListProjectsPaginationOptions_GetPerPage(tt *testing.T) { - tt.Parallel() - var zeroValue int - l := &ListProjectsPaginationOptions{PerPage: &zeroValue} - l.GetPerPage() - l = &ListProjectsPaginationOptions{} - l.GetPerPage() - l = nil - l.GetPerPage() -} - func TestListProvisionedSCIMGroupsEnterpriseOptions_GetCount(tt *testing.T) { tt.Parallel() var zeroValue int @@ -40617,28 +40452,6 @@ func TestUserLDAPMapping_GetURL(tt *testing.T) { u.GetURL() } -func TestUserListOptions_GetPerPage(tt *testing.T) { - tt.Parallel() - var zeroValue int - u := &UserListOptions{PerPage: &zeroValue} - u.GetPerPage() - u = &UserListOptions{} - u.GetPerPage() - u = nil - u.GetPerPage() -} - -func TestUserListOptions_GetSince(tt *testing.T) { - tt.Parallel() - var zeroValue int64 - u := &UserListOptions{Since: &zeroValue} - u.GetSince() - u = &UserListOptions{} - u.GetSince() - u = nil - u.GetSince() -} - func TestUserMigration_GetCreatedAt(tt *testing.T) { tt.Parallel() var zeroValue string diff --git a/github/orgs_codesecurity_configurations.go b/github/orgs_codesecurity_configurations.go index d1ed6e25793..6bacf0ba079 100644 --- a/github/orgs_codesecurity_configurations.go +++ b/github/orgs_codesecurity_configurations.go @@ -102,18 +102,18 @@ type RepositoryCodeSecurityConfiguration struct { // per page (max 100 per GitHub API docs). type ListOrgCodeSecurityConfigurationOptions struct { // A cursor, as given in the Link header. If specified, the query only searches for security configurations before this cursor. - Before *string `url:"before,omitempty"` + Before string `url:"before,omitempty"` // A cursor, as given in the Link header. If specified, the query only searches for security configurations after this cursor. - After *string `url:"after,omitempty"` + After string `url:"after,omitempty"` // For paginated result sets, the number of results to include per page. - PerPage *int `url:"per_page,omitempty"` + PerPage int `url:"per_page,omitempty"` // The target type of the code security configurations to get. // // `target_type` defaults to all, can be one of `global`, `all` - TargetType *string `url:"target_type,omitempty"` + TargetType string `url:"target_type,omitempty"` } // ListCodeSecurityConfigurationRepositoriesOptions specifies optional parameters to list repositories for security configurations for orgs and enterprises. @@ -126,18 +126,18 @@ type ListOrgCodeSecurityConfigurationOptions struct { // per page (max 100 per GitHub API docs). type ListCodeSecurityConfigurationRepositoriesOptions struct { // A cursor, as given in the Link header. If specified, the query only searches for repositories before this cursor. - Before *string `url:"before,omitempty"` + Before string `url:"before,omitempty"` // A cursor, as given in the Link header. If specified, the query only searches for repositories after this cursor. - After *string `url:"after,omitempty"` + After string `url:"after,omitempty"` // For paginated result sets, the number of results to include per page. - PerPage *int `url:"per_page,omitempty"` + PerPage int `url:"per_page,omitempty"` // A comma-separated list of statuses. If specified, only repositories with these attachment statuses will be returned. // // `status` defaults to all, can be one of `all`, `attached`, `attaching`, `removed`, `enforced`, `failed`, `updating`, `removed_by_enterprise` and also `detached` but only for the org endpoint. - Status *string `url:"status,omitempty"` + Status string `url:"status,omitempty"` } // ListCodeSecurityConfigurations gets code security configurations for an organization. diff --git a/github/orgs_codesecurity_configurations_test.go b/github/orgs_codesecurity_configurations_test.go index 0ee45657694..708fe2a0c41 100644 --- a/github/orgs_codesecurity_configurations_test.go +++ b/github/orgs_codesecurity_configurations_test.go @@ -16,7 +16,7 @@ import ( func TestOrganizationsService_ListCodeSecurityConfigurations(t *testing.T) { t.Parallel() - opts := &ListOrgCodeSecurityConfigurationOptions{Before: Ptr("1"), After: Ptr("2"), PerPage: Ptr(30), TargetType: Ptr("all")} + opts := &ListOrgCodeSecurityConfigurationOptions{Before: "1", After: "2", PerPage: 30, TargetType: "all"} ctx := t.Context() client, mux, _ := setup(t) @@ -533,7 +533,7 @@ func TestOrganizationsService_SetDefaultCodeSecurityConfiguration(t *testing.T) func TestOrganizationsService_ListCodeSecurityConfigurationRepositories(t *testing.T) { t.Parallel() - opts := &ListCodeSecurityConfigurationRepositoriesOptions{Before: Ptr("1"), After: Ptr("2"), PerPage: Ptr(30), Status: Ptr("attached")} + opts := &ListCodeSecurityConfigurationRepositoriesOptions{Before: "1", After: "2", PerPage: 30, Status: "attached"} ctx := t.Context() client, mux, _ := setup(t) diff --git a/github/projects.go b/github/projects.go index d2c52f37944..8d6cbf8dae0 100644 --- a/github/projects.go +++ b/github/projects.go @@ -96,13 +96,13 @@ func (p ProjectV2) String() string { return Stringify(p) } // per page (max 100 per GitHub API docs). type ListProjectsPaginationOptions struct { // A cursor, as given in the Link header. If specified, the query only searches for events before this cursor. - Before *string `url:"before,omitempty"` + Before string `url:"before,omitempty"` // A cursor, as given in the Link header. If specified, the query only searches for events after this cursor. - After *string `url:"after,omitempty"` + After string `url:"after,omitempty"` // For paginated result sets, the number of results to include per page. - PerPage *int `url:"per_page,omitempty"` + PerPage int `url:"per_page,omitempty"` } // ListProjectsOptions specifies optional parameters to list projects for user / organization. @@ -110,7 +110,7 @@ type ListProjectsOptions struct { ListProjectsPaginationOptions // Q is an optional query string to limit results to projects of the specified type. - Query *string `url:"q,omitempty"` + Query string `url:"q,omitempty"` } // ProjectV2TextContent represents text content in a project field option or iteration. diff --git a/github/projects_test.go b/github/projects_test.go index ddfa2bd6a4e..746d95fbafa 100644 --- a/github/projects_test.go +++ b/github/projects_test.go @@ -31,7 +31,7 @@ func TestProjectsService_ListOrganizationProjects(t *testing.T) { fmt.Fprint(w, `[{"id":1,"title":"T1","created_at":"2011-01-02T15:04:05Z","updated_at":"2012-01-02T15:04:05Z"}]`) }) - opts := &ListProjectsOptions{Query: Ptr("alpha"), ListProjectsPaginationOptions: ListProjectsPaginationOptions{After: Ptr("2"), Before: Ptr("1")}} + opts := &ListProjectsOptions{Query: "alpha", ListProjectsPaginationOptions: ListProjectsPaginationOptions{After: "2", Before: "1"}} ctx := t.Context() projects, _, err := client.Projects.ListOrganizationProjects(ctx, "o", opts) if err != nil { @@ -57,7 +57,7 @@ func TestProjectsService_ListOrganizationProjects(t *testing.T) { // still allow both set (no validation enforced) – ensure it does not error ctxBypass := context.WithValue(t.Context(), BypassRateLimitCheck, true) - if _, _, err = client.Projects.ListOrganizationProjects(ctxBypass, "o", &ListProjectsOptions{ListProjectsPaginationOptions: ListProjectsPaginationOptions{Before: Ptr("b"), After: Ptr("a")}}); err != nil { + if _, _, err = client.Projects.ListOrganizationProjects(ctxBypass, "o", &ListProjectsOptions{ListProjectsPaginationOptions: ListProjectsPaginationOptions{Before: "b", After: "a"}}); err != nil { t.Fatalf("unexpected error when both before/after set: %v", err) } } @@ -106,7 +106,7 @@ func TestProjectsService_ListUserProjects(t *testing.T) { fmt.Fprint(w, `[{"id":2,"title":"UProj","created_at":"2011-01-02T15:04:05Z","updated_at":"2012-01-02T15:04:05Z"}]`) }) - opts := &ListProjectsOptions{Query: Ptr("beta"), ListProjectsPaginationOptions: ListProjectsPaginationOptions{Before: Ptr("1"), After: Ptr("2"), PerPage: Ptr(2)}} + opts := &ListProjectsOptions{Query: "beta", ListProjectsPaginationOptions: ListProjectsPaginationOptions{Before: "1", After: "2", PerPage: 2}} ctx := t.Context() var ctxBypass context.Context projects, _, err := client.Projects.ListUserProjects(ctx, "u", opts) @@ -133,7 +133,7 @@ func TestProjectsService_ListUserProjects(t *testing.T) { // still allow both set (no validation enforced) – ensure it does not error ctxBypass = context.WithValue(t.Context(), BypassRateLimitCheck, true) - if _, _, err = client.Projects.ListUserProjects(ctxBypass, "u", &ListProjectsOptions{ListProjectsPaginationOptions: ListProjectsPaginationOptions{Before: Ptr("b"), After: Ptr("a")}}); err != nil { + if _, _, err = client.Projects.ListUserProjects(ctxBypass, "u", &ListProjectsOptions{ListProjectsPaginationOptions: ListProjectsPaginationOptions{Before: "b", After: "a"}}); err != nil { t.Fatalf("unexpected error when both before/after set: %v", err) } } @@ -204,7 +204,7 @@ func TestProjectsService_ListOrganizationProjectFields(t *testing.T) { ]`) }) - opts := &ListProjectsOptions{Query: Ptr("text"), ListProjectsPaginationOptions: ListProjectsPaginationOptions{After: Ptr("2"), Before: Ptr("1")}} + opts := &ListProjectsOptions{Query: "text", ListProjectsPaginationOptions: ListProjectsPaginationOptions{After: "2", Before: "1"}} ctx := t.Context() fields, _, err := client.Projects.ListOrganizationProjectFields(ctx, "o", 1, opts) if err != nil { @@ -230,7 +230,7 @@ func TestProjectsService_ListOrganizationProjectFields(t *testing.T) { return resp, err }) ctxBypass := context.WithValue(ctx, BypassRateLimitCheck, true) - if _, _, err = client.Projects.ListOrganizationProjectFields(ctxBypass, "o", 1, &ListProjectsOptions{ListProjectsPaginationOptions: ListProjectsPaginationOptions{Before: Ptr("b"), After: Ptr("a")}}); err != nil { + if _, _, err = client.Projects.ListOrganizationProjectFields(ctxBypass, "o", 1, &ListProjectsOptions{ListProjectsPaginationOptions: ListProjectsPaginationOptions{Before: ("b"), After: ("a")}}); err != nil { t.Fatalf("unexpected error when both before/after set: %v", err) } } @@ -273,7 +273,7 @@ func TestProjectsService_ListUserProjectFields(t *testing.T) { ]`) }) - opts := &ListProjectsOptions{Query: Ptr("text"), ListProjectsPaginationOptions: ListProjectsPaginationOptions{After: Ptr("2"), Before: Ptr("1")}} + opts := &ListProjectsOptions{Query: ("text"), ListProjectsPaginationOptions: ListProjectsPaginationOptions{After: ("2"), Before: ("1")}} ctx := t.Context() fields, _, err := client.Projects.ListUserProjectFields(ctx, "u", 1, opts) if err != nil { @@ -299,7 +299,7 @@ func TestProjectsService_ListUserProjectFields(t *testing.T) { return resp, err }) ctxBypass := context.WithValue(ctx, BypassRateLimitCheck, true) - if _, _, err = client.Projects.ListUserProjectFields(ctxBypass, "u", 1, &ListProjectsOptions{ListProjectsPaginationOptions: ListProjectsPaginationOptions{Before: Ptr("b"), After: Ptr("a")}}); err != nil { + if _, _, err = client.Projects.ListUserProjectFields(ctxBypass, "u", 1, &ListProjectsOptions{ListProjectsPaginationOptions: ListProjectsPaginationOptions{Before: ("b"), After: ("a")}}); err != nil { t.Fatalf("unexpected error when both before/after set: %v", err) } } @@ -417,7 +417,7 @@ func TestProjectsService_ListUserProjects_pagination(t *testing.T) { t.Fatalf("expected resp.After=ucursor2 got %q", resp.After) } - opts := &ListProjectsOptions{ListProjectsPaginationOptions: ListProjectsPaginationOptions{After: Ptr(resp.After)}} + opts := &ListProjectsOptions{ListProjectsPaginationOptions: ListProjectsPaginationOptions{After: (resp.After)}} second, resp2, err := client.Projects.ListUserProjects(ctx, "u", opts) if err != nil { t.Fatalf("second page error: %v", err) @@ -490,7 +490,7 @@ func TestProjectsService_ListOrganizationProjectFields_pagination(t *testing.T) t.Fatalf("expected resp.After=cursor2 got %q", resp.After) } - opts := &ListProjectsOptions{ListProjectsPaginationOptions: ListProjectsPaginationOptions{After: Ptr(resp.After)}} + opts := &ListProjectsOptions{ListProjectsPaginationOptions: ListProjectsPaginationOptions{After: (resp.After)}} second, resp2, err := client.Projects.ListOrganizationProjectFields(ctx, "o", 1, opts) if err != nil { t.Fatalf("second page error: %v", err) @@ -536,7 +536,7 @@ func TestProjectsService_ListOrganizationProjects_pagination(t *testing.T) { t.Fatalf("expected resp.After=ocursor2 got %q", resp.After) } - opts := &ListProjectsOptions{ListProjectsPaginationOptions: ListProjectsPaginationOptions{After: Ptr(resp.After)}} + opts := &ListProjectsOptions{ListProjectsPaginationOptions: ListProjectsPaginationOptions{After: (resp.After)}} second, resp2, err := client.Projects.ListOrganizationProjects(ctx, "o", opts) if err != nil { t.Fatalf("second page error: %v", err) @@ -765,7 +765,7 @@ func TestProjectsService_ListOrganizationProjectItems(t *testing.T) { fmt.Fprint(w, `[{"id":17,"node_id":"PVTI_node"}]`) }) - opts := &ListProjectItemsOptions{ListProjectsOptions: ListProjectsOptions{ListProjectsPaginationOptions: ListProjectsPaginationOptions{After: Ptr("2"), Before: Ptr("1"), PerPage: Ptr(50)}, Query: Ptr("status:open")}, Fields: []int64{10, 11}} + opts := &ListProjectItemsOptions{ListProjectsOptions: ListProjectsOptions{ListProjectsPaginationOptions: ListProjectsPaginationOptions{After: ("2"), Before: ("1"), PerPage: (50)}, Query: ("status:open")}, Fields: []int64{10, 11}} ctx := t.Context() items, _, err := client.Projects.ListOrganizationProjectItems(ctx, "o", 1, opts) if err != nil { @@ -790,7 +790,7 @@ func TestProjectsService_ListOrganizationProjectItems(t *testing.T) { }) ctxBypass := context.WithValue(ctx, BypassRateLimitCheck, true) - if _, _, err = client.Projects.ListOrganizationProjectItems(ctxBypass, "o", 1, &ListProjectItemsOptions{ListProjectsOptions: ListProjectsOptions{ListProjectsPaginationOptions: ListProjectsPaginationOptions{Before: Ptr("b"), After: Ptr("a")}}}); err != nil { + if _, _, err = client.Projects.ListOrganizationProjectItems(ctxBypass, "o", 1, &ListProjectItemsOptions{ListProjectsOptions: ListProjectsOptions{ListProjectsPaginationOptions: ListProjectsPaginationOptions{Before: ("b"), After: ("a")}}}); err != nil { t.Fatalf("unexpected error when both before/after set: %v", err) } } @@ -1038,7 +1038,7 @@ func TestProjectsService_ListUserProjectItems(t *testing.T) { fmt.Fprint(w, `[{"id":7,"node_id":"PVTI_user"}]`) }) ctx := t.Context() - items, _, err := client.Projects.ListUserProjectItems(ctx, "u", 2, &ListProjectItemsOptions{ListProjectsOptions: ListProjectsOptions{ListProjectsPaginationOptions: ListProjectsPaginationOptions{PerPage: Ptr(20)}, Query: Ptr("type:issue")}}) + items, _, err := client.Projects.ListUserProjectItems(ctx, "u", 2, &ListProjectItemsOptions{ListProjectsOptions: ListProjectsOptions{ListProjectsPaginationOptions: ListProjectsPaginationOptions{PerPage: (20)}, Query: ("type:issue")}}) if err != nil { t.Fatalf("ListUserProjectItems error: %v", err) } diff --git a/github/users.go b/github/users.go index d9591da8ae4..ae5027d3155 100644 --- a/github/users.go +++ b/github/users.go @@ -209,8 +209,8 @@ func (s *UsersService) GetHovercard(ctx context.Context, user string, opts *Hove // method. type UserListOptions struct { // A user ID. Only return users with an ID greater than this ID. - Since *int64 `url:"since,omitempty"` - PerPage *int `url:"per_page,omitempty"` + Since int64 `url:"since,omitempty"` + PerPage int `url:"per_page,omitempty"` } // ListAll lists all GitHub users. diff --git a/github/users_test.go b/github/users_test.go index 23a00bb7e06..ea3cb53bb30 100644 --- a/github/users_test.go +++ b/github/users_test.go @@ -330,7 +330,7 @@ func TestUsersService_ListAll(t *testing.T) { fmt.Fprint(w, `[{"id":2}]`) }) - opt := &UserListOptions{Since: Ptr(int64(1)), PerPage: Ptr(30)} + opt := &UserListOptions{Since: 1, PerPage: 30} ctx := t.Context() users, _, err := client.Users.ListAll(ctx, opt) if err != nil { @@ -497,10 +497,7 @@ func TestUserListOptions_Marshal(t *testing.T) { t.Parallel() testJSONMarshal(t, &UserListOptions{}, "{}") - u := &UserListOptions{ - Since: Ptr(int64(1900)), - PerPage: Ptr(30), - } + u := &UserListOptions{Since: 1900, PerPage: 30} want := `{ "since" : 1900, diff --git a/script/run-check-structfield-settings.sh b/script/run-check-structfield-settings.sh new file mode 100755 index 00000000000..06f7018827f --- /dev/null +++ b/script/run-check-structfield-settings.sh @@ -0,0 +1,2 @@ +#!/bin/bash -e +pushd tools/check-structfield-settings && go run . "$@" diff --git a/tools/check-structfield-settings/go.mod b/tools/check-structfield-settings/go.mod new file mode 100644 index 00000000000..d279790d057 --- /dev/null +++ b/tools/check-structfield-settings/go.mod @@ -0,0 +1,18 @@ +module github.com/google/go-github/v82/tools/check-structfield-settings + +go 1.24.0 + +require ( + github.com/golangci/plugin-module-register v0.1.1 + github.com/google/go-github/v82/tools/structfield v0.0.0 + gopkg.in/yaml.v3 v3.0.1 +) + +require ( + golang.org/x/mod v0.22.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/tools v0.29.0 +) + +// Use version at HEAD, not the latest published. +replace github.com/google/go-github/v82/tools/structfield v0.0.0 => ../structfield diff --git a/tools/check-structfield-settings/go.sum b/tools/check-structfield-settings/go.sum new file mode 100644 index 00000000000..91901205d47 --- /dev/null +++ b/tools/check-structfield-settings/go.sum @@ -0,0 +1,14 @@ +github.com/golangci/plugin-module-register v0.1.1 h1:TCmesur25LnyJkpsVrupv1Cdzo+2f7zX0H6Jkw1Ol6c= +github.com/golangci/plugin-module-register v0.1.1/go.mod h1:TTpqoB6KkwOJMV8u7+NyXMrkwwESJLOkfl9TxR1DGFc= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE= +golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/tools/check-structfield-settings/main.go b/tools/check-structfield-settings/main.go new file mode 100644 index 00000000000..94b02ae6919 --- /dev/null +++ b/tools/check-structfield-settings/main.go @@ -0,0 +1,414 @@ +// Copyright 2026 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// check-structfield-settings reads the settings for +// the custom `structfield` linter in ".golangci.yml" - +// specifically, the "allowed-tag-names" and "allowed-tag-types" +// exceptions, then scans the code repo to find all exceptions +// that are no longer needed and reports a list. +package main + +import ( + "errors" + "flag" + "fmt" + "io/fs" + "log" + "os" + "path/filepath" + "regexp" + "sort" + "strings" + + "github.com/golangci/plugin-module-register/register" + "github.com/google/go-github/v82/tools/structfield" + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/checker" + "golang.org/x/tools/go/packages" + "gopkg.in/yaml.v3" +) + +func init() { + register.Plugin("structfield", structfield.New) +} + +func main() { + log.SetFlags(0) + configPath := flag.String("config", "", "path to .golangci.yml (defaults to searching up from cwd)") + packagesFlag := flag.String("packages", "./...", "comma-separated list of package patterns to analyze") + includeTests := flag.Bool("tests", false, "include test files in analysis") + fix := flag.Bool("fix", false, "remove obsolete exceptions and sort/dedupe lists in .golangci.yml") + flag.Parse() + + resolvedConfig, repoRoot, err := resolveConfig(*configPath) + if err != nil { + log.Fatalf("config: %v", err) + } + + allowedNamesList, allowedTypesList, allowedNames, allowedTypes, err := readStructfieldSettings(resolvedConfig) + if err != nil { + log.Fatalf("parse config: %v", err) + } + if len(allowedNames) == 0 && len(allowedTypes) == 0 { + log.Fatalf("no structfield settings found in %s", resolvedConfig) + } + + duplicateNames := findDuplicates(allowedNamesList) + duplicateTypes := findDuplicates(allowedTypesList) + + patterns := strings.Split(*packagesFlag, ",") + for i, pattern := range patterns { + patterns[i] = strings.TrimSpace(pattern) + } + + usedNames, usedTypes, err := analyzeRepo(repoRoot, patterns, *includeTests, allowedNames, allowedTypes) + if err != nil { + log.Fatalf("analyze: %v", err) + } + + obsoleteNames := diffKeys(allowedNames, usedNames) + obsoleteTypes := diffKeys(allowedTypes, usedTypes) + + if len(obsoleteNames) == 0 && len(obsoleteTypes) == 0 && len(duplicateNames) == 0 && len(duplicateTypes) == 0 { + log.Print("No obsolete structfield exceptions found.") + return + } + + if *fix { + if err := removeObsoleteExceptions(resolvedConfig, obsoleteNames, obsoleteTypes); err != nil { + log.Fatalf("fix: %v", err) + } + } + + if len(obsoleteNames) > 0 { + fmt.Println("Obsolete allowed-tag-names:") + for _, name := range obsoleteNames { + fmt.Printf(" - %v\n", name) + } + } + if len(obsoleteTypes) > 0 { + if len(obsoleteNames) > 0 { + fmt.Println() + } + fmt.Println("Obsolete allowed-tag-types:") + for _, name := range obsoleteTypes { + fmt.Printf(" - %v\n", name) + } + } + if len(duplicateNames) > 0 { + if len(obsoleteNames) > 0 || len(obsoleteTypes) > 0 { + fmt.Println() + } + fmt.Println("Duplicate allowed-tag-names:") + for _, name := range sortedKeys(duplicateNames) { + fmt.Printf(" - %v (%v)\n", name, duplicateNames[name]) + } + } + if len(duplicateTypes) > 0 { + if len(obsoleteNames) > 0 || len(obsoleteTypes) > 0 || len(duplicateNames) > 0 { + fmt.Println() + } + fmt.Println("Duplicate allowed-tag-types:") + for _, name := range sortedKeys(duplicateTypes) { + fmt.Printf(" - %v (%v)\n", name, duplicateTypes[name]) + } + } +} + +type golangciConfig struct { + Linters struct { + Settings struct { + Custom struct { + Structfield struct { + Settings struct { + AllowedTagNames []string `yaml:"allowed-tag-names"` + AllowedTagTypes []string `yaml:"allowed-tag-types"` + } `yaml:"settings"` + } `yaml:"structfield"` + } `yaml:"custom"` + } `yaml:"settings"` + } `yaml:"linters"` +} + +func resolveConfig(configPath string) (string, string, error) { + if configPath != "" { + resolved, err := filepath.Abs(configPath) + if err != nil { + return "", "", err + } + repoRoot := filepath.Dir(resolved) + return resolved, repoRoot, nil + } + + cwd, err := os.Getwd() + if err != nil { + return "", "", err + } + + for dir := cwd; ; dir = filepath.Dir(dir) { + candidate := filepath.Join(dir, ".golangci.yml") + if _, err := os.Stat(candidate); err == nil { + return candidate, dir, nil + } else if !errors.Is(err, fs.ErrNotExist) { + return "", "", err + } + + parent := filepath.Dir(dir) + if parent == dir { + break + } + } + + return "", "", errors.New("unable to locate .golangci.yml") +} + +func readStructfieldSettings(configPath string) ([]string, []string, map[string]bool, map[string]bool, error) { + data, err := os.ReadFile(configPath) + if err != nil { + return nil, nil, nil, nil, err + } + + var cfg golangciConfig + if err := yaml.Unmarshal(data, &cfg); err != nil { + return nil, nil, nil, nil, err + } + + allowedNamesList := cfg.Linters.Settings.Custom.Structfield.Settings.AllowedTagNames + allowedTypesList := cfg.Linters.Settings.Custom.Structfield.Settings.AllowedTagTypes + + allowedNames := make(map[string]bool) + for _, name := range allowedNamesList { + allowedNames[name] = true + } + + allowedTypes := make(map[string]bool) + for _, name := range allowedTypesList { + allowedTypes[name] = true + } + + return allowedNamesList, allowedTypesList, allowedNames, allowedTypes, nil +} + +func analyzeRepo(repoRoot string, patterns []string, includeTests bool, allowedNames, allowedTypes map[string]bool) (map[string]bool, map[string]bool, error) { + plugin, err := structfield.New(nil) + if err != nil { + return nil, nil, err + } + created, err := plugin.BuildAnalyzers() + if err != nil { + return nil, nil, err + } + if len(created) == 0 { + return nil, nil, errors.New("no analyzers returned by structfield") + } + analyzer := created[0] + + cfg := &packages.Config{ + Mode: packages.LoadAllSyntax, + Dir: repoRoot, + Tests: includeTests, + } + pkgs, err := packages.Load(cfg, patterns...) + if err != nil { + return nil, nil, err + } + if packages.PrintErrors(pkgs) > 0 { + return nil, nil, errors.New("package load errors") + } + + graph, err := checker.Analyze([]*analysis.Analyzer{analyzer}, pkgs, &checker.Options{Sequential: true}) + if err != nil { + return nil, nil, err + } + + usedNames := make(map[string]bool) + usedTypes := make(map[string]bool) + + for act := range graph.All() { + if !act.IsRoot || act.Analyzer != analyzer { + continue + } + for _, diag := range act.Diagnostics { + markUsedException(diag.Message, allowedNames, allowedTypes, usedNames, usedTypes) + } + } + + return usedNames, usedTypes, nil +} + +var ( + nameMismatchRE = regexp.MustCompile(`^change Go field name "([^"]+)" to ".*" for .* tag ".*" in struct "([^"]+)"$`) + typeChangeRE = regexp.MustCompile(`^change the "([^"]+)" field type to ".*" in the struct "([^"]+)"`) + fieldInStructRE = regexp.MustCompile(`^the "([^"]+)" field in struct "([^"]+)" .*`) +) + +func markUsedException(msg string, allowedNames, allowedTypes, usedNames, usedTypes map[string]bool) { + if match := nameMismatchRE.FindStringSubmatch(msg); match != nil { + key := match[2] + "." + match[1] + if allowedNames[key] { + usedNames[key] = true + } + return + } + + if match := typeChangeRE.FindStringSubmatch(msg); match != nil { + key := match[2] + "." + match[1] + if allowedTypes[key] { + usedTypes[key] = true + } + return + } + + if match := fieldInStructRE.FindStringSubmatch(msg); match != nil { + key := match[2] + "." + match[1] + if allowedTypes[key] { + usedTypes[key] = true + } + } +} + +func diffKeys(all, used map[string]bool) []string { + var obsolete []string + for key := range all { + if !used[key] { + obsolete = append(obsolete, key) + } + } + sort.Strings(obsolete) + return obsolete +} + +func findDuplicates(values []string) map[string]int { + counts := make(map[string]int) + duplicates := make(map[string]int) + for _, value := range values { + counts[value]++ + if counts[value] > 1 { + duplicates[value] = counts[value] + } + } + return duplicates +} + +func sortedKeys(values map[string]int) []string { + keys := make([]string, 0, len(values)) + for key := range values { + keys = append(keys, key) + } + sort.Strings(keys) + return keys +} + +func removeObsoleteExceptions(configPath string, obsoleteNames, obsoleteTypes []string) error { + data, err := os.ReadFile(configPath) + if err != nil { + return err + } + + fileInfo, statErr := os.Stat(configPath) + fileMode := os.FileMode(0o644) + if statErr == nil { + fileMode = fileInfo.Mode() + } + + hasTrailingNewline := strings.HasSuffix(string(data), "\n") + lines := strings.Split(string(data), "\n") + + obsoleteNamesSet := make(map[string]bool, len(obsoleteNames)) + for _, name := range obsoleteNames { + obsoleteNamesSet[name] = true + } + obsoleteTypesSet := make(map[string]bool, len(obsoleteTypes)) + for _, name := range obsoleteTypes { + obsoleteTypesSet[name] = true + } + seenNames := make(map[string]bool) + seenTypes := make(map[string]bool) + var items []*listItem + + updated := make([]string, 0, len(lines)) + section := "" + + for i := 0; i < len(lines); { + line := lines[i] + trimmed := strings.TrimSpace(line) + + if section == "" { + switch { + case strings.HasPrefix(trimmed, "allowed-tag-names:"): + section = "names" + items = items[:0] + updated = append(updated, line) + i++ + continue + case strings.HasPrefix(trimmed, "allowed-tag-types:"): + section = "types" + items = items[:0] + updated = append(updated, line) + i++ + continue + default: + updated = append(updated, line) + i++ + continue + } + } + + if strings.HasPrefix(trimmed, "- ") { + value := strings.TrimSpace(trimmed[2:]) + if hash := strings.Index(value, "#"); hash >= 0 { + value = strings.TrimSpace(value[:hash]) + } + if section == "names" { + if obsoleteNamesSet[value] || seenNames[value] { + i++ + continue + } + seenNames[value] = true + } + if section == "types" { + if obsoleteTypesSet[value] || seenTypes[value] { + i++ + continue + } + seenTypes[value] = true + } + items = append(items, &listItem{value: value, line: line}) + i++ + continue + } + + updated = appendSortedItems(updated, items) + section = "" + items = items[:0] + continue + } + + if section != "" { + updated = appendSortedItems(updated, items) + } + + content := strings.Join(updated, "\n") + if hasTrailingNewline && !strings.HasSuffix(content, "\n") { + content += "\n" + } + + return os.WriteFile(configPath, []byte(content), fileMode) +} + +type listItem struct { + value string + line string +} + +func appendSortedItems(lines []string, items []*listItem) []string { + sort.Slice(items, func(i, j int) bool { + return items[i].value < items[j].value + }) + for _, item := range items { + lines = append(lines, item.line) + } + return lines +} diff --git a/tools/structfield/go.mod b/tools/structfield/go.mod index 22571c72626..4a48aa02cf4 100644 --- a/tools/structfield/go.mod +++ b/tools/structfield/go.mod @@ -1,4 +1,4 @@ -module tools/structfield +module github.com/google/go-github/v82/tools/structfield go 1.24.0 diff --git a/tools/structfield/structfield.go b/tools/structfield/structfield.go index dd25e538877..cbecb51f786 100644 --- a/tools/structfield/structfield.go +++ b/tools/structfield/structfield.go @@ -9,7 +9,8 @@ // It honors idiomatic Go initialisms and handles the // special case of `Github` vs `GitHub` as agreed upon // by the original author of the repo. -// It also checks that fields with "omitempty" tags are reference types. +// It also checks that fields with "omitempty" tags are reference types +// for `json` struct tags and value types for `url` struct tags. package structfield import ( @@ -17,6 +18,7 @@ import ( "go/ast" "go/token" "go/types" + "log" "reflect" "regexp" "strings" @@ -83,7 +85,8 @@ func (f *StructFieldPlugin) BuildAnalyzers() ([]*analysis.Analyzer, error) { Name: "structfield", Doc: `Reports mismatches between Go field and JSON or URL tag names and types. Note that the JSON or URL tag name is the source-of-truth and the Go field name needs to match it. -If the tag contains "omitempty", then the Go field must be a reference type.`, +If the "json" tag contains "omitempty", then the Go field must be a reference type. +If the "url" tag contains "omitempty", then the Go field must be a value type (unless it is a timestamp).`, Run: func(pass *analysis.Pass) (any, error) { return run(pass, f.allowedTagNames, f.allowedTagTypes) }, @@ -150,22 +153,17 @@ func processTag(structName string, goField *ast.Ident, field *ast.Field, structT hasOmitZero := strings.Contains(tagName, ",omitzero") if hasOmitEmpty || hasOmitZero { - if tagType == "url" && hasOmitZero { - const msg = "the %q field in struct %q uses unsupported omitzero tag for URL tags" - pass.Reportf(field.Pos(), msg, goField.Name, structName) - } else { - checkGoFieldType(structName, goField.Name, field, field.Pos(), pass, allowedTagTypes, hasOmitEmpty, hasOmitZero) - } + checkGoFieldType(structName, goField.Name, tagType, field, field.Pos(), pass, allowedTagTypes, hasOmitEmpty, hasOmitZero) tagName = strings.ReplaceAll(tagName, ",omitzero", "") tagName = strings.ReplaceAll(tagName, ",omitempty", "") } if tagType == "url" { tagName = strings.ReplaceAll(tagName, ",comma", "") } - checkGoFieldName(structName, goField.Name, tagName, goField.Pos(), pass, allowedTagNames) + checkGoFieldName(structName, goField.Name, tagType, tagName, goField.Pos(), pass, allowedTagNames) } -func checkAndReportInvalidTypesForOmitzero(structName, goFieldName string, fieldType ast.Expr, tokenPos token.Pos, pass *analysis.Pass) bool { +func checkAndReportInvalidTypesForOmitzero(structName, tagType, goFieldName string, fieldType ast.Expr, tokenPos token.Pos, pass *analysis.Pass) bool { switch ft := fieldType.(type) { case *ast.StarExpr: // Check for *[]T where T is builtin - should be []T @@ -184,7 +182,7 @@ func checkAndReportInvalidTypesForOmitzero(structName, goFieldName string, field } return true } - // Check for *int - should not to be used with omitzero only with omitempty + // Check for *int and other pointers to builtin types if ident, ok := ft.X.(*ast.Ident); ok { if isBuiltinType(ident.Name) { const msg = `the %q field in struct %q uses "omitzero" with a primitive type; remove "omitzero" and use only "omitempty" for pointer primitive types"` @@ -202,6 +200,11 @@ func checkAndReportInvalidTypesForOmitzero(structName, goFieldName string, field case *ast.MapType: return true case *ast.ArrayType: + if tagType == "url" { + const msg = "the %q field in struct %q uses unsupported omitzero tag for URL tags" + pass.Reportf(tokenPos, msg, goFieldName, structName) + return true + } checkStructArrayType(structName, goFieldName, ft, tokenPos, pass) return true case *ast.Ident: @@ -213,17 +216,26 @@ func checkAndReportInvalidTypesForOmitzero(structName, goFieldName string, field pass.Reportf(tokenPos, msg, goFieldName, "*"+ft.Name, structName) return true case *types.Basic: + if tagType == "url" { + const msg = "the %q field in struct %q uses unsupported omitzero tag for URL tags" + pass.Reportf(tokenPos, msg, goFieldName, structName) + return true + } // For Builtin - should not to be used with omitzero const msg = `the %q field in struct %q uses "omitzero" with a primitive type; remove "omitzero", as it is only allowed with structs, maps, and slices` pass.Reportf(tokenPos, msg, goFieldName, structName) return true } } + case *ast.SelectorExpr: + return true + default: + log.Fatalf("unhandled type: %T", ft) } return false } -func checkGoFieldName(structName, goFieldName, tagName string, tokenPos token.Pos, pass *analysis.Pass, allowedNames map[string]bool) { +func checkGoFieldName(structName, goFieldName, tagType, tagName string, tokenPos token.Pos, pass *analysis.Pass, allowedNames map[string]bool) { fullName := structName + "." + goFieldName if allowedNames[fullName] { return @@ -231,33 +243,32 @@ func checkGoFieldName(structName, goFieldName, tagName string, tokenPos token.Po want, alternate := tagNameToPascal(tagName) if goFieldName != want && goFieldName != alternate { - const msg = "change Go field name %q to %q for tag %q in struct %q" - pass.Reportf(tokenPos, msg, goFieldName, want, tagName, structName) + const msg = "change Go field name %q to %q for %v tag %q in struct %q" + pass.Reportf(tokenPos, msg, goFieldName, want, tagType, tagName, structName) } } -func checkGoFieldType(structName, goFieldName string, field *ast.Field, tokenPos token.Pos, pass *analysis.Pass, allowedTypes map[string]bool, omitempty, omitzero bool) { +func checkGoFieldType(structName, goFieldName, tagType string, field *ast.Field, tokenPos token.Pos, pass *analysis.Pass, allowedTypes map[string]bool, omitempty, omitzero bool) { if allowedTypes[structName+"."+goFieldName] { return } switch { case omitzero: - skipOmitzero := checkAndReportInvalidTypesForOmitzero(structName, goFieldName, field.Type, tokenPos, pass) + skipOmitzero := checkAndReportInvalidTypesForOmitzero(structName, tagType, goFieldName, field.Type, tokenPos, pass) if !skipOmitzero { const msg = `the %q field in struct %q uses "omitzero"; remove "omitzero", as it is only allowed with structs, maps, and slices` pass.Reportf(tokenPos, msg, goFieldName, structName) } case omitempty: - skipOmitempty := checkAndReportInvalidTypes(structName, goFieldName, field.Type, tokenPos, pass) - if !skipOmitempty { - const msg = `change the %q field type to %q in the struct %q because its tag uses "omitempty"` - pass.Reportf(tokenPos, msg, goFieldName, "*"+exprToString(field.Type), structName) + if newFieldType, ok := checkAndReportInvalidTypes(structName, tagType, goFieldName, field.Type, tokenPos, pass); !ok { + const msg = `change the %q field type to %q in the struct %q because its %v tag uses "omitempty"` + pass.Reportf(tokenPos, msg, goFieldName, newFieldType, structName, tagType) } } } -func checkAndReportInvalidTypes(structName, goFieldName string, fieldType ast.Expr, tokenPos token.Pos, pass *analysis.Pass) bool { +func checkAndReportInvalidTypes(structName, tagType, goFieldName string, fieldType ast.Expr, tokenPos token.Pos, pass *analysis.Pass) (newFieldType string, ok bool) { switch ft := fieldType.(type) { case *ast.StarExpr: // Check for *[]T where T is builtin - should be []T @@ -280,24 +291,41 @@ func checkAndReportInvalidTypes(structName, goFieldName string, fieldType ast.Ex const msg = "change the %q field type to %q in the struct %q" pass.Reportf(tokenPos, msg, goFieldName, exprToString(ft.X), structName) } - return true + if ident, ok := ft.X.(*ast.Ident); ok && tagType == "url" { + switch ident.Name { + // Remove the pointer for primitives in url tags + case "string", "int", "int64", "float64", "bool": + return ident.Name, false + } + } + return "", true case *ast.MapType: - return true + return "", true case *ast.ArrayType: checkStructArrayType(structName, goFieldName, ft, tokenPos, pass) - return true + return "", true case *ast.SelectorExpr: // Check for json.RawMessage if ident, ok := ft.X.(*ast.Ident); ok && ident.Name == "json" && ft.Sel.Name == "RawMessage" { - return true + return "", true } case *ast.Ident: // Check for `any` type if ft.Name == "any" { - return true + return "", true } + if tagType == "url" { + switch ft.Name { + case "string", "int", "int64", "float64", "bool": + return "", true + } + } + default: + log.Fatalf("unhandled type: %T", ft) } - return false + + newFieldType = "*" + exprToString(fieldType) + return newFieldType, false } func checkStructArrayType(structName, goFieldName string, arrType *ast.ArrayType, tokenPos token.Pos, pass *analysis.Pass) { diff --git a/tools/structfield/testdata/src/has-warnings/main.go b/tools/structfield/testdata/src/has-warnings/main.go index 4d0576e1294..06eca6a3f13 100644 --- a/tools/structfield/testdata/src/has-warnings/main.go +++ b/tools/structfield/testdata/src/has-warnings/main.go @@ -6,15 +6,15 @@ package main type JSONFieldName struct { - GitHubThing string `json:"github_thing"` // want `change Go field name "GitHubThing" to "GithubThing" for tag "github_thing" in struct "JSONFieldName"` - Id *string `json:"id,omitempty"` // want `change Go field name "Id" to "ID" for tag "id" in struct "JSONFieldName"` - strings *string `json:"strings,omitempty"` // want `change Go field name "strings" to "Strings" for tag "strings" in struct "JSONFieldName"` - camelcaseexample *int `json:"camelCaseExample,omitempty"` // want `change Go field name "camelcaseexample" to "CamelCaseExample" for tag "camelCaseExample" in struct "JSONFieldName"` - DollarRef string `json:"$ref"` // want `change Go field name "DollarRef" to "Ref" for tag "\$ref" in struct "JSONFieldName"` + GitHubThing string `json:"github_thing"` // want `change Go field name "GitHubThing" to "GithubThing" for json tag "github_thing" in struct "JSONFieldName"` + Id *string `json:"id,omitempty"` // want `change Go field name "Id" to "ID" for json tag "id" in struct "JSONFieldName"` + strings *string `json:"strings,omitempty"` // want `change Go field name "strings" to "Strings" for json tag "strings" in struct "JSONFieldName"` + camelcaseexample *int `json:"camelCaseExample,omitempty"` // want `change Go field name "camelcaseexample" to "CamelCaseExample" for json tag "camelCaseExample" in struct "JSONFieldName"` + DollarRef string `json:"$ref"` // want `change Go field name "DollarRef" to "Ref" for json tag "\$ref" in struct "JSONFieldName"` } type JSONFieldType struct { - String string `json:"string,omitempty"` // want `change the "String" field type to "\*string" in the struct "JSONFieldType" because its tag uses "omitempty"` + String string `json:"string,omitempty"` // want `change the "String" field type to "\*string" in the struct "JSONFieldType" because its json tag uses "omitempty"` SliceOfStringPointers []*string `json:"slice_of_string_pointers,omitempty"` // want `change the "SliceOfStringPointers" field type to "\[\]string" in the struct "JSONFieldType"` PointerToSliceOfStrings *[]string `json:"pointer_to_slice_of_strings,omitempty"` // want `change the "PointerToSliceOfStrings" field type to "\[\]string" in the struct "JSONFieldType"` SliceOfStructs []Struct `json:"slice_of_structs,omitempty"` // want `change the "SliceOfStructs" field type to "\[\]\*Struct" in the struct "JSONFieldType"` @@ -44,14 +44,14 @@ type JSONFieldType struct { type Struct struct{} type URLFieldName struct { - GitHubThing string `url:"github_thing"` // want `change Go field name "GitHubThing" to "GithubThing" for tag "github_thing" in struct "URLFieldName"` + GitHubThing string `url:"github_thing"` // want `change Go field name "GitHubThing" to "GithubThing" for url tag "github_thing" in struct "URLFieldName"` } type URLFieldType struct { - Page string `url:"page,omitempty"` // want `change the "Page" field type to "\*string" in the struct "URLFieldType" because its tag uses "omitempty"` - PerPage int `url:"per_page,omitempty"` // want `change the "PerPage" field type to "\*int" in the struct "URLFieldType" because its tag uses "omitempty"` - Participating bool `url:"participating,omitempty"` // want `change the "Participating" field type to "\*bool" in the struct "URLFieldType" because its tag uses "omitempty"` + Page *string `url:"page,omitempty"` // want `change the "Page" field type to "string" in the struct "URLFieldType" because its url tag uses "omitempty"` + PerPage *int `url:"per_page,omitempty"` // want `change the "PerPage" field type to "int" in the struct "URLFieldType" because its url tag uses "omitempty"` + Participating *bool `url:"participating,omitempty"` // want `change the "Participating" field type to "bool" in the struct "URLFieldType" because its url tag uses "omitempty"` PerPageZeros []int `url:"per_page_zeros,omitzero"` // want `the "PerPageZeros" field in struct "URLFieldType" uses unsupported omitzero tag for URL tags` - PerPageBoth *int `url:"per_page_both,omitempty,omitzero"` // want `the "PerPageBoth" field in struct "URLFieldType" uses unsupported omitzero tag for URL tags` + PerPageBoth int `url:"per_page_both,omitempty,omitzero"` // want `the "PerPageBoth" field in struct "URLFieldType" uses unsupported omitzero tag for URL tags` } diff --git a/tools/structfield/testdata/src/no-warnings/main.go b/tools/structfield/testdata/src/no-warnings/main.go index 7c43789c659..3b2a61a0389 100644 --- a/tools/structfield/testdata/src/no-warnings/main.go +++ b/tools/structfield/testdata/src/no-warnings/main.go @@ -40,15 +40,16 @@ type JSONFieldType struct { } type URLFieldName struct { - ID *string `url:"id,omitempty"` - Query string `url:"q"` + ID string `url:"id,omitempty"` + Query string `url:"q"` } type URLFieldType struct { - Page *string `url:"page,omitempty"` - PerPage *int `url:"per_page,omitempty"` + Page string `url:"page,omitempty"` + PerPage int `url:"per_page,omitempty"` Labels []string `url:"labels,omitempty,comma"` Since *time.Time `url:"since,omitempty"` + Since2 time.Time `url:"since2,omitzero"` Fields []int64 `url:"fields,omitempty,comma"` Exception string `url:"exception,omitempty"` }