You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by an...@apache.org on 2022/03/08 23:04:04 UTC

[mynewt-newt] branch master updated: Add dependency graph output in DOT format

This is an automated email from the ASF dual-hosted git repository.

andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-newt.git


The following commit(s) were added to refs/heads/master by this push:
     new 406930b  Add dependency graph output in DOT format
406930b is described below

commit 406930b774a6f180533191381420efe6e0a9d300
Author: Andrzej Kaczmarek <an...@codecoup.pl>
AuthorDate: Mon Mar 7 12:40:09 2022 +0100

    Add dependency graph output in DOT format
    
    This adds two commands "target depviz" and "target revdepviz" which can
    output dependency graph in DOT format. The usage is the same as "target
    dep" and "target revdep", only the ouput format is different.
---
 newt/builder/depgraph.go | 43 ++++++++++++++++++++++++++++++++++
 newt/cli/target_cmds.go  | 60 ++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 101 insertions(+), 2 deletions(-)

diff --git a/newt/builder/depgraph.go b/newt/builder/depgraph.go
index f114d1f..a4d18b7 100644
--- a/newt/builder/depgraph.go
+++ b/newt/builder/depgraph.go
@@ -23,6 +23,7 @@ import (
 	"bytes"
 	"fmt"
 	"sort"
+	"strings"
 
 	"mynewt.apache.org/newt/newt/parse"
 	"mynewt.apache.org/newt/newt/resolve"
@@ -182,6 +183,27 @@ func DepGraphText(graph DepGraph) string {
 	return buffer.String()
 }
 
+func DepGraphViz(graph DepGraph) string {
+	parents := make([]string, 0, len(graph))
+	for pname, _ := range graph {
+		parents = append(parents, pname)
+	}
+	sort.Strings(parents)
+
+	buffer := bytes.NewBufferString("")
+
+	fmt.Fprintf(buffer, "digraph deps {\n")
+	for _, pname := range parents {
+		for _, child := range graph[pname] {
+			depStr := strings.TrimPrefix(depString(child), child.PkgName)
+			fmt.Fprintf(buffer, "  \"%s\" -> \"%s\" [label=\"%s\"];\n", pname, child.PkgName, depStr)
+		}
+	}
+	fmt.Fprintf(buffer, "}\n")
+
+	return buffer.String()
+}
+
 func RevdepGraphText(graph DepGraph) string {
 	parents := make([]string, 0, len(graph))
 	for pname, _ := range graph {
@@ -206,6 +228,27 @@ func RevdepGraphText(graph DepGraph) string {
 	return buffer.String()
 }
 
+func RevdepGraphViz(graph DepGraph) string {
+	parents := make([]string, 0, len(graph))
+	for pname, _ := range graph {
+		parents = append(parents, pname)
+	}
+	sort.Strings(parents)
+
+	buffer := bytes.NewBufferString("")
+
+	fmt.Fprintf(buffer, "digraph revdeps {\n")
+	for _, pname := range parents {
+		for _, child := range graph[pname] {
+			depStr := strings.TrimPrefix(depString(child), child.PkgName)
+			fmt.Fprintf(buffer, "  \"%s\" -> \"%s\" [label=\"%s\"];\n", child.PkgName, pname, depStr)
+		}
+	}
+	fmt.Fprintf(buffer, "}\n")
+
+	return buffer.String()
+}
+
 // Extracts a new dependency graph containing only the specified parents.
 //
 // @param dg                    The source graph to filter.
diff --git a/newt/cli/target_cmds.go b/newt/cli/target_cmds.go
index acafd01..525ea75 100644
--- a/newt/cli/target_cmds.go
+++ b/newt/cli/target_cmds.go
@@ -572,7 +572,7 @@ func targetCopyCmd(cmd *cobra.Command, args []string) {
 		srcTarget.FullName(), dstTarget.FullName())
 }
 
-func targetDepCmd(cmd *cobra.Command, args []string) {
+func targetDepCommonCmd(cmd *cobra.Command, args []string) builder.DepGraph {
 	if len(args) < 1 {
 		NewtUsage(cmd,
 			util.NewNewtError("Must specify target or unittest name"))
@@ -611,13 +611,27 @@ func targetDepCmd(cmd *cobra.Command, args []string) {
 		}
 	}
 
+	return dg
+}
+
+func targetDepCmd(cmd *cobra.Command, args []string) {
+	dg := targetDepCommonCmd(cmd, args)
+
 	if len(dg) > 0 {
 		util.StatusMessage(util.VERBOSITY_DEFAULT,
 			builder.DepGraphText(dg)+"\n")
 	}
 }
 
-func targetRevdepCmd(cmd *cobra.Command, args []string) {
+func targetDepvizCmd(cmd *cobra.Command, args []string) {
+	dg := targetDepCommonCmd(cmd, args)
+
+	if len(dg) > 0 {
+		fmt.Print(builder.DepGraphViz(dg))
+	}
+}
+
+func targetRevdepCommonCmd(cmd *cobra.Command, args []string) builder.DepGraph {
 	if len(args) < 1 {
 		NewtUsage(cmd, util.NewNewtError("Must specify target name"))
 	}
@@ -655,12 +669,26 @@ func targetRevdepCmd(cmd *cobra.Command, args []string) {
 		}
 	}
 
+	return dg
+}
+
+func targetRevdepCmd(cmd *cobra.Command, args []string) {
+	dg := targetRevdepCommonCmd(cmd, args)
+
 	if len(dg) > 0 {
 		util.StatusMessage(util.VERBOSITY_DEFAULT,
 			builder.RevdepGraphText(dg)+"\n")
 	}
 }
 
+func targetRevdepvizCmd(cmd *cobra.Command, args []string) {
+	dg := targetRevdepCommonCmd(cmd, args)
+
+	if len(dg) > 0 {
+		fmt.Print(builder.RevdepGraphViz(dg))
+	}
+}
+
 func AddTargetCommands(cmd *cobra.Command) {
 	targetHelpText := ""
 	targetHelpEx := ""
@@ -819,6 +847,20 @@ func AddTargetCommands(cmd *cobra.Command) {
 		return append(targetList(), unittestList()...)
 	})
 
+	depvizHelpText := "Output dependency graph in DOT format."
+
+	depvizCmd := &cobra.Command{
+		Use:   "depviz <target> [pkg-1] [pkg-2] [...]",
+		Short: "Output dependency graph in DOT format",
+		Long:  depvizHelpText,
+		Run:   targetDepvizCmd,
+	}
+
+	targetCmd.AddCommand(depvizCmd)
+	AddTabCompleteFn(depvizCmd, func() []string {
+		return append(targetList(), unittestList()...)
+	})
+
 	revdepHelpText := "View a target's reverse-dependency graph."
 
 	revdepCmd := &cobra.Command{
@@ -833,6 +875,20 @@ func AddTargetCommands(cmd *cobra.Command) {
 		return append(targetList(), unittestList()...)
 	})
 
+	revdepvizHelpText := "Output reverse-dependency graph in DOT format."
+
+	revdepvizCmd := &cobra.Command{
+		Use:   "revdepviz <target> [pkg-1] [pkg-2] [...]",
+		Short: "Output reverse-dependency graph in DOT format",
+		Long:  revdepvizHelpText,
+		Run:   targetRevdepvizCmd,
+	}
+
+	targetCmd.AddCommand(revdepvizCmd)
+	AddTabCompleteFn(revdepvizCmd, func() []string {
+		return append(targetList(), unittestList()...)
+	})
+
 	for _, cmd := range targetCfgCmdAll() {
 		targetCmd.AddCommand(cmd)
 	}