maruto 0.0.1 → 0.0.2

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.
data/lib/maruto.rb CHANGED
@@ -1,4 +1,5 @@
1
- require "maruto/version"
1
+ require 'maruto/version'
2
+ require 'maruto/magento_config'
2
3
 
3
4
  module Maruto
4
5
  # Your code goes here...
@@ -0,0 +1,134 @@
1
+ require 'tsort'
2
+
3
+ module Maruto
4
+ class MagentoConfig
5
+ include TSort
6
+
7
+ def initialize(magento_root)
8
+
9
+ @modules = {}
10
+ @global_events_observers = {}
11
+ @warnings = []
12
+
13
+ Dir.chdir(magento_root) do
14
+
15
+ # load module definitions
16
+ Dir.glob('app/etc/modules/*.xml') do |file|
17
+ f = File.open(file)
18
+ doc = Nokogiri::XML(f) { |config| config.strict }
19
+ f.close
20
+
21
+ doc.xpath('//modules/*').each do |node|
22
+ load_module_definition(file, node)
23
+ end
24
+ end
25
+
26
+ # sort modules dependency graph, then load their config
27
+ modules().each do |mm_name, mm_config|
28
+ if mm_config[:active] then
29
+ # check dependencies
30
+ mm_config[:dependencies].each do |dep|
31
+ @warnings << "module:#{mm_name} - missing dependency (#{dep})" unless is_active_module?(dep)
32
+ end
33
+
34
+ # puts mm_name
35
+ # puts mm_config
36
+
37
+ parts = mm_name.split('_')
38
+ abort "module:#{mm_name} - unrecognized module name format" unless parts.size == 2
39
+ config_path = "app/code/#{mm_config[:code_pool]}/#{parts[0]}/#{parts[1]}/etc/config.xml"
40
+
41
+ if !File.exists?(config_path)
42
+ @warnings << "module:#{mm_name} is defined (#{mm_config[:defined]}) but does not exists (#{config_path})"
43
+ next
44
+ end
45
+
46
+ f = File.open(config_path)
47
+ doc = Nokogiri::XML(f) { |config| config.strict }
48
+ f.close
49
+
50
+ mm_config[:version] = doc.at_xpath("/config/modules/#{mm_name}/version").content if doc.at_xpath("/config/modules/#{mm_name}/version")
51
+
52
+ # TODO same for:
53
+ # '/config/frontend/events/*'
54
+ # '/config/adminhtml/events/*'
55
+ doc.xpath('/config/global/events/*').each do |node|
56
+ # puts node
57
+ event = node.name
58
+ observers = @global_events_observers[event] ||= {}
59
+
60
+ # puts node if mm_name == 'Enterprise_Reminder'
61
+
62
+ node.xpath("observers/*").each do |observer_node|
63
+ observer_name = observer_node.name
64
+ if observers.include? observer_name
65
+ mod_first = observers[observer_name][:defined]
66
+ mod_second = mm_name
67
+ @warnings << "event:#{event} observer:#{observer_name} - defined in #{mod_first} and redefined in #{mod_second}"
68
+ # TODO check if there is a dependency path between mod_first and mod_second
69
+ # print_module(mod_first)
70
+ # print_module(mod_second)
71
+ end
72
+ observers[observer_name] = {
73
+ :class => observer_node.at_xpath('class').content,
74
+ :method => observer_node.at_xpath('method').content,
75
+ :defined => mm_name,
76
+ }
77
+ end
78
+
79
+ @global_events_observers[event] = observers
80
+ end
81
+
82
+ end
83
+ end
84
+
85
+ end
86
+ end
87
+
88
+ def modules()
89
+ Hash[tsort.map { |name| [name, @modules[name]] }]
90
+ end
91
+
92
+ def events()
93
+ @global_events_observers
94
+ end
95
+
96
+ def is_active_module?(name)
97
+ @modules.include?(name) && @modules[name][:active]
98
+ end
99
+
100
+ def print_module(name)
101
+ puts @modules[name]
102
+ end
103
+
104
+ def print_warnings()
105
+ puts @warnings
106
+ end
107
+
108
+ def tsort_each_node(&block)
109
+ @modules.each_key(&block)
110
+ end
111
+
112
+ def tsort_each_child(node, &block)
113
+ @modules[node][:dependencies].each(&block)
114
+ end
115
+
116
+ private
117
+
118
+ def load_module_definition(file, xml_node)
119
+ name = xml_node.name
120
+ config = {
121
+ :active => xml_node.at_xpath('active').content == 'true',
122
+ :code_pool => xml_node.at_xpath('codePool').content,
123
+ :dependencies => xml_node.xpath('depends/*').map(&:name),
124
+ :defined => file,
125
+ }
126
+ if @modules.include? name then
127
+ # TODO test this
128
+ @warnings << "module:#{name} - duplicate module definition (#{@modules[name][:defined]} and file)"
129
+ end
130
+ @modules[name] = config
131
+ end
132
+
133
+ end
134
+ end
data/lib/maruto/runner.rb CHANGED
@@ -1,23 +1,22 @@
1
1
  require 'maruto'
