github.com/cli/cli@v1.14.1-0.20210902173923-1af6a669e342/pkg/cmd/release/list/list.go (about)

     1  package list
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"time"
     7  
     8  	"github.com/cli/cli/internal/ghrepo"
     9  	"github.com/cli/cli/pkg/cmdutil"
    10  	"github.com/cli/cli/pkg/iostreams"
    11  	"github.com/cli/cli/pkg/text"
    12  	"github.com/cli/cli/utils"
    13  	"github.com/spf13/cobra"
    14  )
    15  
    16  type ListOptions struct {
    17  	HttpClient func() (*http.Client, error)
    18  	IO         *iostreams.IOStreams
    19  	BaseRepo   func() (ghrepo.Interface, error)
    20  
    21  	LimitResults int
    22  }
    23  
    24  func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Command {
    25  	opts := &ListOptions{
    26  		IO:         f.IOStreams,
    27  		HttpClient: f.HttpClient,
    28  	}
    29  
    30  	cmd := &cobra.Command{
    31  		Use:   "list",
    32  		Short: "List releases in a repository",
    33  		Args:  cobra.NoArgs,
    34  		RunE: func(cmd *cobra.Command, args []string) error {
    35  			// support `-R, --repo` override
    36  			opts.BaseRepo = f.BaseRepo
    37  
    38  			if runF != nil {
    39  				return runF(opts)
    40  			}
    41  			return listRun(opts)
    42  		},
    43  	}
    44  
    45  	cmd.Flags().IntVarP(&opts.LimitResults, "limit", "L", 30, "Maximum number of items to fetch")
    46  
    47  	return cmd
    48  }
    49  
    50  func listRun(opts *ListOptions) error {
    51  	httpClient, err := opts.HttpClient()
    52  	if err != nil {
    53  		return err
    54  	}
    55  
    56  	baseRepo, err := opts.BaseRepo()
    57  	if err != nil {
    58  		return err
    59  	}
    60  
    61  	releases, err := fetchReleases(httpClient, baseRepo, opts.LimitResults)
    62  	if err != nil {
    63  		return err
    64  	}
    65  
    66  	now := time.Now()
    67  	table := utils.NewTablePrinter(opts.IO)
    68  	iofmt := opts.IO.ColorScheme()
    69  	seenLatest := false
    70  	for _, rel := range releases {
    71  		title := text.ReplaceExcessiveWhitespace(rel.Name)
    72  		if title == "" {
    73  			title = rel.TagName
    74  		}
    75  		table.AddField(title, nil, nil)
    76  
    77  		badge := ""
    78  		var badgeColor func(string) string
    79  		if !rel.IsDraft && !rel.IsPrerelease && !seenLatest {
    80  			badge = "Latest"
    81  			badgeColor = iofmt.Green
    82  			seenLatest = true
    83  		} else if rel.IsDraft {
    84  			badge = "Draft"
    85  			badgeColor = iofmt.Red
    86  		} else if rel.IsPrerelease {
    87  			badge = "Pre-release"
    88  			badgeColor = iofmt.Yellow
    89  		}
    90  		table.AddField(badge, nil, badgeColor)
    91  
    92  		tagName := rel.TagName
    93  		if table.IsTTY() {
    94  			tagName = fmt.Sprintf("(%s)", tagName)
    95  		}
    96  		table.AddField(tagName, nil, nil)
    97  
    98  		pubDate := rel.PublishedAt
    99  		if rel.PublishedAt.IsZero() {
   100  			pubDate = rel.CreatedAt
   101  		}
   102  		publishedAt := pubDate.Format(time.RFC3339)
   103  		if table.IsTTY() {
   104  			publishedAt = utils.FuzzyAgo(now.Sub(pubDate))
   105  		}
   106  		table.AddField(publishedAt, nil, iofmt.Gray)
   107  		table.EndRow()
   108  	}
   109  	err = table.Render()
   110  	if err != nil {
   111  		return err
   112  	}
   113  
   114  	return nil
   115  }