Class: Archruby::Architecture::ModuleDefinition

Inherits:
Object
  • Object
show all
Defined in:
lib/archruby/architecture/module_definition.rb

Constant Summary collapse

ALLOWED_CONSTRAINTS =
['required', 'allowed', 'forbidden']

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config_definition, base_directory) ⇒ ModuleDefinition

Returns a new instance of ModuleDefinition.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/archruby/architecture/module_definition.rb', line 13

def initialize config_definition, base_directory
  @config_definition = config_definition
  @name = @config_definition.module_name
  @allowed_modules = @config_definition.allowed_modules
  @required_modules = @config_definition.required_modules
  @forbidden_modules = @config_definition.forbidden_modules
  @base_directory = base_directory
  @files_and_contents = []
  @classes = []
  @dependencies = []
  @classes_and_dependencies = []
  extract_content_of_files
  extract_dependencies
end

Instance Attribute Details

#allowed_modulesObject (readonly)

Returns the value of attribute allowed_modules.



8
9
10
# File 'lib/archruby/architecture/module_definition.rb', line 8

def allowed_modules
  @allowed_modules
end

#classesObject

Returns the value of attribute classes.



11
12
13
# File 'lib/archruby/architecture/module_definition.rb', line 11

def classes
  @classes
end

#classes_and_dependenciesObject (readonly)

Returns the value of attribute classes_and_dependencies.



8
9
10
# File 'lib/archruby/architecture/module_definition.rb', line 8

def classes_and_dependencies
  @classes_and_dependencies
end

#dependenciesObject (readonly)

Returns the value of attribute dependencies.



8
9
10
# File 'lib/archruby/architecture/module_definition.rb', line 8

def dependencies
  @dependencies
end

#forbidden_modulesObject (readonly)

Returns the value of attribute forbidden_modules.



8
9
10
# File 'lib/archruby/architecture/module_definition.rb', line 8

def forbidden_modules
  @forbidden_modules
end

#nameObject (readonly)

Returns the value of attribute name.



8
9
10
# File 'lib/archruby/architecture/module_definition.rb', line 8

def name
  @name
end

#required_modulesObject (readonly)

Returns the value of attribute required_modules.



8
9
10
# File 'lib/archruby/architecture/module_definition.rb', line 8

def required_modules
  @required_modules
end

Instance Method Details

#extract_content_of_files(file_extractor = Archruby::Architecture::FileContent) ⇒ Object



28
29
30
31
32
33
34
35
# File 'lib/archruby/architecture/module_definition.rb', line 28

def extract_content_of_files file_extractor = Archruby::Architecture::FileContent
  return if !@classes.empty?
  file_extractor = file_extractor.new(@base_directory)
  @config_definition.files.each do |file|
    file_content = file_extractor.all_content_from_directory file
    @files_and_contents << file_content
  end
end

#extract_dependencies(ruby_parser = Archruby::Ruby::Parser) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/archruby/architecture/module_definition.rb', line 37

def extract_dependencies ruby_parser = Archruby::Ruby::Parser
  return if !@classes.empty?
  @files_and_contents.each do |file_and_content|
    file_and_content.each do |file_name, content|
      parser = ruby_parser.new content
      @classes << parser.classes
      @dependencies << parser.dependencies
      @classes_and_dependencies << parser.classes_and_dependencies
    end
  end
  @classes << @config_definition.gems
  @classes.flatten!
  @dependencies.flatten!
end

#is_empty?Boolean

Returns:

  • (Boolean)


115
116
117
# File 'lib/archruby/architecture/module_definition.rb', line 115

def is_empty?
  @classes.empty?
end

#is_external?Boolean

Returns:

  • (Boolean)


111
112
113
# File 'lib/archruby/architecture/module_definition.rb', line 111

def is_external?
  !@config_definition.gems.empty?
end

#is_mine?(class_name) ⇒ Boolean

Returns:

  • (Boolean)


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/archruby/architecture/module_definition.rb', line 52

