dependencytree 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5c634c0026c52f65f94bb052cb1526f03ad0d923
4
- data.tar.gz: bde9b61df5be813ff5a804d4f3361183a433d8d0
3
+ metadata.gz: 0eaccd9262969019a4816794b1523655b1e640d5
4
+ data.tar.gz: a8815740f3dee55ec51cf34e6155c16f340240f3
5
5
  SHA512:
6
- metadata.gz: 87b9307a388b23abf36e7684547284caafd7bf1027e83f928d580fa0e7adbfa8ab4b274e01b816644f8bf4930fb5ad4c05286918947630b317b59a32676677fc
7
- data.tar.gz: 03c3aa6f2601cd40dd6f07ce5e45b894ff72bc96bf530d82b4f51dd7443c68503a25444a8f3091272ed84b9e1a31c12d2029ff1beb33c8ca17528e1f167bc48e
6
+ metadata.gz: 544cd47f79beda8c029892f0c6ff991baa90c1b7e3aa34a5f1643384977aee3c3824024be83438efc8ad7753ba47069e7e7587ee8b9b862451a62b0fde97a0f7
7
+ data.tar.gz: 0fef2ba73b64d6724cf947cf04ea8d75e491a2ce8a4bee079854ec621df1323e6a50e143289ea867e1264ea7c53e49edb9d6a66fe153581d2b7e62bfe132b0cd
data/Rakefile CHANGED
@@ -1,2 +1,10 @@
1
1
  require "bundler/gem_tasks"
2
- task :default => :spec
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << "test"
6
+ t.test_files = FileList['test/**/*_test.rb']
7
+ end
8
+ desc "Run tests"
9
+
10
+ task :default => :test
@@ -23,7 +23,8 @@ Gem::Specification.new do |spec|
23
23
  spec.require_paths = ["lib"]
24
24
 
25
25
  spec.add_development_dependency "bundler", "~> 1.15"
26
- spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "rake", "~> 12.3"
27
+ spec.add_development_dependency "minitest", "~> 5.11"
27
28
  spec.add_dependency "parser", "~> 2.5.0.5"
28
29
  spec.add_dependency "ast", "~> 2.4.0"
29
30
  end
@@ -1,82 +1,9 @@
1
- require "dependencytree/treeinterpreter"
2
- require "dependencytree/dependencyresolver"
3
-
4
1
  require "dependencytree/version"
5
- require 'parser/current'
6
- require 'optparse'
7
- require 'pp'
8
- require 'json'
2
+ require "dependencytree/treemain"
9
3
  require 'logger'
10
4
 
11
5
  module Dependencytree
12
6
 
