visualize_packwerk 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 358f7f6ce6490e9a49b9a898af9d877181c1ecffd99068dea9cbaa5267f1a552
4
- data.tar.gz: 4ff54f1b92868804ce3a49bba54f54668ccc1510b446873fc7dbb3da7d9d4cfe
3
+ metadata.gz: c15049155fd43dca095255941ff8f996409fd2712f28008874fe3a772ba9b28b
4
+ data.tar.gz: 406b008fa89777838b588080aa3ee25afd417f16663124b668937ea91c3b9c17
5
5
  SHA512:
6
- metadata.gz: 4933f49f8868128aaecd6b6696d79cc677d8185bea9b18e3f2f7bdbafec85dfd9d055ebe8c196aad7008b52a92f5fcad53d69af5535ffad152b6c8188ebbb8bb
7
- data.tar.gz: 5f72a6c8a97623326a94e4fca096b5a836c9208e801a5f70f720d515115f074a41d35f7b4ccc801f02bb44d01e95e338826d3ce2ee39f50808ce3d8006a6709a
6
+ metadata.gz: b6ee92e733adf0da1062cf262849685a5adb053baef2adb34793aadedbb68c072193a19df4ff9d8eed280e491cfb0afac4bb9a1211962f6cd1d8a9b20c4bf6d8
7
+ data.tar.gz: 6ca30bbcadd94b1b8241456001c6d8144f6b395718cb1d765605cb0c2f1fb7b0bffe4d36c312cbb7510ed9930385013eafe598788f63d6c675abbcd8b6034539
data/README.md CHANGED
@@ -1,8 +1,19 @@
1
1
  # visualize_packwerk
2
2
 
3
- This gem contains rake tasks to help visualize relationships between packwerk packs.
3
+ This gem helps visualize relationships between packwerk packs.
4
4
 
