cpp_dependency_graph 0.4.0 → 0.4.1

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
  SHA256:
3
- metadata.gz: 49dbf00badc862586088263651f5b0eeb26b9953fae870baa86e14e9d96dee36
4
- data.tar.gz: e935e59934e696511cde583c8b89b60b201cafc84e65e3dab487829769f3f9ad
3
+ metadata.gz: bab309d43e6015c06bf3836941534efe150bd78759d81f0e4ff538b4f33a054f
4
+ data.tar.gz: 46b1aadfe5915a147b9c89090c4cc7d047cdad269d9ec70a11c12567b56e8eb0
5
5
  SHA512:
6
- metadata.gz: 203cf7a07370d1fde0cb90e376d1b45ec605aa7332dff34247e99463099b1e496d3f05c831589df73c03c50c776a3838db201acd759468062db49c87560de48f
7
- data.tar.gz: 4e122ad96022ba802effbc94c9ac9c185810838ed762514380444d2227ede7f25a97c66eafd7f8436a59d984f5816dad39fc35379dc2131ff8b0012a5d2e8ce8
6
+ metadata.gz: 4ef9120a1d26f432cfc26e9906412391fa03aadbd34ebc5a110e3dfc674e22a6258f9f453044428da590d8ea51c873307345f09116b847c384ecc3f5787dddd0
7
+ data.tar.gz: 99995d31dce112db4b38fd9a4e71c4cb4d012829d727a260a396d0dd1def7008af60d0fcd3febe717c224582dd499c36c4ccfec5574c7166629daa72564dd8b2
data/bin/console CHANGED
File without changes
@@ -29,8 +29,8 @@ Gem::Specification.new do |s|
29
29
  s.rubygems_version = '3.1.2'
30
30
 
31
31
  s.add_runtime_dependency 'docopt', '~> 0.6'
32
- s.add_runtime_dependency 'ruby-graphviz', '~> 1.2'
33
32
  s.add_runtime_dependency 'json', '~> 2.3.0'
33
+ s.add_runtime_dependency 'ruby-graphviz', '~> 1.2'
34
34
 
35
35
  s.add_development_dependency 'bundler', '~> 2.1'
36
36
  s.add_development_dependency 'debase', '~> 0.2'
File without changes
@@ -25,6 +25,7 @@ class BidirectionalHash
25
25
 
26
26
  def fetch_from(hash, key)
27
27
  return nil unless hash.key?(key)
28
+
28
29
  v = hash[key]
29
30
  v.length == 1 ? v.first : v.dup
30
31
  end
@@ -20,6 +20,7 @@ class ComponentDependencyGraph
20
20
 
21
21
  def links(name)
22
22
  return {} unless all_links.key?(name)
23
+
23
24
  links = incoming_links(name)
24
25
  links.merge!(outgoing_links(name))
25
26
  links
@@ -11,7 +11,7 @@ class DirTree
11
11
  attr_reader :tree
12
12
 
13
13
  def initialize(path)
14
- @tree ||= File.directory?(path) ? parse_dirs(path) : {}
14
+ @tree = File.directory?(path) ? parse_dirs(path) : {}
15
15
  end
16
16
 
17
17
  private
@@ -22,9 +22,12 @@ class DirTree
22
22
  # TODO: Use Dir.map.compact|filter instead here
23
23
  Dir.foreach(path) do |entry|
24
24
  next if ['..', '.'].include?(entry)
25
+
25
26
  full_path = File.join(path, entry)
26
27
  next unless File.directory?(full_path)
28
+
27
29
  next unless source_files_present?(full_path)
30
+
28
31
  data[:children] << parse_dirs(full_path, entry)
29
32
  end
30
33
  data
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Utility methods for parsing directories
4
+ module DirectoryParser
5
+ def fetch_all_dirs(root_dir)
6
+ Find.find(root_dir).select { |e| File.directory?(e) && e != root_dir }
7
+ end
8
+
9
+ def glob_files(path, extensions)
10
+ path = File.join(path, File::SEPARATOR, '**', File::SEPARATOR, '*' + extensions)
11
+ Dir.glob(path).select { |entry| File.file?(entry) }.compact
12
+ end
13
+ end
@@ -20,6 +20,7 @@ class FileDependencyGraph
20
20
 
