You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: repo_clone.go
    path of file: ./repos/glab/commands/project/clone
    
    the code of the file until where you have to start completion: package clone

import (
	"errors"
	"fmt"
	"strconv"
	"strings"

	"github.com/profclems/glab/pkg/iostreams"

	"github.com/MakeNowJust/heredoc"
	"github.com/profclems/glab/api"
	"github.com/profclems/glab/commands/cmdutils"
	"github.com/profclems/glab/internal/config"
	"github.com/profclems/glab/internal/glrepo"
	"github.com/profclems/glab/pkg/git"
	"github.com/profclems/glab/pkg/glinstance"
	"github.com/spf13/cobra"
	"github.com/spf13/pflag"
	"github.com/xanzy/go-gitlab"
)

type CloneOptions struct {
	GroupName         string
	IncludeSubgroups  bool
	PreserveNamespace bool
	WithMREnabled     bool
	WithIssuesEnabled bool
	WithShared        bool
	Archived          bool
	ArchivedSet       bool
	Visibility        string
	Owned             bool
	GitFlags          []string
	Dir               string
	Host              string
	Protocol          string

	Page    int
	PerPage int

	IO        *iostreams.IOStreams
	API
    
func groupClone(opts *CloneOptions, ctxOpts *ContextOpts) error {
	c := opts.IO.Color()
	ListGroupProjectOpts := &gitlab.ListGroupProjectsOptions{}
	if opts.WithShared {
		ListGroupProjectOpts.WithShared = gitlab.Bool(true)
	}
	if opts.WithMREnabled {
		ListGroupProjectOpts.WithMergeRequestsEnabled = gitlab.Bool(true)
	}
	if opts.WithIssuesEnabled {
		ListGroupProjectOpts.WithIssuesEnabled = gitlab.Bool(true)
	}
	if opts.Owned {
		ListGroupProjectOpts.Owned = gitlab.Bool(true)
	}
	if opts.ArchivedSet {
		ListGroupProjectOpts.Archived = gitlab.Bool(opts.Archived)
	}
	if opts.IncludeSubgroups {
		ListGroupProjectOpts.IncludeSubgroups = gitlab.Bool(true)
	}
	if opts.Visibility != "" {
		ListGroupProjectOpts.Visibility = gitlab.Visibility(gitlab.VisibilityValue(opts.Visibility))
	}
	ListGroupProjectOpts.PerPage = 100
	if opts.PerPage != 0 {
		ListGroupProjectOpts.PerPage = opts.PerPage
	}
	if opts.Page != 0 {
		ListGroupProjectOpts.Page = opts.Page
	}
	projects, err := api.ListGroupProjects(opts.APIClient.Lab(), opts.GroupName, ListGroupProjectOpts)
	if err != nil {
		return err
	}
	if len(projects) == 0 {
		fmt.Fprintf(opts.IO.StdErr, "Group %q does not have any projects\n", opts.GroupName)
		return cmdutils.SilentError
	}
	var finalOutput []string
	for _, project := range projects {
		ctxOpt := *ctxOpts
		ctxOpt.Project = project
		ctxOpt.Repo = project.PathWithNamespace
		err = cloneRun(opts, &ctxOpt)
		if err != nil {
			finalOutput = append(finalOutput, fmt.Sprintf("%s %s - Error: %q", c.RedCheck(), project.PathWithNamespace, err.Error()))
		} else {
			finalOutput = append(finalOutput, fmt.Sprintf("%s %s", c.GreenCheck(), project.PathWithNamespace))
		}
	}

	// Print error/success msgs in human-readable formats
	for _, out := range finalOutput {
		fmt.Fprintln(opts.IO.StdOut, out)
	}
	if err != nil { // if any error came up
		return cmdutils.SilentError
	}
	return nil
}