func dataSourceGitlabProjectsRead()

in internal/provider/sdk/data_source_gitlab_projects.go [1085:1315]


func dataSourceGitlabProjectsRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
	client := meta.(*gitlab.Client)
	var projectList []*gitlab.Project

	// Permanent parameters

	page := d.Get("page").(int)
	perPage := d.Get("per_page").(int)
	maxQueryablePages := d.Get("max_queryable_pages").(int)

	// Conditional parameters
	// Only way I found to conditionally pass a search parameter to the List(Group/Project)Options
	// Json marshalling a complete List(Group/Project)Options JSON object had conversion issues with booleans
	var archivedPtr *bool
	var includeSubGroupsPtr *bool
	var membershipPtr *bool
	var minAccessLevelPtr *gitlab.AccessLevelValue
	var orderByPtr *string
	var ownedPtr *bool
	var searchPtr *string
	var simplePtr *bool
	var sortPtr *string
	var starredPtr *bool
	var topicPtr *string
	var statisticsPtr *bool
	var visibilityPtr *gitlab.VisibilityValue
	var withCustomAttributesPtr *bool
	var withIssuesEnabledPtr *bool
	var withMergeRequestsEnabledPtr *bool
	var withProgrammingLanguagePtr *string
	var withSharedPtr *bool

	// NOTE: `GetOkExists()` is deprecated, but until there is a replacement we need to use it.
	//       see https://github.com/hashicorp/terraform-plugin-sdk/pull/350#issuecomment-597888969

	// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
	// lintignore: XR001 // TODO: replace with alternative for GetOkExists
	if data, ok := d.GetOkExists("archived"); ok {
		d := data.(bool)
		archivedPtr = &d
	}
	// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
	// lintignore: XR001 // TODO: replace with alternative for GetOkExists
	if data, ok := d.GetOkExists("include_subgroups"); ok {
		d := data.(bool)
		includeSubGroupsPtr = &d
	}
	// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
	// lintignore: XR001 // TODO: replace with alternative for GetOkExists
	if data, ok := d.GetOkExists("membership"); ok {
		d := data.(bool)
		membershipPtr = &d
	}
	if data, ok := d.GetOk("min_access_level"); ok {
		minAccessLevelPtr = gitlab.Ptr(gitlab.AccessLevelValue(data.(int)))
	}
	if data, ok := d.GetOk("order_by"); ok {
		d := data.(string)
		orderByPtr = &d
	}
	// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
	// lintignore: XR001 // TODO: replace with alternative for GetOkExists
	if data, ok := d.GetOkExists("owned"); ok {
		d := data.(bool)
		ownedPtr = &d
	}
	if data, ok := d.GetOk("search"); ok {
		d := data.(string)
		searchPtr = &d
	}
	// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
	// lintignore: XR001 // TODO: replace with alternative for GetOkExists
	if data, ok := d.GetOkExists("simple"); ok {
		d := data.(bool)
		simplePtr = &d
	}
	if data, ok := d.GetOk("sort"); ok {
		d := data.(string)
		sortPtr = &d
	}
	// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
	// lintignore: XR001 // TODO: replace with alternative for GetOkExists
	if data, ok := d.GetOkExists("starred"); ok {
		d := data.(bool)
		starredPtr = &d
	}
	if data, ok := d.GetOk("topic"); ok {
		d := data.(*schema.Set)
		topics := make([]string, d.Len())
		for i, t := range d.List() {
			topics[i] = t.(string)
		}
		s := strings.Join(topics, ",")
		topicPtr = &s
	}
	// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
	// lintignore: XR001 // TODO: replace with alternative for GetOkExists
	if data, ok := d.GetOkExists("statistics"); ok {
		d := data.(bool)
		statisticsPtr = &d
	}
	if data, ok := d.GetOk("visibility"); ok {
		visibilityPtr = gitlab.Ptr(gitlab.VisibilityValue(data.(string)))
	}
	// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
	// lintignore: XR001 // TODO: replace with alternative for GetOkExists
	if data, ok := d.GetOkExists("with_custom_attributes"); ok {
		d := data.(bool)
		withCustomAttributesPtr = &d
	}
	// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
	// lintignore: XR001 // TODO: replace with alternative for GetOkExists
	if data, ok := d.GetOkExists("with_issues_enabled"); ok {
		d := data.(bool)
		withIssuesEnabledPtr = &d
	}
	// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
	// lintignore: XR001 // TODO: replace with alternative for GetOkExists
	if data, ok := d.GetOkExists("with_merge_requests_enabled"); ok {
		d := data.(bool)
		withMergeRequestsEnabledPtr = &d
	}
	if data, ok := d.GetOk("with_programming_language"); ok {
		d := data.(string)
		withProgrammingLanguagePtr = &d
	}
	// nolint:staticcheck // SA1019 ignore deprecated GetOkExists
	// lintignore: XR001 // TODO: replace with alternative for GetOkExists
	if data, ok := d.GetOkExists("with_shared"); ok {
		d := data.(bool)
		withSharedPtr = &d
	}

	tflog.Debug(ctx, "[DEBUG] Reading Gitlab projects")

	switch groupId, ok := d.GetOk("group_id"); ok {
	// GroupProject case
	case true:
		opts := &gitlab.ListGroupProjectsOptions{
			ListOptions: gitlab.ListOptions{
				Page:    page,
				PerPage: perPage,
			},
			Archived:                 archivedPtr,
			Visibility:               visibilityPtr,
			OrderBy:                  orderByPtr,
			Sort:                     sortPtr,
			Search:                   searchPtr,
			Simple:                   simplePtr,
			Owned:                    ownedPtr,
			Starred:                  starredPtr,
			Topic:                    topicPtr,
			WithIssuesEnabled:        withIssuesEnabledPtr,
			WithMergeRequestsEnabled: withMergeRequestsEnabledPtr,
			WithShared:               withSharedPtr,
			IncludeSubGroups:         includeSubGroupsPtr,
			WithCustomAttributes:     withCustomAttributesPtr,
		}

		for {
			projects, response, err := client.Groups.ListGroupProjects(groupId.(int), opts, gitlab.WithContext(ctx))
			if err != nil {
				return diag.FromErr(err)
			}
			projectList = append(projectList, projects...)
			opts.ListOptions.Page++

			tflog.Debug(ctx, fmt.Sprintf("[INFO] Currentpage: %d, Total: %d", response.CurrentPage, response.TotalPages))
			if response.CurrentPage == response.TotalPages || response.CurrentPage > maxQueryablePages {
				break
			}
		}
		h, err := hashstructure.Hash(*opts, hashstructure.FormatV1, nil)
		if err != nil {
			return diag.FromErr(err)
		}
		d.SetId(fmt.Sprintf("%d-%d", groupId.(int), h))
		if err := d.Set("projects", flattenProjects(projectList)); err != nil {
			return diag.FromErr(err)
		}

	// Project case
	default:
		opts := &gitlab.ListProjectsOptions{
			ListOptions: gitlab.ListOptions{
				Page:    page,
				PerPage: perPage,
			},
			Archived:                 archivedPtr,
			OrderBy:                  orderByPtr,
			Sort:                     sortPtr,
			Search:                   searchPtr,
			Simple:                   simplePtr,
			Owned:                    ownedPtr,
			Membership:               membershipPtr,
			Starred:                  starredPtr,
			Topic:                    topicPtr,
			Statistics:               statisticsPtr,
			Visibility:               visibilityPtr,
			WithIssuesEnabled:        withIssuesEnabledPtr,
			WithMergeRequestsEnabled: withMergeRequestsEnabledPtr,
			MinAccessLevel:           minAccessLevelPtr,
			WithCustomAttributes:     withCustomAttributesPtr,
			WithProgrammingLanguage:  withProgrammingLanguagePtr,
		}

		for {
			projects, response, err := client.Projects.ListProjects(opts, nil, gitlab.WithContext(ctx))
			if err != nil {
				return diag.FromErr(err)
			}
			projectList = append(projectList, projects...)
			opts.ListOptions.Page++

			tflog.Debug(ctx, fmt.Sprintf("[INFO] Currentpage: %d, Total: %d", response.CurrentPage, response.TotalPages))
			if response.CurrentPage == response.TotalPages || response.CurrentPage > maxQueryablePages {
				break
			}
		}
		h, err := hashstructure.Hash(*opts, hashstructure.FormatV1, nil)
		if err != nil {
			return diag.FromErr(err)
		}
		d.SetId(fmt.Sprintf("%d", h))
		if err := d.Set("projects", flattenProjects(projectList)); err != nil {
			return diag.FromErr(err)
		}
	}

	return nil
}