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 }