13
- def self.handle_path(options, consumer, path)
14
- if options[:ignore].match(path)
15
- return
16
- end
17
- if File.directory?(path)
18
- STDERR.puts path if options[:verbose]
19
- Dir.entries(path).each { |x|
20
- resolved = File.join(path, x)
21
- handle_path(options, consumer, resolved) if File.directory?(resolved) && x != "." && x != ".."
22
- handle_path(options, consumer, resolved) if File.file?(resolved) && options[:pattern].match(resolved)
23
- }
24
- elsif File.file?(path)
25
- STDERR.puts path if options[:verbose]
26
- LOG.debug("Handling path #{path}")
27
- tree = Parser::CurrentRuby.parse_file(path)
28
- LOG.debug("Parsed tree: #{tree}") if LOG.debug?
29
- consumer.visit(path, tree)
30
- end
31
- end
32
-
33
- options = {}
34
- options[:ignore] = /^$/
35
- options[:pattern] = /.*\.rb/
36
- OptionParser.new do |opt|
37
- opt.on("-v", "--verbose", "Verbose output") do |o|
38
- options[:verbose] = true
39
- end
40
- opt.on("-d", "--debug", "Log debugging output to file 'dependencytree.log'") do |o|
41
- options[:debug] = true
42
- end
43
- opt.on("-p", "--pattern[=OPTIONAL]", "Pattern to accept source codes with (default: #{options[:pattern].to_s})") do |o|
44
- options[:pattern] = /#{o}/
45
- end
46
- opt.on("-i", "--ignore[=OPTIONAL]", "Paths to not load (default: #{options[:ignore].to_s})") do |o|
47
- options[:ignore] = /#{o}/
48
- end
49
- opt.on("-o", "--output[=OPTIONAL]", "Output path for the JSON file") do |o|
50
- options[:output] = o
51
- end
52
- opt.on_tail("-h", "--help", "Show this message") do
53
- puts opt
54
- exit
55
- end
56
- end.parse!
57
-
58
- if options[:debug]
59
- log = Logger.new('dependencytree.log')
60
- log.level = Logger::WARN
61
- else
62
- log = Logger.new(STDOUT)
63
- log.level = Logger::WARN
64
- end
65
- LOG = log
66
-
67
- treeinterpreter = TreeInterpreter.new
68
- ARGV.each do |path|
69
- handle_path(options, treeinterpreter, File.absolute_path(path))
70
- end
71
-
72
- dependencyresolver = DependencyResolver.new(treeinterpreter.classes_and_modules)
73
- dependencyresolver.resolve_references
74
-
75
- json = dependencyresolver.classes_and_modules.to_json
76
- if options[:output]
77
- File.write(options[:output], json)
78
- else
79
- puts json
80
- end
7
+ TreeMain.main
81
8
  end
82
9
 
@@ -16,13 +16,15 @@ module Dependencytree
16
16
  attr_reader :resolved_references
17
17
  attr_reader :unresolved_references
18
18
 
19
+ @@generator = SecureRandom
20
+
19
21
  # type: :class or :module
20
22
  # path: the filesystem path the parsed class was found in
21
23
  # module_name: eventual module name or :anonymous
22
24
  # class_name: the class name
23
25
  def initialize(type, path, name)
24
26
  # unique uuid for reference
25
- @uuid = SecureRandom.uuid
27
+ @uuid = @@generator.uuid
26
28
  # :module or :class
27
29
  @type = type
28
30
  # filesystem path of (first) definition
@@ -36,10 +38,17 @@ module Dependencytree
36
38
  # list of (unresolved) references as arrays
37
39
  @references = []
38
40
 
41
+ # no parent by default (will be set later)
42
+ @parent = nil
43
+
39
44
  @resolved_references = []
40
45
  @unresolved_references = []
41
46
  end
42
47
 
48
+ def self.generator=(generator)
49
+ @@generator = generator
50
+ end
51
+
43
52
  # Gets the full name of the class/module as an array.
44
53
  # @return the full name, for example ["ModuleA","ModuleB","ClassA"]
45
54
  def full_name_array
@@ -12,7 +12,9 @@ module Dependencytree
12
12
  # path: the filesystem path the parsed class was found in
13
13
  # module_name: eventual module name or :anonymous
14
14
  # class_name: the class name
15
- def initialize(classes_and_modules)
15
+ def initialize(log, classes_and_modules)
16
+ # store logger
17
+ @@log = log
16
18
  @classes_and_modules = classes_and_modules
17
19
  @by_full_name = @classes_and_modules.each_with_object({}) { |clazz, hash| hash[clazz.full_name()] = clazz }
18
20
  end
@@ -20,7 +22,7 @@ module Dependencytree
20
22
  # Goes thru all classes and tries to resolve the references.
21
23
  def resolve_references
22
24
  @classes_and_modules.each do |clazz|
23
- LOG.debug("Processing class #{clazz.full_name} located in #{clazz.path}")
25
+ @@log.debug("Processing class #{clazz.full_name} located in #{clazz.path}")
24
26
  clazz.references.each do |reference_array|
25
27
  refered_class = resolve_reference(clazz, reference_array)
26
28
  if refered_class
@@ -43,9 +45,9 @@ module Dependencytree
43
45
  end
44
46
 
