rubrowser 0.2.7 → 0.3.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 +4 -4
- data/.gitignore +4 -1
- data/.hound.yml +2 -0
- data/.rspec +1 -0
- data/.rubocop.yml +3 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +33 -2
- data/Rakefile +15 -7
- data/_config.yml +1 -0
- data/bin/rubrowser +5 -4
- data/lib/rubrowser/data.rb +47 -14
- data/lib/rubrowser/formatter/json.rb +5 -1
- data/lib/rubrowser/graph.rb +11 -0
- data/lib/rubrowser/parser/definition/base.rb +9 -0
- data/lib/rubrowser/parser/file.rb +24 -18
- data/lib/rubrowser/parser/relation/base.rb +11 -1
- data/lib/rubrowser/version.rb +1 -1
- data/public/css/application.css +4 -0
- data/public/javascript/application.js +11 -5
- data/readme.md +2 -5
- data/rubrowser.gemspec +3 -0
- metadata +48 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 663f1d03a44347696b31955a262839e433933415
|
4
|
+
data.tar.gz: fcd25e95549c33597fc2635ab9304d3a8c6296da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a950758287c25f65f648e029e180846ab6624c0df49b4a48cc5d3415bcca13c7de1f3ede57be426a6158b154f57089f7006dff2925c086c08357afb28baf6cf1
|
7
|
+
data.tar.gz: dafc101e84347031ac0f59eb14c5bdad3929e11f0956c4c822d34c363b4dbcfde14d207815eb72249f276deb78a9db5d93636b9f85b8543e8015734824c4a78d
|
data/.gitignore
CHANGED
data/.hound.yml
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
source
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
gemspec
|
data/Gemfile.lock
CHANGED
@@ -1,24 +1,55 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rubrowser (0.
|
4
|
+
rubrowser (0.3.0)
|
5
5
|
parser (~> 2.3, >= 2.3.0)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
10
|
ast (2.2.0)
|
11
|
+
byebug (9.0.6)
|
12
|
+
diff-lcs (1.3)
|
13
|
+
parallel (1.12.0)
|
11
14
|
parser (2.4.0.0)
|
12
15
|
ast (~> 2.2)
|
16
|
+
powerpack (0.1.1)
|
17
|
+
rainbow (2.2.2)
|
18
|
+
rake
|
13
19
|
rake (10.4.2)
|
20
|
+
rspec (3.6.0)
|
21
|
+
rspec-core (~> 3.6.0)
|
22
|
+
rspec-expectations (~> 3.6.0)
|
23
|
+
rspec-mocks (~> 3.6.0)
|
24
|
+
rspec-core (3.6.0)
|
25
|
+
rspec-support (~> 3.6.0)
|
26
|
+
rspec-expectations (3.6.0)
|
27
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
28
|
+
rspec-support (~> 3.6.0)
|
29
|
+
rspec-mocks (3.6.0)
|
30
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
31
|
+
rspec-support (~> 3.6.0)
|
32
|
+
rspec-support (3.6.0)
|
33
|
+
rubocop (0.49.1)
|
34
|
+
parallel (~> 1.10)
|
35
|
+
parser (>= 2.3.3.1, < 3.0)
|
36
|
+
powerpack (~> 0.1)
|
37
|
+
rainbow (>= 1.99.1, < 3.0)
|
38
|
+
ruby-progressbar (~> 1.7)
|
39
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
40
|
+
ruby-progressbar (1.8.1)
|
41
|
+
unicode-display_width (1.3.0)
|
14
42
|
|
15
43
|
PLATFORMS
|
16
44
|
ruby
|
17
45
|
|
18
46
|
DEPENDENCIES
|
19
47
|
bundler (~> 1.14)
|
48
|
+
byebug
|
20
49
|
rake (~> 10.0)
|
50
|
+
rspec
|
51
|
+
rubocop
|
21
52
|
rubrowser!
|
22
53
|
|
23
54
|
BUNDLED WITH
|
24
|
-
1.
|
55
|
+
1.15.2
|
data/Rakefile
CHANGED
@@ -1,10 +1,18 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rubocop/rake_task'
|
3
|
+
require 'rspec/core/rake_task'
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
t.libs << "lib"
|
7
|
-
t.test_files = FileList['test/**/*_test.rb']
|
5
|
+
task :server do
|
6
|
+
ruby './bin/rubrowser'
|
8
7
|
end
|
9
8
|
|
10
|
-
|
9
|
+
RuboCop::RakeTask.new(:rubocop) do |t|
|
10
|
+
t.options = ['--display-cop-names']
|
11
|
+
end
|
12
|
+
|
13
|
+
RSpec::Core::RakeTask.new(:spec)
|
14
|
+
|
15
|
+
task all: %I[spec rubocop] do
|
16
|
+
end
|
17
|
+
|
18
|
+
task default: :all
|
data/_config.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
theme: jekyll-theme-minimal
|
data/bin/rubrowser
CHANGED
@@ -5,7 +5,7 @@ require 'optparse'
|
|
5
5
|
require 'rubrowser'
|
6
6
|
require 'rubrowser/server'
|
7
7
|
|
8
|
-
|
8
|
+
options = {
|
9
9
|
port: 9000,
|
10
10
|
files: ARGV.empty? ? ['.'] : ARGV
|
11
11
|
}
|
@@ -13,8 +13,9 @@ OPTIONS = {
|
|
13
13
|
OptionParser.new do |opts|
|
14
14
|
opts.banner = "Usage: #{__FILE__} [options] [file] ..."
|
15
15
|
|
16
|
-
|
17
|
-
|
16
|
+
message = 'Specify port number for server, default = 9000'
|
17
|
+
opts.on('-pPORT', '--port=PORT', message) do |port|
|
18
|
+
options[:port] = port.to_i
|
18
19
|
end
|
19
20
|
|
20
21
|
opts.on('-v', '--version', 'Print Rubrowser version') do
|
@@ -28,4 +29,4 @@ OptionParser.new do |opts|
|
|
28
29
|
end
|
29
30
|
end.parse!
|
30
31
|
|
31
|
-
Rubrowser::Server.start(
|
32
|
+
Rubrowser::Server.start(options)
|
data/lib/rubrowser/data.rb
CHANGED
@@ -1,30 +1,24 @@
|
|
1
1
|
require 'rubrowser/parser/factory'
|
2
|
+
require 'rubrowser/graph'
|
2
3
|
|
3
4
|
module Rubrowser
|
4
5
|
class Data
|
6
|
+
attr_reader :definitions, :relations
|
7
|
+
|
5
8
|
def initialize(files)
|
6
9
|
@files = files
|
7
|
-
@parsed = false
|
8
10
|
parse
|
9
11
|
end
|
10
12
|
|
11
|
-
def definitions
|
12
|
-
@_definitions ||= parsers.map(&:definitions).reduce(:+).to_a
|
13
|
-
end
|
14
|
-
|
15
|
-
def relations
|
16
|
-
@_relations ||= parsers.map(&:relations).reduce(:+).to_a
|
17
|
-
end
|
18
|
-
|
19
13
|
private
|
20
14
|
|
21
|
-
attr_reader :files, :parsed
|
22
|
-
alias parsed? parsed
|
23
|
-
|
24
15
|
def parse
|
25
|
-
return if parsed?
|
26
16
|
parsers.each(&:parse)
|
27
|
-
|
17
|
+
|
18
|
+
@definitions ||= parsers.map(&:definitions).reduce(:+).to_a
|
19
|
+
@relations ||= parsers.map(&:relations).reduce(:+).to_a
|
20
|
+
|
21
|
+
mark_circular_dependencies
|
28
22
|
end
|
29
23
|
|
30
24
|
def parsers
|
@@ -32,5 +26,44 @@ module Rubrowser
|
|
32
26
|
Rubrowser::Parser::Factory.build(file)
|
33
27
|
end
|
34
28
|
end
|
29
|
+
|
30
|
+
def mark_circular_dependencies
|
31
|
+
components = make_components
|
32
|
+
@definitions.each do |definition|
|
33
|
+
if components.include?(definition.namespace.first.to_s)
|
34
|
+
definition.set_circular
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
@relations.each do |relation|
|
39
|
+
relation.set_circular if circular_relation?(components, relation)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def make_components
|
44
|
+
graph = Graph.new { |h, k| h[k] = [] }
|
45
|
+
|
46
|
+
@relations.each do |relation|
|
47
|
+
graph[relation.caller_namespace.to_s] <<
|
48
|
+
relation.resolve(definitions).to_s
|
49
|
+
end
|
50
|
+
|
51
|
+
find_coupled_components(graph)
|
52
|
+
end
|
53
|
+
|
54
|
+
def find_coupled_components(graph)
|
55
|
+
graph
|
56
|
+
.strongly_connected_components
|
57
|
+
.select { |c| c.length > 1 }
|
58
|
+
.flatten
|
59
|
+
.to_set
|
60
|
+
end
|
61
|
+
|
62
|
+
def circular_relation?(components, relation)
|
63
|
+
components.include?(relation.namespace.to_s) &&
|
64
|
+
components.include?(relation.caller_namespace.to_s)
|
65
|
+
end
|
66
|
+
|
67
|
+
attr_reader :files
|
35
68
|
end
|
36
69
|
end
|
@@ -10,7 +10,9 @@ module Rubrowser
|
|
10
10
|
def call
|
11
11
|
{
|
12
12
|
definitions: data.definitions.map { |d| definition_as_json(d) },
|
13
|
-
relations: data.relations.map
|
13
|
+
relations: data.relations.map do |r|
|
14
|
+
relation_as_json(r, data.definitions)
|
15
|
+
end
|
14
16
|
}.to_json
|
15
17
|
end
|
16
18
|
|
@@ -22,6 +24,7 @@ module Rubrowser
|
|
22
24
|
{
|
23
25
|
type: demoularize(definition.class.name),
|
24
26
|
namespace: definition.to_s,
|
27
|
+
circular: definition.circular?,
|
25
28
|
file: definition.file,
|
26
29
|
line: definition.line,
|
27
30
|
lines: definition.lines
|
@@ -35,6 +38,7 @@ module Rubrowser
|
|
35
38
|
resolved_namespace: relation.resolve(definitions).to_s,
|
36
39
|
caller: relation.caller_namespace.to_s,
|
37
40
|
file: relation.file,
|
41
|
+
circular: relation.circular?,
|
38
42
|
line: relation.line
|
39
43
|
}
|
40
44
|
end
|
@@ -9,6 +9,7 @@ module Rubrowser
|
|
9
9
|
@file = file
|
10
10
|
@line = line
|
11
11
|
@lines = lines
|
12
|
+
@circular = false
|
12
13
|
end
|
13
14
|
|
14
15
|
def name
|
@@ -23,6 +24,14 @@ module Rubrowser
|
|
23
24
|
namespace.empty?
|
24
25
|
end
|
25
26
|
|
27
|
+
def circular?
|
28
|
+
@circular
|
29
|
+
end
|
30
|
+
|
31
|
+
def set_circular
|
32
|
+
@circular = true
|
33
|
+
end
|
34
|
+
|
26
35
|
def ==(other)
|
27
36
|
namespace == other.namespace
|
28
37
|
end
|
@@ -19,22 +19,29 @@ module Rubrowser
|
|
19
19
|
|
20
20
|
def parse
|
21
21
|
return unless valid_file?(file)
|
22
|
+
constants = constants_from_file
|
23
|
+
|
24
|
+
@definitions = constants[:definitions]
|
25
|
+
@relations = constants[:relations]
|
26
|
+
rescue ::Parser::SyntaxError
|
27
|
+
warn "SyntaxError in #{file}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def constants_from_file
|
22
31
|
contents = ::File.read(file)
|
23
32
|
|
24
33
|
buffer = ::Parser::Source::Buffer.new(file, 1)
|
25
34
|
buffer.source = contents.force_encoding(Encoding::UTF_8)
|
26
35
|
|
36
|
+
ast = parser.parse(buffer)
|
37
|
+
parse_block(ast)
|
38
|
+
end
|
39
|
+
|
40
|
+
def parser
|
27
41
|
parser = ::Parser::CurrentRuby.new(Builder.new)
|
28
42
|
parser.diagnostics.ignore_warnings = true
|
29
43
|
parser.diagnostics.all_errors_are_fatal = false
|
30
|
-
|
31
|
-
ast = parser.parse(buffer)
|
32
|
-
constants = parse_block(ast)
|
33
|
-
|
34
|
-
@definitions = constants[:definitions]
|
35
|
-
@relations = constants[:relations]
|
36
|
-
rescue ::Parser::SyntaxError
|
37
|
-
warn "SyntaxError in #{file}"
|
44
|
+
parser
|
38
45
|
end
|
39
46
|
|
40
47
|
def valid_file?(file)
|
@@ -58,26 +65,25 @@ module Rubrowser
|
|
58
65
|
|
59
66
|
def parse_module(node, parents = [])
|
60
67
|
namespace = ast_consts_to_array(node.children.first, parents)
|
61
|
-
definition = Definition::Module
|
62
|
-
namespace,
|
63
|
-
file: file,
|
64
|
-
line: node.loc.line,
|
65
|
-
lines: node.loc.last_line - node.loc.line + 1
|
66
|
-
)
|
68
|
+
definition = build_definition(Definition::Module, namespace, node)
|
67
69
|
constants = { definitions: [definition] }
|
68
70
|
children_constants = parse_array(node.children[1..-1], namespace)
|
69
71
|
|
70
72
|
merge_constants(children_constants, constants)
|
71
73
|
end
|
72
74
|
|
73
|
-
def
|
74
|
-
|
75
|
-
definition = Definition::Class.new(
|
75
|
+
def build_definition(klass, namespace, node)
|
76
|
+
klass.new(
|
76
77
|
namespace,
|
77
78
|
file: file,
|
78
79
|
line: node.loc.line,
|
79
80
|
lines: node.loc.last_line - node.loc.line + 1
|
80
81
|
)
|
82
|
+
end
|
83
|
+
|
84
|
+
def parse_class(node, parents = [])
|
85
|
+
namespace = ast_consts_to_array(node.children.first, parents)
|
86
|
+
definition = build_definition(Definition::Class, namespace, node)
|
81
87
|
constants = { definitions: [definition] }
|
82
88
|
children_constants = parse_array(node.children[1..-1], namespace)
|
83
89
|
|
@@ -111,7 +117,7 @@ module Rubrowser
|
|
111
117
|
|
112
118
|
def ast_consts_to_array(node, parents = [])
|
113
119
|
return parents unless valid_node?(node) &&
|
114
|
-
[
|
120
|
+
%I[const cbase].include?(node.type)
|
115
121
|
ast_consts_to_array(node.children.first, parents) + [node.children.last]
|
116
122
|
end
|
117
123
|
|
@@ -11,6 +11,7 @@ module Rubrowser
|
|
11
11
|
@caller_namespace = caller_namespace
|
12
12
|
@file = file
|
13
13
|
@line = line
|
14
|
+
@is_circular = false
|
14
15
|
end
|
15
16
|
|
16
17
|
def namespace
|
@@ -21,6 +22,14 @@ module Rubrowser
|
|
21
22
|
Definition::Base.new(@caller_namespace, file: file, line: line)
|
22
23
|
end
|
23
24
|
|
25
|
+
def circular?
|
26
|
+
@is_circular
|
27
|
+
end
|
28
|
+
|
29
|
+
def set_circular
|
30
|
+
@is_circular = true
|
31
|
+
end
|
32
|
+
|
24
33
|
def resolve(definitions)
|
25
34
|
possibilities.find do |possibility|
|
26
35
|
definitions.any? { |definition| definition == possibility }
|
@@ -29,7 +38,8 @@ module Rubrowser
|
|
29
38
|
|
30
39
|
def ==(other)
|
31
40
|
namespace == other.namespace &&
|
32
|
-
caller_namespace == other.caller_namespace
|
41
|
+
caller_namespace == other.caller_namespace &&
|
42
|
+
circular? == other.circular?
|
33
43
|
end
|
34
44
|
|
35
45
|
private
|
data/lib/rubrowser/version.rb
CHANGED
data/public/css/application.css
CHANGED
@@ -4,6 +4,10 @@ d3.json("/data.json", function(error, data) {
|
|
4
4
|
$('.toolbox').show();
|
5
5
|
});
|
6
6
|
|
7
|
+
var classForCircular = function(d) {
|
8
|
+
return d.circular ? 'circular' : '';
|
9
|
+
};
|
10
|
+
|
7
11
|
var parseGraph = function(data){
|
8
12
|
var svg = d3.select(".dependency_graph svg"),
|
9
13
|
$svg = $('.dependency_graph svg'),
|
@@ -13,16 +17,17 @@ var parseGraph = function(data){
|
|
13
17
|
.on("start", dragstarted)
|
14
18
|
.on("drag", dragged)
|
15
19
|
.on("end", dragended),
|
16
|
-
dup_definitions = data.definitions.map(function(d){ return {id: d.namespace, type: d.type, lines: d.lines }; }),
|
20
|
+
dup_definitions = data.definitions.map(function(d){ return {id: d.namespace, type: d.type, lines: d.lines, circular: d.circular }; }),
|
17
21
|
definitions = _(dup_definitions).groupBy('id').map(function(group) {
|
18
22
|
return {
|
19
23
|
id: group[0].id,
|
20
24
|
type: group[0].type,
|
21
|
-
lines: _(group).sumBy('lines')
|
25
|
+
lines: _(group).sumBy('lines'),
|
26
|
+
circular: group[0].circular
|
22
27
|
};
|
23
28
|
}).value(),
|
24
29
|
namespaces = definitions.map(function(d){ return d.id; }),
|
25
|
-
relations = data.relations.map(function(d){ return {source: d.caller, target: d.resolved_namespace }; }),
|
30
|
+
relations = data.relations.map(function(d){ return {source: d.caller, target: d.resolved_namespace, circular: d.circular}; }),
|
26
31
|
max_lines = _.maxBy(definitions, 'lines').lines,
|
27
32
|
max_circle_r = 50;
|
28
33
|
|
@@ -58,7 +63,7 @@ var parseGraph = function(data){
|
|
58
63
|
.selectAll("path")
|
59
64
|
.data(relations)
|
60
65
|
.enter().append("path")
|
61
|
-
.attr("class", 'link')
|
66
|
+
.attr("class", function(d) { return 'link ' + classForCircular(d); })
|
62
67
|
.attr("marker-end", function(d){ return "url(#" + d.target.id + ")"; }),
|
63
68
|
node = container.append("g")
|
64
69
|
.attr("class", "nodes")
|
@@ -69,7 +74,8 @@ var parseGraph = function(data){
|
|
69
74
|
.on("dblclick", dblclick),
|
70
75
|
circle = node
|
71
76
|
.append("circle")
|
72
|
-
.attr("r", function(d) { return d.lines / max_lines * max_circle_r + 6; })
|
77
|
+
.attr("r", function(d) { return d.lines / max_lines * max_circle_r + 6; })
|
78
|
+
.attr("class", function (d) { return classForCircular(d) ; }),
|
73
79
|
type = node
|
74
80
|
.append("text")
|
75
81
|
.attr("class", "type")
|
data/readme.md
CHANGED
@@ -60,11 +60,8 @@ it'll analyze the current directory and open port 9000, so you can access the gr
|
|
60
60
|
* hide relations
|
61
61
|
* change graph appearance (collision radius)
|
62
62
|
* stop animation immediately
|
63
|
-
|
64
|
-
|
65
|
-
## Tests?
|
66
|
-
|
67
|
-
What tests? :smile:
|
63
|
+
* Module/class circle size on the graph will be relative to module number of lines in your code
|
64
|
+
* cyclical dependencies are marked in red
|
68
65
|
|
69
66
|
## Why?
|
70
67
|
|
data/rubrowser.gemspec
CHANGED
@@ -22,4 +22,7 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.add_runtime_dependency 'parser', '~> 2.3', '>= 2.3.0'
|
23
23
|
s.add_development_dependency 'bundler', '~> 1.14'
|
24
24
|
s.add_development_dependency 'rake', '~> 10.0'
|
25
|
+
s.add_development_dependency 'byebug'
|
26
|
+
s.add_development_dependency 'rubocop'
|
27
|
+
s.add_development_dependency 'rspec'
|
25
28
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubrowser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Emad Elsaid
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-10-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -58,6 +58,48 @@ dependencies:
|
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: '10.0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: byebug
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: rubocop
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: rspec
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
61
103
|
description: A ruby interactive dependency graph visualizer
|
62
104
|
email:
|
63
105
|
- blazeeboy@gmail.com
|
@@ -67,15 +109,19 @@ extensions: []
|
|
67
109
|
extra_rdoc_files: []
|
68
110
|
files:
|
69
111
|
- ".gitignore"
|
112
|
+
- ".hound.yml"
|
113
|
+
- ".rspec"
|
70
114
|
- ".rubocop.yml"
|
71
115
|
- Gemfile
|
72
116
|
- Gemfile.lock
|
73
117
|
- MIT-LICENSE
|
74
118
|
- Rakefile
|
119
|
+
- _config.yml
|
75
120
|
- bin/rubrowser
|
76
121
|
- lib/rubrowser.rb
|
77
122
|
- lib/rubrowser/data.rb
|
78
123
|
- lib/rubrowser/formatter/json.rb
|
124
|
+
- lib/rubrowser/graph.rb
|
79
125
|
- lib/rubrowser/parser/definition/base.rb
|
80
126
|
- lib/rubrowser/parser/definition/class.rb
|
81
127
|
- lib/rubrowser/parser/definition/module.rb
|