zen 0.2.3 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +12 -2
- data/MANIFEST +17 -10
- data/ROADMAP.md +8 -4
- data/bin/zen +2 -3
- data/lib/zen.rb +20 -14
- data/lib/zen/bin/{zen_binary.rb → base.rb} +0 -0
- data/lib/zen/controller/main_controller.rb +7 -4
- data/lib/zen/{base/database.rb → database.rb} +3 -2
- data/lib/zen/error/language_error.rb +10 -0
- data/lib/zen/error/package_error.rb +10 -0
- data/lib/zen/error/plugin_error.rb +10 -0
- data/lib/zen/error/theme_error.rb +10 -0
- data/lib/zen/helper/acl.rb +11 -4
- data/lib/zen/{base/language.rb → language.rb} +11 -3
- data/lib/zen/layout/admin.xhtml +21 -12
- data/lib/zen/layout/login.xhtml +17 -11
- data/lib/zen/liquid/general.rb +1 -27
- data/lib/zen/{base/logger.rb → logger.rb} +0 -0
- data/lib/zen/{base/package.rb → package.rb} +65 -55
- data/lib/zen/package/all.rb +5 -0
- data/lib/zen/package/categories/lib/categories.rb +7 -8
- data/lib/zen/package/comments/lib/comments.rb +7 -8
- data/lib/zen/package/comments/lib/comments/controller/comments_form.rb +1 -1
- data/lib/zen/package/comments/lib/comments/liquid/comments.rb +3 -1
- data/lib/zen/package/custom_fields/lib/custom_fields.rb +7 -8
- data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field_value.rb +14 -0
- data/lib/zen/package/custom_fields/migrations/1295255665_create_schema.rb +1 -1
- data/lib/zen/package/menus/lib/menus.rb +5 -6
- data/lib/zen/package/sections/lib/sections.rb +4 -5
- data/lib/zen/package/sections/lib/sections/language/en/section_entries.yml +2 -2
- data/lib/zen/package/sections/lib/sections/liquid/section_entries.rb +9 -2
- data/lib/zen/package/settings/lib/settings.rb +7 -8
- data/lib/zen/package/users/lib/users.rb +7 -8
- data/lib/zen/package/users/lib/users/view/admin/access-rules/form.xhtml +5 -5
- data/lib/zen/package/users/lib/users/view/admin/access-rules/index.xhtml +4 -4
- data/lib/zen/plugin.rb +172 -0
- data/lib/zen/plugin/markup.rb +30 -0
- data/lib/zen/public/admin/css/layout.css +17 -0
- data/lib/zen/strict_struct.rb +36 -0
- data/lib/zen/task/db.rb +14 -4
- data/lib/zen/task/package.rb +13 -8
- data/lib/zen/task/theme.rb +88 -0
- data/lib/zen/theme.rb +129 -0
- data/lib/zen/{base/version.rb → version.rb} +1 -1
- data/proto/app/config/config.rb +19 -6
- data/proto/app/config/database.rb +58 -2
- data/proto/app/config/middlewares.rb +69 -4
- data/proto/app/config/requires.rb +9 -2
- data/proto/app/{logs → log}/.gitkeep +0 -0
- data/proto/package/lib/package.rb +3 -13
- data/proto/package/lib/package/controller/controllers.rb +5 -9
- data/proto/package/lib/package/language/en/languages.yml +4 -0
- metadata +66 -26
- data/proto/package/LICENSE +0 -0
- data/proto/package/README.textile +0 -0
- data/proto/package/lib/package/language/en/languages.rb +0 -3
@@ -196,7 +196,12 @@ module Sections
|
|
196
196
|
end
|
197
197
|
end
|
198
198
|
|
199
|
-
values['comment'] =
|
199
|
+
values['comment'] = Zen::Plugin.call(
|
200
|
+
'com.zen.plugin.markup',
|
201
|
+
entry.section.comment_format.to_sym,
|
202
|
+
values['comment']
|
203
|
+
)
|
204
|
+
|
200
205
|
context['comments'].push(values)
|
201
206
|
end
|
202
207
|
|
@@ -204,7 +209,9 @@ module Sections
|
|
204
209
|
entry.custom_field_values.each do |field_value|
|
205
210
|
field = field_value.custom_field
|
206
211
|
name = field.slug
|
207
|
-
value =
|
212
|
+
value = ::Zen::Plugin.call(
|
213
|
+
'com.zen.plugin.markup', field.format.to_sym, field_value.value
|
214
|
+
)
|
208
215
|
|
209
216
|
context[name.to_s] = value
|
210
217
|
end
|
@@ -6,14 +6,13 @@ require __DIR__ 'settings/liquid/setting'
|
|
6
6
|
Liquid::Template.register_tag('setting', Settings::Liquid::Setting)
|
7
7
|
|
8
8
|
Zen::Package.add do |p|
|
9
|
-
p.
|
10
|
-
p.
|
11
|
-
p.
|
12
|
-
p.
|
13
|
-
p.
|
14
|
-
p.
|
15
|
-
p.
|
16
|
-
p.directory = __DIR__('settings')
|
9
|
+
p.name = 'Settings'
|
10
|
+
p.author = 'Yorick Peterse'
|
11
|
+
p.url = 'http://yorickpeterse.com/'
|
12
|
+
p.about = 'Module for managing settings such as the default module, whether or not to allow registration, etc.'
|
13
|
+
p.identifier = 'com.zen.settings'
|
14
|
+
p.directory = __DIR__('settings')
|
15
|
+
p.migration_dir = __DIR__('../migrations')
|
17
16
|
|
18
17
|
p.menu = [{
|
19
18
|
:title => "Settings",
|
@@ -18,15 +18,14 @@ Liquid::Template.register_tag('user' , Users::Liquid::User)
|
|
18
18
|
Zen::Controllers::BaseController.trait(:user_model => Users::Models::User)
|
19
19
|
|
20
20
|
Zen::Package.add do |p|
|
21
|
-
p.
|
22
|
-
p.
|
23
|
-
p.
|
24
|
-
p.
|
25
|
-
p.version = '1.0'
|
26
|
-
p.about = "Module for managing users along with handling authentication and authorization."
|
21
|
+
p.name = 'Users'
|
22
|
+
p.author = 'Yorick Peterse'
|
23
|
+
p.url = 'http://yorickpeterse.com/'
|
24
|
+
p.about = "Module for managing users along with handling authentication and authorization."
|
27
25
|
|
28
|
-
p.identifier
|
29
|
-
p.directory
|
26
|
+
p.identifier = 'com.zen.users'
|
27
|
+
p.directory = __DIR__('users')
|
28
|
+
p.migration_dir = __DIR__('../migrations')
|
30
29
|
|
31
30
|
p.menu = [{
|
32
31
|
:title => "Users",
|
@@ -18,7 +18,7 @@
|
|
18
18
|
users[user.id.to_s] = user.name
|
19
19
|
end
|
20
20
|
|
21
|
-
Zen::Package.
|
21
|
+
Zen::Package.packages.each do |ident, ext|
|
22
22
|
extensions[ident] = ext.name
|
23
23
|
end
|
24
24
|
|
@@ -74,28 +74,28 @@
|
|
74
74
|
lang('access_rules.labels.create'),
|
75
75
|
:create_access,
|
76
76
|
@access_rule.create_access,
|
77
|
-
:values => @boolean_hash
|
77
|
+
:values => @boolean_hash
|
78
78
|
)
|
79
79
|
|
80
80
|
f.input_radio(
|
81
81
|
lang('access_rules.labels.read'),
|
82
82
|
:read_access,
|
83
83
|
@access_rule.read_access,
|
84
|
-
:values => @boolean_hash
|
84
|
+
:values => @boolean_hash
|
85
85
|
)
|
86
86
|
|
87
87
|
f.input_radio(
|
88
88
|
lang('access_rules.labels.update'),
|
89
89
|
:update_access,
|
90
90
|
@access_rule.update_access,
|
91
|
-
:values => @boolean_hash
|
91
|
+
:values => @boolean_hash
|
92
92
|
)
|
93
93
|
|
94
94
|
f.input_radio(
|
95
95
|
lang('access_rules.labels.delete'),
|
96
96
|
:delete_access,
|
97
97
|
@access_rule.delete_access,
|
98
|
-
:values => @boolean_hash
|
98
|
+
:values => @boolean_hash
|
99
99
|
)
|
100
100
|
|
101
101
|
f.g.div(:class => 'clearfix') do
|
@@ -49,10 +49,10 @@
|
|
49
49
|
<td>#{rule.extension}</td>
|
50
50
|
<?r end ?>
|
51
51
|
|
52
|
-
<td>#{@boolean_hash[rule.create_access]}</td>
|
53
|
-
<td>#{@boolean_hash[rule.read_access]}</td>
|
54
|
-
<td>#{@boolean_hash[rule.update_access]}</td>
|
55
|
-
<td>#{@boolean_hash[rule.delete_access]}</td>
|
52
|
+
<td>#{@boolean_hash.invert[rule.create_access]}</td>
|
53
|
+
<td>#{@boolean_hash.invert[rule.read_access]}</td>
|
54
|
+
<td>#{@boolean_hash.invert[rule.update_access]}</td>
|
55
|
+
<td>#{@boolean_hash.invert[rule.delete_access]}</td>
|
56
56
|
<td>
|
57
57
|
<?r if !rule.user_id.nil? ?>
|
58
58
|
#{rule.user.name}
|
data/lib/zen/plugin.rb
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
require __DIR__('error/plugin_error')
|
2
|
+
|
3
|
+
#:nodoc:
|
4
|
+
module Zen
|
5
|
+
##
|
6
|
+
# Plugins in Zen are quite similar to packages except for a few differences. The biggest
|
7
|
+
# difference is that plugins won't update any Ramaze root directories or language
|
8
|
+
# direactories. This means that they can't have controllers, models and so on. On top
|
9
|
+
# of that they're nothing more than lambda's. Plugins are useful for supporting multiple
|
10
|
+
# markup formats (Markdown, Textile, etc) and other small tasks such as replacing Email
|
11
|
+
# addresses and so on.
|
12
|
+
#
|
13
|
+
# ## Creating Plugins
|
14
|
+
#
|
15
|
+
# Creating plugins works in a similar way as creating packages. Plugins are added by
|
16
|
+
# calling Zen::Plugin#add and passing a block to it with details such as the name of
|
17
|
+
# the plugin, the author, the identifier and a list of actions. The last two are very
|
18
|
+
# important as the plugin won't work without them.
|
19
|
+
#
|
20
|
+
# ### Actions
|
21
|
+
#
|
22
|
+
# Each plugin has a getter/setter called "actions", this is just a simple key/value
|
23
|
+
# hash where the keys are the names of the actions and the values lambda's. The keys
|
24
|
+
# should always be symbols. Example:
|
25
|
+
#
|
26
|
+
# actions = {
|
27
|
+
# :downcase => lambda do |string|
|
28
|
+
# string.downcase
|
29
|
+
# end
|
30
|
+
# }
|
31
|
+
#
|
32
|
+
# Note that you don't *have to* use lambda's, anything that responds to call() will do.
|
33
|
+
#
|
34
|
+
# Because the actions method contains just a hash you can easily add functionality to
|
35
|
+
# existing plugins as following:
|
36
|
+
#
|
37
|
+
# # First retrieve our plugin
|
38
|
+
# plugin = Zen::Plugin['com.something.plugin.name']
|
39
|
+
# plugin.actions[:my_action] = lamda do
|
40
|
+
# # Do something....
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# This can be very useful for extending plugins such as the markup plugin that's used to
|
44
|
+
# convert Markdown or Textile to HTML. By default this plugin only converts Markdown and
|
45
|
+
# Textile or HTML (it escapes all HTML) but by modifying the actions hash we can easily
|
46
|
+
# add new markup engines such as RDoc or even Latex.
|
47
|
+
#
|
48
|
+
# ## Calling Plugins
|
49
|
+
#
|
50
|
+
# Plugins can be called using Zen::Plugin#call, this method requires you to specify the
|
51
|
+
# plugin identifier, the action to call and optionally any data to send to the plugin.
|
52
|
+
# An example of calling a plugin would look like the following:
|
53
|
+
#
|
54
|
+
# Zen::Plugin.call('com.zen.plugin.markup', :markdown, 'hello **world**')
|
55
|
+
#
|
56
|
+
# ## Identifiers
|
57
|
+
#
|
58
|
+
# Plugin identifiers should always have the following format:
|
59
|
+
#
|
60
|
+
# com.VENDOR.plugin.NAME
|
61
|
+
#
|
62
|
+
# For example:
|
63
|
+
#
|
64
|
+
# com.zen.plugin.markup
|
65
|
+
#
|
66
|
+
# @author Yorick Peterse
|
67
|
+
# @since 0.2.4
|
68
|
+
# @attr_reader [Hash] plugins Hash containing all plugins.
|
69
|
+
#
|
70
|
+
module Plugin
|
71
|
+
class << self
|
72
|
+
attr_reader :plugins
|
73
|
+
end
|
74
|
+
|
75
|
+
##
|
76
|
+
# Adds a new plugin with the given details.
|
77
|
+
#
|
78
|
+
# @example
|
79
|
+
# Zen::Plugin.add do |p|
|
80
|
+
# p.name = 'Markup'
|
81
|
+
# p.author = 'Yorick Peterse'
|
82
|
+
# p.actions = {
|
83
|
+
# :markdown => lambda do |markup|
|
84
|
+
# RDiscount.new(markup).to_html
|
85
|
+
# end
|
86
|
+
# end
|
87
|
+
#
|
88
|
+
# @author Yorick Peterse
|
89
|
+
# @since 0.2.4
|
90
|
+
# @yield [plugin] Struct object containing all the details of a plugin.
|
91
|
+
# @raise [Zen::PluginError] Error raised whenever the plugin already exists or is missing
|
92
|
+
# a certain setter.
|
93
|
+
#
|
94
|
+
def self.add
|
95
|
+
@plugins ||= {}
|
96
|
+
required = [:name, :author, :about, :identifier, :actions]
|
97
|
+
plugin = Zen::StrictStruct.new(
|
98
|
+
:name, :author, :about, :url, :identifier, :actions
|
99
|
+
).new
|
100
|
+
|
101
|
+
yield plugin
|
102
|
+
|
103
|
+
# Check if all the required keys have been set
|
104
|
+
plugin.validate(required) do |k|
|
105
|
+
raise(Zen::PluginError, "The following plugin key is missing: #{k}")
|
106
|
+
end
|
107
|
+
|
108
|
+
# The actions getter should be a hash
|
109
|
+
if plugin.actions.class != Hash
|
110
|
+
raise(Zen::PluginError, "The actions setter/getter should be an instance of Hash.")
|
111
|
+
end
|
112
|
+
|
113
|
+
# Add our plugin
|
114
|
+
if !@plugins[plugin.identifier].nil?
|
115
|
+
raise(Zen::PluginError, "The plugin #{plugin.name} already exists.")
|
116
|
+
end
|
117
|
+
|
118
|
+
@plugins[plugin.identifier] = plugin
|
119
|
+
end
|
120
|
+
|
121
|
+
##
|
122
|
+
# Returns a plugin for the given identifier.
|
123
|
+
#
|
124
|
+
# @example
|
125
|
+
# Zen::Plugin['com.zen.plugin.markup']
|
126
|
+
#
|
127
|
+
# @author Yorick Peterse
|
128
|
+
# @since 0.2.4
|
129
|
+
# @param [String] ident The plugin identifier.
|
130
|
+
# @raise Zen::PluginError Error that's raised when no plugins have been added yet or
|
131
|
+
# the specified plugin doesn't exist.
|
132
|
+
# @return [Struct] Instance of the plugin.
|
133
|
+
#
|
134
|
+
def self.[](ident)
|
135
|
+
if @plugins.nil?
|
136
|
+
raise(Zen::PluginError, "No plugins have been added.")
|
137
|
+
end
|
138
|
+
|
139
|
+
if !@plugins[ident]
|
140
|
+
raise(Zen::PluginError, "The plugin #{ident} doesn't exist.")
|
141
|
+
end
|
142
|
+
|
143
|
+
return @plugins[ident]
|
144
|
+
end
|
145
|
+
|
146
|
+
##
|
147
|
+
# Calls the plugin for the given identifier and executes the action.
|
148
|
+
#
|
149
|
+
# @example
|
150
|
+
# Zen::Plugin.call('com.zen.foobar', :markdown, 'hello **world**')
|
151
|
+
#
|
152
|
+
# @author Yorick Peterse
|
153
|
+
# @since 0.2.4
|
154
|
+
# @param [String] ident The plugin identifier.
|
155
|
+
# @param [Symbol] action The plugin action to call.
|
156
|
+
# @param [Array] data Any data to pass to the plugin's action (a lambda).
|
157
|
+
# @return [Mixed]
|
158
|
+
#
|
159
|
+
def self.call(ident, action, *data)
|
160
|
+
plugin = self[ident]
|
161
|
+
action = action.to_sym
|
162
|
+
|
163
|
+
if !plugin.actions[action]
|
164
|
+
raise(Zen::PluginError, "The action #{action} doesn't exist for #{ident}.")
|
165
|
+
end
|
166
|
+
|
167
|
+
# Call the plugin and return it's value
|
168
|
+
return plugin.actions[action].call(*data)
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
Zen::Plugin.add do |plugin|
|
2
|
+
plugin.name = 'Markup'
|
3
|
+
plugin.author = 'Yorick Peterse'
|
4
|
+
plugin.about = 'Plugin used for converting various markup formats to HTML.'
|
5
|
+
plugin.identifier = 'com.zen.plugin.markup'
|
6
|
+
plugin.actions = {
|
7
|
+
|
8
|
+
# Converts HTML to, well, HTML.
|
9
|
+
:html => lambda do |markup|
|
10
|
+
markup
|
11
|
+
end,
|
12
|
+
|
13
|
+
# Converts the given markup to plain text by escaping all HTML
|
14
|
+
:plain => lambda do |markup|
|
15
|
+
include Ramaze::Helper::CGI
|
16
|
+
h(markup)
|
17
|
+
end,
|
18
|
+
|
19
|
+
# Comvert Markdown documents to HTML
|
20
|
+
:markdown => lambda do |markup|
|
21
|
+
RDiscount.new(markup).to_html
|
22
|
+
end,
|
23
|
+
|
24
|
+
# Convert Textile documents to HTML
|
25
|
+
:textile => lambda do |markup|
|
26
|
+
RedCloth.new(markup).to_html
|
27
|
+
end
|
28
|
+
|
29
|
+
}
|
30
|
+
end
|
@@ -103,6 +103,7 @@
|
|
103
103
|
margin: 20px auto;
|
104
104
|
width: 500px;
|
105
105
|
}
|
106
|
+
|
106
107
|
#login #container
|
107
108
|
{
|
108
109
|
margin-top: 50px;
|
@@ -116,7 +117,23 @@
|
|
116
117
|
margin-top: 20px;
|
117
118
|
text-align: center;
|
118
119
|
}
|
120
|
+
|
119
121
|
#main_footer p
|
120
122
|
{
|
121
123
|
margin-bottom: 8px;
|
124
|
+
margin: 0 auto 8px auto;
|
125
|
+
width: 300px;
|
126
|
+
}
|
127
|
+
|
128
|
+
#main_footer ul
|
129
|
+
{
|
130
|
+
list-style-type: none;
|
131
|
+
margin: 0 auto;
|
132
|
+
width: 300px;
|
122
133
|
}
|
134
|
+
#main_footer ul li
|
135
|
+
{
|
136
|
+
float: left;
|
137
|
+
margin: 0px 8px;
|
138
|
+
text-align: center;
|
139
|
+
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#:nodoc:
|
2
|
+
module Zen
|
3
|
+
##
|
4
|
+
# StrictStruct is a simple extension of the Struct class, it provides a method that
|
5
|
+
# checks if all getters/setters have a value and if one doesn't it will call the
|
6
|
+
# appropriate block.
|
7
|
+
#
|
8
|
+
# @author Yorick Peterse
|
9
|
+
# @since 0.2.4
|
10
|
+
#
|
11
|
+
class StrictStruct < Struct
|
12
|
+
|
13
|
+
##
|
14
|
+
# Validates all getter/setters in the current class to see if all values are set.
|
15
|
+
#
|
16
|
+
# @example
|
17
|
+
# struct = Zen::StrictStruct.new(:name, :age).new
|
18
|
+
# struct.validate([:name, :age]) do |k|
|
19
|
+
# puts "The key #{k} is required!"
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# @author Yorick Peterse
|
23
|
+
# @since 0.2.4
|
24
|
+
# @param [Array] required Array of getters that should return a value.
|
25
|
+
# @param [Block] block The block to call whenever an item doesn't have a value.
|
26
|
+
#
|
27
|
+
def validate(required, &block)
|
28
|
+
required.each do |k|
|
29
|
+
if !self.respond_to?(k) or self.send(k).nil?
|
30
|
+
block.call(k)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
data/lib/zen/task/db.rb
CHANGED
@@ -22,12 +22,17 @@ module Zen
|
|
22
22
|
# @since 0.2
|
23
23
|
#
|
24
24
|
def migrate(show_output = true)
|
25
|
-
exts = Zen::Package.
|
25
|
+
exts = Zen::Package.packages
|
26
26
|
|
27
27
|
puts "Migrating..." if show_output === true
|
28
28
|
|
29
29
|
exts.each do |ident, ext|
|
30
|
-
|
30
|
+
if ext.respond_to?(:migration_dir) and !ext.migration_dir.nil?
|
31
|
+
dir = ext.migration_dir
|
32
|
+
else
|
33
|
+
dir = ext.directory + '/../../migrations'
|
34
|
+
end
|
35
|
+
|
31
36
|
table = ext.identifier.gsub('.', '_').to_sym
|
32
37
|
|
33
38
|
if File.directory?(dir)
|
@@ -49,10 +54,15 @@ module Zen
|
|
49
54
|
# @since 0.2
|
50
55
|
#
|
51
56
|
def delete
|
52
|
-
exts = Zen::Package.
|
57
|
+
exts = Zen::Package.packages.map { |ident, ext| [ident, ext] }
|
53
58
|
|
54
59
|
exts.reverse.each do |ident, ext|
|
55
|
-
|
60
|
+
if ext.respond_to?(:migration_dir) and !ext.migration_dir.nil?
|
61
|
+
dir = ext.migration_dir
|
62
|
+
else
|
63
|
+
dir = ext.directory + '/../../migrations'
|
64
|
+
end
|
65
|
+
|
56
66
|
table = ext.identifier.gsub('.', '_').to_sym
|
57
67
|
|
58
68
|
if File.directory?(dir)
|
data/lib/zen/task/package.rb
CHANGED
@@ -14,19 +14,18 @@ module Zen
|
|
14
14
|
desc('list', 'Lists all installed packages')
|
15
15
|
|
16
16
|
##
|
17
|
-
# Lists all installed
|
17
|
+
# Lists all installed packages
|
18
18
|
#
|
19
19
|
# @author Yorick Peterse
|
20
20
|
# @since 0.2
|
21
21
|
#
|
22
22
|
def list
|
23
23
|
table = []
|
24
|
-
table.push(['Name', 'Author', 'Identifier', '
|
25
|
-
table.push(['------', '------', '------', '------'
|
26
|
-
packages = Zen::Package.extensions.merge(Zen::Package.themes)
|
24
|
+
table.push(['Name', 'Author', 'Identifier', 'Directory'])
|
25
|
+
table.push(['------', '------', '------', '------'])
|
27
26
|
|
28
|
-
packages.each do |ident, ext|
|
29
|
-
table.push([ext.name, ext.author, ext.identifier, ext.
|
27
|
+
Zen::Package.packages.each do |ident, ext|
|
28
|
+
table.push([ext.name, ext.author, ext.identifier, ext.directory])
|
30
29
|
end
|
31
30
|
|
32
31
|
print_table(table)
|
@@ -47,7 +46,7 @@ module Zen
|
|
47
46
|
version = options[:version]
|
48
47
|
ident = options[:identifier]
|
49
48
|
|
50
|
-
if Zen::Package.
|
49
|
+
if Zen::Package.packages.nil? or Zen::Package.extensions.empty?
|
51
50
|
abort "No packages have been loaded. Be sure to add them to config/requires.rb."
|
52
51
|
end
|
53
52
|
|
@@ -61,7 +60,13 @@ module Zen
|
|
61
60
|
abort "You specified an invalid identifier."
|
62
61
|
end
|
63
62
|
|
64
|
-
|
63
|
+
# Get the directory from the migration_dir getter, generate it if it isn't there.
|
64
|
+
if install_ext.respond_to?(:migration_dir) and !install_ext.migration_dir.nil?
|
65
|
+
dir = install_ext.migration_dir
|
66
|
+
else
|
67
|
+
dir = install_ext.directory + '/../../migrations'
|
68
|
+
end
|
69
|
+
|
65
70
|
table = install_ext.identifier.gsub('.', '_').to_sym
|
66
71
|
|
67
72
|
puts "Migrating package..."
|