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