github.com/grantbow/fit@v0.7.1-0.20220916164603-1f7c88ac81e6/fitapp/Roadmap.go (about)

     1  package fitapp
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/blang/semver"
     6  	bugs "github.com/grantbow/fit/issues"
     7  	"sort"
     8  	"strconv"
     9  	"strings"
    10  )
    11  
    12  // IssueListByMilestone is a pkg global to hold a list of issues.
    13  type IssueListByMilestone [](bugs.Issue)
    14  
    15  // Len, Swap and Less sort issues.
    16  func (a IssueListByMilestone) Len() int      { return len(a) }
    17  func (a IssueListByMilestone) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
    18  func (a IssueListByMilestone) Less(i, j int) bool {
    19  	iMS := a[i].Milestone()
    20  	jMS := a[j].Milestone()
    21  	// If there's a "v" at the start, strip it out
    22  	// before doing any comparisons of semantic
    23  	// versions
    24  	if len(iMS) > 1 && iMS[0] == "v"[0] {
    25  		iMS = iMS[1:]
    26  	}
    27  	if len(jMS) > 1 && jMS[0] == "v"[0] {
    28  		jMS = jMS[1:]
    29  	}
    30  	// First try semantic versioning comparison
    31  	iVer, iVerErr := semver.Make(iMS)
    32  	jVer, jVerErr := semver.Make(jMS)
    33  	if iVerErr == nil && jVerErr == nil {
    34  		return iVer.LT(jVer)
    35  	}
    36  
    37  	// Next try floating point comparison as an
    38  	// approximation of real number comparison..
    39  	iFloat, iVerErr := strconv.ParseFloat(iMS, 32)
    40  	jFloat, jVerErr := strconv.ParseFloat(jMS, 32)
    41  	if iVerErr == nil && jVerErr == nil {
    42  		return iFloat < jFloat
    43  	}
    44  
    45  	// Finally, just use a normal string collation
    46  	return iMS < jMS
    47  }
    48  
    49  // Roadmap is a subcommand to output issues by milestone.
    50  func Roadmap(args argumentList, config bugs.Config) {
    51  	var bgs []bugs.Issue
    52  
    53  	if args.HasArgument("--filter") {
    54  		tags := strings.Split(args.GetArgument("--filter", ""), ",")
    55  		fmt.Printf("%s", tags)
    56  		bgs = bugs.FindIssuesByTag(tags, config)
    57  	} else {
    58  		bgs = bugs.GetAllIssues(config)
    59  	}
    60  	sort.Sort(IssueListByMilestone(bgs))
    61  
    62  	fmt.Printf("# Roadmap for %s\n", bugs.RootDirer(&config).ShortNamer().ToTitle())
    63  	milestone := ""
    64  	for i := len(bgs) - 1; i >= 0; i -= 1 {
    65  		b := bgs[i]
    66  		newMilestone := b.Milestone()
    67  		if milestone != newMilestone {
    68  			if newMilestone == "" {
    69  				fmt.Printf("\n## No milestone set:\n")
    70  			} else {
    71  				fmt.Printf("\n## %s:\n", newMilestone)
    72  			}
    73  		}
    74  		if args.HasArgument("--simple") {
    75  			fmt.Printf("- %s\n", b.Title(""))
    76  		} else {
    77  			options := ""
    78  			if !args.HasArgument("--no-status") {
    79  				options += "status"
    80  			}
    81  			if !args.HasArgument("--no-priority") {
    82  				options += " priority"
    83  			}
    84  			if !args.HasArgument("--no-identifier") {
    85  				options += " identifier"
    86  			}
    87  
    88  			if args.HasArgument("--tags") {
    89  				options += "tags"
    90  			}
    91  			fmt.Printf("- %s\n", b.Title(options))
    92  		}
    93  		milestone = newMilestone
    94  
    95  	}
    96  }