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,202 @@
|
|
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
|
+
RSpec.describe Build::Dependency do
|
22
|
+
describe "valid dependency resolution" do
|
23
|
+
let(:a) do
|
24
|
+
Package.new.tap do |package|
|
25
|
+
package.provides 'apple' do
|
26
|
+
fruit ['apple']
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
let(:b) do
|
32
|
+
Package.new.tap do |package|
|
33
|
+
package.provides 'orange' do
|
34
|
+
fruit ['orange']
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
let(:c) do
|
40
|
+
Package.new.tap do |package|
|
41
|
+
package.provides 'fruit-juice' do
|
42
|
+
juice ['ice', 'cold']
|
43
|
+
end
|
44
|
+
|
45
|
+
package.depends 'apple'
|
46
|
+
package.depends 'orange'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should resolve direct dependency chain" do
|
51
|
+
chain = Build::Dependency::Chain.expand(['fruit-juice'], [a, b, c])
|
52
|
+
expect(chain.ordered.collect(&:first)).to be == [a, b, c]
|
53
|
+
expect(chain.unresolved).to be == []
|
54
|
+
end
|
55
|
+
|
56
|
+
let(:d) do
|
57
|
+
Package.new.tap do |package|
|
58
|
+
package.provides 'pie'
|
59
|
+
package.depends 'apple'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it "shouldn't include unrelated units" do
|
64
|
+
chain = Build::Dependency::Chain.expand(['pie'], [a, b, c, d])
|
65
|
+
|
66
|
+
expect(chain.unresolved).to be == []
|
67
|
+
expect(chain.ordered.collect(&:first)).to be == [a, d]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "incomplete dependency resolution" do
|
72
|
+
it "should report conflicts" do
|
73
|
+
apple = Package.new('apple')
|
74
|
+
apple.provides 'apple'
|
75
|
+
apple.provides 'fruit'
|
76
|
+
|
77
|
+
bananna = Package.new('bananna')
|
78
|
+
bananna.provides 'fruit'
|
79
|
+
|
80
|
+
salad = Package.new('salad')
|
81
|
+
salad.depends 'fruit'
|
82
|
+
salad.provides 'salad'
|
83
|
+
|
84
|
+
chain = Build::Dependency::Chain.new(['salad'], [apple, bananna, salad])
|
85
|
+
expect(chain.unresolved.first).to be == [Build::Dependency::Depends.new("fruit"), salad]
|
86
|
+
expect(chain.conflicts).to be == {Build::Dependency::Depends.new("fruit") => [apple, bananna]}
|
87
|
+
|
88
|
+
chain = Build::Dependency::Chain.new(['salad'], [apple, bananna, salad], ['apple'])
|
89
|
+
expect(chain.unresolved).to be == []
|
90
|
+
expect(chain.conflicts).to be == {}
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "multiple provisions" do
|
95
|
+
let(:fruit) do
|
96
|
+
Package.new('fruit').tap do |package|
|
97
|
+
package.provides 'apple' do
|
98
|
+
end
|
99
|
+
|
100
|
+
package.provides 'orange' do
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
let(:salad) do
|
106
|
+
Package.new('salad').tap do |package|
|
107
|
+
package.depends 'apple'
|
108
|
+
package.depends 'orange'
|
109
|
+
package.provides 'salad'
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
let(:lunch) do
|
114
|
+
Package.new('lunch').tap do |package|
|
115
|
+
package.depends 'apple'
|
116
|
+
package.depends 'salad'
|
117
|
+
package.provides 'lunch'
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
let(:chain) {Build::Dependency::Chain.new(['lunch'], [fruit, salad, lunch])}
|
122
|
+
|
123
|
+
it "should include both provisions" do
|
124
|
+
expect(chain.provisions.count).to be == 4
|
125
|
+
expect(chain.provisions.collect(&:name)).to be == ['apple', 'orange', 'salad', 'lunch']
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should include both provisions in partial chain" do
|
129
|
+
partial_chain = chain.partial(lunch)
|
130
|
+
expect(partial_chain.provisions.count).to be == 3
|
131
|
+
expect(partial_chain.provisions.collect(&:name)).to be == ['apple', 'orange', 'salad']
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should resolve aliases" do
|
136
|
+
apple = Package.new('apple')
|
137
|
+
apple.provides 'apple'
|
138
|
+
apple.provides :fruit => 'apple'
|
139
|
+
|
140
|
+
bananna = Package.new('bananna')
|
141
|
+
bananna.provides 'bananna'
|
142
|
+
bananna.provides :fruit => 'bananna'
|
143
|
+
|
144
|
+
salad = Package.new('salad')
|
145
|
+
salad.depends :fruit
|
146
|
+
salad.provides 'salad'
|
147
|
+
|
148
|
+
chain = Build::Dependency::Chain.expand(['salad'], [apple, bananna, salad], ['apple'])
|
149
|
+
expect(chain.unresolved).to be == []
|
150
|
+
expect(chain.conflicts).to be == {}
|
151
|
+
|
152
|
+
expect(chain.ordered.size).to be == 2
|
153
|
+
expect(chain.ordered[0]).to be == Build::Dependency::Resolution.new(apple, Build::Dependency::Depends.new("apple"))
|
154
|
+
expect(chain.ordered[1]).to be == Build::Dependency::Resolution.new(salad, Build::Dependency::Depends.new("salad"))
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should select dependencies with high priority" do
|
158
|
+
bad_apple = Package.new('bad_apple')
|
159
|
+
bad_apple.provides 'apple'
|
160
|
+
bad_apple.priority = 20
|
161
|
+
|
162
|
+
good_apple = Package.new('good_apple')
|
163
|
+
good_apple.provides 'apple'
|
164
|
+
good_apple.priority = 40
|
165
|
+
|
166
|
+
chain = Build::Dependency::Chain.expand(['apple'], [bad_apple, good_apple])
|
167
|
+
|
168
|
+
expect(chain.unresolved).to be == []
|
169
|
+
expect(chain.conflicts).to be == {}
|
170
|
+
|
171
|
+
# Should select higher priority package by default:
|
172
|
+
expect(chain.ordered).to be == [Build::Dependency::Resolution.new(good_apple, Build::Dependency::Depends.new('apple'))]
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should expose direct dependencies" do
|
176
|
+
system = Package.new('linux')
|
177
|
+
system.provides 'linux'
|
178
|
+
system.provides 'clang'
|
179
|
+
system.provides system: 'linux'
|
180
|
+
system.provides compiler: 'clang'
|
181
|
+
|
182
|
+
library = Package.new('library')
|
183
|
+
library.provides 'library'
|
184
|
+
library.depends :system
|
185
|
+
library.depends :compiler
|
186
|
+
|
187
|
+
application = Package.new('application')
|
188
|
+
application.provides 'application'
|
189
|
+
application.depends :compiler
|
190
|
+
application.depends 'library'
|
191
|
+
|
192
|
+
chain = Build::Dependency::Chain.expand(['application'], [system, library, application])
|
193
|
+
|
194
|
+
expect(chain.unresolved).to be == []
|
195
|
+
expect(chain.conflicts).to be == {}
|
196
|
+
expect(chain.ordered).to be == [
|
197
|
+
Build::Dependency::Resolution.new(system, Build::Dependency::Depends.new('clang')),
|
198
|
+
Build::Dependency::Resolution.new(library, Build::Dependency::Depends.new('library')),
|
199
|
+
Build::Dependency::Resolution.new(application, Build::Dependency::Depends.new('application')),
|
200
|
+
]
|
201
|
+
end
|
202
|
+
end
|
@@ -0,0 +1,116 @@
|
|
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
|
+
RSpec.describe Build::Dependency::PartialChain do
|
22
|
+
describe "app chain" do
|
23
|
+
include_context "app packages"
|
24
|
+
|
25
|
+
let(:chain) {Build::Dependency::Chain.expand(['app', 'lib'], packages)}
|
26
|
+
|
27
|
+
it "should generate full list of ordered providers" do
|
28
|
+
expect(chain.ordered).to be == [
|
29
|
+
Build::Dependency::Resolution.new(variant, Build::Dependency::Depends.new('Variant/debug')),
|
30
|
+
Build::Dependency::Resolution.new(platform, Build::Dependency::Depends.new('Platform/linux')),
|
31
|
+
Build::Dependency::Resolution.new(compiler, Build::Dependency::Depends.new("Language/C++17")),
|
32
|
+
Build::Dependency::Resolution.new(lib, Build::Dependency::Depends.new('lib')),
|
33
|
+
Build::Dependency::Resolution.new(app, Build::Dependency::Depends.new('app')),
|
34
|
+
]
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should generate a full list of provisions" do
|
38
|
+
expect(chain.provisions).to be == [
|
39
|
+
variant.provision_for(Build::Dependency::Depends['Variant/debug']),
|
40
|
+
platform.provision_for(Build::Dependency::Depends['Platform/linux']),
|
41
|
+
compiler.provision_for(Build::Dependency::Depends['Language/C++17']),
|
42
|
+
lib.provision_for(Build::Dependency::Depends.new('lib')),
|
43
|
+
compiler.provision_for(Build::Dependency::Depends['Language/C++14']),
|
44
|
+
app.provision_for(Build::Dependency::Depends.new('app')),
|
45
|
+
]
|
46
|
+
|
47
|
+
graph = visualization.generate(chain)
|
48
|
+
|
49
|
+
Graphviz::output(graph, path: "full.svg")
|
50
|
+
end
|
51
|
+
|
52
|
+
subject {described_class.new(chain, app.dependencies)}
|
53
|
+
|
54
|
+
it "should select app packages" do
|
55
|
+
expect(subject.ordered).to be == [
|
56
|
+
Build::Dependency::Resolution.new(variant, Build::Dependency::Depends.new('Variant/debug')),
|
57
|
+
Build::Dependency::Resolution.new(platform, Build::Dependency::Depends.new('Platform/linux')),
|
58
|
+
Build::Dependency::Resolution.new(lib, Build::Dependency::Depends.new('lib')),
|
59
|
+
Build::Dependency::Resolution.new(compiler, Build::Dependency::Depends.new("Language/C++14")),
|
60
|
+
]
|
61
|
+
|
62
|
+
graph = visualization.generate(subject)
|
63
|
+
|
64
|
+
Graphviz::output(graph, path: "partial.svg")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "private dependencies" do
|
69
|
+
let(:a) do
|
70
|
+
Package.new('a').tap do |package|
|
71
|
+
package.provides 'a'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
let(:b) do
|
76
|
+
Package.new('b').tap do |package|
|
77
|
+
package.provides 'b'
|
78
|
+
package.depends 'a', private: true
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
let(:c) do
|
83
|
+
Package.new('c').tap do |package|
|
84
|
+
package.provides 'c'
|
85
|
+
package.depends 'b'
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
let(:d) do
|
90
|
+
Package.new('d').tap do |package|
|
91
|
+
package.provides 'd'
|
92
|
+
package.depends 'c'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
let(:chain) {Build::Dependency::Chain.expand(['d'], [a, b, c, d])}
|
97
|
+
|
98
|
+
it "should include direct private dependencies" do
|
99
|
+
partial_chain = chain.partial(b)
|
100
|
+
|
101
|
+
expect(partial_chain.ordered.collect(&:first)).to be == [a]
|
102
|
+
end
|
103
|
+
|
104
|
+
it "shouldn't include nested private dependencies" do
|
105
|
+
partial_chain = chain.partial(c)
|
106
|
+
|
107
|
+
expect(partial_chain.ordered.collect(&:first)).to be == [b]
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should follow non-private dependencies" do
|
111
|
+
partial_chain = chain.partial(d)
|
112
|
+
|
113
|
+
expect(partial_chain.ordered.collect(&:first)).to be == [b, c]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,31 @@
|
|
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
|
+
RSpec.describe Build::Dependency::Visualization do
|
22
|
+
include_context "app packages"
|
23
|
+
|
24
|
+
it "should visualize dependency chain" do
|
25
|
+
chain = Build::Dependency::Chain.expand(['app', 'tests'], packages)
|
26
|
+
|
27
|
+
graph = subject.generate(chain)
|
28
|
+
|
29
|
+
Graphviz::output(graph, path: "visualization.svg")
|
30
|
+
end
|
31
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
|
2
|
+
if ENV['COVERAGE']
|
3
|
+
begin
|
4
|
+
require 'simplecov'
|
5
|
+
|
6
|
+
SimpleCov.start do
|
7
|
+
add_filter "/spec/"
|
8
|
+
end
|
9
|
+
|
10
|
+
if ENV['TRAVIS']
|
11
|
+
require 'coveralls'
|
12
|
+
Coveralls.wear!
|
13
|
+
end
|
14
|
+
rescue LoadError
|
15
|
+
warn "Could not load simplecov: #{$!}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
require "bundler/setup"
|
20
|
+
require "build/dependency"
|
21
|
+
|
22
|
+
class Package
|
23
|
+
include Build::Dependency
|
24
|
+
|
25
|
+
def initialize(name = nil)
|
26
|
+
@name = name
|
27
|
+
end
|
28
|
+
|
29
|
+
attr :name
|
30
|
+
|
31
|
+
def inspect
|
32
|
+
"<Package:#{@name}>"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
RSpec.shared_context "app packages" do
|
37
|
+
let(:app) do
|
38
|
+
Package.new('app').tap do |package|
|
39
|
+
package.provides 'app'
|
40
|
+
package.depends 'lib', private: true
|
41
|
+
package.depends :platform, private: true
|
42
|
+
package.depends 'Language/C++14', private: true
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
let(:tests) do
|
47
|
+
Package.new('tests').tap do |package|
|
48
|
+
package.provides 'tests'
|
49
|
+
package.depends 'lib', private: true
|
50
|
+
package.depends :platform, private: true
|
51
|
+
package.depends 'Language/C++17', private: true
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
let(:lib) do
|
56
|
+
Package.new('lib').tap do |package|
|
57
|
+
package.provides 'lib'
|
58
|
+
package.depends :platform, private: true
|
59
|
+
package.depends 'Language/C++17', private: true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
let(:platform) do
|
64
|
+
Package.new('Platform/linux').tap do |package|
|
65
|
+
package.provides platform: 'Platform/linux'
|
66
|
+
package.provides 'Platform/linux'
|
67
|
+
package.depends :variant
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
let(:variant) do
|
72
|
+
Package.new('Variant/debug').tap do |package|
|
73
|
+
package.provides variant: 'Variant/debug'
|
74
|
+
package.provides 'Variant/debug'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
let(:compiler) do
|
79
|
+
Package.new('Compiler/clang').tap do |package|
|
80
|
+
package.provides 'Language/C++14'
|
81
|
+
package.provides 'Language/C++17'
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
let(:packages) {[app, tests, lib, platform, variant, compiler]}
|
86
|
+
|
87
|
+
let(:visualization) {Build::Dependency::Visualization.new}
|
88
|
+
end
|
89
|
+
|
90
|
+
RSpec.configure do |config|
|
91
|
+
# Enable flags like --only-failures and --next-failure
|
92
|
+
config.example_status_persistence_file_path = ".rspec_status"
|
93
|
+
|
94
|
+
config.expect_with :rspec do |c|
|
95
|
+
c.syntax = :expect
|
96
|
+
end
|
97
|
+
end
|
data/visualization.svg
ADDED
@@ -0,0 +1,147 @@
|
|
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="385pt" height="404pt"
|
8
|
+
viewBox="0.00 0.00 385.00 404.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 400)">
|
10
|
+
<title>G</title>
|
11
|
+
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-400 381,-400 381,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="282,-36 156,-36 156,0 282,0 282,-36"/>
|
16
|
+
<text text-anchor="middle" x="219" 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="256.5,-108 181.5,-108 181.5,-72 256.5,-72 256.5,-108"/>
|
22
|
+
<text text-anchor="middle" x="219" 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="M219,-71.8314C219,-61 219,-47.2876 219,-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="286,-180 152,-180 152,-144 286,-144 286,-180"/>
|
33
|
+
<text text-anchor="middle" x="219" 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="M219,-143.8314C219,-136.131 219,-126.9743 219,-118.4166"/>
|
39
|
+
<polygon fill="#000000" stroke="#000000" points="222.5001,-118.4132 219,-108.4133 215.5001,-118.4133 222.5001,-118.4132"/>
|
40
|
+
</g>
|
41
|
+
<!-- platform -->
|
42
|
+
<g id="node4" class="node">
|
43
|
+
<title>platform</title>
|
44
|
+
<polygon fill="#d3d3d3" stroke="#000000" points="225,-252 141,-252 141,-216 225,-216 225,-252"/>
|
45
|
+
<text text-anchor="middle" x="183" 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="M192.0843,-215.8314C197.5,-205 204.3562,-191.2876 209.7934,-180.4133"/>
|
51
|
+
</g>
|
52
|
+
<!-- Compiler/clang -->
|
53
|
+
<g id="node5" class="node">
|
54
|
+
<title>Compiler/clang</title>
|
55
|
+
<polygon fill="#add8e6" stroke="#000000" points="134,-180 0,-180 0,-144 134,-144 134,-180"/>
|
56
|
+
<text text-anchor="middle" x="67" y="-158.3" font-family="Monaco" font-size="14.00" fill="#000000">Compiler/clang</text>
|
57
|
+
</g>
|
58
|
+
<!-- Language/C++14 -->
|
59
|
+
<g id="node6" class="node">
|
60
|
+
<title>Language/C++14</title>
|
61
|
+
<polygon fill="#ffffff" stroke="#000000" stroke-width="2" points="134,-324 0,-324 0,-288 134,-288 134,-324"/>
|
62
|
+
<text text-anchor="middle" x="67" y="-302.3" font-family="Monaco" font-size="14.00" fill="#000000">Language/C++14</text>
|
63
|
+
</g>
|
64
|
+
<!-- Language/C++14->Compiler/clang -->
|
65
|
+
<g id="edge4" class="edge">
|
66
|
+
<title>Language/C++14->Compiler/clang</title>
|
67
|
+
<path fill="none" stroke="#000000" d="M67,-287.7623C67,-260.0633 67,-207.7005 67,-180.0896"/>
|
68
|
+
</g>
|
69
|
+
<!-- Language/C++17 -->
|
70
|
+
<g id="node7" class="node">
|
71
|
+
<title>Language/C++17</title>
|
72
|
+
<polygon fill="#ffffff" stroke="#000000" stroke-width="2" points="377,-252 243,-252 243,-216 377,-216 377,-252"/>
|
73
|
+
<text text-anchor="middle" x="310" y="-230.3" font-family="Monaco" font-size="14.00" fill="#000000">Language/C++17</text>
|
74
|
+
</g>
|
75
|
+
<!-- Language/C++17->Compiler/clang -->
|
76
|
+
<g id="edge5" class="edge">
|
77
|
+
<title>Language/C++17->Compiler/clang</title>
|
78
|
+
<path fill="none" stroke="#000000" d="M248.9945,-215.9243C212.0197,-204.9688 165.0099,-191.04 128.0306,-180.0831"/>
|
79
|
+
</g>
|
80
|
+
<!-- lib -->
|
81
|
+
<g id="node8" class="node">
|
82
|
+
<title>lib</title>
|
83
|
+
<polygon fill="#ffffff" stroke="#000000" stroke-width="2" points="282,-324 228,-324 228,-288 282,-288 282,-324"/>
|
84
|
+
<text text-anchor="middle" x="255" y="-302.3" font-family="Monaco" font-size="14.00" fill="#000000">lib</text>
|
85
|
+
</g>
|
86
|
+
<!-- lib->platform -->
|
87
|
+
<g id="edge6" class="edge">
|
88
|
+
<title>lib->platform</title>
|
89
|
+
<path fill="none" stroke="#000000" stroke-opacity="0.372549" d="M236.8314,-287.8314C228.2848,-279.2848 217.9443,-268.9443 208.6198,-259.6198"/>
|
90
|
+
<polygon fill="none" stroke="#000000" stroke-opacity="0.372549" points="210.9592,-257.0095 201.4133,-252.4133 206.0095,-261.9592 210.9592,-257.0095"/>
|
91
|
+
</g>
|
92
|
+
<!-- lib->Language/C++17 -->
|
93
|
+
<g id="edge7" class="edge">
|
94
|
+
<title>lib->Language/C++17</title>
|
95
|
+
<path fill="none" stroke="#000000" stroke-opacity="0.372549" d="M268.8788,-287.8314C275.2136,-279.5386 282.8384,-269.557 289.7926,-260.4533"/>
|
96
|
+
<polygon fill="none" stroke="#000000" stroke-opacity="0.372549" points="292.6452,-262.4847 295.9343,-252.4133 287.0825,-258.2353 292.6452,-262.4847"/>
|
97
|
+
</g>
|
98
|
+
<!-- app -->
|
99
|
+
<g id="node9" class="node">
|
100
|
+
<title>app</title>
|
101
|
+
<polygon fill="#ffa500" stroke="#000000" stroke-width="2" points="189,-396 135,-396 135,-360 189,-360 189,-396"/>
|
102
|
+
<text text-anchor="middle" x="162" y="-374.3" font-family="Monaco" font-size="14.00" fill="#000000">app</text>
|
103
|
+
</g>
|
104
|
+
<!-- app->platform -->
|
105
|
+
<g id="edge9" class="edge">
|
106
|
+
<title>app->platform</title>
|
107
|
+
<path fill="none" stroke="#000000" stroke-opacity="0.372549" d="M164.6597,-359.7623C168.2415,-335.201 174.6514,-291.2474 178.865,-262.3541"/>
|
108
|
+
<polygon fill="none" stroke="#000000" stroke-opacity="0.372549" points="182.3821,-262.4901 180.3619,-252.0896 175.4554,-261.4798 182.3821,-262.4901"/>
|
109
|
+
</g>
|
110
|
+
<!-- app->Language/C++14 -->
|
111
|
+
<g id="edge10" class="edge">
|
112
|
+
<title>app->Language/C++14</title>
|
113
|
+
<path fill="none" stroke="#000000" stroke-opacity="0.372549" d="M138.0275,-359.8314C126.2139,-350.8779 111.8028,-339.9558 99.0565,-330.2955"/>
|
114
|
+
<polygon fill="none" stroke="#000000" stroke-opacity="0.372549" points="101.0486,-327.4137 90.9648,-324.1628 96.8205,-332.9925 101.0486,-327.4137"/>
|
115
|
+
</g>
|
116
|
+
<!-- app->lib -->
|
117
|
+
<g id="edge8" class="edge">
|
118
|
+
<title>app->lib</title>
|
119
|
+
<path fill="none" stroke="#000000" stroke-opacity="0.372549" d="M185.4678,-359.8314C197.0327,-350.8779 211.1404,-339.9558 223.6183,-330.2955"/>
|
120
|
+
<polygon fill="none" stroke="#000000" stroke-opacity="0.372549" points="225.775,-333.0521 231.5397,-324.1628 221.4898,-327.5171 225.775,-333.0521"/>
|
121
|
+
</g>
|
122
|
+
<!-- tests -->
|
123
|
+
<g id="node10" class="node">
|
124
|
+
<title>tests</title>
|
125
|
+
<polygon fill="#ffa500" stroke="#000000" stroke-width="2" points="284.5,-396 225.5,-396 225.5,-360 284.5,-360 284.5,-396"/>
|
126
|
+
<text text-anchor="middle" x="255" y="-374.3" font-family="Monaco" font-size="14.00" fill="#000000">tests</text>
|
127
|
+
</g>
|
128
|
+
<!-- tests->platform -->
|
129
|
+
<g id="edge12" class="edge">
|
130
|
+
<title>tests->platform</title>
|
131
|
+
<path fill="none" stroke="#000000" stroke-opacity="0.372549" d="M241.3445,-359.5973C234.154,-349.4209 225.5044,-336.3651 219,-324 208.4065,-303.8615 198.9605,-279.8887 192.405,-261.7501"/>
|
132
|
+
<polygon fill="none" stroke="#000000" stroke-opacity="0.372549" points="195.6176,-260.3365 188.9822,-252.0768 189.0185,-262.6716 195.6176,-260.3365"/>
|
133
|
+
</g>
|
134
|
+
<!-- tests->Language/C++17 -->
|
135
|
+
<g id="edge13" class="edge">
|
136
|
+
<title>tests->Language/C++17</title>
|
137
|
+
<path fill="none" stroke="#000000" stroke-opacity="0.372549" d="M269.8853,-359.5185C277.2462,-349.5296 285.672,-336.6716 291,-324 299.3306,-304.1876 304.1533,-280.3321 306.8541,-262.1605"/>
|
138
|
+
<polygon fill="none" stroke="#000000" stroke-opacity="0.372549" points="310.3302,-262.5721 308.2095,-252.1917 303.3941,-261.6289 310.3302,-262.5721"/>
|
139
|
+
</g>
|
140
|
+
<!-- tests->lib -->
|
141
|
+
<g id="edge11" class="edge">
|
142
|
+
<title>tests->lib</title>
|
143
|
+
<path fill="none" stroke="#000000" stroke-opacity="0.372549" d="M255,-359.8314C255,-352.131 255,-342.9743 255,-334.4166"/>
|
144
|
+
<polygon fill="none" stroke="#000000" stroke-opacity="0.372549" points="258.5001,-334.4132 255,-324.4133 251.5001,-334.4133 258.5001,-334.4132"/>
|
145
|
+
</g>
|
146
|
+
</g>
|
147
|
+
</svg>
|