philiprehberger-dependency_graph 0.4.0 → 0.6.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: d893dfbce550ce9ba6022f2f647b4b70cf2306a972b52b93ed096d7bc9384c9c
4
- data.tar.gz: 57ef5e2ddea71da6b58e15adeb0e1d1d38443b455d99c17aa14a795cfdf7a421
3
+ metadata.gz: 9041e502079017386899d6e6333b3da03684b8f30afde0e9b432345a3770da7e
4
+ data.tar.gz: 0b21f4dcf958d6e0d4c6511427d130a3f4ef2a91b2df0c0350cbda64c85778da
5
5
  SHA512:
6
- metadata.gz: a3096da9a20d0a487aec73c8f5fccd26483e4ef6d19e237f767892f8ef3c5f1a8ad670d859b137b3c10c7afb4e28a86467e9485f0d081fe4bc1ca2be706eb0af
7
- data.tar.gz: 657e23b74e72698eefd35515b25ce8f3a8d508107384460fac9d9d608589018d6b11705f49fd2547fe5d879fe5f06e68a2361d28cf2009adb5c560c6a572fef2
6
+ metadata.gz: 572bd0a2ab419176f76d55908b7022375a3eb7f565e2b7a3aa9de4903bd627b4d46a93a52ccb4a89e1f5188f7f83468e2f3da55e38fab18ee52b721261daa22b
7
+ data.tar.gz: 6c1fe938a2fe004bfaba2e1a32dd6864efb43709a841b2fb61bbc01464aa7758e178b5ec993fd1148ebc0795cb74d1b40e09ae900dad5cfa3340e8aa349dd5ad
data/CHANGELOG.md CHANGED
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.6.0] - 2026-05-12
11
+
12
+ ### Added
13
+ - `Graph#remove(item)` deletes a node and every incident edge; returns `true` when present, `false` when the node is unknown
14
+
15
+ ## [0.5.0] - 2026-05-01
16
+
17
+ ### Added
18
+ - `Graph#in_degree(item)` — count of direct dependents (how many items depend on this one)
19
+ - `Graph#out_degree(item)` — count of direct dependencies for an item
20
+
10
21
  ## [0.4.0] - 2026-04-21
11
22
 
12
23
  ### Added
data/README.md CHANGED
@@ -77,6 +77,9 @@ graph.add(:d, depends_on: [:b, :c])
77
77
  graph.dependencies_of(:d) # => [:b, :c]
78
78
  graph.all_dependencies_of(:d) # => [:b, :c, :a]
79
79
  graph.dependents_of(:b) # => [:c, :d]
80
+
81
+ graph.out_degree(:d) # => 2
82
+ graph.in_degree(:b) # => 2
80
83
  ```
81
84
 
82
85
  ### Path Finding
@@ -133,6 +136,7 @@ graph.to_dot(name: 'MyDeps') # Customize the digraph name
133
136
  |--------|-------------|
134
137
  | `DependencyGraph.new` | Create a new empty graph |
135
138
  | `Graph#add(item, depends_on:)` | Add an item with dependencies |
139
+ | `Graph#remove(item)` | Remove a node and all incident edges; returns true when present, false otherwise |
136
140
  | `Graph#resolve` | Topological sort, dependencies first |
137
141
  | `Graph#parallel_batches` | Group into parallel execution batches |
138
142
  | `Graph#cycle?` | Check if the graph contains cycles |
@@ -140,6 +144,8 @@ graph.to_dot(name: 'MyDeps') # Customize the digraph name
140
144
  | `Graph#dependencies_of(item)` | Direct dependencies of an item |
141
145
  | `Graph#all_dependencies_of(item)` | All transitive dependencies |
142
146
  | `Graph#dependents_of(item)` | Items that directly depend on an item |
147
+ | `Graph#in_degree(item)` | Count of direct dependents for an item |
148
+ | `Graph#out_degree(item)` | Count of direct dependencies for an item |
143
149
  | `Graph#path(from, to)` | Shortest dependency path (BFS), or nil |
144
150
  | `Graph#subgraph(*items)` | Extract a new graph with specified nodes |
145
151
  | `Graph#roots` | Nodes with no dependencies |
@@ -146,6 +146,28 @@ module Philiprehberger
146
146
  end
147
147
  end
148
148
 
149
+ # Number of direct dependencies for an item.
150
+ #
151
+ # Returns 0 for unknown items, matching the defensive behavior of
152
+ # {#dependencies_of}.
153
+ #
154
+ # @param item [Object] the item to query
155
+ # @return [Integer] count of direct dependencies
156
+ def out_degree(item)
157
+ (@nodes[item] || []).size
158
+ end
159
+
160
+ # Number of direct dependents for an item (how many items depend on it).
161
+ #
162
+ # Returns 0 for unknown items, matching the defensive behavior of
163
+ # {#dependents_of}.
164
+ #
165
+ # @param item [Object] the item to query
166
+ # @return [Integer] count of direct dependents
167
+ def in_degree(item)
168
+ @nodes.count { |_node, deps| deps.include?(item) }
169
+ end
170
+
149
171
  # Find shortest dependency path between two nodes using BFS
150
172
  #
151
173
  # @param from [Object] the starting node
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Philiprehberger
4
4
  module DependencyGraph
5
- VERSION = '0.4.0'
5
+ VERSION = '0.6.0'
6
6
  end
7
7
  end
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.0
4
+ version: 0.6.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-21 00:00:00.000000000 Z
11
+ date: 2026-05-12 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