github.com/gfleury/gobbs@v0.0.0-20200831213239-44ca2b94c1a1/repos/list.go (about)

     1  package repos
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"net"
     8  	"net/http"
     9  	"sort"
    10  
    11  	"github.com/gfleury/gobbs/common"
    12  	"github.com/gfleury/gobbs/common/log"
    13  
    14  	bitbucketv1 "github.com/gfleury/go-bitbucket-v1"
    15  	"github.com/spf13/cobra"
    16  )
    17  
    18  var (
    19  	all *bool
    20  )
    21  
    22  func init() {
    23  	all = List.Flags().BoolP("all", "A", false, "List repositories from ALL Projects.")
    24  }
    25  
    26  // List is the cmd implementation for Listing Repositories
    27  var List = &cobra.Command{
    28  	Use:     "list",
    29  	Aliases: []string{"ls"},
    30  	Short:   "List repositories",
    31  	Args:    cobra.MinimumNArgs(0),
    32  	RunE: func(cmd *cobra.Command, args []string) error {
    33  		var repos []bitbucketv1.Repository
    34  
    35  		opts := map[string]interface{}{
    36  			// "state": *listState,
    37  			"limit": 1000,
    38  		}
    39  
    40  		for {
    41  			var hasNext bool
    42  			apiClient, cancel, err := common.APIClient(cmd)
    43  			defer cancel()
    44  
    45  			if err != nil {
    46  				cmd.SilenceUsage = true
    47  				return err
    48  			}
    49  
    50  			stashInfo := cmd.Context().Value(common.StashInfoKey).(*common.StashInfo)
    51  
    52  			var response *bitbucketv1.APIResponse
    53  			if !*all {
    54  				err = mustHaveProject(stashInfo)
    55  				if err != nil {
    56  					return err
    57  				}
    58  				response, err = apiClient.DefaultApi.GetRepositoriesWithOptions(*stashInfo.Project(), opts)
    59  			} else {
    60  				response, err = apiClient.DefaultApi.GetRepositories_19(opts)
    61  			}
    62  
    63  			if netError, ok := err.(net.Error); (!ok || (ok && !netError.Timeout())) &&
    64  				!errors.Is(err, context.Canceled) &&
    65  				!errors.Is(err, context.DeadlineExceeded) &&
    66  				response != nil && response.Response != nil &&
    67  				response.Response.StatusCode >= http.StatusMultipleChoices {
    68  				common.PrintApiError(response.Values)
    69  				cmd.SilenceUsage = true
    70  				log.Debugf(err.Error())
    71  				return fmt.Errorf("Unable to process request, API Error")
    72  			} else if err != nil {
    73  				cmd.SilenceUsage = true
    74  				return err
    75  			}
    76  
    77  			pagedRepos, err := bitbucketv1.GetRepositoriesResponse(response)
    78  			if err != nil {
    79  				cmd.SilenceUsage = true
    80  				return err
    81  			}
    82  			repos = append(repos, pagedRepos...)
    83  
    84  			hasNext, opts["start"] = bitbucketv1.HasNextPage(response)
    85  			if !hasNext {
    86  				break
    87  			}
    88  		}
    89  
    90  		sort.Slice(repos, func(i, j int) bool {
    91  			return repos[i].Slug > repos[j].Slug
    92  		})
    93  
    94  		header := []string{"ID", "Project", "Slug", "Links", "Status"}
    95  		table := common.Table(header)
    96  
    97  		for _, repo := range repos {
    98  			table.Append([]string{
    99  				fmt.Sprintf("%d", repo.ID),
   100  				repo.Project.Key,
   101  				repo.Slug,
   102  				func() (r string) {
   103  					for _, link := range repo.Links.Clone {
   104  						r = fmt.Sprintf("%s%s: %s\n", r, link.Name, link.Href)
   105  					}
   106  					return
   107  				}(),
   108  				repo.StatusMessage,
   109  			})
   110  		}
   111  		table.Render()
   112  
   113  		return nil
   114  	},
   115  }