cpp_dependency_graph 0.4.0 → 0.4.1

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