caterpillar 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSES.txt +25 -0
- data/README +21 -0
- data/Rakefile +26 -0
- data/bin/caterpillar +39 -0
- data/db/migrate/20081205000001_lportal_portlets.rb +12 -0
- data/db/migrate/20081205000002_lportal_sequences.rb +50 -0
- data/generators/caterpillar/USAGE +1 -0
- data/generators/caterpillar/caterpillar_generator.rb +52 -0
- data/generators/caterpillar/templates/config/portlets.rb +59 -0
- data/generators/caterpillar/templates/images/caterpillar/caterpillar.gif +0 -0
- data/generators/caterpillar/templates/javascripts/caterpillar/caterpillar.js +15 -0
- data/generators/caterpillar/templates/stylesheets/caterpillar/caterpillar.css +48 -0
- data/init.rb +8 -0
- data/install.rb +3 -0
- data/lib/caterpillar.rb +27 -0
- data/lib/caterpillar/config.rb +57 -0
- data/lib/caterpillar/liferay.rb +235 -0
- data/lib/caterpillar/liferay_portlet.rb +8 -0
- data/lib/caterpillar/navigation.rb +40 -0
- data/lib/caterpillar/parser.rb +110 -0
- data/lib/caterpillar/portlet.rb +98 -0
- data/lib/caterpillar/task.rb +285 -0
- data/lib/caterpillar/usage.rb +21 -0
- data/lib/caterpillar/util.rb +80 -0
- data/lib/caterpillar/version.rb +9 -0
- data/lib/web/portlet_name.rb +8 -0
- data/test/portlets_test.rb +43 -0
- data/test/xml_test.rb +24 -0
- data/views/caterpillar/_navigation.html.erb +45 -0
- metadata +116 -0
@@ -0,0 +1,285 @@
|
|
1
|
+
#--
|
2
|
+
# (c) Copyright 2008 Mikael Lammentausta
|
3
|
+
#
|
4
|
+
# Thanks to Nick Sieger for the rake structure!
|
5
|
+
#
|
6
|
+
# See the file LICENSES.txt included with the distribution for
|
7
|
+
# software license details.
|
8
|
+
#++
|
9
|
+
|
10
|
+
require 'rake'
|
11
|
+
require 'rake/tasklib'
|
12
|
+
|
13
|
+
require 'actionpack'
|
14
|
+
require 'action_controller'
|
15
|
+
|
16
|
+
# --
|
17
|
+
# Rake task. Allows defining multiple configurations inside the same
|
18
|
+
# Rakefile by using different task names.
|
19
|
+
# ++
|
20
|
+
module Caterpillar
|
21
|
+
class << self
|
22
|
+
attr_writer :project_application
|
23
|
+
def project_application
|
24
|
+
@project_application || Rake.application
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Task < Rake::TaskLib
|
29
|
+
|
30
|
+
# Task name
|
31
|
+
attr_accessor :name
|
32
|
+
|
33
|
+
# Config
|
34
|
+
attr_accessor :config
|
35
|
+
|
36
|
+
# Portlets
|
37
|
+
attr_reader :portlets
|
38
|
+
|
39
|
+
# The main task.
|
40
|
+
# Reads the configuration file and launches appropriate tasks.
|
41
|
+
# Defines the rake task prefix 'jsr'.
|
42
|
+
def initialize(name = :usage, config = nil, tasks = :define_tasks)
|
43
|
+
@name = name
|
44
|
+
@config = Util.eval_configuration(config)
|
45
|
+
yield self if block_given?
|
46
|
+
send tasks
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def define_tasks
|
52
|
+
define_main_task
|
53
|
+
define_usage_task
|
54
|
+
define_pluginize_task
|
55
|
+
define_environment_task
|
56
|
+
define_portletxml_task
|
57
|
+
define_liferayportletappxml_task
|
58
|
+
define_liferaydisplayxml_task
|
59
|
+
define_parse_task
|
60
|
+
define_portlets_task
|
61
|
+
define_fixtures_task
|
62
|
+
define_liferayportlets_task
|
63
|
+
define_migrate_task
|
64
|
+
define_rollback_task
|
65
|
+
end
|
66
|
+
|
67
|
+
# the main XML generator task
|
68
|
+
def define_main_task
|
69
|
+
desc 'Create all XML files according to configuration'
|
70
|
+
tasks = [:parse,"#{@name}:portletxml"]
|
71
|
+
if @config.container.kind_of? Liferay
|
72
|
+
tasks << "#{@name}:liferayportletappxml"
|
73
|
+
tasks << "#{@name}:liferaydisplayxml"
|
74
|
+
end
|
75
|
+
tasks << "portlets" # finally print produced portlets
|
76
|
+
task :jsr => tasks
|
77
|
+
end
|
78
|
+
|
79
|
+
def define_usage_task
|
80
|
+
task :usage do
|
81
|
+
Usage.show
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def define_pluginize_task
|
86
|
+
desc "Unpack Caterpillar as a plugin in your Rails application"
|
87
|
+
task :pluginize do
|
88
|
+
if !Dir["vendor/plugins/caterpillar*"].empty?
|
89
|
+
puts "I found an old nest in vendor/plugins; please trash it so I can make a new one"
|
90
|
+
puts "(directory vendor/plugins/caterpillar* exists)"
|
91
|
+
elsif !File.directory?("vendor/plugins")
|
92
|
+
puts "I can't find a place to build my nest"
|
93
|
+
puts "(directory 'vendor/plugins' is missing)"
|
94
|
+
else
|
95
|
+
Dir.chdir("vendor/plugins") do
|
96
|
+
ruby "-S", "gem", "unpack", "caterpillar"
|
97
|
+
end
|
98
|
+
ruby "./script/generate caterpillar"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# navigation debugging task
|
104
|
+
def define_portlets_task
|
105
|
+
desc 'Prints portlet configuration'
|
106
|
+
task :portlets => :parse do
|
107
|
+
print_portlets(@portlets)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def define_fixtures_task
|
112
|
+
desc 'Creates YAML fixtures from live data for testing.'
|
113
|
+
task :fixtures => :environment do
|
114
|
+
require 'active_record'
|
115
|
+
|
116
|
+
sql = "SELECT * from %s"
|
117
|
+
|
118
|
+
skip_tables = []
|
119
|
+
begin
|
120
|
+
skip_tables = @config.container.skip_fixture_tables
|
121
|
+
end
|
122
|
+
|
123
|
+
ActiveRecord::Base.establish_connection
|
124
|
+
(ActiveRecord::Base.connection.tables - skip_tables).each do |table|
|
125
|
+
i = "000"
|
126
|
+
File.open("#{RAILS_ROOT}/test/fixtures/#{table}.yml", 'w') do |file|
|
127
|
+
puts "* %s" % file.inspect
|
128
|
+
data = ActiveRecord::Base.connection.select_all(sql % table)
|
129
|
+
file.write data.inject({}) { |hash, record|
|
130
|
+
hash["#{table}_#{i.succ!}"] = record
|
131
|
+
hash
|
132
|
+
}.to_yaml
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
### SUB-TASKS
|
139
|
+
|
140
|
+
# reads Rails environment configuration
|
141
|
+
def define_environment_task
|
142
|
+
task :default => :test
|
143
|
+
task :environment do
|
144
|
+
require(File.join(@config.rails_root, 'config', 'environment'))
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# collects Rails' routes and parses the config
|
149
|
+
def define_parse_task
|
150
|
+
task :parse => :environment do
|
151
|
+
@config.routes = Util.parse_routes(@config)
|
152
|
+
@portlets = Parser.new(@config).portlets
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
# Writes the portlet.xml file
|
157
|
+
def define_portletxml_task
|
158
|
+
@name = :jsr
|
159
|
+
# set the output filename
|
160
|
+
if @config.container.kind_of? Liferay
|
161
|
+
file = 'portlet-ext.xml'
|
162
|
+
else
|
163
|
+
file = 'portlet.xml'
|
164
|
+
end
|
165
|
+
with_namespace_and_config do |name, config|
|
166
|
+
desc "Create JSR286 portlet XML"
|
167
|
+
task "portletxml" do
|
168
|
+
system('touch %s' % file)
|
169
|
+
f=File.open(file,'w')
|
170
|
+
f.write Portlet.xml(@portlets)
|
171
|
+
f.close
|
172
|
+
STDOUT.puts 'Created %s' % file
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# Writes liferay-portlet-ext.xml
|
178
|
+
def define_liferayportletappxml_task
|
179
|
+
@name = :jsr
|
180
|
+
file = 'liferay-portlet-ext.xml'
|
181
|
+
with_namespace_and_config do |name, config|
|
182
|
+
desc 'Create Liferay portlet XML'
|
183
|
+
task "liferayportletappxml" do
|
184
|
+
system('touch %s' % file)
|
185
|
+
f=File.open(file,'w')
|
186
|
+
f.write config.container.portletapp_xml(@portlets)
|
187
|
+
f.close
|
188
|
+
STDOUT.puts 'Created %s' % file
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
# Writes liferay-display.xml
|
194
|
+
def define_liferaydisplayxml_task
|
195
|
+
@name = :jsr
|
196
|
+
file = 'liferay-display.xml'
|
197
|
+
with_namespace_and_config do |name, config|
|
198
|
+
desc "Create Liferay display XML"
|
199
|
+
task "liferaydisplayxml" do
|
200
|
+
system('touch %s' % file)
|
201
|
+
f=File.open(file,'w')
|
202
|
+
f.write config.container.display_xml(@portlets)
|
203
|
+
f.close
|
204
|
+
STDOUT.puts 'Created %s' % file
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def define_liferayportlets_task
|
210
|
+
@name = :jsr
|
211
|
+
with_namespace_and_config do |name, config|
|
212
|
+
desc 'Analyses native Liferay portlets XML'
|
213
|
+
task "portlets" do
|
214
|
+
@portlets = config.container.analyze(:native)
|
215
|
+
print_portlets(@portlets)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
|
221
|
+
def define_migrate_task
|
222
|
+
@name = :db
|
223
|
+
with_namespace_and_config do |name, config|
|
224
|
+
desc "Migrates Caterpillar database tables"
|
225
|
+
task :migrate => :environment do
|
226
|
+
require 'active_record'
|
227
|
+
ActiveRecord::Migrator.migrate(
|
228
|
+
File.expand_path(
|
229
|
+
File.dirname(__FILE__) + "/../../db/migrate"))
|
230
|
+
# Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
|
231
|
+
|
232
|
+
@portlets = config.container.analyze(:native)
|
233
|
+
@portlets.each do |portlet|
|
234
|
+
LiferayPortlet.create(
|
235
|
+
:name => portlet[:name],
|
236
|
+
:title => portlet[:title]
|
237
|
+
)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
def define_rollback_task
|
244
|
+
with_namespace_and_config do |name, config|
|
245
|
+
desc "Wipes out Caterpillar database tables"
|
246
|
+
task :rollback => :environment do
|
247
|
+
require 'active_record'
|
248
|
+
version = ENV['VERSION'].to_i || 0
|
249
|
+
ActiveRecord::Migrator.migrate(
|
250
|
+
File.expand_path(
|
251
|
+
File.dirname(__FILE__) + "/../../db/migrate"), version)
|
252
|
+
# Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def with_namespace_and_config
|
258
|
+
name, config = @name, @config
|
259
|
+
namespace name do
|
260
|
+
yield name, config
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
protected
|
265
|
+
|
266
|
+
def print_portlets(hash)
|
267
|
+
Util.categorize(hash).each_pair do |category,portlets|
|
268
|
+
puts category
|
269
|
+
portlets.each do |portlet|
|
270
|
+
# spaces
|
271
|
+
spaces = ''
|
272
|
+
0.upto(50-portlet[:title].size+1) do
|
273
|
+
spaces << ' '
|
274
|
+
end
|
275
|
+
|
276
|
+
field = :path
|
277
|
+
puts "\t"+ portlet[:title] +spaces+ portlet[field].inspect
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
|
283
|
+
|
284
|
+
end
|
285
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#--
|
2
|
+
# (c) Copyright 2008 Mikael Lammentausta
|
3
|
+
# See the file LICENSES.txt included with the distribution for
|
4
|
+
# software license details.
|
5
|
+
#++
|
6
|
+
|
7
|
+
module Caterpillar
|
8
|
+
class Usage
|
9
|
+
def self.show
|
10
|
+
puts 'Caterpillar v.%s (c) Copyright 2008 Mikael Lammentausta' % VERSION
|
11
|
+
puts 'Caterpillar is provided under the terms of the MIT license.'
|
12
|
+
puts
|
13
|
+
puts 'Usage:'
|
14
|
+
puts ' See "%s --describe" for an overview of the tasks.' % $0
|
15
|
+
puts
|
16
|
+
puts ' cd to Rails root, and run the "%s pluginize" task' % $0
|
17
|
+
# puts ' Run "%s" in Rails root' % $0
|
18
|
+
# puts ' See
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
#--
|
2
|
+
# (c) Copyright 2008 Mikael Lammentausta
|
3
|
+
# See the file LICENSES.txt included with the distribution for
|
4
|
+
# software license details.
|
5
|
+
#++
|
6
|
+
|
7
|
+
module Caterpillar
|
8
|
+
# Common utility methods
|
9
|
+
class Util
|
10
|
+
class << self
|
11
|
+
|
12
|
+
# Reads the configuration
|
13
|
+
def eval_configuration(config=nil)
|
14
|
+
if config.nil? && File.exists?(Config::FILE)
|
15
|
+
config = eval(File.open(Config::FILE) {|f| f.read})
|
16
|
+
end
|
17
|
+
config ||= Config.new
|
18
|
+
unless config.kind_of? Config
|
19
|
+
warn "Portlet config not provided by override in initializer or #{Config::FILE}; using defaults"
|
20
|
+
config = Config.new
|
21
|
+
end
|
22
|
+
return config
|
23
|
+
end
|
24
|
+
|
25
|
+
# Collects Rails' routes and parses the config
|
26
|
+
def parse_routes(config)
|
27
|
+
# taken from Rails' "routes" task
|
28
|
+
# routes = ActionController::Routing::Routes.routes.collect do |route|
|
29
|
+
# name = ActionController::Routing::Routes.named_routes.routes.index(route).to_s
|
30
|
+
# verb = route.conditions[:method].to_s.upcase
|
31
|
+
# segs = route.segments.inject("") { |str,s| str << s.to_s }
|
32
|
+
# segs.chop! if segs.length > 1
|
33
|
+
# reqs = route.requirements.empty? ? "" : route.requirements.inspect
|
34
|
+
# {:name => name, :verb => verb, :segs => segs, :reqs => reqs}
|
35
|
+
# end
|
36
|
+
|
37
|
+
ActionController::Routing::Routes.named_routes.collect do |route|
|
38
|
+
name = route[0]
|
39
|
+
# segments; the path
|
40
|
+
segs = route[1].segments.inject("") { |str,s| str << s.to_s }
|
41
|
+
segs.chop! if segs.length > 1
|
42
|
+
# controller and action
|
43
|
+
reqs = route[1].requirements
|
44
|
+
|
45
|
+
# extra variables
|
46
|
+
keys = route[1].significant_keys
|
47
|
+
vars = keys - [:action, :controller]
|
48
|
+
|
49
|
+
{:name => name, :path => segs, :reqs => reqs, :vars => vars}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Reorganizes the portlets hash by category.
|
54
|
+
#
|
55
|
+
# {'Category 1' => [portlets], 'Category 2' => [portlets]}
|
56
|
+
def categorize(portlets)
|
57
|
+
ret = {}
|
58
|
+
# STDERR.puts portlets.first.inspect
|
59
|
+
|
60
|
+
# organize into categories
|
61
|
+
categories = portlets.collect{|p| p[:category]}.uniq.each do |category|
|
62
|
+
# select the portlets in this category
|
63
|
+
_portlets = portlets.select{|p| p[:category]==category}
|
64
|
+
ret.update(category => _portlets)
|
65
|
+
end
|
66
|
+
|
67
|
+
# puts ret.inspect
|
68
|
+
|
69
|
+
|
70
|
+
# {'Zcore' => [], 'Foo' => []}
|
71
|
+
|
72
|
+
return ret
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
end # static
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
module Web # :nodoc:
|
4
|
+
# This model does not appear in the lportal database. This is created by a migration and contains the portlet id => name mappings.
|
5
|
+
class PortletName < ActiveRecord::Base # :nodoc:
|
6
|
+
set_table_name :web_portlet_names
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require File.dirname(File.expand_path(__FILE__))+'/test_helper'
|
3
|
+
|
4
|
+
class PortletsTest < Caterpillar::TestCase # :nodoc:
|
5
|
+
|
6
|
+
# def test_get
|
7
|
+
# @portlets.each do |portlet|
|
8
|
+
# next if portlet[:reqs].empty?
|
9
|
+
# @controller = portlet[:reqs][:controller]
|
10
|
+
# action = portlet[:reqs][:action]
|
11
|
+
# get action
|
12
|
+
# end
|
13
|
+
# end
|
14
|
+
|
15
|
+
def test_name
|
16
|
+
@portlets.each do |portlet|
|
17
|
+
assert_not_nil portlet[:name], '%s has no name' % portlet
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_path
|
22
|
+
@portlets.each do |portlet|
|
23
|
+
assert_not_nil portlet[:path], '%s has no path' % portlet[:name]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_reqs
|
28
|
+
@portlets.each do |portlet|
|
29
|
+
assert_not_nil portlet[:reqs], '%s has no reqs' % portlet[:name]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_vars
|
34
|
+
valid_variables = [:uid,:gid] # the rails-portlet can handle these
|
35
|
+
@portlets.each do |portlet|
|
36
|
+
assert_not_nil portlet[:vars], '%s has no vars' % portlet[:name]
|
37
|
+
portlet[:vars].each do |var|
|
38
|
+
assert valid_variables.include?(var), '%s is not supported by Rails-portlet, file a feature request' % var
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|