def is_mine? class_name
  splited_class_name = class_name.split('::')
  first_class_name = splited_class_name.first
  is_mine = false
  if first_class_name.empty?
    #pocurando por um match exato de dependencia
    first_name = splited_class_name[1]
    splited_class_name.shift # retirando o elemento ''
    class_name = splited_class_name.join("::")
    @classes.each do |klass|
      #TODO Arrumar isso com uma expressao regular
      if klass.include?(class_name) && klass.size == class_name.size
        is_mine = true
        break
      end
    end
    if !is_mine && !@config_definition.gems.empty?
      @classes.each do |klass|
        #TODO Arrumar isso com uma expressao regular
        if klass.include?(first_name) && klass.size == first_name.size
          is_mine = true
          break
        end
      end
    end
  end
  if !is_mine
    # procurando por acesso a classe que possa ser desse modulo
    class_name = splited_class_name.join("::")
    included_separator = class_name.include?("::")
    @classes.each do |klass|
      #TODO Arrumar isso com uma expressao regular
      if included_separator
        if klass.include?(class_name)
          is_mine = true
          break
        end
      else
        if klass.include?(class_name) && klass.size == class_name.size
          is_mine = true
          break
        end
      end
    end
  end
  if !is_mine
    # procurando por GEM
    @classes.each do |klass|
      #TODO Arrumar isso com uma expressao regular
      if klass.include?(first_class_name) && klass.size == first_class_name.size
        is_mine = true
        break
      end
    end
  end

  return is_mine
end

#verify_allowed(architecture) ⇒ Object



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/archruby/architecture/module_definition.rb', line 191

def verify_allowed architecture
  return if @config_definition.allowed_modules.empty?
  breaks = []
  @classes_and_dependencies.each do |class_and_depencies|
    class_and_depencies.each do |class_name, dependencies|
      dependencies.each do |dependency|
        module_name = architecture.module_name(dependency.class_name)
        next if architecture.is_ruby_internals? module_name
        if module_name != self.name && !@config_definition.allowed_modules.include?(module_name)
          next if /[A-Z]_+[A-Z]/.match(dependency.class_name)
          breaks << Archruby::Architecture::ConstraintBreak.new(
            :type => 'divergence',
            :class_origin => class_name,
            :line_origin => dependency.line_number,
            :class_target => dependency.class_name,
            :module_origin => self.name,
            :module_target => module_name,
            :msg => "module #{self.name} is not allowed to depend on module #{module_name}")
        end
      end
    end
  end
  breaks
end

#verify_constraints(architecture) ⇒ Object



119
120
121
122
123
124
125
126
# File 'lib/archruby/architecture/module_definition.rb', line 119

def verify_constraints architecture
  required_breaks = verify_required architecture
  forbidden_breaks = verify_forbidden architecture
  allowed_breaks = verify_allowed architecture
  all_constraints_breaks = [required_breaks, forbidden_breaks, allowed_breaks].flatten
  all_constraints_breaks.delete(nil)
  all_constraints_breaks
end

#verify_forbidden(architecture) ⇒ Object



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/archruby/architecture/module_definition.rb', line 166

def verify_forbidden architecture
  return if @config_definition.forbidden_modules.empty?
  breaks = []
  @classes_and_dependencies.each do |class_and_depencies|
    class_and_depencies.each do |class_name, dependencies|
      dependencies.each do |dependency|
        module_name = architecture.module_name(dependency.class_name)
        next if architecture.is_ruby_internals? module_name
        if @config_definition.forbidden_modules.include? module_name
          next if /[A-Z]_+[A-Z]/.match(dependency.class_name)
          breaks << Archruby::Architecture::ConstraintBreak.new(
            :type => 'divergence',
            :class_origin => class_name,
            :line_origin => dependency.line_number,
            :class_target => dependency.class_name,
            :module_origin => self.name,
            :module_target => module_name,
            :msg => "accessing a module which is forbidden")
        end
      end
    end
  end
  breaks
end

#verify_required(architecture) ⇒ Object

Verifica todas as classes do modulo Cada uma deve, de alguma forma, depender dos modulos que estao listados como required



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/archruby/architecture/module_definition.rb', line 130

def verify_required architecture
  return if @config_definition.required_modules.empty?
  breaks = []
  @classes_and_dependencies.each_with_index do |class_and_depencies, index|
    if class_and_depencies.empty?
      breaks << Archruby::Architecture::ConstraintBreak.new(
        :type => 'absence',
        :module_origin => self.name,
        :module_target => @config_definition.required_modules.first,
        :class_origin => @classes[index],
        :msg => "not implement a required module"
      )
      next
    end
    class_and_depencies.each do |class_name, dependencies|
      dependency_module_names = []
      dependencies.each do |dependency|
        module_name = architecture.module_name(dependency.class_name)
        dependency_module_names << module_name
      end
      @config_definition.required_modules.each do |required_module|
        if !dependency_module_names.include?(required_module)
          breaks << Archruby::Architecture::ConstraintBreak.new(
            :type => 'absence',
            :module_origin => self.name,
            :module_target => required_module,
            :class_origin => class_name,
            :msg => "not implement a required module"
          )
        end
      end
    end
  end
  breaks
end