2
+ require 'nokogiri'
3
+ require 'pathname'
2
4
  require 'thor'
3
5
 
4
6
  class Maruto::Runner < Thor
5
7
  include Thor::Actions
6
8
 
7
- desc "lint MAGENTO_ROOT", "lint php files"
8
- def lint(magento_root)
9
-
10
- # TODO move this into a magento_folder? method
9
+ desc "magento? MAGENTO_ROOT", "check if MAGENTO_ROOT contains a magento app"
10
+ def magento?(magento_root)
11
11
  magento_root = Pathname.new(magento_root).cleanpath
12
+ check_magento_folder(magento_root)
13
+ end
12
14
 
13
- raise Thor::Error, "not a folder: #{magento_root}" unless magento_root.directory?
15
+ desc "lint MAGENTO_ROOT", "lint php files in MAGENTO_ROOT/app/code"
16
+ def lint(magento_root)
14
17
 
15
- is_magento = (magento_root + 'app').directory? &&
16
- (magento_root + 'app/code').directory? &&
17
- (magento_root + 'app/etc').directory? &&
18
- (magento_root + 'app/etc/modules').directory? &&
19
- (magento_root + 'app/etc/local.xml').file?
20
- raise Thor::Error, "could not find magento in this folder: #{magento_root}" unless is_magento
18
+ magento_root = Pathname.new(magento_root).cleanpath
19
+ check_magento_folder(magento_root)
21
20
 
22
21
  # TODO move this into a lint_php method
23
22
  inside(magento_root) do
@@ -34,6 +33,35 @@ class Maruto::Runner < Thor
34
33
  end
35
34
  end
36
35
 
36
+ desc "events MAGENTO_ROOT", "list events and their observers"
37
+ def events(magento_root)
38
+
39
+ magento_root = Pathname.new(magento_root).cleanpath
40
+ check_magento_folder(magento_root)
41
+
42
+ magento_config = Maruto::MagentoConfig.new magento_root
43
+
44
+ magento_config.events.sort_by { |k, v| k }.each do |event, observers|
45
+ puts event
46
+ observers.each do |observer|
47
+ puts " #{observer}"
48
+ end
49
+ end
50
+
51
+ end
52
+
53
+ no_commands do
54
+ def check_magento_folder(magento_root)
55
+ raise Thor::Error, "not a folder: #{magento_root}" unless magento_root.directory?
56
+
57
+ is_magento = (magento_root + 'app').directory? &&
58
+ (magento_root + 'app/code').directory? &&
59
+ (magento_root + 'app/etc').directory? &&
60
+ (magento_root + 'app/etc/modules').directory? &&
61
+ (magento_root + 'app/etc/local.xml').file?
62
+ raise Thor::Error, "could not find magento in this folder: #{magento_root}" unless is_magento
63
+ end
64
+ end
37
65
  end
38
66
 
39
67
 
@@ -1,3 +1,3 @@
1
1
  module Maruto
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/maruto.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["jlgeering.13@gmail.com"]
11
11
  spec.description = %q{Magento Ruby Tools}
12
12
  spec.summary = %q{config parser and analyser, ...}
13
- spec.homepage = ""
13
+ spec.homepage = "https://github.com/jlgeering/maruto"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: maruto
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-28 00:00:00.000000000 Z
12
+ date: 2013-03-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
@@ -91,10 +91,11 @@ files:
91
91
  - Rakefile
92
92
  - bin/maruto
93
93
  - lib/maruto.rb
94
+ - lib/maruto/magento_config.rb
94
95
  - lib/maruto/runner.rb
95
96
  - lib/maruto/version.rb
96
97
  - maruto.gemspec
97
- homepage: ''
98
+ homepage: https://github.com/jlgeering/maruto
98
99
  licenses:
99
100
  - MIT
100
101
  post_install_message:
@@ -107,18 +108,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
107
108
  - - ! '>='
108
109
  - !ruby/object:Gem::Version
109
110
  version: '0'
110
- segments:
111
- - 0
112
- hash: -1944508487977522432
113
111
  required_rubygems_version: !ruby/object:Gem::Requirement
114
112
  none: false
115
113
  requirements:
116
114
  - - ! '>='
117
115
  - !ruby/object:Gem::Version
118
116
  version: '0'
119
- segments:
120
- - 0
121
- hash: -1944508487977522432
122
117
  requirements: []
123
118
  rubyforge_project:
124
119
  rubygems_version: 1.8.23