Skip to content

Commit

Permalink
Add support for multiple limit path prefixes
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrajz committed Jan 23, 2017
1 parent d5d9c6d commit 2dc5fd5
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 21 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ Purpose of this tool is to provide a visual overview of your program by using th

- focus specific package in a program
- group functions by package and methods by type
- limit packages to custom prefix path
- ignore packages containing custom prefix
- limit packages to custom path prefixes
- ignore packages containing path prefixes

### Output preview

Expand Down Expand Up @@ -100,11 +100,11 @@ Represents | Style
-focus string
Focus package with import path or name. (default: main)
-limit string
Limit package path to prefix.
Limit package paths to prefix. (separate multiple by comma)
-group string
Grouping functions by [pkg, type] (separate multiple by comma).
Grouping functions by [pkg, type]. (separate multiple by comma)
-ignore string
Ignore package paths with prefix (separate multiple by comma).
Ignore package paths with prefix. (separate multiple by comma)
-minlen uint
Minimum edge length (for wider output). (default: 2)
-nodesep float
Expand Down
32 changes: 20 additions & 12 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ var Version = "0.0.0-src"

var (
focusFlag = flag.String("focus", "main", "Focus package with name or import path.")
limitFlag = flag.String("limit", "", "Limit package path to prefix.")
limitFlag = flag.String("limit", "", "Limit package paths to prefix. (separate multiple by comma)")
groupFlag = flag.String("group", "", "Grouping functions by [pkg, type] (separate multiple by comma).")
ignoreFlag = flag.String("ignore", "", "Ignore package paths with prefix (separate multiple by comma).")
testFlag = flag.Bool("tests", false, "Include test code.")
Expand All @@ -44,14 +44,6 @@ func main() {
log.SetFlags(log.Lmicroseconds)
}

ignorePaths := []string{}
for _, p := range strings.Split(*ignoreFlag, ",") {
p = strings.TrimSpace(p)
if p != "" {
ignorePaths = append(ignorePaths, p)
}
}

groupBy := make(map[string]bool)
for _, g := range strings.Split(*groupFlag, ",") {
g := strings.TrimSpace(g)
Expand All @@ -65,13 +57,29 @@ func main() {
groupBy[g] = true
}

if err := run(&build.Default, *focusFlag, *limitFlag, groupBy, ignorePaths, *testFlag, flag.Args()); err != nil {
limitPaths := []string{}
for _, p := range strings.Split(*limitFlag, ",") {
p = strings.TrimSpace(p)
if p != "" {
limitPaths = append(limitPaths, p)
}
}

ignorePaths := []string{}
for _, p := range strings.Split(*ignoreFlag, ",") {
p = strings.TrimSpace(p)
if p != "" {
ignorePaths = append(ignorePaths, p)
}
}

if err := run(&build.Default, *focusFlag, groupBy, limitPaths, ignorePaths, *testFlag, flag.Args()); err != nil {
fmt.Fprintf(os.Stderr, "go-callvis: %s\n", err)
os.Exit(1)
}
}

func run(ctxt *build.Context, focus, limitPath string, groupBy map[string]bool, ignorePaths []string, tests bool, args []string) error {
func run(ctxt *build.Context, focus string, groupBy map[string]bool, limitPaths, ignorePaths []string, tests bool, args []string) error {
if len(args) == 0 {
return fmt.Errorf("missing arguments")
}
Expand Down Expand Up @@ -154,7 +162,7 @@ func run(ctxt *build.Context, focus, limitPath string, groupBy map[string]bool,
logf("analysis took: %v", time.Since(t0))

return printOutput(mains[0].Pkg, result.CallGraph,
focusPkg, limitPath, ignorePaths, groupBy)
focusPkg, limitPaths, ignorePaths, groupBy)
}

func logf(f string, a ...interface{}) {
Expand Down
33 changes: 29 additions & 4 deletions output.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (

var output io.Writer = os.Stdout

func printOutput(mainPkg *types.Package, cg *callgraph.Graph, focusPkg *build.Package, limitPath string, ignorePaths []string, groupBy map[string]bool) error {
func printOutput(mainPkg *types.Package, cg *callgraph.Graph, focusPkg *build.Package, limitPaths, ignorePaths []string, groupBy map[string]bool) error {
groupType := groupBy["type"]
groupPkg := groupBy["pkg"]

Expand All @@ -39,6 +39,32 @@ func printOutput(mainPkg *types.Package, cg *callgraph.Graph, focusPkg *build.Pa

cg.DeleteSyntheticNodes()

logf("%d limit prefixes: %v", len(limitPaths), limitPaths)
logf("%d ignore prefixes: %v", len(ignorePaths), ignorePaths)

var inLimit = func(from, to *callgraph.Node) bool {
if len(limitPaths) == 0 {
return true
}
var fromOk, toOk bool
fromPath := from.Func.Pkg.Pkg.Path()
toPath := to.Func.Pkg.Pkg.Path()
for _, p := range limitPaths {
if strings.HasPrefix(fromPath, p) {
fromOk = true
}
if strings.HasPrefix(toPath, p) {
toOk = true
}
if fromOk && toOk {
logf("in limit: %s -> %s", from, to)
return true
}
}
logf("NOT in limit: %s -> %s", from, to)
return false
}

err := callgraph.GraphVisitEdges(cg, func(edge *callgraph.Edge) error {
caller := edge.Caller
callee := edge.Callee
Expand All @@ -57,9 +83,8 @@ func printOutput(mainPkg *types.Package, cg *callgraph.Graph, focusPkg *build.Pa
return nil
}

// limit to path prefix
if !(strings.HasPrefix(callerPkg.Path(), limitPath) &&
strings.HasPrefix(calleePkg.Path(), limitPath)) {
// limit path prefixes
if !inLimit(caller, callee) {
return nil
}

Expand Down

0 comments on commit 2dc5fd5

Please sign in to comment.