Skip to content

Commit

Permalink
Merge pull request #52 from moul/dev/moul/focus-mode
Browse files Browse the repository at this point in the history
feat: add focus mode
  • Loading branch information
moul authored Sep 19, 2018
2 parents b36a289 + f249a6b commit 4097ce4
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 14 deletions.
26 changes: 14 additions & 12 deletions cmd_run.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,20 @@ import (

type runOptions struct {
// pull
PullOpts pullOptions
NoPull bool
PullOpts pullOptions
NoPull bool
ReposToFetch []string

// db
DBOpts dbOptions

// run
ShowClosed bool `mapstructure:"show-closed"`
ShowOrphans bool
EpicLabel string
Destination string
DebugGraph bool
ShowClosed bool `mapstructure:"show-closed"`
ShowOrphans bool
AdditionalPulls []string
EpicLabel string
Destination string
DebugGraph bool

Targets []string
//Preview bool
Expand All @@ -44,6 +46,7 @@ func runSetupFlags(flags *pflag.FlagSet, opts *runOptions) {
flags.BoolVarP(&opts.ShowOrphans, "show-orphans", "", false, "show issues not linked to an epic")
flags.StringVarP(&opts.EpicLabel, "epic-label", "", "epic", "label used for epics (empty means issues with dependencies but without dependants)")
flags.StringVarP(&opts.Destination, "destination", "", "-", "destination ('-' for stdout)")
flags.StringSliceVarP(&opts.AdditionalPulls, "additional-pull", "", []string{}, "additional pull that won't necessarily be displayed on the graph")
//flags.BoolVarP(&opts.Preview, "preview", "p", false, "preview result")
viper.BindPFlags(flags)
}
Expand All @@ -63,7 +66,7 @@ func newRunCommand() *cobra.Command {
return err
}
opts.PullOpts.DBOpts = opts.DBOpts
opts.PullOpts.Targets = args
opts.PullOpts.Targets = append(args, opts.AdditionalPulls...)
opts.Targets = args
return run(opts)
},
Expand Down Expand Up @@ -91,14 +94,13 @@ func run(opts *runOptions) error {
return errors.Wrap(err, "failed to prepare issues")
}

issues.processEpicLinks()
if !opts.ShowClosed {
issues.HideClosed()
}
if !opts.ShowOrphans && issues.HasNonOrphans() {
issues.HideOrphans()
issues.filterByTargets(opts.Targets)
if opts.ShowOrphans {
logger().Warn("--show-orphans is deprecated and will be removed")
}
issues.processEpicLinks()

out, err := graphviz(issues, opts)

Expand Down
26 changes: 26 additions & 0 deletions graphviz.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,17 @@ import (
"sort"

"github.com/awalterschulze/gographviz"
"go.uber.org/zap"
)

func graphviz(issues Issues, opts *runOptions) (string, error) {
var (
stats = map[string]int{
"nodes": 0,
"edges": 0,
"hidden": 0,
"subgraphs": 0,
}
invisStyle = map[string]string{"style": "invis", "label": escape("")}
weightMap = map[int]bool{}
weights = []int{}
Expand All @@ -19,6 +26,7 @@ func graphviz(issues Issues, opts *runOptions) (string, error) {
}
for _, issue := range issues {
if issue.Hidden {
stats["hidden"]++
continue
}
weightMap[issue.Weight()] = true
Expand Down Expand Up @@ -83,11 +91,13 @@ func graphviz(issues Issues, opts *runOptions) (string, error) {
}

panicIfErr(issue.AddNodeToGraph(g, parent))
stats["nodes"]++
}

// issue relationships
for _, issue := range issues {
panicIfErr(issue.AddEdgesToGraph(g))
stats["edges"]++
}

// orphans cluster and placeholder
Expand All @@ -97,18 +107,21 @@ func graphviz(issues Issues, opts *runOptions) (string, error) {
"cluster_orphans_without_links",
map[string]string{"label": escape("orphans without links"), "style": "dashed"},
))
stats["subgraphs"]++

panicIfErr(g.AddSubGraph(
"cluster_orphans_without_links",
"cluster_orphans_without_links_0",
invisStyle,
))
stats["subgraphs"]++
for i := 0; i < orphansCols; i++ {
panicIfErr(g.AddNode(
fmt.Sprintf("cluster_orphans_without_links_%d", i),
fmt.Sprintf("placeholder_orphans_without_links_%d", i),
invisStyle,
))
stats["nodes"]++
}

panicIfErr(g.AddEdge(
Expand All @@ -117,36 +130,46 @@ func graphviz(issues Issues, opts *runOptions) (string, error) {
true,
invisStyle,
))
stats["edges"]++

for i := 1; i < orphansCols; i++ {
panicIfErr(g.AddSubGraph(
"cluster_orphans_without_links",
fmt.Sprintf("cluster_orphans_without_links_%d", i),
invisStyle,
))
stats["subgraphs"]++
panicIfErr(g.AddEdge(
fmt.Sprintf("placeholder_orphans_without_links_%d", i-1),
fmt.Sprintf("placeholder_orphans_without_links_%d", i),
true,
invisStyle,
))
stats["edges"]++
}
}
if hasOrphansWithLinks {
panicIfErr(g.AddSubGraph("G", "cluster_orphans_with_links", map[string]string{"label": escape("orphans with links"), "style": "dashed"}))
stats["subgraphs"]++

panicIfErr(g.AddNode("cluster_orphans_with_links", "placeholder_orphans_with_links", invisStyle))
stats["nodes"]++

panicIfErr(g.AddEdge(
"placeholder_orphans_with_links",
fmt.Sprintf("placeholder_%d", weights[0]),
true,
invisStyle,
))
stats["edges"]++
}

// set weights clusters and placeholders
for _, weight := range weights {
clusterName := fmt.Sprintf("anon%d", weight)
panicIfErr(g.AddSubGraph("G", clusterName, map[string]string{"rank": "same"}))
stats["subgraphs"]++

//clusterName := fmt.Sprintf("cluster_w%d", weight)
//panicIfErr(g.AddSubGraph("G", clusterName, map[string]string{"label": fmt.Sprintf("w%d", weight)}))
panicIfErr(g.AddNode(
Expand All @@ -157,6 +180,7 @@ func graphviz(issues Issues, opts *runOptions) (string, error) {
"label": fmt.Sprintf(`"weight=%d"`, weight),
},
))
stats["nodes"]++
}
for i := 0; i < len(weights)-1; i++ {
panicIfErr(g.AddEdge(
Expand All @@ -165,7 +189,9 @@ func graphviz(issues Issues, opts *runOptions) (string, error) {
true,
invisStyle,
))
stats["edges"]++
}

logger().Debug("graph stats", zap.Any("stats", stats))
return g.String(), nil
}
36 changes: 35 additions & 1 deletion issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ func (i Issue) NodeTitle() string {
for _, err := range i.Errors {
errors = append(errors, err.Error())
}
errorsText = fmt.Sprintf(`<tr><td bgcolor="red">ERR: %s</td></tr>`, strings.Join(errors, "; "))
errorsText = fmt.Sprintf(`<tr><td bgcolor="red">ERR: %s</td></tr>`, strings.Join(errors, ";<br />ERR: "))
}
return fmt.Sprintf(`<<table><tr><td>%s</td></tr>%s%s%s</table>>`, title, labelsText, assigneeText, errorsText)
}
Expand Down Expand Up @@ -471,6 +471,40 @@ func (issues Issues) processEpicLinks() {
}
}

func (issues Issues) filterByTargets(targets []string) {
for _, issue := range issues {
if issue.Hidden {
continue
}
issue.Hidden = !issue.MatchesWithATarget(targets)
}
}

func (i Issue) MatchesWithATarget(targets []string) bool {
issueParts := strings.Split(strings.TrimRight(i.URL, "/"), "/")
for _, target := range targets {
fullTarget := i.GetRelativeIssueURL(target)
targetParts := strings.Split(strings.TrimRight(fullTarget, "/"), "/")
if len(issueParts) == len(targetParts) {
if i.URL == fullTarget {
return true
}
} else {
if i.URL[:len(fullTarget)] == fullTarget {
return true
}
}
}

for _, parent := range i.Blocks {
if parent.MatchesWithATarget(targets) {
return true
}
}

return false
}

func (issues Issues) HideClosed() {
for _, issue := range issues {
if issue.IsClosed() {
Expand Down
17 changes: 16 additions & 1 deletion util.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,26 @@ func getReposFromTargets(targets []string) []string {
logger().Fatal("filesystem target are not yet supported")
}
repo := strings.Split(target, "/issues")[0]
repo = strings.Split(target, "#")[0]
reposMap[repo] = true
}
repos := []string{}
for repo := range reposMap {
repos = append(repos, repo)
}
return repos
return uniqueStrings(repos)
}

func uniqueStrings(input []string) []string {
u := make([]string, 0, len(input))
m := make(map[string]bool)

for _, val := range input {
if _, ok := m[val]; !ok {
m[val] = true
u = append(u, val)
}
}

return u
}

0 comments on commit 4097ce4

Please sign in to comment.