build-dependency 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/.rspec +5 -0
- data/.travis.yml +19 -0
- data/Gemfile +14 -0
- data/Guardfile +9 -0
- data/README.md +73 -0
- data/Rakefile +8 -0
- data/build-dependency.gemspec +23 -0
- data/full.svg +123 -0
- data/lib/build/dependency.rb +26 -0
- data/lib/build/dependency/chain.rb +234 -0
- data/lib/build/dependency/partial_chain.rb +95 -0
- data/lib/build/dependency/unit.rb +135 -0
- data/lib/build/dependency/version.rb +25 -0
- data/lib/build/dependency/visualization.rb +151 -0
- data/partial.svg +93 -0
- data/spec/build/dependency/chain_spec.rb +202 -0
- data/spec/build/dependency/partial_chain_spec.rb +116 -0
- data/spec/build/dependency/visualization_spec.rb +31 -0
- data/spec/spec_helper.rb +97 -0
- data/visualization.svg +147 -0
- metadata +125 -0
@@ -0,0 +1,95 @@
|
|
1
|
+
# Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require_relative 'chain'
|
22
|
+
|
23
|
+
module Build
|
24
|
+
module Dependency
|
25
|
+
class Chain
|
26
|
+
def partial(provider)
|
27
|
+
PartialChain.expand(self, provider.dependencies)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class PartialChain < Resolver
|
32
|
+
# An `UnresolvedDependencyError` will be thrown if there are any unresolved dependencies.
|
33
|
+
def self.expand(*args)
|
34
|
+
chain = self.new(*args)
|
35
|
+
|
36
|
+
chain.freeze
|
37
|
+
|
38
|
+
return chain
|
39
|
+
end
|
40
|
+
|
41
|
+
def initialize(chain, dependencies)
|
42
|
+
super()
|
43
|
+
|
44
|
+
@chain = chain
|
45
|
+
|
46
|
+
# The list of dependencies that needs to be satisfied:
|
47
|
+
@dependencies = dependencies.collect{|dependency| Depends[dependency]}
|
48
|
+
|
49
|
+
expand_top
|
50
|
+
end
|
51
|
+
|
52
|
+
def selection
|
53
|
+
@chain.selection
|
54
|
+
end
|
55
|
+
|
56
|
+
attr :dependencies
|
57
|
+
|
58
|
+
def providers
|
59
|
+
@chain.providers
|
60
|
+
end
|
61
|
+
|
62
|
+
def freeze
|
63
|
+
return unless frozen?
|
64
|
+
|
65
|
+
@chain.freeze
|
66
|
+
@dependencies.freeze
|
67
|
+
|
68
|
+
super
|
69
|
+
end
|
70
|
+
|
71
|
+
protected
|
72
|
+
|
73
|
+
def expand_top
|
74
|
+
expand_nested(@dependencies, TOP)
|
75
|
+
end
|
76
|
+
|
77
|
+
def expand(dependency, parent)
|
78
|
+
unless @dependencies.include?(dependency)
|
79
|
+
return if dependency.private?
|
80
|
+
end
|
81
|
+
|
82
|
+
super(dependency, parent)
|
83
|
+
end
|
84
|
+
|
85
|
+
def find_provider(dependency, parent)
|
86
|
+
@chain.resolved[dependency]
|
87
|
+
end
|
88
|
+
|
89
|
+
def provision_for(provider, dependency)
|
90
|
+
# @chain.resolved[provider] does work, but it points to the most recently added provision, but we want the provision related to the specific dependency.
|
91
|
+
provider.provision_for(dependency)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require 'set'
|
22
|
+
|
23
|
+
module Build
|
24
|
+
module Dependency
|
25
|
+
def self.included(klass)
|
26
|
+
klass.include(Unit)
|
27
|
+
end
|
28
|
+
|
29
|
+
# A provision is a thing which satisfies a dependency.
|
30
|
+
Provision = Struct.new(:name, :provider, :value) do
|
31
|
+
def alias?
|
32
|
+
false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
Alias = Struct.new(:name, :provider, :dependencies) do
|
37
|
+
def alias?
|
38
|
+
true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
Resolution = Struct.new(:provider, :dependency) do
|
43
|
+
def name
|
44
|
+
dependency.name
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
Depends = Struct.new(:name) do
|
49
|
+
def initialize(name, **options)
|
50
|
+
super(name)
|
51
|
+
|
52
|
+
@options = options
|
53
|
+
end
|
54
|
+
|
55
|
+
attr :options
|
56
|
+
|
57
|
+
def private?
|
58
|
+
@options[:private]
|
59
|
+
end
|
60
|
+
|
61
|
+
def alias?
|
62
|
+
name.is_a?(Symbol)
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.[] name_or_dependency
|
66
|
+
name_or_dependency.is_a?(self) ? name_or_dependency : self.new(name_or_dependency)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
module Unit
|
71
|
+
def freeze
|
72
|
+
return unless frozen?
|
73
|
+
|
74
|
+
provisions.freeze
|
75
|
+
dependencies.freeze
|
76
|
+
|
77
|
+
super
|
78
|
+
end
|
79
|
+
|
80
|
+
# Assign a priority to this unit.
|
81
|
+
def priority= value
|
82
|
+
@priority = value
|
83
|
+
end
|
84
|
+
|
85
|
+
# The units default priority
|
86
|
+
def priority
|
87
|
+
@priority ||= 0
|
88
|
+
end
|
89
|
+
|
90
|
+
# @return Hash<String, Provision> a table of named provisions.
|
91
|
+
def provisions
|
92
|
+
@provisions ||= {}
|
93
|
+
end
|
94
|
+
|
95
|
+
# @return Set<Dependency>
|
96
|
+
def dependencies
|
97
|
+
@dependencies ||= Set.new
|
98
|
+
end
|
99
|
+
|
100
|
+
# Does this unit provide the named thing?
|
101
|
+
def provides?(dependency)
|
102
|
+
provisions.key?(dependency.name)
|
103
|
+
end
|
104
|
+
|
105
|
+
def provision_for(dependency)
|
106
|
+
provisions[dependency.name]
|
107
|
+
end
|
108
|
+
|
109
|
+
# Mark this unit as providing the named thing, with an optional block.
|
110
|
+
def provides(name_or_aliases, &block)
|
111
|
+
if String === name_or_aliases || Symbol === name_or_aliases
|
112
|
+
name = name_or_aliases
|
113
|
+
|
114
|
+
provisions[name] = Provision.new(name, self, block)
|
115
|
+
else
|
116
|
+
aliases = name_or_aliases
|
117
|
+
|
118
|
+
aliases.each do |name, dependencies|
|
119
|
+
provisions[name] = Alias.new(name, self, Array(dependencies))
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def depends(*names, **options)
|
125
|
+
names.each do |name|
|
126
|
+
dependencies << Depends.new(name, **options)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def depends?(name)
|
131
|
+
dependencies.include?(name)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
module Build
|
22
|
+
module Dependency
|
23
|
+
VERSION = "1.0.0"
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
# Copyright, 20127, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require 'graphviz'
|
22
|
+
|
23
|
+
module Build
|
24
|
+
module Dependency
|
25
|
+
class Visualization
|
26
|
+
def initialize
|
27
|
+
@base_attributes = {
|
28
|
+
:shape => 'box',
|
29
|
+
:style => 'filled',
|
30
|
+
:fillcolor => 'white',
|
31
|
+
:fontname => 'Monaco',
|
32
|
+
}
|
33
|
+
|
34
|
+
@provision_attributes = @base_attributes.dup
|
35
|
+
|
36
|
+
@alias_attributes = @base_attributes.merge(
|
37
|
+
:fillcolor => 'lightgrey',
|
38
|
+
)
|
39
|
+
|
40
|
+
@dependency_attributes = @base_attributes.merge(
|
41
|
+
:fillcolor => 'orange',
|
42
|
+
)
|
43
|
+
|
44
|
+
@selection_attributes = {
|
45
|
+
:fillcolor => 'lightbrown',
|
46
|
+
}
|
47
|
+
|
48
|
+
@private_edge_attributes = {
|
49
|
+
:arrowhead => 'empty',
|
50
|
+
:color => '#0000005f'
|
51
|
+
}
|
52
|
+
|
53
|
+
@provider_attributes = {
|
54
|
+
:fillcolor => 'lightblue',
|
55
|
+
}
|
56
|
+
|
57
|
+
@provider_edge_attributes = {
|
58
|
+
:arrowhead => 'none',
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
attr :base_attributes
|
63
|
+
attr :provision_attributes
|
64
|
+
|
65
|
+
attr :provider_attributes
|
66
|
+
attr :provider_edge_attributes
|
67
|
+
|
68
|
+
attr :alias_attributes
|
69
|
+
|
70
|
+
attr :dependency_attributes
|
71
|
+
attr :selection_attributes
|
72
|
+
attr :private_edge_attributes
|
73
|
+
|
74
|
+
def generate(chain)
|
75
|
+
graph = Graphviz::Graph.new
|
76
|
+
graph.attributes[:ratio] = :auto
|
77
|
+
|
78
|
+
chain.ordered.each do |resolution|
|
79
|
+
provider = resolution.provider
|
80
|
+
name = provider.name
|
81
|
+
|
82
|
+
# Provider is the dependency that provides the dependency referred to by name.
|
83
|
+
node = graph.add_node(name.to_s, @base_attributes.dup)
|
84
|
+
|
85
|
+
if chain.dependencies.include?(resolution.dependency)
|
86
|
+
node.attributes.update(@dependency_attributes)
|
87
|
+
elsif chain.selection.include?(provider.name)
|
88
|
+
node.attributes.update(@selection_attributes)
|
89
|
+
end
|
90
|
+
|
91
|
+
# A provision has dependencies...
|
92
|
+
provider.dependencies.each do |dependency|
|
93
|
+
if dependency_node = graph.nodes[dependency.name.to_s]
|
94
|
+
edge = node.connect(dependency_node)
|
95
|
+
|
96
|
+
if dependency.private?
|
97
|
+
edge.attributes.update(@private_edge_attributes)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# A provision provides other provisions...
|
103
|
+
provider.provisions.each do |provision_name, provision|
|
104
|
+
next if name == provision_name
|
105
|
+
|
106
|
+
provides_node = graph.nodes[provision_name.to_s] || graph.add_node(provision_name.to_s, @provision_attributes)
|
107
|
+
|
108
|
+
if provision.alias?
|
109
|
+
provides_node.attributes = @alias_attributes
|
110
|
+
end
|
111
|
+
|
112
|
+
node.attributes.update(@provider_attributes)
|
113
|
+
|
114
|
+
unless provides_node.connected?(node)
|
115
|
+
edge = provides_node.connect(node)
|
116
|
+
|
117
|
+
edge.attributes.update(@provider_edge_attributes)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
chain.provisions.each do |provision|
|
123
|
+
node = graph.nodes[provision.name.to_s]
|
124
|
+
|
125
|
+
node.attributes.update(penwidth: 2.0)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Put all dependencies at the same level so as to not make the graph too confusingraph.
|
129
|
+
done = Set.new
|
130
|
+
chain.ordered.each do |resolution|
|
131
|
+
provider = resolution.provider
|
132
|
+
name = "subgraph-#{provider.name}"
|
133
|
+
|
134
|
+
subgraph = graph.nodes[name] || graph.add_subgraph(name, :rank => :same)
|
135
|
+
|
136
|
+
provider.dependencies.each do |dependency|
|
137
|
+
next if done.include? dependency
|
138
|
+
|
139
|
+
done << dependency
|
140
|
+
|
141
|
+
if dependency_node = graph.nodes[dependency.name.to_s]
|
142
|
+
subgraph.add_node(dependency_node.name)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
return graph
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
data/partial.svg
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
3
|
+
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
4
|
+
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
|
5
|
+
-->
|
6
|
+
<!-- Title: G Pages: 1 -->
|
7
|
+
<svg width="465pt" height="332pt"
|
8
|
+
viewBox="0.00 0.00 465.00 332.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
9
|
+
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 328)">
|
10
|
+
<title>G</title>
|
11
|
+
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-328 461,-328 461,4 -4,4"/>
|
12
|
+
<!-- Variant/debug -->
|
13
|
+
<g id="node1" class="node">
|
14
|
+
<title>Variant/debug</title>
|
15
|
+
<polygon fill="#add8e6" stroke="#000000" stroke-width="2" points="130,-36 4,-36 4,0 130,0 130,-36"/>
|
16
|
+
<text text-anchor="middle" x="67" y="-14.3" font-family="Monaco" font-size="14.00" fill="#000000">Variant/debug</text>
|
17
|
+
</g>
|
18
|
+
<!-- variant -->
|
19
|
+
<g id="node2" class="node">
|
20
|
+
<title>variant</title>
|
21
|
+
<polygon fill="#d3d3d3" stroke="#000000" points="104.5,-108 29.5,-108 29.5,-72 104.5,-72 104.5,-108"/>
|
22
|
+
<text text-anchor="middle" x="67" y="-86.3" font-family="Monaco" font-size="14.00" fill="#000000">variant</text>
|
23
|
+
</g>
|
24
|
+
<!-- variant->Variant/debug -->
|
25
|
+
<g id="edge1" class="edge">
|
26
|
+
<title>variant->Variant/debug</title>
|
27
|
+
<path fill="none" stroke="#000000" d="M67,-71.8314C67,-61 67,-47.2876 67,-36.4133"/>
|
28
|
+
</g>
|
29
|
+
<!-- Platform/linux -->
|
30
|
+
<g id="node3" class="node">
|
31
|
+
<title>Platform/linux</title>
|
32
|
+
<polygon fill="#add8e6" stroke="#000000" stroke-width="2" points="134,-180 0,-180 0,-144 134,-144 134,-180"/>
|
33
|
+
<text text-anchor="middle" x="67" y="-158.3" font-family="Monaco" font-size="14.00" fill="#000000">Platform/linux</text>
|
34
|
+
</g>
|
35
|
+
<!-- Platform/linux->variant -->
|
36
|
+
<g id="edge2" class="edge">
|
37
|
+
<title>Platform/linux->variant</title>
|
38
|
+
<path fill="none" stroke="#000000" d="M67,-143.8314C67,-136.131 67,-126.9743 67,-118.4166"/>
|
39
|
+
<polygon fill="#000000" stroke="#000000" points="70.5001,-118.4132 67,-108.4133 63.5001,-118.4133 70.5001,-118.4132"/>
|
40
|
+
</g>
|
41
|
+
<!-- platform -->
|
42
|
+
<g id="node4" class="node">
|
43
|
+
<title>platform</title>
|
44
|
+
<polygon fill="#d3d3d3" stroke="#000000" points="109,-252 25,-252 25,-216 109,-216 109,-252"/>
|
45
|
+
<text text-anchor="middle" x="67" y="-230.3" font-family="Monaco" font-size="14.00" fill="#000000">platform</text>
|
46
|
+
</g>
|
47
|
+
<!-- platform->Platform/linux -->
|
48
|
+
<g id="edge3" class="edge">
|
49
|
+
<title>platform->Platform/linux</title>
|
50
|
+
<path fill="none" stroke="#000000" d="M67,-215.8314C67,-205 67,-191.2876 67,-180.4133"/>
|
51
|
+
</g>
|
52
|
+
<!-- lib -->
|
53
|
+
<g id="node5" class="node">
|
54
|
+
<title>lib</title>
|
55
|
+
<polygon fill="#ffa500" stroke="#000000" stroke-width="2" points="94,-324 40,-324 40,-288 94,-288 94,-324"/>
|
56
|
+
<text text-anchor="middle" x="67" y="-302.3" font-family="Monaco" font-size="14.00" fill="#000000">lib</text>
|
57
|
+
</g>
|
58
|
+
<!-- lib->platform -->
|
59
|
+
<g id="edge4" class="edge">
|
60
|
+
<title>lib->platform</title>
|
61
|
+
<path fill="none" stroke="#000000" stroke-opacity="0.372549" d="M67,-287.8314C67,-280.131 67,-270.9743 67,-262.4166"/>
|
62
|
+
<polygon fill="none" stroke="#000000" stroke-opacity="0.372549" points="70.5001,-262.4132 67,-252.4133 63.5001,-262.4133 70.5001,-262.4132"/>
|
63
|
+
</g>
|
64
|
+
<!-- Compiler/clang -->
|
65
|
+
<g id="node6" class="node">
|
66
|
+
<title>Compiler/clang</title>
|
67
|
+
<polygon fill="#add8e6" stroke="#000000" points="349,-180 215,-180 215,-144 349,-144 349,-180"/>
|
68
|
+
<text text-anchor="middle" x="282" y="-158.3" font-family="Monaco" font-size="14.00" fill="#000000">Compiler/clang</text>
|
69
|
+
</g>
|
70
|
+
<!-- Language/C++14 -->
|
71
|
+
<g id="node7" class="node">
|
72
|
+
<title>Language/C++14</title>
|
73
|
+
<polygon fill="#ffffff" stroke="#000000" stroke-width="2" points="305,-252 171,-252 171,-216 305,-216 305,-252"/>
|
74
|
+
<text text-anchor="middle" x="238" y="-230.3" font-family="Monaco" font-size="14.00" fill="#000000">Language/C++14</text>
|
75
|
+
</g>
|
76
|
+
<!-- Language/C++14->Compiler/clang -->
|
77
|
+
<g id="edge5" class="edge">
|
78
|
+
<title>Language/C++14->Compiler/clang</title>
|
79
|
+
<path fill="none" stroke="#000000" d="M249.1031,-215.8314C255.7222,-205 264.102,-191.2876 270.7474,-180.4133"/>
|
80
|
+
</g>
|
81
|
+
<!-- Language/C++17 -->
|
82
|
+
<g id="node8" class="node">
|
83
|
+
<title>Language/C++17</title>
|
84
|
+
<polygon fill="#ffffff" stroke="#000000" points="457,-252 323,-252 323,-216 457,-216 457,-252"/>
|
85
|
+
<text text-anchor="middle" x="390" y="-230.3" font-family="Monaco" font-size="14.00" fill="#000000">Language/C++17</text>
|
86
|
+
</g>
|
87
|
+
<!-- Language/C++17->Compiler/clang -->
|
88
|
+
<g id="edge6" class="edge">
|
89
|
+
<title>Language/C++17->Compiler/clang</title>
|
90
|
+
<path fill="none" stroke="#000000" d="M362.747,-215.8314C346.3751,-204.9167 325.6147,-191.0764 309.2442,-180.1628"/>
|
91
|
+
</g>
|
92
|
+
</g>
|
93
|
+
</svg>
|