21
21
  def links(name)
22
22
  return {} unless all_links.key?(name)
23
+
23
24
  links = incoming_links(name)
24
25
  links.merge!(outgoing_links(name))
25
26
  links
@@ -6,9 +6,9 @@ require 'ruby-graphviz'
6
6
  class GraphToDotVisualiser
7
7
  def generate(deps, file)
8
8
  @g = GraphViz.new('dependency_graph')
9
- nodes = create_nodes(deps)
10
- connect_nodes(deps, nodes)
11
- @g.output(:dot => file)
9
+ create_nodes(deps)
10
+ connect_nodes(deps)
11
+ @g.output(dot: file)
12
12
  end
13
13
 
14
14
  private
@@ -17,20 +17,20 @@ class GraphToDotVisualiser
17
17
  node_names = deps.flat_map do |_, links|
18
18
  links.map { |link| [link.source, link.target] }.flatten
19
19
  end.uniq
20
- nodes = node_names.map { |name| [name, create_node(name)] }.to_h
21
- nodes
20
+ node_names.each do |name|
21
+ add_node(name)
22
+ end
22
23
  end
23
24
 
24
- def create_node(name)
25
- node = @g.add_node(name, :shape => 'box3d')
26
- node
25
+ def add_node(name)
26
+ @g.add_node(name, shape: 'box3d')
27
27
  end
28
28
 
29
- def connect_nodes(deps, nodes)
29
+ def connect_nodes(deps)
30
30
  deps.each do |source, links|
31
31
  links.each do |link|
32
32
  if link.cyclic?
33
- @g.add_edges(source, link.target, :color => 'red')
33
+ @g.add_edges(source, link.target, color: 'red')
34
34
  else
35
35
  @g.add_edges(source, link.target)
36
36
  end
@@ -11,9 +11,7 @@ class IncludeComponentDependencyGraph
11
11
  end
12
12
 
13
13
  def all_links
14
- components = @project.source_components
15
- all_source_files = components.values.flat_map(&:source_files)
16
- all_source_files.map do |file|
14
+ @project.source_files.map do |file|
17
15
  links = file.includes.map { |inc| Link.new(file.basename, inc, false) }
18
16
  [file.basename, links]
19
17
  end.to_h
@@ -10,22 +10,15 @@ class IncludeFileDependencyGraph
10
10
  @project = project
11
11
  end
12
12
 
13
- def all_links
14
- # TODO: Implement
15
- {}
16
- end
17
-
18
13
  def all_cyclic_links
19
14
  # TODO: Implement
20
15
  end
21
16
 
22
17
  def links(file_name)
23
- components = @project.source_components
24
- all_source_files = components.values.flat_map(&:source_files)
25
- files = all_source_files.select do |file|
18
+ files = @project.source_files.select do |_, file|
26
19
  file.includes.include?(file_name)
27
20
  end
28
- files.map do |file|
21
+ files.map do |_, file|
29
22
  links = [Link.new(file.basename, file_name, false)]
30
23
  [file.basename, links]
31
24
  end.to_h
@@ -19,6 +19,7 @@ class IncludeToComponentResolver
19
19
 
20
20
  def component_for_include(include)
21
21
  return '' unless source_files.key?(include)
22
+
22
23
  @component_include_map_cache[include] = component_for_include_private(include) unless @component_include_map_cache.key?(include)
23
24
  @component_include_map_cache[include]
24
25
  end
@@ -35,6 +36,7 @@ class IncludeToComponentResolver
35
36
  header_file = source_files[include]
36
37
  implementation_files = implementation_files(header_file)
37
38
  return header_file.parent_component if implementation_files.empty?
39
+
38
40
  implementation_files[0].parent_component
39
41
  end
40
42
 
@@ -2,11 +2,14 @@
2
2
 
3
3
  require 'find'
4
4
 
5
+ require_relative 'directory_parser'
5
6
  require_relative 'include_to_component_resolver'
6
7
  require_relative 'source_component'
7
8
 
8
9
  # Parses all components of a project
9
10
  class Project
