dependencytree 0.1.7 → 0.1.8

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 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: