build-dependency 1.0.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 +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>
|