tangle 0.8.2 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/tangle/graph.rb +9 -7
- data/lib/tangle/graph_edges.rb +12 -9
- data/lib/tangle/graph_vertices.rb +34 -3
- data/lib/tangle/mixin/directory.rb +28 -11
- 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: 49ee5268eb1851a1087ba45efac9f00794a248dfce75aadab846f6617d91620e
|
4
|
+
data.tar.gz: cc4d0d76f99b86c5494758311637bcb4610555afb58118e059833f62992ef492
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c785bb5d7b83a53db61c03ffff2b6a26c17659eb9f79868e4882c884d0e97339b8748d32778bd2e73bb5293b5dd3a9a9adfef22ff38ab9e0f2c1c660dc0dd09c
|
7
|
+
data.tar.gz: f042503d2a4d65f6f9ed4cce56e6ba94623ef6e57e73b306a690edce5d2276aa01a7e211d83a2d2aec096a85def0923e4c8da350eb417a37101217764c84c18e
|
data/lib/tangle/graph.rb
CHANGED
@@ -62,14 +62,10 @@ module Tangle
|
|
62
62
|
#
|
63
63
|
# Unless a selector is provided, the subgraph contains the entire graph.
|
64
64
|
#
|
65
|
-
def subgraph(included = nil)
|
66
|
-
included ||= vertices
|
65
|
+
def subgraph(included = nil, &selector)
|
67
66
|
result = clone
|
68
|
-
|
69
|
-
|
70
|
-
next unless block_given?
|
71
|
-
result.remove_vertex(vertex) unless yield(vertex)
|
72
|
-
end
|
67
|
+
result.select_vertices!(included) unless included.nil?
|
68
|
+
result.select_vertices!(&selector) if block_given?
|
73
69
|
result
|
74
70
|
end
|
75
71
|
|
@@ -77,5 +73,11 @@ module Tangle
|
|
77
73
|
"#<#{self.class}: #{vertices.count} vertices, #{edges.count} edges>"
|
78
74
|
end
|
79
75
|
alias inspect to_s
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def callback(receiver, method, *args)
|
80
|
+
receiver.send(method, *args) if receiver.respond_to?(method)
|
81
|
+
end
|
80
82
|
end
|
81
83
|
end
|
data/lib/tangle/graph_edges.rb
CHANGED
@@ -17,15 +17,16 @@ module Tangle
|
|
17
17
|
# add_edge(vtx1, vtx2, ...) => Edge
|
18
18
|
#
|
19
19
|
def add_edge(*vertices, **kvargs)
|
20
|
-
|
20
|
+
edge = self.class::Edge.new(*vertices, mixins: @mixins, **kvargs)
|
21
|
+
insert_edge(edge)
|
22
|
+
vertices.each { |vertex| callback(vertex, :edge_added, edge) }
|
23
|
+
edge
|
21
24
|
end
|
22
25
|
|
23
26
|
# Remove an edge from the graph
|
24
27
|
def remove_edge(edge)
|
25
|
-
edge
|
26
|
-
|
27
|
-
end
|
28
|
-
@edges.delete(edge)
|
28
|
+
delete_edge(edge)
|
29
|
+
edge.each_vertex { |vertex| callback(vertex, :edge_removed, edge) }
|
29
30
|
end
|
30
31
|
|
31
32
|
protected
|
@@ -34,10 +35,12 @@ module Tangle
|
|
34
35
|
#
|
35
36
|
def insert_edge(edge)
|
36
37
|
@edges << edge
|
37
|
-
edge.each_vertex
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
edge.each_vertex { |vertex| @vertices.fetch(vertex) << edge }
|
39
|
+
end
|
40
|
+
|
41
|
+
def delete_edge(edge)
|
42
|
+
edge.each_vertex { |vertex| @vertices.fetch(vertex).delete(edge) }
|
43
|
+
@edges.delete(edge)
|
41
44
|
end
|
42
45
|
|
43
46
|
private
|
@@ -18,12 +18,19 @@ module Tangle
|
|
18
18
|
@vertices.keys
|
19
19
|
end
|
20
20
|
|
21
|
+
# Select vertices in the graph
|
22
|
+
def select(&selector)
|
23
|
+
@vertices.each_key.select(&selector)
|
24
|
+
end
|
25
|
+
|
21
26
|
# Add a vertex into the graph
|
22
27
|
#
|
23
|
-
# If a name: is given,
|
28
|
+
# If a name: is given, or the vertex responds to :name,
|
29
|
+
# it will be registered by name in the graph
|
24
30
|
def add_vertex(vertex, name: nil)
|
25
|
-
|
26
|
-
|
31
|
+
name ||= callback(vertex, :name)
|
32
|
+
insert_vertex(vertex, name)
|
33
|
+
callback(vertex, :added_to_graph, self)
|
27
34
|
self
|
28
35
|
end
|
29
36
|
alias << add_vertex
|
@@ -33,7 +40,31 @@ module Tangle
|
|
33
40
|
@vertices[vertex].each do |edge|
|
34
41
|
remove_edge(edge) if edge.include?(vertex)
|
35
42
|
end
|
43
|
+
delete_vertex(vertex)
|
44
|
+
callback(vertex, :removed_from_graph, self)
|
45
|
+
end
|
46
|
+
|
47
|
+
protected
|
48
|
+
|
49
|
+
def select_vertices!(selected = nil)
|
50
|
+
vertices.each do |vertex|
|
51
|
+
delete_vertex(vertex) if block_given? && !yield(vertex)
|
52
|
+
next if selected.nil?
|
53
|
+
delete_vertex(vertex) unless selected.any? { |vtx| vtx.eql?(vertex) }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def insert_vertex(vertex, name = nil)
|
58
|
+
@vertices[vertex] = Set[]
|
59
|
+
@vertices_by_name[name] = vertex unless name.nil?
|
60
|
+
end
|
61
|
+
|
62
|
+
def delete_vertex(vertex)
|
63
|
+
@vertices[vertex].each do |edge|
|
64
|
+
delete_edge(edge) if edge.include?(vertex)
|
65
|
+
end
|
36
66
|
@vertices.delete(vertex)
|
67
|
+
@vertices_by_name.delete_if { |_, vtx| vtx.eql?(vertex) }
|
37
68
|
end
|
38
69
|
|
39
70
|
private
|
@@ -7,17 +7,23 @@ module Tangle
|
|
7
7
|
# options are:
|
8
8
|
# root: root directory for the structure (mandatory)
|
9
9
|
# loaders: list of object loader lambdas (mandatory)
|
10
|
+
# ->(graph, **) { ... } => finished?
|
10
11
|
# follow_links: bool for following symlinks to directories
|
11
12
|
# (default false)
|
12
13
|
#
|
13
|
-
# A loader lambda
|
14
|
-
#
|
14
|
+
# A loader lambda is called with the graph as only positional
|
15
|
+
# argument, and a number of keyword arguments:
|
15
16
|
#
|
16
|
-
#
|
17
|
+
# path: Path of current filesystem object
|
18
|
+
# parent: Path of filesystem parent object
|
19
|
+
# lstat: File.lstat for path
|
20
|
+
# stat: File.stat for path, if lstat.symlink?
|
21
|
+
#
|
22
|
+
# The lambdas are called in order until one returns true.
|
17
23
|
#
|
18
24
|
# Example:
|
19
|
-
# loader = lambda do |g, path
|
20
|
-
# vertex =
|
25
|
+
# loader = lambda do |g, path:, parent:, lstat:, **|
|
26
|
+
# vertex = kwargs[:lstat]
|
21
27
|
# g.add_vertex(vertex, name: path)
|
22
28
|
# g.add_edge(g[parent], vertex) unless parent.nil?
|
23
29
|
# end
|
@@ -38,17 +44,28 @@ module Tangle
|
|
38
44
|
end
|
39
45
|
|
40
46
|
def load_directory_graph(path, parent = nil)
|
41
|
-
|
42
|
-
loader.to_proc.call(self, path, parent)
|
43
|
-
end
|
44
|
-
|
45
|
-
return if File.symlink?(path) && !@follow_directory_links
|
46
|
-
return unless File.directory?(path)
|
47
|
+
return unless load_directory_object(path, parent)
|
47
48
|
|
48
49
|
Dir.each_child(path) do |file|
|
49
50
|
load_directory_graph(File.join(path, file), path)
|
50
51
|
end
|
51
52
|
end
|
53
|
+
|
54
|
+
# Load a filesystem object into the graph, returning
|
55
|
+
# +true+ if the object was a directory (or link to one,
|
56
|
+
# and we're following links).
|
57
|
+
def load_directory_object(path, parent = nil)
|
58
|
+
stat = lstat = File.lstat(path)
|
59
|
+
stat = File.stat(path) if lstat.symlink?
|
60
|
+
|
61
|
+
@directory_loaders.any? do |loader|
|
62
|
+
loader.to_proc.call(self, path: path, parent: parent,
|
63
|
+
lstat: lstat, stat: stat)
|
64
|
+
end
|
65
|
+
|
66
|
+
return if lstat.symlink? && !@follow_directory_links
|
67
|
+
stat.directory?
|
68
|
+
end
|
52
69
|
end
|
53
70
|
end
|
54
71
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tangle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Calle Englund
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-05-
|
11
|
+
date: 2018-05-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: git-version-bump
|