Module: Maruto::ModuleDefinition

Defined in:
lib/maruto/module_definition.rb

Defined Under Namespace

Classes: ModuleSorter

Class Method Summary collapse

Class Method Details

.analyse_module_definitions(module_definitions) ⇒ Object



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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/maruto/module_definition.rb', line 77

def self.analyse_module_definitions(module_definitions)
  h = Hash.new
  module_definitions.each do |m|
    mod_name = m[:name]
    if h.include? mod_name then
      # disable first module
      h[mod_name][:active] = false
      m[:warnings] ||= []
      m[:warnings] << { :file => m[:defined], :message => "duplicate module definition (in '#{h[mod_name][:defined]}' and '#{m[:defined]}')" }
    end
    if m[:active]
      h[mod_name] = m
      m[:config_path] = "app/code/#{m[:code_pool]}/#{mod_name.to_s.gsub(/_/, '/')}/etc/config.xml"
      if !File.exist?(m[:config_path])
        m[:warnings] ||= []
        m[:warnings]<< { :file => m[:defined], :message => "config.xml is missing (searching '#{m[:config_path]}' for #{m[:name]})" }
        m[:active] = false
      end
    else
      if m[:code_pool] == :core and m[:name].to_s.start_with? 'Mage_' then
        m[:warnings] ||= []
        m[:warnings] << { :file => m[:defined], :message => "core/#{m[:name]} is inactive, but models and helpers will still be loaded" }
      end
    end
  end
  # remove inactive modules
  h.reject!{|n,m| !m[:active]}
  # check dependencies
  h.reject{|n,m| !m.include? :dependencies}.each do |mod_name, m|
    # group by module name: hash of module_name => [module_name]
    dependencies = m[:dependencies].group_by{ |e| e }
    # find duplicates
    duplicates       = Hash[dependencies.select{ |k, v| v.size > 1 }].keys  # in ruby 1.8.7 select returns an array of tuples
    # unique values
    m[:dependencies] = dependencies.keys
    if duplicates.size > 0
      m[:warnings] ||= []
      m[:warnings] << { :file => m[:defined], :message => "duplicate dependencies (#{duplicates.join(', ')})" }
    end
    m[:dependencies].delete_if do |d|
      unless h.include? d
        m[:warnings] ||= []
        m[:warnings] << { :file => m[:defined], :message => "missing dependency: '#{d}'" }
        true
      end
    end
  end
  [ModuleSorter.new(h).sorted, h]
end

.parse_all_module_definitionsObject



57
58
59
# File 'lib/maruto/module_definition.rb', line 57

def self.parse_all_module_definitions()
  Dir.glob('app/etc/modules/*.xml').reduce([]) { |result, path| result + self.parse_module_definition_file(path) }
end

.parse_module_definition(xml_node) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/maruto/module_definition.rb', line 7

def self.parse_module_definition(xml_node)
  module_definition = { :name => xml_node.name.to_sym }

  module_definition[:active]    = !(/^(false|off)$/ =~ xml_node.at_xpath('active').content) if xml_node.at_xpath('active')
  module_definition[:code_pool] = xml_node.at_xpath('codePool').content.to_sym if xml_node.at_xpath('codePool')

  deps = xml_node.xpath('depends/*').map { |e| e.name.to_sym }
  module_definition[:dependencies] = deps if deps.size > 0

  unless xml_node.at_xpath('active') and /^(true|false|off)$/ =~ xml_node.at_xpath('active').content then
    module_definition[:warnings] = []
    # TODO write test
    if xml_node.at_xpath('active')
      module_definition[:warnings] << { :message => "value for active element should be in ['true','false','off'] (element: #{xml_node.at_xpath('active')})" }
    else
      module_definition[:warnings] << { :message => "missing element: active (#{xml_node.path})" }
    end
  end

  unless xml_node.at_xpath('codePool') and /^(core|community|local)$/ =~ xml_node.at_xpath('codePool').content then
    module_definition[:warnings] ||= []
    # TODO write test
    if xml_node.at_xpath('codePool')
      module_definition[:warnings] << { :message => "value for codePool element should be in ['core','community','local'] (element: #{xml_node.at_xpath('codePool')})" }
    else
      module_definition[:warnings] << { :message => "missing element: codePool (#{xml_node.path})" }
    end
  end

  module_definition
end

.parse_module_definition_file(path) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/maruto/module_definition.rb', line 39

def self.parse_module_definition_file(path)
  f = File.open(path)
  doc = Nokogiri::XML(f) { |config| config.strict }
  f.close

  modules = doc.xpath('//modules/*').map { |xml_node| self.parse_module_definition(xml_node).merge({:defined => path}) }

  modules.each do |m|
    if m.include? :warnings then
      m[:warnings].each do |w|
        w[:file] = path
      end
    end
  end

  modules
end