45
47
  if refered_class_model
46
- LOG.debug("Resolved #{reference_array.join('::')} to uuid #{refered_class_model.uuid}")
48
+ @@log.debug("Resolved #{reference_array.join('::')} to uuid #{refered_class_model.uuid}")
47
49
  else
48
- LOG.debug("Could not resolve #{reference_array.join('::')}")
50
+ @@log.debug("Could not resolve #{reference_array.join('::')}")
49
51
  end
50
52
  refered_class_model
51
53
  end
@@ -59,16 +61,16 @@ module Dependencytree
59
61
  reference_part = reference_array[0..-2]
60
62
  constant_name = reference_array[-1]
61
63
 
62
- LOG.debug("Resolving reference array #{reference_array.to_s} as reference #{reference_part.to_s} and constant #{constant_name}")
64
+ @@log.debug("Resolving reference array #{reference_array.to_s} as reference #{reference_part.to_s} and constant #{constant_name}")
63
65
 
64
66
  refered_class_model = resolve_reference_direct(referer_class_model, reference_part)
65
67
  if refered_class_model
66
- LOG.debug("Found reference to possible parent #{reference_part.to_s}")
68
+ @@log.debug("Found reference to possible parent #{reference_part.to_s}")
67
69
  if refered_class_model.constant_names.include? constant_name.to_sym
68
- LOG.debug("Found class #{refered_class_model.full_name} constant #{constant_name}")
70
+ @@log.debug("Found class #{refered_class_model.full_name} constant #{constant_name}")
69
71
  refered_class_model
70
72
  else
71
- LOG.debug("Found class #{refered_class_model.full_name}, but not constant #{constant_name}. Known constants: #{refered_class_model.constant_names}")
73
+ @@log.debug("Found class #{refered_class_model.full_name}, but not constant #{constant_name}. Known constants: #{refered_class_model.constant_names}")
72
74
  nil
73
75
  end
74
76
  else
@@ -81,15 +83,15 @@ module Dependencytree
81
83
  # @param reference_array the reference as in the source, can be absolute or relative to the referer class.
82
84
  # @return the refered class model or nil
83
85
  def resolve_reference_direct(referer_class_model, reference_array)
84
- LOG.debug("Resolving reference array #{reference_array.to_s}")
86
+ @@log.debug("Resolving reference array #{reference_array.to_s}")
85
87
 
86
88
  referer_array = referer_class_model.full_name_array
87
89
  i = 0
88
90
  refered_class_model = nil
89
91
  while !refered_class_model do
90
- LOG.debug("Referer array #{i} is #{referer_array.to_s}")
92
+ @@log.debug("Referer array #{i} is #{referer_array.to_s}")
91
93
  full_name = (referer_array+reference_array).join("::")
92
- LOG.debug("Full name #{i} is #{full_name} #{full_name.class.name}")
94
+ @@log.debug("Full name #{i} is #{full_name} #{full_name.class.name}")
93
95
  refered_class_model = resolve_by_full_name(full_name)
94
96
 
95
97
  break if referer_array.empty?
@@ -8,7 +8,10 @@ module Dependencytree
8
8
  class TreeInterpreter
9
9
  attr_reader :classes_and_modules
10
10
 
11
- def initialize
11
+ def initialize(log)
12
+ # the logging instance
13
+ @@log = log
14
+
12
15
  # path will be the file system path of the source file
13
16
  @path = nil
14
17
  # context_stack is the stack of modules/classes loaded (namespacing)
@@ -52,14 +55,14 @@ module Dependencytree
52
55
  # Handle a const expression.
53
56
  # @param node the const node itself to handle.
54
57
  def _const(node)
55
- LOG.debug("const")
58
+ @@log.debug("const")
56
59
 
57
60
  raise ArgumentError, "type needs to be const (#{node.type})" if node.type != :const
58
61
  raise ArgumentError, "Children count needs to be 2 (#{node.children.length})" if node.children.length != 2
59
62
 
