modbuild 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source :rubygems
2
+
3
+ gem 'builder'
4
+ gem 'rspec'
5
+ gem 'logger'
6
+ gem 'rake'
data/Gemfile.lock ADDED
@@ -0,0 +1,24 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ builder (3.0.0)
5
+ diff-lcs (1.1.3)
6
+ logger (1.2.8)
7
+ rake (0.9.2.2)
8
+ rspec (2.11.0)
9
+ rspec-core (~> 2.11.0)
10
+ rspec-expectations (~> 2.11.0)
11
+ rspec-mocks (~> 2.11.0)
12
+ rspec-core (2.11.1)
13
+ rspec-expectations (2.11.2)
14
+ diff-lcs (~> 1.1.3)
15
+ rspec-mocks (2.11.1)
16
+
17
+ PLATFORMS
18
+ ruby
19
+
20
+ DEPENDENCIES
21
+ builder
22
+ logger
23
+ rake
24
+ rspec
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require "bundler/gem_tasks"
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task :default => :spec
data/Readme.md ADDED
@@ -0,0 +1,32 @@
1
+ # Magento Package XML Builder for Modman
2
+
3
+ [![Build Status](https://secure.travis-ci.org/punkstar/modbuild.png?branch=master)](http://travis-ci.org/punkstar/modbuild)
4
+
5
+ I use [modman](https://github.com/colinmollenhour/modman) to manage any Magento Extensions that I write. An extension must be packaged once it's complete. I don't enjoy using the "Package Magento Extension" interface in the Magento admin, nor do I like writing the XML by hand.
6
+
7
+ This script gives you a running start by generating an XML file that you can then load in the admin interface containing most of the information you'll need, such as all of the files included in the extension and any metadata that you've included in your modman file.
8
+
9
+ ### Example modman File
10
+
11
+ You can include basic information, such as extension name, version, summary and description, in your modman file to be included in the generated XML file. For example:
12
+
13
+ # Name: Meanbee_Topsecret
14
+ # Version: 1.0.0
15
+ # Description: This is a topsecret module, and no-one must know about it.
16
+ # Summary: I'm not telling.
17
+
18
+ app/etc/modules/Meanbee_Topsecret.xml app/etc/modules/
19
+
20
+ ### Example Usage
21
+
22
+ If I had a Magento installation in `~/Sites/meanbee/module_topsecret/`, and a modman compatible repoistory checked out in `~/Sites/meanbee/module_topsecreet/.modman/topsecret`, then I would run the following to generate an almost complete package file in `var/connect`:
23
+
24
+ modbuild ~/Sites/meanbee/module_topsecreet/.modman/topsecret > ~/Sites/meanbee/module_topsecret/var/connect/Meanbee_Topsecret.xml
25
+
26
+ ### License
27
+
28
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
29
+
30
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
31
+
32
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/bin/modbuild ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
4
+
5
+ require 'modbuild'
6
+
7
+ options = {}
8
+ opts = OptionParser.new do |opts|
9
+ opts.banner = "Usage: modbuild.rb [options] filename"
10
+
11
+ opts.on("--debug", "Enable debug mode") do |v|
12
+ options[:debug] = v
13
+ end
14
+
15
+ opts.on("--help", "Show help") do |v|
16
+ puts opts
17
+ exit
18
+ end
19
+ end
20
+
21
+ filename = opts.parse!
22
+
23
+ if filename.length == 1
24
+ modbuild = Meanbee::Modbuild::Base.new filename[0]
25
+ modbuild.enable_debug() if options[:debug]
26
+ puts modbuild.build
27
+ else
28
+ raise 'You need to provide a filename'
29
+ end
data/lib/modbuild.rb ADDED
@@ -0,0 +1,273 @@
1
+ require 'pathname'
2
+ require 'logger'
3
+ require 'builder'
4
+ require 'optparse'
5
+
6
+ module Meanbee
7
+ module Modbuild
8
+ VERSION = "1.0.0"
9
+
10
+ class Base
11
+ attr_accessor :package_name, :package_version, :package_summary, :package_description
12
+
13
+ def initialize(module_directory)
14
+ @logger = Logger.new(STDERR)
15
+ @logger.level = Logger::FATAL
16
+
17
+ @module_location = module_directory
18
+ @modman_location = File.join(module_directory, 'modman')
19
+ @magento_location = File.join(module_directory, '..', '..')
20
+
21
+ @package_name = 'Unspecified_Name'
22
+ @package_version = '1.0.0'
23
+ @package_summary = 'Unspecified package summary'
24
+ @package_description = 'Unspecified package description'
25
+ @package_files = []
26
+
27
+ @logger.debug "Module Directory: #{@module_location}"
28
+ @logger.debug "Modman Directory: #{@modman_location}"
29
+ @logger.debug "Magento Directory: #{@magento_location}"
30
+ end
31
+
32
+ def enable_debug
33
+ @logger.level = Logger::DEBUG
34
+ end
35
+
36
+ def build
37
+ get_package_files
38
+
39
+ @logger.debug 'Generating XML file..'
40
+ package_xml = PackageXml.new @package_name, @package_version, @package_summary, @package_description
41
+
42
+ @package_files.each do |file|
43
+ package_xml.add_file file
44
+ end
45
+
46
+ return package_xml.to_string
47
+ end
48
+
49
+ def get_package_files
50
+ # List all of the files related to this module, base on the modman contents
51
+ modman_file = File.new @modman_location, 'r'
52
+
53
+ @logger.debug "Reading modman file"
54
+ while (line = modman_file.gets)
55
+ line.chomp!
56
+
57
+ if (line =~ /^\s*#/)
58
+ @logger.debug " Comment line: #{line}"
59
+ if (/^#\s*(?<key>\w+)\s*:\s*(?<value>.*)$/ =~ line)
60
+ @logger.debug " Extracted: #{key} = #{value}"
61
+
62
+ case key.downcase.to_sym
63
+ when :name
64
+ @package_name = value
65
+ when :version
66
+ @package_version = value
67
+ when :summary
68
+ @package_summary = value
69
+ when :description
70
+ @package_description = value
71
+ else
72
+ @logger.debug " Unknown package variables"
73
+ end
74
+ end
75
+ elsif (line =~ /^.*\s+.*$/)
76
+ @logger.debug " Line: #{line}"
77
+ # local_file is the file in the .modman directory, the magento_file is where
78
+ # the file is placed in the magento root
79
+ local_file, magento_file = line.split ' '
80
+
81
+ @logger.debug " Local: #{local_file}"
82
+ @logger.debug " Magento: #{magento_file}"
83
+
84
+ if local_file.match /\*$/
85
+ local_file_directory = File.dirname local_file
86
+
87
+ @logger.debug " Identified as glob"
88
+ @logger.debug " Local file directory: #{local_file_directory}"
89
+
90
+ Dir.glob(File.join(@module_location, local_file)).each do |f|
91
+ @logger.debug " Globbed file: #{f}"
92
+
93
+ f_regex = Regexp.new "^#{@module_location}#{local_file_directory}\/?"
94
+ f_relative = f.gsub(f_regex, '')
95
+ f_magento = File.join(magento_file, f_relative)
96
+
97
+ @logger.debug " Globbed file as relative: #{f_magento}"
98
+ @logger.debug " Adding: #{f_magento}"
99
+ @package_files << f_magento
100
+ end
101
+ else
102
+ @logger.debug " Adding: #{magento_file}"
103
+ @package_files << magento_file
104
+ end
105
+ end
106
+ end
107
+
108
+ modman_file.close
109
+
110
+ return @package_files
111
+ end
112
+ end
113
+
114
+ class PackageXml
115
+ def initialize(name, version, summary, description)
116
+ @php_min = '5.2.0'
117
+ @php_max = '6.0.0'
118
+ @stability = 'stable'
119
+ @license = 'Open Software License v3.0 (OSL-3.0)'
120
+ @license_uri = 'http://opensource.org/licenses/OSL-3.0'
121
+ @name = name
122
+ @channel = 'community'
123
+ @summary = summary
124
+ @description = description
125
+ @version = version
126
+ @authors = []
127
+ @depends_packages = []
128
+ @depends_extensions = []
129
+ @files = []
130
+
131
+ add_extension_dependency 'Core', '', ''
132
+ end
133
+
134
+ def add_author(name, user, email)
135
+ @authors << {
136
+ :name => name,
137
+ :user => user,
138
+ :email => email
139
+ }
140
+ end
141
+
142
+ def add_package_dependency(name, channel, min, max, files)
143
+ @depends_packages << {
144
+ :name => name,
145
+ :channel => channel,
146
+ :min => min,
147
+ :max => max,
148
+ :files => files
149
+ }
150
+ end
151
+
152
+ def add_extension_dependency(name, min, max)
153
+ @depends_extensions << {
154
+ :name => name,
155
+ :min => min,
156
+ :max => max
157
+ }
158
+ end
159
+
160
+ def add_file(name)
161
+ @files << identify_file(name)
162
+ end
163
+
164
+ def to_string
165
+ xml = Builder::XmlMarkup.new(:indent => 4)
166
+
167
+ xml._ {
168
+ xml.form_key "imtotallyirrelevant"
169
+ xml.name @name
170
+ xml.channel @channel
171
+ xml.version_id {
172
+ xml.version_ids 2
173
+ }
174
+ xml.summary @summary
175
+ xml.description @description
176
+ xml.license @license
177
+ xml.license_uri @license_uri
178
+ xml.version @version
179
+ xml.stability @stability
180
+ xml.notes @notes
181
+ xml.authors {
182
+ xml.names {
183
+ @authors.each do |a|
184
+ xml.name a[:name]
185
+ end
186
+ }
187
+ xml.user {
188
+ @authors.each do |a|
189
+ xml.user a[:user]
190
+ end
191
+ }
192
+ xml.email {
193
+ @authors.each do |a|
194
+ xml.email a[:email]
195
+ end
196
+ }
197
+ }
198
+ xml.depends_php_min @php_min
199
+ xml.depends_php_max @php_max
200
+ xml.depends {
201
+ xml.package {
202
+ [:name, :channel, :min, :max, :files].each do |key|
203
+ @depends_packages.each do |pkg|
204
+ xml.tag!(key) {
205
+ xml.tag!(key, pkg[key])
206
+ }
207
+ end
208
+ end
209
+ }
210
+
211
+ xml.extension {
212
+ [:name, :min, :max].each do |key|
213
+ @depends_extensions.each do |pkg|
214
+ xml.tag!(key) {
215
+ xml.tag!(key, pkg[key])
216
+ }
217
+ end
218
+ end
219
+ }
220
+ }
221
+ xml.contents {
222
+ [:target, :path, :type].each do |key|
223
+ xml.tag!(key) {
224
+ @files.each do |f|
225
+ xml.tag!(key, f[key])
226
+ end
227
+ }
228
+ end
229
+ [:include, :ignore].each do |key|
230
+ xml.tag!(key) {
231
+ @files.length.times do |i|
232
+ xml.tag!(key)
233
+ end
234
+ }
235
+ end
236
+ }
237
+ }
238
+
239
+ return xml.target!
240
+ end
241
+
242
+ def identify_file(name)
243
+ targets = {
244
+ :magelocal => 'app/code/local',
245
+ :magecommunity => 'app/code/community',
246
+ :magecore => 'app/code/core',
247
+ :mageetc => 'app/etc',
248
+ :magedesign => 'app/design',
249
+ :mageskin => 'skin'
250
+ # :mageweb is for everything else
251
+ }
252
+
253
+ file_type = (name =~ /\w*\.\w+$/) ? 'file' : 'dir'
254
+
255
+ targets.each do |key, value|
256
+ if name =~ /^#{value}/
257
+ return {
258
+ :target => key.to_s,
259
+ :path => name.gsub(/^#{value}\/?/, ''),
260
+ :type => file_type
261
+ }
262
+ end
263
+ end
264
+
265
+ return {
266
+ :target => 'mageweb',
267
+ :path => name,
268
+ :type => file_type
269
+ }
270
+ end
271
+ end
272
+ end
273
+ end
@@ -0,0 +1,4 @@
1
+ # Name: My Magento Extension
2
+ # Version: 1.0.1
3
+ # Description: My extension description
4
+ # Summary: My extension summary
@@ -0,0 +1,54 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+
3
+ require 'modbuild'
4
+
5
+ describe Meanbee::Modbuild::Base, '#get_package_files' do
6
+ it "should extract variables from comments" do
7
+ pkg = Meanbee::Modbuild::Base.new File.dirname(__FILE__) + '/fixtures/001_variables'
8
+ pkg.get_package_files
9
+
10
+ pkg.package_name.should eq 'My Magento Extension'
11
+ pkg.package_version.should eq '1.0.1'
12
+ pkg.package_summary.should eq 'My extension summary'
13
+ pkg.package_description.should eq 'My extension description'
14
+ end
15
+ end
16
+
17
+ describe Meanbee::Modbuild::PackageXml, '#identify_file' do
18
+ it "should identify file targets" do
19
+ pkgxml = Meanbee::Modbuild::PackageXml.new 'a', 'b', 'c', 'd'
20
+
21
+ pkgxml.identify_file('app/code/local/Meanbee/Awesome')[:target].should eq 'magelocal'
22
+ pkgxml.identify_file('app/code/community/Meanbee/Awesome')[:target].should eq 'magecommunity'
23
+ pkgxml.identify_file('app/code/core/Meanbee/Awesome')[:target].should eq 'magecore'
24
+ pkgxml.identify_file('app/etc/modules/Meanbee_Awesome.xml')[:target].should eq 'mageetc'
25
+ pkgxml.identify_file('app/design/frontend/base/default/template/meanbee/awesome')[:target].should eq 'magedesign'
26
+ pkgxml.identify_file('skin/frontend/base/default/css/awesome.css')[:target].should eq 'mageskin'
27
+ pkgxml.identify_file('random/directory/file.css')[:target].should eq 'mageweb'
28
+ end
29
+
30
+ it "should differentiate between files and directories" do
31
+ pkgxml = Meanbee::Modbuild::PackageXml.new 'a', 'b', 'c', 'd'
32
+
33
+ pkgxml.identify_file('app/code/local/Meanbee/Awesome')[:type].should eq 'dir'
34
+ pkgxml.identify_file('app/code/local/Meanbee/Awesome/')[:type].should eq 'dir'
35
+ pkgxml.identify_file('app/code/local/Meanbee/Awesome/etc/config.xml')[:type].should eq 'file'
36
+ pkgxml.identify_file('app/code/local/Meanbee/Awesome/etc/.htaccess')[:type].should eq 'file'
37
+ pkgxml.identify_file('app/code/local/Meanbee/Awesome/etc/.htaccess/')[:type].should eq 'dir'
38
+ pkgxml.identify_file('app/code/local/Meanbee/Awesome/etc/.htaccess/subdir')[:type].should eq 'dir'
39
+ pkgxml.identify_file('app/code/local/Meanbee/Awesome/etc/.htaccess/subdir/file.txt')[:type].should eq 'file'
40
+ pkgxml.identify_file('.htaccess')[:type].should eq 'file'
41
+ end
42
+
43
+ it "should provide file paths relative to target base directories" do
44
+ pkgxml = Meanbee::Modbuild::PackageXml.new 'a', 'b', 'c', 'd'
45
+
46
+ pkgxml.identify_file('app/code/local/Meanbee/Awesome')[:path].should eq 'Meanbee/Awesome'
47
+ pkgxml.identify_file('app/code/community/Meanbee/Awesome')[:path].should eq 'Meanbee/Awesome'
48
+ pkgxml.identify_file('app/code/core/Meanbee/Awesome')[:path].should eq 'Meanbee/Awesome'
49
+ pkgxml.identify_file('app/etc/modules/Meanbee_Awesome.xml')[:path].should eq 'modules/Meanbee_Awesome.xml'
50
+ pkgxml.identify_file('app/design/frontend/base/default/template/meanbee/awesome')[:path].should eq 'frontend/base/default/template/meanbee/awesome'
51
+ pkgxml.identify_file('skin/frontend/base/default/css/awesome.css')[:path].should eq 'frontend/base/default/css/awesome.css'
52
+ pkgxml.identify_file('random/directory/file.css')[:path].should eq 'random/directory/file.css'
53
+ end
54
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: modbuild
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Nick Jones
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-13 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: This script gives you a running start by generating an XML file that
15
+ you can then load in the admin interface containing most of the information you'll
16
+ need, such as all of the files included in the extension and any metadata that you've
17
+ included in your modman file.
18
+ email:
19
+ - nick@nicksays.co.uk
20
+ executables:
21
+ - modbuild
22
+ extensions: []
23
+ extra_rdoc_files: []
24
+ files:
25
+ - .gitignore
26
+ - .travis.yml
27
+ - Gemfile
28
+ - Gemfile.lock
29
+ - Rakefile
30
+ - Readme.md
31
+ - bin/modbuild
32
+ - lib/modbuild.rb
33
+ - spec/fixtures/001_variables/modman
34
+ - spec/modbuild_spec.rb
35
+ homepage: https://github.com/punkstar/modbuild
36
+ licenses: []
37
+ post_install_message:
38
+ rdoc_options: []
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ requirements: []
54
+ rubyforge_project:
55
+ rubygems_version: 1.8.24
56
+ signing_key:
57
+ specification_version: 3
58
+ summary: Build a skeleton Magento Connect extension package file from your modman
59
+ contents
60
+ test_files:
61
+ - spec/fixtures/001_variables/modman
62
+ - spec/modbuild_spec.rb