philiprehberger-dependency_graph 0.3.0 → 0.4.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 +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +18 -0
- data/lib/philiprehberger/dependency_graph/graph.rb +25 -10
- data/lib/philiprehberger/dependency_graph/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d893dfbce550ce9ba6022f2f647b4b70cf2306a972b52b93ed096d7bc9384c9c
|
|
4
|
+
data.tar.gz: 57ef5e2ddea71da6b58e15adeb0e1d1d38443b455d99c17aa14a795cfdf7a421
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a3096da9a20d0a487aec73c8f5fccd26483e4ef6d19e237f767892f8ef3c5f1a8ad670d859b137b3c10c7afb4e28a86467e9485f0d081fe4bc1ca2be706eb0af
|
|
7
|
+
data.tar.gz: 657e23b74e72698eefd35515b25ce8f3a8d508107384460fac9d9d608589018d6b11705f49fd2547fe5d879fe5f06e68a2361d28cf2009adb5c560c6a572fef2
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.4.0] - 2026-04-21
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- `Graph#to_dot` — Graphviz DOT export for visualization
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- `bug_report.yml` — require Ruby version; add Gem version input per guide
|
|
17
|
+
|
|
10
18
|
## [0.3.0] - 2026-04-09
|
|
11
19
|
|
|
12
20
|
### Added
|
data/README.md
CHANGED
|
@@ -110,6 +110,23 @@ graph.add(:a).add(:b, depends_on: [:a]).add(:c, depends_on: [:b])
|
|
|
110
110
|
graph.resolve # => [:a, :b, :c]
|
|
111
111
|
```
|
|
112
112
|
|
|
113
|
+
### Graphviz Export
|
|
114
|
+
|
|
115
|
+
```ruby
|
|
116
|
+
graph = Philiprehberger::DependencyGraph.new
|
|
117
|
+
graph.add(:a)
|
|
118
|
+
graph.add(:b, depends_on: [:a])
|
|
119
|
+
graph.add(:c, depends_on: [:b])
|
|
120
|
+
|
|
121
|
+
puts graph.to_dot
|
|
122
|
+
# digraph dependencies {
|
|
123
|
+
# "b" -> "a";
|
|
124
|
+
# "c" -> "b";
|
|
125
|
+
# }
|
|
126
|
+
|
|
127
|
+
graph.to_dot(name: 'MyDeps') # Customize the digraph name
|
|
128
|
+
```
|
|
129
|
+
|
|
113
130
|
## API
|
|
114
131
|
|
|
115
132
|
| Method | Description |
|
|
@@ -131,6 +148,7 @@ graph.resolve # => [:a, :b, :c]
|
|
|
131
148
|
| `Graph#reverse` | Return a new graph with all edges flipped |
|
|
132
149
|
| `Graph#all_dependents_of(item)` | All transitive dependents of a node |
|
|
133
150
|
| `Graph#independent?(a, b)` | Whether two nodes are mutually unreachable |
|
|
151
|
+
| `#to_dot(name:)` | Graphviz DOT representation |
|
|
134
152
|
|
|
135
153
|
## Development
|
|
136
154
|
|
|
@@ -298,18 +298,33 @@ module Philiprehberger
|
|
|
298
298
|
!all_dependencies_of(node_b).include?(node_a)
|
|
299
299
|
end
|
|
300
300
|
|
|
301
|
-
# Export the graph in Graphviz DOT format
|
|
301
|
+
# Export the graph in Graphviz DOT format.
|
|
302
302
|
#
|
|
303
|
-
#
|
|
304
|
-
#
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
303
|
+
# Nodes are emitted in alphabetical order (cast to string for sort key),
|
|
304
|
+
# and edges within a node are sorted alphabetically for deterministic
|
|
305
|
+
# output. Nodes that participate in at least one edge (incoming or
|
|
306
|
+
# outgoing) are emitted implicitly via the edge lines; truly isolated
|
|
307
|
+
# nodes are declared explicitly so they still appear in the rendered
|
|
308
|
+
# graph. Works on graphs containing cycles.
|
|
309
|
+
#
|
|
310
|
+
# @param name [String] the digraph name used in the `digraph` header
|
|
311
|
+
# @return [String] Graphviz DOT source, terminated by a newline
|
|
312
|
+
def to_dot(name: 'dependencies')
|
|
313
|
+
output = "digraph #{name} {\n"
|
|
314
|
+
depended_on = @nodes.each_with_object({}) do |(_node, deps), acc|
|
|
315
|
+
deps.each { |dep| acc[dep] = true }
|
|
316
|
+
end
|
|
317
|
+
sorted_nodes = @nodes.keys.sort_by(&:to_s)
|
|
318
|
+
sorted_nodes.each do |node|
|
|
319
|
+
deps = (@nodes[node] || []).sort_by(&:to_s)
|
|
320
|
+
if deps.empty?
|
|
321
|
+
output << " #{dot_quote(node)};\n" unless depended_on[node]
|
|
322
|
+
else
|
|
323
|
+
deps.each { |dep| output << " #{dot_quote(node)} -> #{dot_quote(dep)};\n" }
|
|
324
|
+
end
|
|
310
325
|
end
|
|
311
|
-
|
|
312
|
-
|
|
326
|
+
output << "}\n"
|
|
327
|
+
output
|
|
313
328
|
end
|
|
314
329
|
|
|
315
330
|
# Calculate maximum dependency depth for a node (longest path from any root to this node)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: philiprehberger-dependency_graph
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Philip Rehberger
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-04-
|
|
11
|
+
date: 2026-04-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Build and resolve dependency graphs using topological sort, detect cycles,
|
|
14
14
|
generate parallel execution batches, query dependencies and dependents, find shortest
|