5
- # Usage
5
+ ![Example of visualization](docs/example.png)
6
+
7
+ # CLI Usage
8
+ ## bin/packs
9
+ For simpler use, add `bin/packs` via `use_packs` (https://github.com/rubyatscale/use_packs)
10
+ ```
11
+ bin/packs visualize # all packs
12
+ bin/packs visualize packs/a packs/b # subset of packs
13
+ bin/packs # enter interactive mode to select what packs to visualize
14
+ ```
15
+
16
+ # Ruby API Usage
6
17
  ## Building a package graph for a selection of packages
7
18
  ```ruby
8
19
  # Select the packs you want to include
@@ -12,7 +23,7 @@ selected_packs = Packs.all.select{ |p| ['Team 1', 'Team 2'].include?(CodeOwnersh
12
23
  VisualizePackwerk.package_graph!(selected_packs)
13
24
  ```
14
25
 
15
- # Building a team graph for specific teams
26
+ ## Building a team graph for specific teams
16
27
  ```ruby
17
28
  # Select the teams you want to include
18
29
  selected_teams = CodeTeams.all
@@ -20,8 +31,5 @@ selected_teams = CodeTeams.all.select{ |t| ['Team 1', 'Team 2'].include?(t.name)
20
31
  VisualizePackwerk.team_graph!(selected_teams)
21
32
  ```
22
33
 
23
- ## bin/packs
24
- For simpler use, use `bin/packs` in `use_packwerk` (https://github.com/rubyatscale/use_packwerk)
25
-
26
34
  # Want to change something or add a feature?
27
35
  Submit a PR or post an issue!
Binary file
@@ -45,7 +45,15 @@ module VisualizePackwerk
45
45
  # https://graphviz.org/docs/layouts/
46
46
  default_layout = :dot
47
47
  # other_layout = :sfdp
48
- graphviz_graph = GraphViz.new(:G, type: :digraph, dpi: 100, layout: default_layout)
48
+ graphviz_graph = GraphViz.new(
49
+ :G,
50
+ type: :digraph,
51
+ dpi: 100,
52
+ layout: default_layout,
53
+ label: "Visualization of #{node_names.count} packs, generated using `bin/packs`",
54
+ fontsize: 24,
55
+ labelloc: "t",
56
+ )
49
57
 
50
58
  # Create graph nodes
51
59
  graphviz_nodes = T.let({}, T::Hash[String, GraphViz::Node])
@@ -56,36 +64,32 @@ module VisualizePackwerk
56
64
  graphviz_nodes[node.name] = add_node(node, graphviz_graph)
57
65
  end
58
66
 
59
- max_edge_width = 10
60
-
61
67
  # Draw all edges
62
68
  nodes_to_draw.each do |node|
63
69
  node.dependencies.each do |to_node|
64
70
  next unless node_names.include?(to_node)
65
71
 
66
- graphviz_graph.add_edges(
67
- graphviz_nodes[node.name],
68
- graphviz_nodes[to_node],
69
- { color: 'darkgreen' }
72
+ add_dependency(
73
+ graph: graphviz_graph,
74
+ node1: T.must(graphviz_nodes[node.name]),
75
+ node2: T.must(graphviz_nodes[to_node]),
70
76
  )
71
77
  end
72
78
 
73
79
  node.violations_by_node_name.each do |to_node_name, violation_count|
74
80
  next unless node_names.include?(to_node_name)
75
81
 
76
- edge_width = [
77
- [(violation_count / 5).to_i, 1].max, # rubocop:disable Lint/NumberConversion
78
- max_edge_width,
79
- ].min
80
-
81
- graphviz_graph.add_edges(
82
- graphviz_nodes[node.name],
83
- graphviz_nodes[to_node_name],
84
- { color: 'red', penwidth: edge_width }
82
+ add_violation(
83
+ graph: graphviz_graph,
84
+ node1: T.must(graphviz_nodes[node.name]),
85
+ node2: T.must(graphviz_nodes[to_node_name]),
86
+ violation_count: violation_count
85
87
  )
86
88
  end
87
89
  end
88
90
 
91
+ add_legend(graphviz_graph)
92
+
89
93
  # Save graph to filesystem
90
94
  puts "Outputting to: #{OUTPUT_FILENAME}"
91
95
  graphviz_graph.output(png: OUTPUT_FILENAME)
@@ -106,6 +110,60 @@ module VisualizePackwerk
106
110
 
107
111
  graph.add_nodes(node.name, **node_options)
108
112
  end
113
+
114
+ sig { params(graph: GraphViz).void }
115
+ def add_legend(graph)
116
+ legend = graph.add_graph("legend")
117
+
118
+ # This commented out code was used to generate an image that I edited by hand.
119
+ # I was unable to figure out how to:
120
+ # - put a box around the legend
121
+ # - layout the node pairs in vertical order
122
+ # - give it a title
123
+ # So I just generated this using graphviz and then pulled the image in.
124
+ # a_node = legend.add_nodes("packs/a")
125
+ # b_node = legend.add_nodes("packs/b")
126
+ # c_node = legend.add_nodes("packs/c")
127
+ # d_node = legend.add_nodes("packs/d")
128
+ # e_node = legend.add_nodes("packs/e")
129
+ # f_node = legend.add_nodes("packs/f")
130
+
131
+ # add_dependency(graph: legend, node1: a_node, node2: b_node, label: 'Dependency in package.yml')
132
+ # add_violation(graph: legend, node1: c_node, node2: d_node, violation_count: 1, label: 'Violations (few)')
133
+ # add_violation(graph: legend, node1: e_node, node2: f_node, violation_count: 30, label: 'Violations (many)')
134
+
135
+ image = legend.add_node("",
136
+ shape: "image",
137
+ image: Pathname.new(__dir__).join("./legend.png").to_s,
138
+ )
139
+ end
140
+
141
+ sig { params(graph: GraphViz, node1: GraphViz::Node, node2: GraphViz::Node, violation_count: Integer, label: T.nilable(String)).void }
142
+ def add_violation(graph:, node1:, node2:, violation_count:, label: nil)
143
+ max_edge_width = 10
144
+
145
+ edge_width = [
146
+ [(violation_count / 5).to_i, 1].max, # rubocop:disable Lint/NumberConversion
147
+ max_edge_width,
148
+ ].min
149
+
150
+ opts = { color: 'red', style: 'dashed', penwidth: edge_width }
151
+ if label
152
+ opts.merge!(label: label)
153
+ end
154
+
155
+ graph.add_edges(node1, node2, opts)
156
+ end
157
+
158
+ sig { params(graph: GraphViz, node1: GraphViz::Node, node2: GraphViz::Node, label: T.nilable(String)).void }
159
+ def add_dependency(graph:, node1:, node2:, label: nil)
160
+ opts = { color: 'darkgreen' }
161
+ if label
162
+ opts.merge!(label: label)
163
+ end
164
+
165
+ graph.add_edges(node1, node2, opts)
166
+ end
109
167
  end
110
168
 
111
169
  private_constant :PackageRelationships
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: visualize_packwerk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gusto Engineers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-09 00:00:00.000000000 Z
11
+ date: 2023-05-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sorbet-runtime
@@ -160,6 +160,7 @@ files:
160
160
  - README.md
161
161
  - lib/visualize_packwerk.rb
162
162
  - lib/visualize_packwerk/graph_interface.rb
163
+ - lib/visualize_packwerk/legend.png
163
164
  - lib/visualize_packwerk/node_interface.rb
164
165
  - lib/visualize_packwerk/package_graph.rb
165
166
  - lib/visualize_packwerk/package_node.rb