11
+ include DirectoryParser
12
+
10
13
  def initialize(path)
11
14
  @path = path
12
15
  @include_resolver = IncludeToComponentResolver.new(source_components)
@@ -18,9 +21,18 @@ class Project
18
21
 
19
22
  def source_component(name)
20
23
  return SourceComponent.new('NULL') unless source_components.key?(name)
24
+
21
25
  source_components[name]
22
26
  end
23
27
 
28
+ def project_component
29
+ @project_component ||= build_project_component
30
+ end
31
+
32
+ def source_files
33
+ @source_files ||= build_source_files
34
+ end
35
+
24
36
  def dependencies(component)
25
37
  # TODO: This is repeating the same work twice! component_for_include is called when calling external_includes
26
38
  external_includes(component).map { |include| @include_resolver.component_for_include(include) }.reject(&:empty?).uniq
@@ -32,6 +44,19 @@ class Project
32
44
 
33
45
  private
34
46
 
47
+ def build_source_files
48
+ # TODO: Breaking Demeter's law here
49
+ files = project_component.values.flat_map(&:source_files)
50
+ files.map do |file|
51
+ [file.path, file]
52
+ end.to_h
53
+ end
54
+
55
+ def build_project_component
56
+ c = SourceComponent.new(@path)
57
+ { c.name => c }
58
+ end
59
+
35
60
  def build_source_components
36
61
  # TODO: Dealing with source components with same dir name?
37
62
  dirs = fetch_all_dirs(@path)
@@ -41,8 +66,4 @@ class Project
41
66
  end.to_h
42
67
  components.delete_if { |_, v| v.source_files.size.zero? }
43
68
  end
44
-
45
- def fetch_all_dirs(source_dir)
46
- Find.find(source_dir).select { |e| File.directory?(e) }
47
- end
48
69
  end
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'config'
4
+ require_relative 'directory_parser'
4
5
  require_relative 'source_file'
5
6
 
6
7
  # Abstracts a source directory containing source files
7
8
  class SourceComponent
8
9
  include Config
10
+ include DirectoryParser
9
11
 
10
12
  attr_reader :path
11
13
 
@@ -32,7 +34,6 @@ class SourceComponent
32
34
  private
33
35
 
34
36
  def parse_source_files(extensions)
35
- path = File.join(@path, File::SEPARATOR) + '*' + extensions
36
- Dir.glob(path).map { |e| SourceFile.new(e) if File.file?(e) }.compact
37
+ glob_files(@path, extensions).map { |e| SourceFile.new(e) }.compact
37
38
  end
38
39
  end
@@ -53,6 +53,7 @@ class SourceFile
53
53
  def sanitised_file_contents
54
54
  contents = File.read(@path)
55
55
  return contents if contents.valid_encoding?
56
+
56
57
  contents.encode('UTF-16be', invalid: :replace, replace: '?').encode('UTF-8')
57
58
  end
58
59
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CppDependencyGraph
4
- VERSION = '0.4.0'
4
+ VERSION = '0.4.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cpp_dependency_graph
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shreyas Balakrishna
@@ -25,33 +25,33 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.6'
27
27
  - !ruby/object:Gem::Dependency
28
- name: ruby-graphviz
28
+ name: json
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.2'
33
+ version: 2.3.0
34
34
  type: :runtime
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: '1.2'
40
+ version: 2.3.0
41
41
  - !ruby/object:Gem::Dependency
42
- name: json
42
+ name: ruby-graphviz
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 2.3.0
47
+ version: '1.2'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 2.3.0
54
+ version: '1.2'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -231,6 +231,7 @@ files:
231
231
  - lib/cpp_dependency_graph/cycle_detector.rb
232
232
  - lib/cpp_dependency_graph/cyclic_link.rb
233
233
  - lib/cpp_dependency_graph/dir_tree.rb
234
+ - lib/cpp_dependency_graph/directory_parser.rb
234
235
  - lib/cpp_dependency_graph/file_dependency_graph.rb
235
236
  - lib/cpp_dependency_graph/graph_to_dot_visualiser.rb
236
237
  - lib/cpp_dependency_graph/graph_to_graphml_visualiser.rb