cpp_dependency_graph 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.rspec +3 -0
  4. data/.vscode/launch.json +79 -0
  5. data/.vscode/tasks.json +12 -0
  6. data/CODE_OF_CONDUCT.md +46 -0
  7. data/Gemfile +7 -0
  8. data/LICENSE +21 -0
  9. data/README.md +84 -0
  10. data/Rakefile +9 -0
  11. data/TODO.md +38 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/cpp_dependency_graph.gemspec +44 -0
  15. data/examples/leveldb_overall.png +0 -0
  16. data/examples/leveldb_overall.svg +215 -0
  17. data/examples/leveldb_overall_d3.png +0 -0
  18. data/examples/leveldb_overall_d3.svg +1 -0
  19. data/examples/rethinkdb_queue_component.png +0 -0
  20. data/examples/rethinkdb_queue_component.svg +234 -0
  21. data/examples/rethinkdb_queue_component_d3.png +0 -0
  22. data/examples/rethinkdb_queue_component_d3.svg +1 -0
  23. data/examples/rethinkdb_queue_include.png +0 -0
  24. data/examples/rethinkdb_queue_include.svg +211 -0
  25. data/examples/rethinkdb_queue_include_d3.png +0 -0
  26. data/examples/rethinkdb_queue_include_d3.svg +1 -0
  27. data/examples/rocksdb_overall_d3.svg +1 -0
  28. data/examples/rocksdb_table_component.png +0 -0
  29. data/exe/cpp_dependency_graph +87 -0
  30. data/lib/cpp_dependency_graph/bidirectional_hash.rb +30 -0
  31. data/lib/cpp_dependency_graph/component_link.rb +37 -0
  32. data/lib/cpp_dependency_graph/cycle_detector.rb +25 -0
  33. data/lib/cpp_dependency_graph/cyclic_link.rb +30 -0
  34. data/lib/cpp_dependency_graph/dependency_graph.rb +49 -0
  35. data/lib/cpp_dependency_graph/graph_to_html_converter.rb +7 -0
  36. data/lib/cpp_dependency_graph/graph_visualiser.rb +59 -0
  37. data/lib/cpp_dependency_graph/include_dependency_graph.rb +24 -0
  38. data/lib/cpp_dependency_graph/project.rb +66 -0
  39. data/lib/cpp_dependency_graph/source_component.rb +37 -0
  40. data/lib/cpp_dependency_graph/source_file.rb +51 -0
  41. data/lib/cpp_dependency_graph/tsortable_hash.rb +12 -0
  42. data/lib/cpp_dependency_graph/version.rb +5 -0
  43. data/lib/cpp_dependency_graph.rb +48 -0
  44. data/views/index.html.template +990 -0
  45. metadata +258 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7a18d32a9e2c0577def09a6698f9bb67804f981a5ec0320cb38357f847b92ac7