60
63
  reference = flatten_const_tree(node)
61
64
 
62
- LOG.debug("Reference to #{reference.to_s}")
65
+ @@log.debug("Reference to #{reference.to_s}")
63
66
  top_of_stack.add_reference(reference)
64
67
  end
65
68
 
@@ -69,7 +72,7 @@ module Dependencytree
69
72
  raise ArgumentError, "Children count for module is != 2 (#{node.children.length})" if node.children.length != 2
70
73
  raise ArgumentError, "First module child needs to be a const (#{node.children[0].type} #{node.children[0].type})" if node.children[0].type != :const
71
74
 
72
- LOG.debug("module #{node.children[0].children[1]}")
75
+ @@log.debug("module #{node.children[0].children[1]}")
73
76
 
74
77
  current_module_name = node.children[0].children[1]
75
78
  _handle_class_module_common(:module, current_module_name, node)
@@ -80,7 +83,7 @@ module Dependencytree
80
83
  def _class(node)
81
84
  raise ArgumentError, "Children count for class is != 3 (#{node.children.length})" if node.children.length != 3
82
85
  raise ArgumentError, "First class child needs to be a const (#{node.children[0].type} #{node.children[0].type})" if node.children[0].type != :const
83
- LOG.debug("class #{node.children[0].children[1]}")
86
+ @@log.debug("class #{node.children[0].children[1]}")
84
87
 
85
88
  current_class_name = node.children[0].children[1]
86
89
  _handle_class_module_common(:class, current_class_name, node)
@@ -97,7 +100,7 @@ module Dependencytree
97
100
  parent = @context_stack[-1]
98
101
  full_name = parent.full_name.to_s + "::" + name.to_s
99
102
  end
100
- LOG.debug("Full name is #{full_name}")
103
+ @@log.debug("Full name is #{full_name}")
101
104
  resolved = _resolve(full_name)
102
105
 
103
106
  if ! resolved.nil?
@@ -113,7 +116,7 @@ module Dependencytree
113
116
  end
114
117
 
115
118
  if resolved.nil?
116
- LOG.debug("Created new ClassModel for #{model.full_name}")
119
+ @@log.debug("Created new ClassModel for #{model.full_name}")
117
120
  end
118
121
 
119
122
  @context_stack << model
@@ -127,7 +130,7 @@ module Dependencytree
127
130
  def _def(node)
128
131
  raise ArgumentError, "Children count for def is != 3 (#{node.children.length})" if node.children.length != 3
129
132
 
130
- LOG.debug("def #{node.children[0]}")
133
+ @@log.debug("def #{node.children[0]}")
131
134
 
132
135
  top_of_stack.add_method(node.children[0])
133
136
 
@@ -139,7 +142,7 @@ module Dependencytree
139
142
  def _casgn(node)
140
143
  raise ArgumentError, "Children count for casgn is != 3 (#{node.children.length})" if node.children.length != 3
141
144
 
142
- LOG.debug("casgn #{node.children[1]}")
145
+ @@log.debug("casgn #{node.children[1]}")
143
146
 
144
147
  top_of_stack.add_constant(node.children[1])
145
148
 
@@ -179,12 +182,12 @@ module Dependencytree
179
182
  # @param tree the AST tree node.
180
183
  def visit(path, tree)
181
184
  begin
182
- LOG.debug("Visiting path #{path}")
185
+ @@log.debug("Visiting path #{path}")
183
186
  @path = path
184
187
  visit_node(tree)
185
188
  @path = nil
186
189
  rescue Exception => e
187
- LOG.error("Error in path #{path}")
190
+ @@log.error("Error in path #{path}")
188
191
  puts "Error in path #{path}"
189
192
  raise e
190
193
  end
