archruby 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +32 -0
- data/Rakefile +1 -0
- data/archruby.gemspec +28 -0
- data/bin/archruby +20 -0
- data/bin/constraints_breaks.yml +29 -0
- data/constraints_breaks.yml +22 -0
- data/lib/archruby.rb +47 -0
- data/lib/archruby/architecture/architecture.rb +83 -0
- data/lib/archruby/architecture/config_definition.rb +66 -0
- data/lib/archruby/architecture/constraint_break.rb +22 -0
- data/lib/archruby/architecture/dependency.rb +11 -0
- data/lib/archruby/architecture/file_content.rb +24 -0
- data/lib/archruby/architecture/module_definition.rb +218 -0
- data/lib/archruby/architecture/parser.rb +58 -0
- data/lib/archruby/presenters/graph.rb +132 -0
- data/lib/archruby/presenters/text.rb +14 -0
- data/lib/archruby/presenters/yaml.rb +28 -0
- data/lib/archruby/ruby/core_library.rb +26 -0
- data/lib/archruby/ruby/parser.rb +409 -0
- data/lib/archruby/ruby/std_library.rb +22 -0
- data/lib/archruby/ruby/var_propagation.rb +46 -0
- data/lib/archruby/version.rb +3 -0
- data/spec/architecture/architecture_spec.rb +48 -0
- data/spec/architecture/config_definition_spec.rb +20 -0
- data/spec/architecture/constraint_break_spec.rb +22 -0
- data/spec/architecture/file_content_spec.rb +12 -0
- data/spec/architecture/module_definition_spec.rb +70 -0
- data/spec/architecture/parser_spec.rb +11 -0
- data/spec/archruby_spec.rb +10 -0
- data/spec/dummy_app/.gitignore +16 -0
- data/spec/dummy_app/Gemfile +45 -0
- data/spec/dummy_app/README.rdoc +28 -0
- data/spec/dummy_app/Rakefile +6 -0
- data/spec/dummy_app/app/assets/images/.keep +0 -0
- data/spec/dummy_app/app/assets/javascripts/application.js +16 -0
- data/spec/dummy_app/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy_app/app/controllers/application_controller.rb +17 -0
- data/spec/dummy_app/app/controllers/concerns/.keep +0 -0
- data/spec/dummy_app/app/helpers/application_helper.rb +2 -0
- data/spec/dummy_app/app/mailers/.keep +0 -0
- data/spec/dummy_app/app/models/.keep +0 -0
- data/spec/dummy_app/app/models/concerns/.keep +0 -0
- data/spec/dummy_app/app/models/module_test.rb +5 -0
- data/spec/dummy_app/app/models/teste.rb +11 -0
- data/spec/dummy_app/app/models/user.rb +9 -0
- data/spec/dummy_app/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy_app/app/views/view_test.rb +5 -0
- data/spec/dummy_app/bin/bundle +3 -0
- data/spec/dummy_app/bin/rails +4 -0
- data/spec/dummy_app/bin/rake +4 -0
- data/spec/dummy_app/config.ru +4 -0
- data/spec/dummy_app/config/application.rb +23 -0
- data/spec/dummy_app/config/boot.rb +4 -0
- data/spec/dummy_app/config/database.yml +25 -0
- data/spec/dummy_app/config/environment.rb +5 -0
- data/spec/dummy_app/config/environments/development.rb +29 -0
- data/spec/dummy_app/config/environments/production.rb +80 -0
- data/spec/dummy_app/config/environments/test.rb +36 -0
- data/spec/dummy_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy_app/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy_app/config/initializers/inflections.rb +16 -0
- data/spec/dummy_app/config/initializers/mime_types.rb +5 -0
- data/spec/dummy_app/config/initializers/secret_token.rb +12 -0
- data/spec/dummy_app/config/initializers/session_store.rb +3 -0
- data/spec/dummy_app/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy_app/config/locales/en.yml +23 -0
- data/spec/dummy_app/config/routes.rb +56 -0
- data/spec/dummy_app/db/seeds.rb +7 -0
- data/spec/dummy_app/lib/assets/.keep +0 -0
- data/spec/dummy_app/lib/fetch_facebook_info.rb +7 -0
- data/spec/dummy_app/lib/integracao_twitter.rb +5 -0
- data/spec/dummy_app/lib/tasks/.keep +0 -0
- data/spec/dummy_app/log/.keep +0 -0
- data/spec/dummy_app/public/404.html +58 -0
- data/spec/dummy_app/public/422.html +58 -0
- data/spec/dummy_app/public/500.html +57 -0
- data/spec/dummy_app/public/favicon.ico +0 -0
- data/spec/dummy_app/public/robots.txt +5 -0
- data/spec/dummy_app/test/controllers/.keep +0 -0
- data/spec/dummy_app/test/fixtures/.keep +0 -0
- data/spec/dummy_app/test/helpers/.keep +0 -0
- data/spec/dummy_app/test/integration/.keep +0 -0
- data/spec/dummy_app/test/mailers/.keep +0 -0
- data/spec/dummy_app/test/models/.keep +0 -0
- data/spec/dummy_app/test/test_helper.rb +15 -0
- data/spec/dummy_app/vendor/assets/javascripts/.keep +0 -0
- data/spec/dummy_app/vendor/assets/stylesheets/.keep +0 -0
- data/spec/fixtures/new_arch_definition.yml +32 -0
- data/spec/fixtures/ruby_example.rb +74 -0
- data/spec/ruby/parser_spec.rb +45 -0
- data/spec/ruby/var_propagation_spec.rb +22 -0
- data/spec/spec_helper.rb +1 -0
- metadata +295 -0
@@ -0,0 +1,218 @@
|
|
1
|
+
module Archruby
|
2
|
+
module Architecture
|
3
|
+
|
4
|
+
class ModuleDefinition
|
5
|
+
|
6
|
+
ALLOWED_CONSTRAINTS = ['required', 'allowed', 'forbidden']
|
7
|
+
|
8
|
+
attr_reader :name, :allowed_modules, :required_modules, :forbidden_modules,
|
9
|
+
:dependencies, :classes_and_dependencies
|
10
|
+
|
11
|
+
attr_accessor :classes
|
12
|
+
|
13
|
+
def initialize config_definition, base_directory
|
14
|
+
@config_definition = config_definition
|
15
|
+
@name = @config_definition.module_name
|
16
|
+
@allowed_modules = @config_definition.allowed_modules
|
17
|
+
@required_modules = @config_definition.required_modules
|
18
|
+
@forbidden_modules = @config_definition.forbidden_modules
|
19
|
+
@base_directory = base_directory
|
20
|
+
@files_and_contents = []
|
21
|
+
@classes = []
|
22
|
+
@dependencies = []
|
23
|
+
@classes_and_dependencies = []
|
24
|
+
extract_content_of_files
|
25
|
+
extract_dependencies
|
26
|
+
end
|
27
|
+
|
28
|
+
def extract_content_of_files file_extractor = Archruby::Architecture::FileContent
|
29
|
+
return if !@classes.empty?
|
30
|
+
file_extractor = file_extractor.new(@base_directory)
|
31
|
+
@config_definition.files.each do |file|
|
32
|
+
file_content = file_extractor.all_content_from_directory file
|
33
|
+
@files_and_contents << file_content
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def extract_dependencies ruby_parser = Archruby::Ruby::Parser
|
38
|
+
return if !@classes.empty?
|
39
|
+
@files_and_contents.each do |file_and_content|
|
40
|
+
file_and_content.each do |file_name, content|
|
41
|
+
parser = ruby_parser.new content
|
42
|
+
@classes << parser.classes
|
43
|
+
@dependencies << parser.dependencies
|
44
|
+
@classes_and_dependencies << parser.classes_and_dependencies
|
45
|
+
end
|
46
|
+
end
|
47
|
+
@classes << @config_definition.gems
|
48
|
+
@classes.flatten!
|
49
|
+
@dependencies.flatten!
|
50
|
+
end
|
51
|
+
|
52
|
+
def is_mine? class_name
|
53
|
+
splited_class_name = class_name.split('::')
|
54
|
+
first_class_name = splited_class_name.first
|
55
|
+
is_mine = false
|
56
|
+
if first_class_name.empty?
|
57
|
+
#pocurando por um match exato de dependencia
|
58
|
+
first_name = splited_class_name[1]
|
59
|
+
splited_class_name.shift # retirando o elemento ''
|
60
|
+
class_name = splited_class_name.join("::")
|
61
|
+
@classes.each do |klass|
|
62
|
+
#TODO Arrumar isso com uma expressao regular
|
63
|
+
if klass.include?(class_name) && klass.size == class_name.size
|
64
|
+
is_mine = true
|
65
|
+
break
|
66
|
+
end
|
67
|
+
end
|
68
|
+
if !is_mine && !@config_definition.gems.empty?
|
69
|
+
@classes.each do |klass|
|
70
|
+
#TODO Arrumar isso com uma expressao regular
|
71
|
+
if klass.include?(first_name) && klass.size == first_name.size
|
72
|
+
is_mine = true
|
73
|
+
break
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
if !is_mine
|
79
|
+
# procurando por acesso a classe que possa ser desse modulo
|
80
|
+
class_name = splited_class_name.join("::")
|
81
|
+
included_separator = class_name.include?("::")
|
82
|
+
@classes.each do |klass|
|
83
|
+
#TODO Arrumar isso com uma expressao regular
|
84
|
+
if included_separator
|
85
|
+
if klass.include?(class_name)
|
86
|
+
is_mine = true
|
87
|
+
break
|
88
|
+
end
|
89
|
+
else
|
90
|
+
if klass.include?(class_name) && klass.size == class_name.size
|
91
|
+
is_mine = true
|
92
|
+
break
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
if !is_mine
|
98
|
+
# procurando por GEM
|
99
|
+
@classes.each do |klass|
|
100
|
+
#TODO Arrumar isso com uma expressao regular
|
101
|
+
if klass.include?(first_class_name) && klass.size == first_class_name.size
|
102
|
+
is_mine = true
|
103
|
+
break
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
return is_mine
|
109
|
+
end
|
110
|
+
|
111
|
+
def is_external?
|
112
|
+
!@config_definition.gems.empty?
|
113
|
+
end
|
114
|
+
|
115
|
+
def is_empty?
|
116
|
+
@classes.empty?
|
117
|
+
end
|
118
|
+
|
119
|
+
def verify_constraints architecture
|
120
|
+
required_breaks = verify_required architecture
|
121
|
+
forbidden_breaks = verify_forbidden architecture
|
122
|
+
allowed_breaks = verify_allowed architecture
|
123
|
+
all_constraints_breaks = [required_breaks, forbidden_breaks, allowed_breaks].flatten
|
124
|
+
all_constraints_breaks.delete(nil)
|
125
|
+
all_constraints_breaks
|
126
|
+
end
|
127
|
+
|
128
|
+
# Verifica todas as classes do modulo
|
129
|
+
# Cada uma deve, de alguma forma, depender dos modulos que estao listados como required
|
130
|
+
def verify_required architecture
|
131
|
+
return if @config_definition.required_modules.empty?
|
132
|
+
breaks = []
|
133
|
+
@classes_and_dependencies.each_with_index do |class_and_depencies, index|
|
134
|
+
if class_and_depencies.empty?
|
135
|
+
breaks << Archruby::Architecture::ConstraintBreak.new(
|
136
|
+
:type => 'absence',
|
137
|
+
:module_origin => self.name,
|
138
|
+
:module_target => @config_definition.required_modules.first,
|
139
|
+
:class_origin => @classes[index],
|
140
|
+
:msg => "not implement a required module"
|
141
|
+
)
|
142
|
+
next
|
143
|
+
end
|
144
|
+
class_and_depencies.each do |class_name, dependencies|
|
145
|
+
dependency_module_names = []
|
146
|
+
dependencies.each do |dependency|
|
147
|
+
module_name = architecture.module_name(dependency.class_name)
|
148
|
+
dependency_module_names << module_name
|
149
|
+
end
|
150
|
+
@config_definition.required_modules.each do |required_module|
|
151
|
+
if !dependency_module_names.include?(required_module)
|
152
|
+
breaks << Archruby::Architecture::ConstraintBreak.new(
|
153
|
+
:type => 'absence',
|
154
|
+
:module_origin => self.name,
|
155
|
+
:module_target => required_module,
|
156
|
+
:class_origin => class_name,
|
157
|
+
:msg => "not implement a required module"
|
158
|
+
)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
breaks
|
164
|
+
end
|
165
|
+
|
166
|
+
def verify_forbidden architecture
|
167
|
+
return if @config_definition.forbidden_modules.empty?
|
168
|
+
breaks = []
|
169
|
+
@classes_and_dependencies.each do |class_and_depencies|
|
170
|
+
class_and_depencies.each do |class_name, dependencies|
|
171
|
+
dependencies.each do |dependency|
|
172
|
+
module_name = architecture.module_name(dependency.class_name)
|
173
|
+
next if architecture.is_ruby_internals? module_name
|
174
|
+
if @config_definition.forbidden_modules.include? module_name
|
175
|
+
next if /[A-Z]_+[A-Z]/.match(dependency.class_name)
|
176
|
+
breaks << Archruby::Architecture::ConstraintBreak.new(
|
177
|
+
:type => 'divergence',
|
178
|
+
:class_origin => class_name,
|
179
|
+
:line_origin => dependency.line_number,
|
180
|
+
:class_target => dependency.class_name,
|
181
|
+
:module_origin => self.name,
|
182
|
+
:module_target => module_name,
|
183
|
+
:msg => "accessing a module which is forbidden")
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
breaks
|
189
|
+
end
|
190
|
+
|
191
|
+
def verify_allowed architecture
|
192
|
+
return if @config_definition.allowed_modules.empty?
|
193
|
+
breaks = []
|
194
|
+
@classes_and_dependencies.each do |class_and_depencies|
|
195
|
+
class_and_depencies.each do |class_name, dependencies|
|
196
|
+
dependencies.each do |dependency|
|
197
|
+
module_name = architecture.module_name(dependency.class_name)
|
198
|
+
next if architecture.is_ruby_internals? module_name
|
199
|
+
if module_name != self.name && !@config_definition.allowed_modules.include?(module_name)
|
200
|
+
next if /[A-Z]_+[A-Z]/.match(dependency.class_name)
|
201
|
+
breaks << Archruby::Architecture::ConstraintBreak.new(
|
202
|
+
:type => 'divergence',
|
203
|
+
:class_origin => class_name,
|
204
|
+
:line_origin => dependency.line_number,
|
205
|
+
:class_target => dependency.class_name,
|
206
|
+
:module_origin => self.name,
|
207
|
+
:module_target => module_name,
|
208
|
+
:msg => "module #{self.name} is not allowed to depend on module #{module_name}")
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
breaks
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Archruby
|
4
|
+
module Architecture
|
5
|
+
|
6
|
+
class Parser
|
7
|
+
attr_reader :modules
|
8
|
+
|
9
|
+
def initialize config_file_path, base_path
|
10
|
+
@config_file = config_file_path
|
11
|
+
@base_path = base_path
|
12
|
+
@modules = []
|
13
|
+
parse
|
14
|
+
ruby_std_lib_module
|
15
|
+
ruby_core_module
|
16
|
+
unknow_module
|
17
|
+
end
|
18
|
+
|
19
|
+
def parse
|
20
|
+
parsed_yaml = yaml_parser.load_file @config_file
|
21
|
+
parsed_yaml.each do |module_name, definitions|
|
22
|
+
begin
|
23
|
+
config_definition = Archruby::Architecture::ConfigDefinition.new module_name, definitions
|
24
|
+
module_definition = Archruby::Architecture::ModuleDefinition.new config_definition, @base_path
|
25
|
+
rescue ArchChecker::MultipleConstraints => e
|
26
|
+
STDOUT.puts "The config file is not right: #{e.msg} | err_code: #{e.status_code} | module_definition: #{module_name}"
|
27
|
+
exit(e.status_code)
|
28
|
+
end
|
29
|
+
@modules << module_definition
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def yaml_parser
|
34
|
+
YAML
|
35
|
+
end
|
36
|
+
|
37
|
+
def ruby_std_lib_module
|
38
|
+
config_definition_std_lib = Archruby::Architecture::ConfigDefinition.new Archruby::Ruby::STD_LIB_NAME, {"gems"=>"", "files"=>"", "allowed"=>"", "forbidden" => ""}
|
39
|
+
module_definiton_std_lib = Archruby::Architecture::ModuleDefinition.new(config_definition_std_lib, @base_path)
|
40
|
+
module_definiton_std_lib.classes = Archruby::Ruby::STD_LIBRARY_CLASSES
|
41
|
+
@modules << module_definiton_std_lib
|
42
|
+
end
|
43
|
+
|
44
|
+
def ruby_core_module
|
45
|
+
config_definition_core = Archruby::Architecture::ConfigDefinition.new Archruby::Ruby::CORE_LIB_NAME, {"gems"=>"", "files"=>"", "allowed"=>"", "forbidden" => ""}
|
46
|
+
module_definiton_core = Archruby::Architecture::ModuleDefinition.new(config_definition_core, @base_path)
|
47
|
+
module_definiton_core.classes = Archruby::Ruby::CORE_LIBRARY_CLASSES
|
48
|
+
@modules << module_definiton_core
|
49
|
+
end
|
50
|
+
|
51
|
+
def unknow_module
|
52
|
+
config_definition_unknow = Archruby::Architecture::ConfigDefinition.new "unknown", {"gems"=>"unknown", "files"=>"", "allowed"=>"", "forbidden" => ""}
|
53
|
+
@modules << Archruby::Architecture::ModuleDefinition.new(config_definition_unknow, @base_path)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'graphviz'
|
2
|
+
|
3
|
+
module Archruby
|
4
|
+
module Presenters
|
5
|
+
|
6
|
+
class Graph
|
7
|
+
|
8
|
+
def render architecture
|
9
|
+
modules = architecture.modules
|
10
|
+
|
11
|
+
g = GraphViz.new(:G)
|
12
|
+
|
13
|
+
g.edge[:color] = "black"
|
14
|
+
g.edge[:style] = "filled"
|
15
|
+
g.edge[:label] = ""
|
16
|
+
|
17
|
+
internal = g.subgraph("internal", "label" => "Internal", "color" => "black")
|
18
|
+
|
19
|
+
external = g.subgraph("external", "label" => "External", "color" => "black", "rank" => "same")
|
20
|
+
|
21
|
+
nodes = {}
|
22
|
+
|
23
|
+
internal_nodes = []
|
24
|
+
external_nodes = []
|
25
|
+
modules.each do |module_definiton|
|
26
|
+
next if module_definiton.name == Archruby::Ruby::STD_LIB_NAME || module_definiton.name == Archruby::Ruby::CORE_LIB_NAME
|
27
|
+
if module_definiton.is_external?
|
28
|
+
nodes[module_definiton.name] = external.add_nodes(module_definiton.name, "shape" => "parallelogram", "color" => "gray60", "style" => "filled")
|
29
|
+
external_nodes << nodes[module_definiton.name]
|
30
|
+
else
|
31
|
+
if module_definiton.is_empty?
|
32
|
+
nodes[module_definiton.name] = internal.add_nodes("#{module_definiton.name}\n [empty]", "color" => "gray74", "shape" => "rectangle")
|
33
|
+
else
|
34
|
+
nodes[module_definiton.name] = internal.add_nodes(module_definiton.name, "color" => "gray92", "style" => "filled", "shape" => "rectangle")
|
35
|
+
end
|
36
|
+
internal_nodes << nodes[module_definiton.name]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
edges = {}
|
41
|
+
edges_objs = []
|
42
|
+
|
43
|
+
modules.each do |module_definiton|
|
44
|
+
module_name = module_definiton.name
|
45
|
+
node_origin = nodes[module_name]
|
46
|
+
edges[module_name] ||= {}
|
47
|
+
edges[module_name][:edges] ||= []
|
48
|
+
|
49
|
+
module_definiton.dependencies.each do |class_name|
|
50
|
+
module_dest = architecture.module_name class_name
|
51
|
+
next if module_dest == Archruby::Ruby::STD_LIB_NAME || module_dest == Archruby::Ruby::CORE_LIB_NAME
|
52
|
+
how_many_access = architecture.how_many_access_to module_name, module_dest
|
53
|
+
if !edges[module_name][:edges].include?(module_dest) && module_dest != module_name
|
54
|
+
edges[module_name][:edges] << module_dest
|
55
|
+
node_dest = nodes[module_dest]
|
56
|
+
edges_objs << internal.add_edges(node_origin, node_dest, :headlabel => how_many_access, :minlen => 2)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
constraints_breaks = architecture.constraints_breaks
|
62
|
+
constraints_breaks.each_with_index do |constraint_break, index|
|
63
|
+
module_origin = constraint_break.module_origin
|
64
|
+
module_target = constraint_break.module_target
|
65
|
+
contraint_type = constraint_break.type
|
66
|
+
node_origin = nodes[module_origin]
|
67
|
+
node_dest = nodes[module_target]
|
68
|
+
node_found = false
|
69
|
+
edges_objs.each do |edge|
|
70
|
+
if edge.node_one == module_origin && edge.node_two == module_target
|
71
|
+
if contraint_type == Archruby::Architecture::ConstraintBreak::ABSENSE
|
72
|
+
edge.set do |e|
|
73
|
+
e.headlabel = "X (##{architecture.how_many_break(module_origin, module_target, Archruby::Architecture::ConstraintBreak::ABSENSE)})"
|
74
|
+
e.color = "red"
|
75
|
+
e.style = "bold"
|
76
|
+
e.minlen = 2
|
77
|
+
end
|
78
|
+
else
|
79
|
+
edge.set do |e|
|
80
|
+
e.headlabel = "! (##{architecture.how_many_break(module_origin, module_target, Archruby::Architecture::ConstraintBreak::DIVERGENCE)})"
|
81
|
+
e.color = "orange"
|
82
|
+
e.style = "bold"
|
83
|
+
e.minlen = 2
|
84
|
+
end
|
85
|
+
end
|
86
|
+
node_found = true
|
87
|
+
break
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
if !node_found
|
92
|
+
if contraint_type == Archruby::Architecture::ConstraintBreak::ABSENSE
|
93
|
+
break_count = architecture.how_many_break(module_origin, module_target, Archruby::Architecture::ConstraintBreak::ABSENSE)
|
94
|
+
edges_objs << g.add_edges(node_origin, node_dest, :color => 'red', :headlabel => "X (##{break_count})", 'style' => 'bold', :minlen => 2)
|
95
|
+
else
|
96
|
+
break_count = architecture.how_many_break(module_origin, module_target, Archruby::Architecture::ConstraintBreak::DIVERGENCE)
|
97
|
+
edges_objs << g.add_edges(node_origin, node_dest, :color => 'red', :headlabel => "! (##{break_count})", 'style' => 'bold', :minlen => 2)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
modules.each do |module_definiton|
|
103
|
+
next if module_definiton.name == Archruby::Ruby::STD_LIB_NAME || module_definiton.name == Archruby::Ruby::CORE_LIB_NAME
|
104
|
+
module_origin = module_definiton.is_empty? ? "#{module_definiton.name}\n [empty]" : module_definiton.name
|
105
|
+
node_origin = nodes[module_origin]
|
106
|
+
#puts module_definiton.name.inspect
|
107
|
+
#puts module_definiton.classes.inspect
|
108
|
+
#puts module_definiton.dependencies.inspect
|
109
|
+
#puts module_definiton.classes_and_dependencies.inspect
|
110
|
+
#puts
|
111
|
+
module_definiton.allowed_modules.each do |allowed_module_name|
|
112
|
+
module_target = allowed_module_name
|
113
|
+
node_dest = nodes[allowed_module_name]
|
114
|
+
edge_found = false
|
115
|
+
edges_objs.each do |edge|
|
116
|
+
if edge.node_one == module_origin && edge.node_two == module_target
|
117
|
+
edge_found = true
|
118
|
+
break
|
119
|
+
end
|
120
|
+
end
|
121
|
+
if !edge_found
|
122
|
+
internal.add_edges(node_origin, node_dest, :color => 'gray74', :label => "[none]", :minlen => 2)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
g.output( :png => "architecture.png" )
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module ArchChecker
|
2
|
+
module Presenters
|
3
|
+
class Text
|
4
|
+
def render constraint_breaks
|
5
|
+
file = File.new('violations.txt', 'w')
|
6
|
+
constraint_breaks.each do |constraint_break|
|
7
|
+
constraint_break.each do |violations|
|
8
|
+
file.puts "#{violations.keys.first} #{violations[violations.keys.first]}"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Archruby
|
4
|
+
module Presenters
|
5
|
+
|
6
|
+
class Yaml
|
7
|
+
def render architecture
|
8
|
+
constraints_breaks = architecture.constraints_breaks
|
9
|
+
file = File.new('constraints_breaks.yml', 'w')
|
10
|
+
contraints = []
|
11
|
+
constraints_breaks.each do |constraint_break|
|
12
|
+
constraint = {}
|
13
|
+
constraint[constraint_break.type] = {}
|
14
|
+
constraint[constraint_break.type]['class_origin'] = constraint_break.class_origin
|
15
|
+
constraint[constraint_break.type]['line_origin'] = constraint_break.line_origin
|
16
|
+
constraint[constraint_break.type]['class_target'] = constraint_break.class_target
|
17
|
+
constraint[constraint_break.type]['module_origin'] = constraint_break.module_origin
|
18
|
+
constraint[constraint_break.type]['module_target'] = constraint_break.module_target
|
19
|
+
constraint[constraint_break.type]['message'] = constraint_break.msg
|
20
|
+
contraints << constraint
|
21
|
+
end
|
22
|
+
file.write contraints.to_yaml
|
23
|
+
file.close
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|