4
+ data.tar.gz: 6573a7087e4e3119db162ad532cd18602cb2fafca5ae00e5d806134edffc9016
5
+ SHA512:
6
+ metadata.gz: a3f8fc5ba2c535832df85b7857d4e62b9b24c522dff5f47085f10b4c4839ab9f89f000ea9798ac8e9c4e6dd596098a1f2fa6dbf13471e3462019fc0a7b0197bb
7
+ data.tar.gz: 60a92bf02b6ed53d3ee740355f0efe8d8acfae33f05c521da2d38b4c04951b6f74d0323172025dd080c6c7c770c95db712fc351869ae768a012919717355e75a
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ /.bundle/
2
+ /Gemfile.lock
3
+ /.yardoc
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
13
+ deps.png
14
+ deps.dot
15
+ deps.html
16
+ deps.json
17
+ deps.graphml
18
+ deps.svg
19
+ index.html
20
+ cpp_dependency_graph.callgrind.out*
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,79 @@
1
+ {
2
+ // Use IntelliSense to learn about possible attributes.
3
+ // Hover to view descriptions of existing attributes.
4
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
+ "version": "0.2.0",
6
+ "configurations": [
7
+ {
8
+ "name": "Launch index.html",
9
+ "type": "chrome",
10
+ "request": "launch",
11
+ "breakOnLoad": true,
12
+ "sourceMapPathOverrides": {
13
+ "webRoot": "${workspaceRoot}"
14
+ },
15
+ "file": "${workspaceRoot}/index.html"
16
+ },
17
+ {
18
+ "name": "Debug Local File",
19
+ "type": "Ruby",
20
+ "request": "launch",
21
+ "cwd": "${workspaceRoot}",
22
+ "program": "${workspaceRoot}/exe/cpp_dependency_graph",
23
+ "useBundler": true,
24
+ "pathToBundler": "C:/tools/ruby25/bin/bundle.bat",
25
+ "pathToRDebugIDE": "C:/tools/ruby25/bin/rdebug-ide.bat",
26
+ "showDebuggerOutput": true,
27
+ "args": ["generate_graph", "--root_dir", "../protobuf/src", "--output_file", "deps.dot"]
28
+ },
29
+ {
30
+ "name": "Listen for rdebug-ide",
31
+ "type": "Ruby",
32
+ "request": "attach",
33
+ "cwd": "${workspaceRoot}",
34
+ "remoteHost": "127.0.0.1",
35
+ "remotePort": "1234",
36
+ "remoteWorkspaceRoot": "${workspaceRoot}"
37
+ },
38
+ {
39
+ "name": "Rails server",
40
+ "type": "Ruby",
41
+ "request": "launch",
42
+ "cwd": "${workspaceRoot}",
43
+ "program": "${workspaceRoot}/bin/rails",
44
+ "args": [
45
+ "server"
46
+ ]
47
+ },
48
+ {
49
+ "name": "RSpec - all",
50
+ "type": "Ruby",
51
+ "request": "launch",
52
+ "cwd": "${workspaceRoot}",
53
+ "program": "C:/tools/ruby25/bin/rspec",
54
+ "args": [
55
+ "-I",
56
+ "${workspaceRoot}"
57
+ ]
58
+ },
59
+ {
60
+ "name": "RSpec - active spec file only",
61
+ "type": "Ruby",
62
+ "request": "launch",
63
+ "cwd": "${workspaceRoot}",
64
+ "program": "C:/tools/ruby25/bin/rspec",
65
+ "args": [
66
+ "-I",
67
+ "${workspaceRoot}",
68
+ "${file}"
69
+ ]
70
+ },
71
+ {
72
+ "name": "Cucumber",
73
+ "type": "Ruby",
74
+ "request": "launch",
75
+ "cwd": "${workspaceRoot}",
76
+ "program": "${workspaceRoot}/bin/cucumber"
77
+ }
78
+ ]
79
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ // See https://go.microsoft.com/fwlink/?LinkId=733558
3
+ // for the documentation about the tasks.json format
4
+ "version": "2.0.0",
5
+ "tasks": [
6
+ {
7
+ "label": "echo",
8
+ "type": "shell",
9
+ "command": "echo Hello"
10
+ }
11
+ ]
12
+ }
@@ -0,0 +1,46 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6
+
7
+ ## Our Standards
8
+
9
+ Examples of behavior that contributes to creating a positive environment include:
10
+
11
+ * Using welcoming and inclusive language
12
+ * Being respectful of differing viewpoints and experiences
13
+ * Gracefully accepting constructive criticism
14
+ * Focusing on what is best for the community
15
+ * Showing empathy towards other community members
16
+
17
+ Examples of unacceptable behavior by participants include:
18
+
19
+ * The use of sexualized language or imagery and unwelcome sexual attention or advances
20
+ * Trolling, insulting/derogatory comments, and personal or political attacks
21
+ * Public or private harassment
22
+ * Publishing others' private information, such as a physical or electronic address, without explicit permission
23
+ * Other conduct which could reasonably be considered inappropriate in a professional setting
24
+
25
+ ## Our Responsibilities
26
+
27
+ Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28
+
29
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30
+
31
+ ## Scope
32
+
33
+ This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34
+
35
+ ## Enforcement
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at shreyasbharath@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38
+
39
+ Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40
+
41
+ ## Attribution
42
+
43
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44
+
45
+ [homepage]: http://contributor-covenant.org
46
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ git_source(:github) { |repo_name| 'https://github.com/shreyasbharath/cpp_dependency_graph' }
6
+
7
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Shreyas Balakrishna
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # Cpp Dependency Graph
2
+
3
+ <!-- [![Gem Version] -->
4
+
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Build Status](https://travis-ci.org/shreyasbharath/cpp_dependency_graph.svg?branch=master)](https://travis-ci.org/shreyasbharath/cpp_dependency_graph) [![Maintainability](https://api.codeclimate.com/v1/badges/2a07b587ca6fc8b1b3db/maintainability)](https://codeclimate.com/github/shreyasbharath/cpp_dependency_graph/maintainability) [![Codacy](https://api.codacy.com/project/badge/Grade/9439dbb7fde44b5380401acba5325e62)](https://www.codacy.com/app/shreyasbharath/cpp_dependency_graph?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=shreyasbharath/cpp_dependency_graph&amp;utm_campaign=Badge_Grade) [![Test Coverage](https://api.codeclimate.com/v1/badges/2a07b587ca6fc8b1b3db/test_coverage)](https://codeclimate.com/github/shreyasbharath/cpp_dependency_graph/test_coverage) [![Release](https://img.shields.io/github/release/shreyasbharath/cpp_dependency_graph.svg?maxAge=3600)](https://github.com/shreyasbharath/cpp_dependency_graph/releases)
6
+
7
+ Generates useful component dependency visualisations (in `dot` or `d3.js`) to study the architecture of C/C++ projects.
8
+
9
+ Why do all the other languages have awesome tools to analyse codebases but C/C++ codebases do not?
10
+
11
+ It's time to change that.
12
+
13
+ This tool aims to -
14
+
15
+ - provide multiple views into the architecture of a codebase
16
+ - generate views at multiple levels of the architecture
17
+
18
+ ## Inspiration
19
+
20
+ This tool is inspired by a number of projects [rubrowser](http://www.emadelsaid.com/rubrowser/), [cpp-dependencies](https://github.com/tomtom-international/cpp-dependencies) and [objc-dependency-visualizer](https://github.com/PaulTaykalo/objc-dependency-visualizer).
21
+
22
+ The pretty `d3` visualisations are directly copied from `objc-dependency-visualiser`.
23
+
24
+ A huge shout out to the people behind these projects.
25
+
26
+ ## Usage
27
+
28
+ ### Installation
29
+
30
+ `gem install cpp_dependency_graph`
31
+
32
+ ### Overall component dependency graph
33
+
34
+ To generate the overall component depenency graph for a project, use it like so -
35
+
36
+ `cpp_dependency_graph visualise -r spec\test\example_project\ -o deps.dot -f dot`
37
+
38
+ Below is the overall `dot` and `d3` component dependency visualisations for [leveldb](https://github.com/google/leveldb)
39
+
40
+ ![Dot](examples/leveldb_overall.svg)
41
+
42
+ ![d3.js visualisation of leveldb](examples/leveldb_overall_d3.svg)
43
+
44
+ ![d3.js visualisation of rocksdb](examples/rocksdb_overall_d3.svg)
45
+
46
+ **NOTE** - If your project has a large number of components (> 100 and lots of connections between them), then generation (and subsequent rendering) may take some time.
47
+
48
+ ### Individual component dependency graph
49
+
50
+ This will highlight the dependencies coming in and going out of a specific component. This allows you to filter out extraneous detail and study individual components in more detail.
51
+
52
+ `cpp_dependency_graph visualise -r spec\test\example_project\ -c Engine -o deps.dot -f dot`
53
+
54
+ Here's a component dependency visualisation generated for the `queue` component in [rethinkdb](https://github.com/rethinkdb/rethinkdb)
55
+
56
+ ![Queue component dot visualisation](examples/rethinkdb_queue_component.svg)
57
+
58
+ ![Queue component d3 visualisation](examples/rethinkdb_queue_component_d3.svg)
59
+
60
+ ### Component include dependency graph
61
+
62
+ This will highlight dependencies of includes within a specific component
63
+
64
+ `cpp_dependency_graph visualise_includes -r spec\test\example_project\ -c Engine`
65
+
66
+ Here's a component include dependency visualisation generated for the `queue` component in [rethinkdb](https://github.com/rethinkdb/rethinkdb)
67
+
68
+ ![Queue include graph dot](examples/rethinkdb_queue_include.svg)
69
+
70
+ ![Queue include graph d3](examples/rethinkdb_queue_include_d3.svg)
71
+
72
+ ## Development
73
+
74
+ `bundle exec cpp_dependency_graph visualise -r <dir>`
75
+
76
+ ## License
77
+
78
+ cpp_dependency_graph is available under the MIT license.
79
+
80
+ ## Warranty
81
+
82
+ This software is provided "as is" and without any express or implied
83
+ warranties, including, without limitation, the implied warranties of
84
+ merchantability and fitness for a particular purpose.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ # task default: spec
8
+
9
+ RuboCop::RakeTask.new
data/TODO.md ADDED
@@ -0,0 +1,38 @@
1
+ # TODO Items
2
+
3
+ - [ ] Documentation
4
+ - [ ] Screencast of how to use tool on projects
5
+ - [ ] Create a github.io homepage
6
+ - [ ] Add a [CONTRIBUTING.md](https://github.com/nayafia/contributing-template/blob/master/CONTRIBUTING-template.md)
7
+ - [ ] Add interactive `html` or `svg` examples into README, is this possible?
8
+ - [ ] Progress messages
9
+ - [ ] Progress bar?
10
+ - [x] Allow user to specify a single component and the tool should print only that component
11
+ - [x] Print out dependency graphs for all components by default if no single component is specified
12
+ - [ ] Use a compiler to get the includes for a file rather than manually scanning the contents
13
+ - [ ] Manual scanning does not work when #includes are #ifdefed out for example
14
+ - [ ] <system> include vs "project" include (how will this work for third party sources that are not part of the codebase?)
15
+ - [ ] Work with any type of include relative includes ('blah.h') vs absolute includes ('/path/blah.h') vs relative with path includes ('blah/blah.h')
16
+ - [ ] Parallelise dependency scanning as much as possible to get the best possible performance
17
+ - [ ] Open up the graph automatically after generating an individual graph
18
+ - [ ] Work with any sort of project structure
19
+ - [ ] Header only projects
20
+ - [x] source and header files for component in same directory
21
+ - [ ] source files in same directory but header files in a separate `inc` directory
22
+ - [x] source files in same directory but header files in a global `inc` directory (all project header files in one place)
23
+ - [ ] source files and header files don't have matching names (i.e. there's an `api.h` header file and various source files implement them)
24
+ - [ ] Try it out on various small/large C/C++ open source projects
25
+ - [ ] Provide coupling/cohesion metrics, lookup metrics from Clean Architecture and [this](https://softwareengineering.stackexchange.com/questions/151004/are-there-metrics-for-cohesion-and-coupling)
26
+ - [ ] Ignore list? Some components may not want to be seen
27
+ - [ ] Use a yaml config file? A pain to pass a whole heap of arguments every time
28
+ - [ ] Make the tool incremental? Only generate parts of the new graph if something has changed. Something to think about
29
+ - [ ] Handling `duplicate` component names? Use a unique identifier (perhaps the path?)
30
+ - [ ] Visualisation
31
+ - [ ] Highlight strongly coupled components (i.e. have lots of outgoing/incoming dependencies). How to visualise strongly coupled components?
32
+ - [ ] Interface vs implementation coupling (interface is worse!). Highlighting interface vs implementation coupling between components on graph?
33
+ - [ ] Look at using subgraphs of the dot/svg language to cluster component dependencies in the graph
34
+ - [ ] Create a d3 donut graph with relative sizes of components in project? This'll probably show which components need to be further split up (something like this https://blog.kathyreid.id.au/2016/12/29/linux-australia-expense-breakdown-a-data-visualisation-in-d3-js/)
35
+ - [ ] Node size - base it on how many source files (or lines of code) or how many connections going in/out of node?
36
+ - [ ] Provide a 'zoom' slider on the visualisation to zoom in/out of the view (high level dependencies to low-level dependencies)
37
+ - [ ] Visualise components matching user provided regex only
38
+ - [ ] 3D visualisation using something like https://github.com/ggeoffrey/cljs-gravity
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'cpp_dependency_graph'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ require 'cpp_dependency_graph/version'
7
+
8
+ Gem::Specification.new do |s|
9
+ s.name = 'cpp_dependency_graph'
10
+ s.version = CppDependencyGraph::VERSION
11
+ s.authors = ['Shreyas Balakrishna']
12
+ s.email = ['shreyasbharath@users.noreply.github.com>']
13
+ s.summary = <<-SUMMARY
14
+ CppDependencyGraph is a program that generates dependency visualisations (dot, d3.js) to study the architecture of C/C++ projects
15
+ SUMMARY
16
+ s.description = <<-DESCRIPTION
17
+ Generates interactive dependency visualisations (dot, d3.js) to study the architecture of C/C++ projects in detail
18
+ DESCRIPTION
19
+ s.homepage = 'https://github.com/shreyasbharath/cpp_dependency_graph'
20
+ s.licenses = ['MIT']
21
+
22
+ s.files = %x[git ls-files -z].split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } -
23
+ %w[.rubocop.yml .travis.yml appveyor.yml]
24
+ s.bindir = 'exe'
25
+ s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
+ s.require_paths = ['lib']
27
+
28
+ s.required_ruby_version = Gem::Requirement.new('>= 2.4.0')
29
+ s.rubygems_version = '2.7.6'
30
+
31
+ s.add_runtime_dependency 'docopt', '~> 0.6'
32
+ s.add_runtime_dependency 'graphviz', '~> 1.0'
33
+ s.add_runtime_dependency 'json', '~> 2.1'
34
+ s.add_runtime_dependency 'parallel', '~> 1.12'
35
+
36
+ s.add_development_dependency 'bundler', '~> 1.16'
37
+ s.add_development_dependency 'coveralls', '~> 0.8'
38
+ s.add_development_dependency 'debase', '~> 0.2'
39
+ s.add_development_dependency 'rake', '~> 12.3'
40
+ s.add_development_dependency 'rspec', '~> 3.7'
41
+ s.add_development_dependency 'rubocop', '~> 0.54'
42
+ s.add_development_dependency 'ruby-prof', '~> 0.17'
43
+ s.add_development_dependency 'ruby-debug-ide', '~> 0.6'
44
+ end
Binary file
@@ -0,0 +1,215 @@
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.38.0 (20140413.2041)
5
+ -->
6
+ <!-- Title: dependency_graph Pages: 1 -->
7
+ <svg width="389pt" height="476pt"
8
+ viewBox="0.00 0.00 389.18 476.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 472)">
10
+ <title>dependency_graph</title>
11
+ <polygon fill="white" stroke="none" points="-4,4 -4,-472 385.182,-472 385.182,4 -4,4"/>
12
+ <!-- db -->
13
+ <g id="node1" class="node"><title>db</title>
14
+ <polygon fill="none" stroke="black" points="165,-396 115,-396 111,-392 111,-360 161,-360 165,-364 165,-396"/>
15
+ <polyline fill="none" stroke="black" points="161,-392 111,-392 "/>
16
+ <polyline fill="none" stroke="black" points="161,-392 161,-360 "/>
17
+ <polyline fill="none" stroke="black" points="161,-392 165,-396 "/>
18
+ <text text-anchor="middle" x="138" y="-374.3" font-family="Times New Roman,serif" font-size="14.00">db</text>
19
+ </g>
20
+ <!-- util -->
21
+ <g id="node2" class="node"><title>util</title>
22
+ <polygon fill="none" stroke="black" points="328,-324 278,-324 274,-320 274,-288 324,-288 328,-292 328,-324"/>
23
+ <polyline fill="none" stroke="black" points="324,-320 274,-320 "/>
24
+ <polyline fill="none" stroke="black" points="324,-320 324,-288 "/>
25
+ <polyline fill="none" stroke="black" points="324,-320 328,-324 "/>
26
+ <text text-anchor="middle" x="301" y="-302.3" font-family="Times New Roman,serif" font-size="14.00">util</text>
27
+ </g>
28
+ <!-- db&#45;&gt;util -->
29
+ <g id="edge1" class="edge"><title>db&#45;&gt;util</title>
30
+ <path fill="none" stroke="black" d="M165.283,-365.284C192.515,-353.589 234.527,-335.547 264.592,-322.635"/>
31
+ <polygon fill="black" stroke="black" points="266.093,-325.8 273.9,-318.638 263.331,-319.368 266.093,-325.8"/>
32
+ </g>
33
+ <!-- leveldb -->
34
+ <g id="node3" class="node"><title>leveldb</title>
35
+ <polygon fill="none" stroke="black" points="221,-252 169,-252 165,-248 165,-216 217,-216 221,-220 221,-252"/>
36
+ <polyline fill="none" stroke="black" points="217,-248 165,-248 "/>
37
+ <polyline fill="none" stroke="black" points="217,-248 217,-216 "/>
38
+ <polyline fill="none" stroke="black" points="217,-248 221,-252 "/>
39
+ <text text-anchor="middle" x="193" y="-230.3" font-family="Times New Roman,serif" font-size="14.00">leveldb</text>
40
+ </g>
41
+ <!-- db&#45;&gt;leveldb -->
42
+ <g id="edge2" class="edge"><title>db&#45;&gt;leveldb</title>
43
+ <path fill="none" stroke="black" d="M144.634,-359.871C154.091,-335.457 171.532,-290.426 182.684,-261.635"/>
44
+ <polygon fill="black" stroke="black" points="185.994,-262.778 186.342,-252.189 179.467,-260.25 185.994,-262.778"/>
45
+ </g>
46
+ <!-- table -->
47
+ <g id="node4" class="node"><title>table</title>
48
+ <polygon fill="none" stroke="black" points="220,-180 170,-180 166,-176 166,-144 216,-144 220,-148 220,-180"/>
49
+ <polyline fill="none" stroke="black" points="216,-176 166,-176 "/>
50
+ <polyline fill="none" stroke="black" points="216,-176 216,-144 "/>
51
+ <polyline fill="none" stroke="black" points="216,-176 220,-180 "/>
52
+ <text text-anchor="middle" x="193" y="-158.3" font-family="Times New Roman,serif" font-size="14.00">table</text>
53
+ </g>
54
+ <!-- db&#45;&gt;table -->
55
+ <g id="edge3" class="edge"><title>db&#45;&gt;table</title>
56
+ <path fill="none" stroke="red" d="M131.823,-359.91C127.377,-329.791 128.254,-265.742 147,-216 150.68,-206.234 156.57,-196.569 163.009,-188.221"/>
57
+ <polygon fill="red" stroke="red" points="165.851,-190.277 169.57,-180.356 160.476,-185.793 165.851,-190.277"/>
58
+ </g>
59
+ <!-- port -->
60
+ <g id="node5" class="node"><title>port</title>
61
+ <polygon fill="none" stroke="black" points="275,-108 225,-108 221,-104 221,-72 271,-72 275,-76 275,-108"/>
62
+ <polyline fill="none" stroke="black" points="271,-104 221,-104 "/>
63
+ <polyline fill="none" stroke="black" points="271,-104 271,-72 "/>
64
+ <polyline fill="none" stroke="black" points="271,-104 275,-108 "/>
65
+ <text text-anchor="middle" x="248" y="-86.3" font-family="Times New Roman,serif" font-size="14.00">port</text>
66
+ </g>
67
+ <!-- db&#45;&gt;port -->
68
+ <g id="edge4" class="edge"><title>db&#45;&gt;port</title>
69
+ <path fill="none" stroke="black" d="M133.97,-359.811C125.294,-318.32 109.282,-211.163 157,-144 170.226,-125.385 192.207,-112.318 211.252,-103.817"/>
70
+ <polygon fill="black" stroke="black" points="212.732,-106.992 220.598,-99.8943 210.022,-100.537 212.732,-106.992"/>
71
+ </g>
72
+ <!-- win -->
73
+ <g id="node6" class="node"><title>win</title>
74
+ <polygon fill="none" stroke="black" points="275,-36 225,-36 221,-32 221,-0 271,-0 275,-4 275,-36"/>
75
+ <polyline fill="none" stroke="black" points="271,-32 221,-32 "/>
76
+ <polyline fill="none" stroke="black" points="271,-32 271,-0 "/>
77
+ <polyline fill="none" stroke="black" points="271,-32 275,-36 "/>
78
+ <text text-anchor="middle" x="248" y="-14.3" font-family="Times New Roman,serif" font-size="14.00">win</text>
79
+ </g>
80
+ <!-- db&#45;&gt;win -->
81
+ <g id="edge5" class="edge"><title>db&#45;&gt;win</title>
82
+ <path fill="none" stroke="black" d="M114.807,-359.613C85.2656,-335.285 38,-288.068 38,-235 38,-235 38,-235 38,-161 38,-78.4157 150.827,-40.6055 211.079,-26.3018"/>
83
+ <polygon fill="black" stroke="black" points="212.001,-29.6816 220.976,-24.0513 210.449,-22.8558 212.001,-29.6816"/>
84
+ </g>
85
+ <!-- util&#45;&gt;leveldb -->
86
+ <g id="edge26" class="edge"><title>util&#45;&gt;leveldb</title>
87
+ <path fill="none" stroke="red" d="M273.878,-291.003C258.075,-281.577 238.269,-268.926 222.15,-258.033"/>
88
+ <polygon fill="red" stroke="red" points="223.852,-254.956 213.623,-252.194 219.897,-260.732 223.852,-254.956"/>
89
+ </g>
90
+ <!-- util&#45;&gt;port -->
91
+ <g id="edge25" class="edge"><title>util&#45;&gt;port</title>
92
+ <path fill="none" stroke="red" d="M292.875,-287.849C280.144,-250.753 258.099,-162.81 250.039,-118.103"/>
93
+ <polygon fill="red" stroke="red" points="253.49,-117.515 248.383,-108.232 246.586,-118.674 253.49,-117.515"/>
94
+ </g>
95
+ <!-- util&#45;&gt;win -->
96
+ <g id="edge24" class="edge"><title>util&#45;&gt;win</title>
97
+ <path fill="none" stroke="black" d="M305.324,-287.97C314.524,-248.151 332.657,-146.682 300,-72 295.247,-61.1295 287.19,-51.2247 278.819,-42.9964"/>
98
+ <polygon fill="black" stroke="black" points="281.184,-40.416 271.457,-36.2148 276.441,-45.5644 281.184,-40.416"/>
99
+ </g>
100
+ <!-- leveldb&#45;&gt;util -->
101
+ <g id="edge13" class="edge"><title>leveldb&#45;&gt;util</title>
102
+ <path fill="none" stroke="red" d="M221.1,-249.582C236.819,-258.991 256.266,-271.428 272.099,-282.136"/>
103
+ <polygon fill="red" stroke="red" points="270.25,-285.111 280.477,-287.876 274.206,-279.337 270.25,-285.111"/>
104
+ </g>
105
+ <!-- leveldb&#45;&gt;table -->
106
+ <g id="edge12" class="edge"><title>leveldb&#45;&gt;table</title>
107
+ <path fill="none" stroke="red" d="M187.084,-215.697C186.289,-207.983 186.062,-198.712 186.405,-190.112"/>
108
+ <polygon fill="red" stroke="red" points="189.898,-190.324 187.105,-180.104 182.915,-189.836 189.898,-190.324"/>
109
+ </g>
110
+ <!-- leveldb&#45;&gt;win -->
111
+ <g id="edge11" class="edge"><title>leveldb&#45;&gt;win</title>
112
+ <path fill="none" stroke="black" d="M211.348,-215.638C233.544,-193.239 269.712,-151.903 284,-108 288.952,-92.7855 288.703,-87.2933 284,-72 280.991,-62.2153 275.493,-52.6161 269.684,-44.3336"/>
113
+ <polygon fill="black" stroke="black" points="272.407,-42.1306 263.61,-36.2264 266.805,-46.3279 272.407,-42.1306"/>
114
+ </g>
115
+ <!-- table&#45;&gt;db -->
116
+ <g id="edge23" class="edge"><title>table&#45;&gt;db</title>
117
+ <path fill="none" stroke="red" d="M185.524,-180.356C178.741,-190.137 169.907,-202.979 165,-216 148.158,-260.69 145.739,-316.929 143.393,-349.734"/>
118
+ <polygon fill="red" stroke="red" points="139.888,-349.663 142.58,-359.91 146.866,-350.221 139.888,-349.663"/>
119
+ </g>
120
+ <!-- table&#45;&gt;util -->
121
+ <g id="edge21" class="edge"><title>table&#45;&gt;util</title>
122
+ <path fill="none" stroke="black" d="M206.074,-180.189C224.912,-204.958 259.82,-250.856 281.65,-279.558"/>
123
+ <polygon fill="black" stroke="black" points="279.133,-282.031 287.973,-287.871 284.705,-277.793 279.133,-282.031"/>
124
+ </g>
125
+ <!-- table&#45;&gt;leveldb -->
126
+ <g id="edge20" class="edge"><title>table&#45;&gt;leveldb</title>
127
+ <path fill="none" stroke="red" d="M198.895,-180.104C199.701,-187.791 199.937,-197.054 199.604,-205.665"/>
128
+ <polygon fill="red" stroke="red" points="196.109,-205.48 198.916,-215.697 203.092,-205.96 196.109,-205.48"/>
129
+ </g>
130
+ <!-- table&#45;&gt;port -->
131
+ <g id="edge22" class="edge"><title>table&#45;&gt;port</title>
132
+ <path fill="none" stroke="black" d="M206.596,-143.697C213.123,-135.389 221.068,-125.277 228.247,-116.141"/>
133
+ <polygon fill="black" stroke="black" points="231.135,-118.13 234.561,-108.104 225.631,-113.805 231.135,-118.13"/>
134
+ </g>
135
+ <!-- table&#45;&gt;win -->
136
+ <g id="edge19" class="edge"><title>table&#45;&gt;win</title>
137
+ <path fill="none" stroke="black" d="M194.697,-143.674C196.95,-125.29 201.888,-95.6852 212,-72 216.084,-62.4333 221.988,-52.7836 227.838,-44.3881"/>
138
+ <polygon fill="black" stroke="black" points="230.78,-46.2938 233.835,-36.1492 225.12,-42.1741 230.78,-46.2938"/>
139
+ </g>
140
+ <!-- port&#45;&gt;util -->
141
+ <g id="edge18" class="edge"><title>port&#45;&gt;util</title>
142
+ <path fill="none" stroke="red" d="M256.153,-108.232C268.871,-145.324 290.847,-232.981 298.927,-277.712"/>
143
+ <polygon fill="red" stroke="red" points="295.522,-278.567 300.63,-287.849 302.425,-277.408 295.522,-278.567"/>
144
+ </g>
145
+ <!-- port&#45;&gt;win -->
146
+ <g id="edge17" class="edge"><title>port&#45;&gt;win</title>
147
+ <path fill="none" stroke="black" d="M248,-71.6966C248,-63.9827 248,-54.7125 248,-46.1124"/>
148
+ <polygon fill="black" stroke="black" points="251.5,-46.1043 248,-36.1043 244.5,-46.1044 251.5,-46.1043"/>
149
+ </g>
150
+ <!-- bench -->
151
+ <g id="node7" class="node"><title>bench</title>
152
+ <polygon fill="none" stroke="black" points="366,-396 316,-396 312,-392 312,-360 362,-360 366,-364 366,-396"/>
153
+ <polyline fill="none" stroke="black" points="362,-392 312,-392 "/>
154
+ <polyline fill="none" stroke="black" points="362,-392 362,-360 "/>
155
+ <polyline fill="none" stroke="black" points="362,-392 366,-396 "/>
156
+ <text text-anchor="middle" x="339" y="-374.3" font-family="Times New Roman,serif" font-size="14.00">bench</text>
157
+ </g>
158
+ <!-- bench&#45;&gt;util -->
159
+ <g id="edge6" class="edge"><title>bench&#45;&gt;util</title>
160
+ <path fill="none" stroke="black" d="M329.607,-359.697C325.235,-351.644 319.943,-341.894 315.105,-332.982"/>
161
+ <polygon fill="black" stroke="black" points="318.132,-331.223 310.285,-324.104 311.98,-334.563 318.132,-331.223"/>
162
+ </g>
163
+ <!-- memenv -->
164
+ <g id="node8" class="node"><title>memenv</title>
165
+ <polygon fill="none" stroke="black" points="184.5,-468 125.5,-468 121.5,-464 121.5,-432 180.5,-432 184.5,-436 184.5,-468"/>
166
+ <polyline fill="none" stroke="black" points="180.5,-464 121.5,-464 "/>
167
+ <polyline fill="none" stroke="black" points="180.5,-464 180.5,-432 "/>
168
+ <polyline fill="none" stroke="black" points="180.5,-464 184.5,-468 "/>
169
+ <text text-anchor="middle" x="153" y="-446.3" font-family="Times New Roman,serif" font-size="14.00">memenv</text>
170
+ </g>
171
+ <!-- memenv&#45;&gt;db -->
172
+ <g id="edge10" class="edge"><title>memenv&#45;&gt;db</title>
173
+ <path fill="none" stroke="black" d="M149.292,-431.697C147.639,-423.983 145.653,-414.712 143.81,-406.112"/>
174
+ <polygon fill="black" stroke="black" points="147.183,-405.149 141.665,-396.104 140.338,-406.616 147.183,-405.149"/>
175
+ </g>
176
+ <!-- memenv&#45;&gt;util -->
177
+ <g id="edge8" class="edge"><title>memenv&#45;&gt;util</title>
178
+ <path fill="none" stroke="black" d="M177.534,-431.915C191.14,-422.014 208.073,-408.972 222,-396 243.501,-375.973 265.494,-350.73 280.797,-332.247"/>
179
+ <polygon fill="black" stroke="black" points="283.699,-334.227 287.331,-324.274 278.285,-329.79 283.699,-334.227"/>
180
+ </g>
181
+ <!-- memenv&#45;&gt;leveldb -->
182
+ <g id="edge7" class="edge"><title>memenv&#45;&gt;leveldb</title>
183
+ <path fill="none" stroke="black" d="M161.174,-431.712C165.648,-421.533 170.898,-408.283 174,-396 185.64,-349.908 190.191,-294.551 191.941,-262.22"/>
184
+ <polygon fill="black" stroke="black" points="195.439,-262.344 192.433,-252.185 188.447,-262.001 195.439,-262.344"/>
185
+ </g>
186
+ <!-- memenv&#45;&gt;port -->
187
+ <g id="edge9" class="edge"><title>memenv&#45;&gt;port</title>
188
+ <path fill="none" stroke="black" d="M121.298,-436.467C76.4837,-416.419 0,-372.594 0,-307 0,-307 0,-307 0,-233 0,-136.966 141.781,-104.975 210.94,-95.0824"/>
189
+ <polygon fill="black" stroke="black" points="211.545,-98.5327 220.988,-93.728 210.61,-91.5954 211.545,-98.5327"/>
190
+ </g>
191
+ <!-- issues -->
192
+ <g id="node9" class="node"><title>issues</title>
193
+ <polygon fill="none" stroke="black" points="273,-468 223,-468 219,-464 219,-432 269,-432 273,-436 273,-468"/>
194
+ <polyline fill="none" stroke="black" points="269,-464 219,-464 "/>
195
+ <polyline fill="none" stroke="black" points="269,-464 269,-432 "/>
196
+ <polyline fill="none" stroke="black" points="269,-464 273,-468 "/>
197
+ <text text-anchor="middle" x="246" y="-446.3" font-family="Times New Roman,serif" font-size="14.00">issues</text>
198
+ </g>
199
+ <!-- issues&#45;&gt;db -->
200
+ <g id="edge15" class="edge"><title>issues&#45;&gt;db</title>
201
+ <path fill="none" stroke="black" d="M219.58,-431.876C205.59,-422.808 188.224,-411.552 173.114,-401.759"/>
202
+ <polygon fill="black" stroke="black" points="174.817,-398.692 164.521,-396.19 171.009,-404.566 174.817,-398.692"/>
203
+ </g>
204
+ <!-- issues&#45;&gt;util -->
205
+ <g id="edge16" class="edge"><title>issues&#45;&gt;util</title>
206
+ <path fill="none" stroke="black" d="M273.222,-446.495C303.874,-442.055 352.353,-429.789 375,-396 383.908,-382.709 382.312,-374.231 375,-360 366.866,-344.17 351.567,-332.01 336.981,-323.356"/>
207
+ <polygon fill="black" stroke="black" points="338.506,-320.199 328.061,-318.418 335.115,-326.324 338.506,-320.199"/>
208
+ </g>
209
+ <!-- issues&#45;&gt;leveldb -->
210
+ <g id="edge14" class="edge"><title>issues&#45;&gt;leveldb</title>
211
+ <path fill="none" stroke="black" d="M241.752,-431.849C232.565,-394.753 210.785,-306.81 199.712,-262.103"/>
212
+ <polygon fill="black" stroke="black" points="203.069,-261.098 197.268,-252.232 196.275,-262.781 203.069,-261.098"/>
213
+ </g>
214
+ </g>
215
+ </svg>
Binary file