@@ -0,0 +1,87 @@
1
+ require "dependencytree/treeinterpreter"
2
+ require "dependencytree/dependencyresolver"
3
+
4
+ require "dependencytree/version"
5
+ require 'parser/current'
6
+ require 'optparse'
7
+ require 'pp'
8
+ require 'json'
9
+ require 'logger'
10
+
11
+ module Dependencytree
12
+
13
+ # Contains the main method for handling the program flow.
14
+ class TreeMain
15
+ def self.handle_path(options, consumer, path)
16
+ if options[:ignore].match(path)
17
+ return
18
+ end
19
+ if File.directory?(path)
20
+ STDERR.puts path if options[:verbose]
21
+ Dir.entries(path).each { |x|
22
+ resolved = File.join(path, x)
23
+ handle_path(options, consumer, resolved) if File.directory?(resolved) && x != "." && x != ".."
24
+ handle_path(options, consumer, resolved) if File.file?(resolved) && options[:pattern].match(resolved)
25
+ }
26
+ elsif File.file?(path)
27
+ STDERR.puts path if options[:verbose]
28
+ @@log.debug("Handling path #{path}")
29
+ tree = Parser::CurrentRuby.parse_file(path)
30
+ @@log.debug("Parsed tree: #{tree}") if @@log.debug?
31
+ consumer.visit(path, tree)
32
+ end
33
+ end
34
+
35
+ def self.main
36
+ options = {}
37
+ options[:ignore] = /^$/
38
+ options[:pattern] = /.*\.rb/
39
+ OptionParser.new do |opt|
40
+ opt.on("-v", "--verbose", "Verbose output") do |o|
41
+ options[:verbose] = true
42
+ end
43
+ opt.on("-d", "--debug", "Log debugging output to file 'dependencytree.log'") do |o|
44
+ options[:debug] = true
45
+ end
46
+ opt.on("-p", "--pattern[=OPTIONAL]", "Pattern to accept source codes with (default: #{options[:pattern].to_s})") do |o|
47
+ options[:pattern] = /#{o}/
48
+ end
49
+ opt.on("-i", "--ignore[=OPTIONAL]", "Paths to not load (default: #{options[:ignore].to_s})") do |o|
50
+ options[:ignore] = /#{o}/
51
+ end
52
+ opt.on("-o", "--output[=OPTIONAL]", "Output path for the JSON file") do |o|
53
+ options[:output] = o
54
+ end
55
+ opt.on_tail("-h", "--help", "Show this message") do
56
+ puts opt
57
+ return
58
+ end
59
+ end.parse!
60
+
61
+ if options[:debug]
62
+ log = Logger.new('dependencytree.log')
63
+ log.level = Logger::WARN
64
+ else
65
+ log = Logger.new(STDOUT)
66
+ log.level = Logger::WARN
67
+ end
68
+ @@log = log
69
+
70
+ treeinterpreter = TreeInterpreter.new(log)
71
+ ARGV.each do |path|
72
+ handle_path(options, treeinterpreter, File.absolute_path(path))
73
+ end
74
+
75
+ dependencyresolver = DependencyResolver.new(log, treeinterpreter.classes_and_modules)
76
+ dependencyresolver.resolve_references
77
+
78
+ json = dependencyresolver.classes_and_modules.to_json
79
+ if options[:output]
80
+ File.write(options[:output], json)
81
+ else
82
+ puts json
83
+ end
84
+ end
85
+ end
86
+ end
87
+
@@ -1,3 +1,3 @@
1
1
  module Dependencytree
2
- VERSION = "0.1.7"
2
+ VERSION = "0.1.8"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependencytree
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephan Fuhrmann
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-09 00:00:00.000000000 Z
11
+ date: 2018-04-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -30,14 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '12.3'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '12.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.11'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.11'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: parser
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -88,6 +102,7 @@ files:
88
102
  - lib/dependencytree/classmodel.rb
89
103
  - lib/dependencytree/dependencyresolver.rb
90
104
  - lib/dependencytree/treeinterpreter.rb
105
+ - lib/dependencytree/treemain.rb
91
106
  - lib/dependencytree/version.rb
92
107
  homepage: http://www.1und1.de
93
108
  licenses: