tb-cli 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/README.md +89 -0
- data/Rakefile +18 -0
- data/bin/tb +4 -0
- data/lib/tb-cli.rb +47 -0
- data/lib/tb-cli/camel_case.rb +18 -0
- data/lib/tb-cli/cli/add.rb +256 -0
- data/lib/tb-cli/cli/rack.rb +51 -0
- data/lib/tb-cli/config_file.rb +76 -0
- data/lib/tb-cli/descriptions.rb +55 -0
- data/lib/tb-cli/templates/Gemfile.tt +6 -0
- data/lib/tb-cli/templates/README.tt +21 -0
- data/lib/tb-cli/templates/Rakefile.tt +1 -0
- data/lib/tb-cli/templates/app.rb.tt +9 -0
- data/lib/tb-cli/templates/config.ru.tt +2 -0
- data/lib/tb-cli/templates/fully-exploded-torquebox.yml.tt +106 -0
- data/lib/tb-cli/templates/template.rb +74 -0
- data/lib/tb-cli/templates/torquebox.yml.tt +3 -0
- data/lib/tb-cli/version.rb +6 -0
- data/spec/spec_helper.rb +3 -0
- data/tb-cli.gemspec +31 -0
- metadata +116 -0
data/.gitignore
ADDED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
-m markdown
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
Torquebox CLI
|
2
|
+
=============
|
3
|
+
The command-line app for making [Torquebox][1] even louder.
|
4
|
+
|
5
|
+
Usage
|
6
|
+
-----
|
7
|
+
|
8
|
+
tb [action] [options]
|
9
|
+
|
10
|
+
Actions that you can perform are `rack` and `add`, which can be described
|
11
|
+
below.
|
12
|
+
|
13
|
+
### Add component with `tb add`
|
14
|
+
Add a component to your torquebox.yml. Torquebox provides a number of features
|
15
|
+
that make writing Rack and Rails-based applications a breeze, such as messaging
|
16
|
+
features, background services, cron-like tasks, and service pooling.
|
17
|
+
|
18
|
+
Types of components can be:
|
19
|
+
|
20
|
+
* `application` - Application types
|
21
|
+
* `web` - WEb configuration settings
|
22
|
+
* `ruby` - version of ruby you want to set, including compilation options
|
23
|
+
* `environment` - add and remove environment variables for the runtime of
|
24
|
+
your JRuby App
|
25
|
+
* `queue` - manipulate queues (create, rename, remove)
|
26
|
+
* `topic` - create a topic
|
27
|
+
* `messaing` - set up handlers for your queues/topics
|
28
|
+
* `task` - create a task with a concurrency setting
|
29
|
+
* `job` - create an external job, including various settings around it
|
30
|
+
(job class, description, crontab)
|
31
|
+
* `service` - Create a long-running service that runs in the background
|
32
|
+
* `auth` - configure your authorization settings
|
33
|
+
* `pooling` - Runtime pooling options
|
34
|
+
|
35
|
+
For help with any component you want to add, you can get help by typing `tb add
|
36
|
+
help [component]`, and you'll get some help.
|
37
|
+
|
38
|
+
### Create baseline Torquebox-Rack app with `tb rack`
|
39
|
+
Generate a Rack-based application. A normal Rack-based Torquebox application
|
40
|
+
only needs a few files, which this generator helps fill out for you:
|
41
|
+
|
42
|
+
* `project_name` folder
|
43
|
+
* `project_name/config.ru` - Your Rackup file
|
44
|
+
* `project_name/lib` directory
|
45
|
+
* `project_name/app.rb` base application file that starts Rack
|
46
|
+
* `project_name/Rakefile` with [Torquebox specific rake tasks][3]
|
47
|
+
* `project_name/torquebox.yml` - Your Torquebox config file
|
48
|
+
* `project_name/Gemfile` if you decide to use it as a Gem
|
49
|
+
|
50
|
+
|
51
|
+
More Help
|
52
|
+
=========
|
53
|
+
|
54
|
+
If you are unfamiliar with the layout of the `torquebox.yml` file or don't know
|
55
|
+
what all this gobbledygook means, you can always reference the torquebox documentation, from
|
56
|
+
which much of this application is based off of.
|
57
|
+
|
58
|
+
http://torquebox.org/documentation/
|
59
|
+
|
60
|
+
Why
|
61
|
+
---
|
62
|
+
Torquebox is a really awesome project and I was interested in doing something
|
63
|
+
with it. Since there didn't appear to be any project-generator-type
|
64
|
+
thing in place, I decided to make one. This is as much an experiment with
|
65
|
+
[Thor][2] as it is an interest in providing Torquebox a command-line application
|
66
|
+
to spin up TB apps quickly.
|
67
|
+
|
68
|
+
Obviously, if you find bugs, report them, throw a pull request my way, and
|
69
|
+
feel free to critique the hell out of this. This is my first project in the
|
70
|
+
Ruby space, and I'm more interested in making this a good app, even if it's not
|
71
|
+
entirely useful to anybody.
|
72
|
+
|
73
|
+
### Note:
|
74
|
+
I have no tests at all for this. I'm interested in trying to test it, but I'm
|
75
|
+
not entirely sure how I would test a command-line app when much of it's
|
76
|
+
functionality is wrapped in Thor (which I trust to do its job) tasks and such.
|
77
|
+
|
78
|
+
To Do
|
79
|
+
=====
|
80
|
+
I don't have an interest in adding too many more features, but I have a small list of things
|
81
|
+
I'd like to include to fill it out a bit:
|
82
|
+
|
83
|
+
* wrap [rake tasks][3]
|
84
|
+
* include the [rails template generator][4] provided by the Torquebox team
|
85
|
+
|
86
|
+
[1]: http://www.torquebox.org/
|
87
|
+
[2]: http://www.github.com/wycats/thor
|
88
|
+
[3]: http://torquebox.org/documentation/1.0.1/deployment.html#deploy-using-rake
|
89
|
+
[4]: http://torquebox.org/documentation/1.0.1/web.html#using-the-rails-application-template
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
gem 'rdoc'
|
2
|
+
require 'rdoc/task'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'bundler'
|
5
|
+
|
6
|
+
Bundler::GemHelper.install_tasks
|
7
|
+
|
8
|
+
CLEAN.include('*.tmp')
|
9
|
+
CLOBBER.include('*.tmp', 'pkg/', 'html/')
|
10
|
+
|
11
|
+
# Default is to build and generate docs. No tests yet, so can't do that
|
12
|
+
task :default => ["build", "rdoc"]
|
13
|
+
|
14
|
+
# Document gem and place in html/
|
15
|
+
Rake::RDocTask.new do |rd|
|
16
|
+
rd.main = "README.md"
|
17
|
+
rd.rdoc_files.include("lib/**/*.rb", "README.md")
|
18
|
+
end
|
data/bin/tb
ADDED
data/lib/tb-cli.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
$: << File.expand_path(File.dirname(__FILE__) + "/../lib")
|
2
|
+
require 'rubygems'
|
3
|
+
require 'thor'
|
4
|
+
require 'thor/group'
|
5
|
+
|
6
|
+
module Tbox
|
7
|
+
# Base Command Line interface. Registers the two major Thor tasks (Rack and
|
8
|
+
# Add).
|
9
|
+
class Cli < Thor
|
10
|
+
require 'tb-cli/camel_case'
|
11
|
+
require 'tb-cli/descriptions'
|
12
|
+
require 'tb-cli/cli/add'
|
13
|
+
require 'tb-cli/cli/rack'
|
14
|
+
require 'tb-cli/config_file'
|
15
|
+
|
16
|
+
register Tbox::Add, "add", "add [component]", ADD
|
17
|
+
register Tbox::Rack, "rack", "rack [project_name]", RACK
|
18
|
+
|
19
|
+
# Default help message when nothing is passed in
|
20
|
+
def help(meth=nil)
|
21
|
+
puts BANNER
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
25
|
+
# override the Basic shell with the colorized one in Thor
|
26
|
+
def self.start(*)
|
27
|
+
Thor::Base.shell = Thor::Shell::Color
|
28
|
+
super
|
29
|
+
end
|
30
|
+
|
31
|
+
# Default Help Message banner.
|
32
|
+
BANNER = <<-BAN
|
33
|
+
Torquebox CLI
|
34
|
+
|
35
|
+
tb [action] [options] # See below for more details on actions
|
36
|
+
|
37
|
+
Use this template generator to make quick Rack applications. If you want a
|
38
|
+
rails app, please use the application template provided by Torquebox
|
39
|
+
(http://torquebox.org/documentation/DEV/rails.html#using-the-rails-application-template):
|
40
|
+
|
41
|
+
rails new my_app -m $TORQUEBOX_HOME/share/rails/template.rb
|
42
|
+
|
43
|
+
BAN
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
Tbox::Cli.start
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# See the 'tb-cli/cli/rack' module for initializing Rack-based projects to see
|
2
|
+
# where this modification is being used.
|
3
|
+
class String
|
4
|
+
|
5
|
+
# Stolen from StackOverflow: http://stackoverflow.com/questions/1509915/converting-camel-case-to-underscore-case-in-ruby
|
6
|
+
#
|
7
|
+
# This converts a string from CamelCase to snake_case. This allows all String
|
8
|
+
# classes to call #underscore to get a proper conversion.
|
9
|
+
#
|
10
|
+
def underscore
|
11
|
+
self.gsub(/::/, '/').
|
12
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
13
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
14
|
+
tr("-", "_").
|
15
|
+
downcase
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,256 @@
|
|
1
|
+
module Tbox
|
2
|
+
# Class for adding components to your `torquebox.yml`, `queues.yml` or
|
3
|
+
# `topics.yml` file.
|
4
|
+
class Add < Thor
|
5
|
+
include Thor::Actions
|
6
|
+
|
7
|
+
desc "add application", "Application"
|
8
|
+
long_desc <<-DESC
|
9
|
+
Add an application component descriptor to your project. See
|
10
|
+
|
11
|
+
http://torquebox.org/documentation/1.0.1/deployment-descriptors.html#general-application-config-in-descriptor
|
12
|
+
|
13
|
+
for more details. The two options you have at your disposal are:
|
14
|
+
|
15
|
+
root_loc: location for your project (/path/to/my/app)
|
16
|
+
env: your environment (development, test, production)
|
17
|
+
DESC
|
18
|
+
method_option :root_loc, :type => :string, :desc => "root for your application"
|
19
|
+
method_option :env, :type => :string, :desc => "Environment to run under (development, test, production)"
|
20
|
+
def application
|
21
|
+
y = ConfigFile.new destination_root
|
22
|
+
if options.root_loc || options.env
|
23
|
+
y.add_config('application', 'root', options.root_loc) if options.root_loc
|
24
|
+
y.add_config('application', 'env', options.env) if options.env
|
25
|
+
replace_yaml(y.yaml)
|
26
|
+
else
|
27
|
+
puts "You need to specify either --root-loc or --env"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "add web", "Web"
|
32
|
+
long_desc <<-DESC
|
33
|
+
Add web-specific configuration to your application. Since Torquebox can deploy multiple applications
|
34
|
+
under one hostname, extra configuration options are allowed to make deployment easier. If you want to
|
35
|
+
specify the specific 'rackup.ru' script for your app, configure with --rackup=location. You can specify
|
36
|
+
a specific context that this application will be avaialble for (such as /application) by using --context.
|
37
|
+
|
38
|
+
Virtual hosts can also be configured with the --host option. Finally, you can also specify a location for
|
39
|
+
your static web content can be pointed to by using the --static=location option.
|
40
|
+
|
41
|
+
See http://torquebox.org/documentation/1.0.1/deployment-descriptors.html#web-specific-config-in-descriptor
|
42
|
+
for more details.
|
43
|
+
DESC
|
44
|
+
method_option :rackup, :type => :string, :default => "config.ru", :desc => "Rackup file (default config.ru)"
|
45
|
+
method_option :host, :type => :string, :default => "localhost", :desc => "virtual host to run as (default localhost)"
|
46
|
+
method_option :context, :type => :string, :default => "/", :desc => "path under http://host/ to deploy to (default: '/')"
|
47
|
+
method_option :static, :type => :string, :desc => "Any static web content provided should be put here (default: none)"
|
48
|
+
def web
|
49
|
+
y = ConfigFile.new destination_root
|
50
|
+
y.add_config('web', 'rackup', options.rackup) if options.rackup
|
51
|
+
y.add_config('web', 'host', options.host) if options.host
|
52
|
+
y.add_config('web', 'context', options.context) if options.context
|
53
|
+
y.add_config('web', 'static', options.static) if options.static
|
54
|
+
replace_yaml(y.yaml)
|
55
|
+
end
|
56
|
+
|
57
|
+
desc "add ruby", "Ruby"
|
58
|
+
long_desc <<-DESC
|
59
|
+
Add Ruby runtime configurations for your web application. JRuby allows for a couple different runtime options:
|
60
|
+
Ruby interpreter version (1.8 or 1.9 through --version), and compile mode (jit, force, off) through --compile_mode.
|
61
|
+
|
62
|
+
See http://torquebox.org/documentation/1.0.1/deployment-descriptors.html#ruby-runtime-config-in-descriptor
|
63
|
+
for more details.
|
64
|
+
DESC
|
65
|
+
method_option :version, :type => :numeric, :desc => "Ruby interpreter version, either 1.8 or 1.9"
|
66
|
+
method_option :compile_mode, :type => :string, :desc => "Compile mode (jit, force, or off)"
|
67
|
+
def ruby
|
68
|
+
y = ConfigFile.new destination_root
|
69
|
+
if [ 1.8, 1.9 ].include? options.version
|
70
|
+
y.add_config('ruby', 'version', options.version)
|
71
|
+
end
|
72
|
+
if [ 'jit', 'force', 'off' ].include? options.compile_mode
|
73
|
+
y.add_config('ruby', 'compile_mode', options.compile_mode)
|
74
|
+
end
|
75
|
+
replace_yaml(y.yaml)
|
76
|
+
end
|
77
|
+
|
78
|
+
desc "add environment", "Add an environment variable, such as MAIL_HOST or REPLY_TO"
|
79
|
+
method_option :options, :type => :hash, :desc => "Add options as you need them: --options=MAIL_HOST:server REPLY_TO:emailaddress, etc., etc."
|
80
|
+
def environment
|
81
|
+
y = ConfigFile.new destination_root
|
82
|
+
options.options.each_pair { |k,v|
|
83
|
+
y.add_config('environment', k, v)
|
84
|
+
}
|
85
|
+
replace_yaml(y.yaml)
|
86
|
+
end
|
87
|
+
|
88
|
+
desc "add queue", "Add a Queue to your application"
|
89
|
+
long_desc <<-DESC
|
90
|
+
Queues are a messaging component that can be often used in load balancing situations. For sending and receiving
|
91
|
+
messages, you define a topic to queue up all of the work to be done, and subscribe a number of queue handlers
|
92
|
+
to retrieve messages off of the queue as the work arrives. Adding a queue to your application is pretty easy.
|
93
|
+
Just add the --name=queue_name. An additional option --not_durable, can be appended to prevent any messages from
|
94
|
+
being written to disk in case of server failure. By default, all queues are durable, but if you want to disable this
|
95
|
+
functionality, you can do so.
|
96
|
+
|
97
|
+
Much more detailed documentation on queues and topics can be found on the Torquebox site, including documentation
|
98
|
+
on how to interact with a queue, sending and receiving messages and the like:
|
99
|
+
|
100
|
+
http://torquebox.org/documentation/1.0.1/messaging.html
|
101
|
+
DESC
|
102
|
+
method_option :name, :type => :string, :required => true
|
103
|
+
method_option :not_durable, :type => :boolean, :default => false, :desc => "Disable Durable subscriber (at your own risk)"
|
104
|
+
def queue
|
105
|
+
# TODO: Add external queues and hosts (see section 7.2.3.3 for details)
|
106
|
+
file = 'queues.yml'
|
107
|
+
y = ConfigFile.new destination_root, file
|
108
|
+
if (options.not_durable && options.name)
|
109
|
+
y.add_config("/queues/#{options.name}", "durable: #{!options.not_durable}")
|
110
|
+
elsif (options.name)
|
111
|
+
y.add_config("/queues/#{options.name}")
|
112
|
+
end
|
113
|
+
replace_yaml(y.yaml, file)
|
114
|
+
end
|
115
|
+
|
116
|
+
desc "add topic", "Add a Topic to your application"
|
117
|
+
long_desc <<-DESC
|
118
|
+
Topics are similar to Queues, except that they follow the pub-sub model for messaging. Currently, the only
|
119
|
+
option allowed is --name=name_of_topic. Much more documentation can be found on how to use Topics and Queues,
|
120
|
+
and how they fit into Torquebox on their website:
|
121
|
+
|
122
|
+
http://torquebox.org/documentation/1.0.1/messaging.html
|
123
|
+
DESC
|
124
|
+
method_option :name, :type => :string, :required => true
|
125
|
+
def topic
|
126
|
+
# TODO: Add external queues and hosts (see section 7.2.3.3 for details)
|
127
|
+
file = 'topics.yml'
|
128
|
+
y = ConfigFile.new destination_root, file
|
129
|
+
y.add_config("/topics/#{options.name}")
|
130
|
+
replace_yaml(y.yaml, file)
|
131
|
+
end
|
132
|
+
|
133
|
+
desc "add messaging", "Add Messaging handlers for your queues and topics"
|
134
|
+
long_desc <<-DESC
|
135
|
+
Handlers are classes that consume messages on either topics or queues. Defining which classes are going to handle
|
136
|
+
these messages can be done by specifying the --queue=name_of_queue, as well as the --handler_class=ClassName to
|
137
|
+
provide a handler for.
|
138
|
+
|
139
|
+
As always, documentation for Message Processors can be found on the Torquebox site:
|
140
|
+
http://torquebox.org/documentation/LATEST/messaging.html#messaging-consumers
|
141
|
+
DESC
|
142
|
+
method_option :queue, :type => :string, :desc => "Name of the queue (/queues/my_queue_name:)"
|
143
|
+
method_option :topic, :type => :string, :desc => "Name of the topic (/topics/my_topic_name:)"
|
144
|
+
method_option :handler_class, :type => :string
|
145
|
+
def messaging
|
146
|
+
if options.queue == nil && options.topic == nil
|
147
|
+
puts "You must specify either a topic or a queue you're configuring a handler for"
|
148
|
+
else
|
149
|
+
if options.handler_class
|
150
|
+
y = ConfigFile.new destination_root
|
151
|
+
messaging = y.add_config["messaging"] || {}
|
152
|
+
if options.queue
|
153
|
+
messaging[options.queue] = options.handler_class
|
154
|
+
elsif options.topic
|
155
|
+
messaging[options.topic] = options.handler_class
|
156
|
+
end
|
157
|
+
y.add_config["messaging"] = messaging
|
158
|
+
puts y.yaml
|
159
|
+
replace_yaml(y.yaml)
|
160
|
+
else
|
161
|
+
puts "You must specify a --handler-class"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
desc "add task", "Add a Task"
|
167
|
+
method_option :name, :type => :string, :desc => "Class Name of Task (MyTaskName)", :required => true
|
168
|
+
method_option :concurrency, :type => :numeric, :desc => "Number of concurrent messages you want to handle"
|
169
|
+
def task
|
170
|
+
y = ConfigFile.new destination_root
|
171
|
+
if options.concurrency
|
172
|
+
y.add_config('tasks', options.name, { "concurrency" => options.concurrency })
|
173
|
+
else
|
174
|
+
y.add_config('tasks', options.name)
|
175
|
+
end
|
176
|
+
replace_yaml(y.yaml)
|
177
|
+
end
|
178
|
+
|
179
|
+
desc "add job", "Add a scheduled job"
|
180
|
+
method_option :job_name, :type => :string, :required => true
|
181
|
+
method_option :job_class, :type => :string, :required => true, :desc => "Class for the Job (Mail::Notifier)"
|
182
|
+
method_option :cron, :type => :string, :required => true,
|
183
|
+
:desc => "crontab-like entry, Similar to the following: '0 */5 * * * ?'"
|
184
|
+
method_option :description, :type => :string, :desc => "Optional Description"
|
185
|
+
def job
|
186
|
+
y = ConfigFile.new destination_root
|
187
|
+
opts = {}
|
188
|
+
opts['job'] = options.job_class
|
189
|
+
opts['cron'] = options.cron
|
190
|
+
opts['description'] = options.description if options.description
|
191
|
+
y.add_config('jobs', options.job_name, opts)
|
192
|
+
replace_yaml(y.yaml)
|
193
|
+
end
|
194
|
+
|
195
|
+
desc "add service", "Add a background service"
|
196
|
+
method_option :name, :type => :string, :desc => "Service Name", :required => true
|
197
|
+
method_option :params, :type => :hash, :desc => "key:value pairs to supply for this service"
|
198
|
+
method_option :singleton, :type => :boolean, :desc => "Will this be a singleton operation?", :default => false
|
199
|
+
def service
|
200
|
+
y = ConfigFile.new destination_root
|
201
|
+
opts = options.params
|
202
|
+
opts["singleton"] = true if options.singleton
|
203
|
+
y.add_config('services', options.name, opts)
|
204
|
+
replace_yaml(y.yaml)
|
205
|
+
end
|
206
|
+
|
207
|
+
desc "add auth", "Auth"
|
208
|
+
method_option :auth_type, :type => :string, :desc => "Authentication type", :required => true
|
209
|
+
method_option :domain, :type => :string, :desc => "domain to authenticate against", :required => true
|
210
|
+
def auth
|
211
|
+
y = ConfigFile.new destination_root
|
212
|
+
y.add_config('auth', options.auth_type, { "domain" => options.domain })
|
213
|
+
replace_yaml(y.yaml)
|
214
|
+
end
|
215
|
+
|
216
|
+
desc "add pooling", "Pooling"
|
217
|
+
method_option :subsystem, :type => :string, :desc => "Subsystem type (web, jobs, messaging, services)",
|
218
|
+
:required => true
|
219
|
+
method_option :bounded, :type => :hash, :desc => "min:1, max:3, etc"
|
220
|
+
method_option :shared, :type => :boolean, :desc => "use this if not using bounded pooling"
|
221
|
+
method_option :global, :type => :boolean, :desc => "if not using bounded or shared"
|
222
|
+
def pooling
|
223
|
+
y = ConfigFile.new destination_root
|
224
|
+
thing = {}
|
225
|
+
thing["pooling"] = {}
|
226
|
+
if [ 'web', 'jobs', 'messaging', 'services' ].include? options.subsystem
|
227
|
+
if options.bounded
|
228
|
+
y.add_config('pooling', options.subsystem, options.bounded)
|
229
|
+
elsif options.shared
|
230
|
+
y.add_config('pooling', options.subsystem, 'shared')
|
231
|
+
elsif options.global
|
232
|
+
y.add_config('pooling', options.subsystem, 'global')
|
233
|
+
end
|
234
|
+
replace_yaml(y.yaml)
|
235
|
+
else
|
236
|
+
puts "subsystem must be one of: web, job, messaging, or services"
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
def help(meth=nil)
|
241
|
+
puts INIT
|
242
|
+
super
|
243
|
+
end
|
244
|
+
|
245
|
+
no_tasks do
|
246
|
+
|
247
|
+
def replace_yaml(yaml_f, file='torquebox.yml')
|
248
|
+
puts "Saving:\n"
|
249
|
+
remove_file(file)
|
250
|
+
create_file(file, yaml_f)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Tbox
|
2
|
+
## Rack tasks for your application.
|
3
|
+
class Rack < Thor
|
4
|
+
|
5
|
+
# For use with generating Rack-based projects
|
6
|
+
include Thor::Actions
|
7
|
+
|
8
|
+
default_task :init
|
9
|
+
|
10
|
+
desc "init", "Initialize a new Rack-based Application"
|
11
|
+
# Initialize a new Rack-based Application
|
12
|
+
def init
|
13
|
+
setup = yes? "Would you like to set up a new Rack-based Application?"
|
14
|
+
if setup
|
15
|
+
say "awesome!", Thor::Color::BOLD + Thor::Color::RED, false
|
16
|
+
say " let's get to work"
|
17
|
+
@project = ask "Name of project: "
|
18
|
+
if @project
|
19
|
+
gen_project @project
|
20
|
+
else
|
21
|
+
say "You need to supply a project name"
|
22
|
+
end
|
23
|
+
else
|
24
|
+
say "Shucks"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
no_tasks do
|
29
|
+
|
30
|
+
# Generates a new project with the provided name:
|
31
|
+
# [project_name] Name of the project and subsequent folder to create
|
32
|
+
# the project for
|
33
|
+
def gen_project(project_name)
|
34
|
+
say_status "new_project", project_name
|
35
|
+
Tbox::Rack.source_root(File.expand_path(File.join(__FILE__, "..", "..")))
|
36
|
+
empty_directory(project_name)
|
37
|
+
empty_directory(project_name + "/lib")
|
38
|
+
%w{ app.rb config.ru Rakefile torquebox.yml README Gemfile }.each { |f|
|
39
|
+
template("templates/#{f}.tt", "#{project_name}/#{f}")
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def method_missing(name, *args) # :nodoc:
|
44
|
+
@project = name.to_s.underscore
|
45
|
+
gen_project name.to_s.underscore
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Tbox
|
2
|
+
# ConfigFile class provides some simple YAML configuration file helpers.
|
3
|
+
# While normal YAML methods within Ruby are fine (and used heavily), these
|
4
|
+
# helpers assist in adding, removing, and replacing configurations for the
|
5
|
+
# Torquebox.yml default specification file. These methods make adding
|
6
|
+
# a config to the torquebox.yml much easier, as it abstracts out the details
|
7
|
+
# of having to know the underlying data structure (Hashes, Arrays, boolean,
|
8
|
+
# string) and just pass in to this ConfigFile the pieces you want to add
|
9
|
+
class ConfigFile
|
10
|
+
require 'yaml'
|
11
|
+
|
12
|
+
attr_accessor :config, :torquebox_yml
|
13
|
+
|
14
|
+
# Create and/or open a YAML configuration file
|
15
|
+
# [destination_root] Directory that you will find the YAML file
|
16
|
+
# [file] Filename of the YAML file to load
|
17
|
+
def initialize(destination_root=nil, file='torquebox.yml')
|
18
|
+
@filename = file
|
19
|
+
@torquebox_yml = File.join(destination_root, @filename)
|
20
|
+
if config_present?
|
21
|
+
@config = YAML.load_file @torquebox_yml
|
22
|
+
else
|
23
|
+
@config = {}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Is the configuration file there or does a new config there to laod?
|
28
|
+
def config_present?
|
29
|
+
File.exist? @torquebox_yml
|
30
|
+
end
|
31
|
+
|
32
|
+
# Convert config to YAML
|
33
|
+
def yaml
|
34
|
+
@config.to_yaml
|
35
|
+
end
|
36
|
+
|
37
|
+
# Dynamically adds to the config object based on what was passed in through
|
38
|
+
# Thor
|
39
|
+
#
|
40
|
+
# @param [Thor::CoreExt::HashWithIndifferentAccess] options options hash given to you by Thor
|
41
|
+
# @param [String] meth string of the method passed in
|
42
|
+
# @param [String] config what the config for that method sets
|
43
|
+
# @param [String] value value assocated with it
|
44
|
+
#
|
45
|
+
# @return [String] the YAML output for this config, e.g.:
|
46
|
+
# options = HashWithIndifferentAccess.new 'topic' => 'some_topic_name'
|
47
|
+
# add_config(options, "topics", "topic"
|
48
|
+
#
|
49
|
+
# ---
|
50
|
+
# topics:
|
51
|
+
# some_topic_name:
|
52
|
+
def add_config(root, config=nil, value=nil)
|
53
|
+
conf = @config[root.to_s] || {}
|
54
|
+
conf[config.to_s] = value if config
|
55
|
+
@config[root.to_s] = nil # Some attributes need no settings and just exist, like queues.yml
|
56
|
+
@config[root.to_s] = conf unless conf.empty?
|
57
|
+
puts "Current #{@filename} configuration file:\n\n#{yaml}\n"
|
58
|
+
end
|
59
|
+
|
60
|
+
# Not tested or documented
|
61
|
+
def remove_config(meth, config)
|
62
|
+
conf = @config[meth.to_s]
|
63
|
+
unless conf
|
64
|
+
puts "No such config available for #{meth}"
|
65
|
+
else
|
66
|
+
puts "removing config \n\t#{config}"
|
67
|
+
begin
|
68
|
+
@config.delete(config)
|
69
|
+
rescue e
|
70
|
+
puts "No such config #{config} to remove, skipping..."
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# Description for when you pass in the 'add' method execution.
|
2
|
+
ADD = <<-COMPONENT
|
3
|
+
Add a new component to the torquebox.yml file. The type of component can be:
|
4
|
+
|
5
|
+
- application
|
6
|
+
- web
|
7
|
+
- ruby
|
8
|
+
- environment
|
9
|
+
- queue
|
10
|
+
- topic
|
11
|
+
- messaging
|
12
|
+
- task
|
13
|
+
- job
|
14
|
+
- service
|
15
|
+
- auth
|
16
|
+
- pooling
|
17
|
+
|
18
|
+
For more help on a particular subcommand, enter
|
19
|
+
|
20
|
+
tb add help [component]
|
21
|
+
|
22
|
+
COMPONENT
|
23
|
+
|
24
|
+
MESSAGING_LONG = <<-MSG
|
25
|
+
Messaging
|
26
|
+
=========
|
27
|
+
For more information, go to (http://torquebox.org/documentation/1.0.0/messaging.html#messaging-consumers) for information (figure 8.15, specifically):
|
28
|
+
|
29
|
+
messaging:
|
30
|
+
/queues/foo:
|
31
|
+
MyFooHandler:
|
32
|
+
filter: "cost > 30"
|
33
|
+
config:
|
34
|
+
type: "premium"
|
35
|
+
season: "fall"
|
36
|
+
concurrency: 2
|
37
|
+
/topics/bar:
|
38
|
+
MyBarHandler:
|
39
|
+
durable: true
|
40
|
+
|
41
|
+
MSG
|
42
|
+
|
43
|
+
RACK = <<-RCK
|
44
|
+
Create a new Rack Application template. By default, will generate the following:
|
45
|
+
|
46
|
+
project_folder
|
47
|
+
|- app.rb (Application stub)
|
48
|
+
|- config.ru (Rackup file)
|
49
|
+
|- Rakefile (Rake with Torquebox configs)
|
50
|
+
|- torquebox.yml (Torquebox config)
|
51
|
+
|
52
|
+
Much of this would be much similar to a rails app, but if you
|
53
|
+
have an interest in doing something more lightweight, you might
|
54
|
+
find this template more appealing and minimal.
|
55
|
+
RCK
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Here's a new application
|
2
|
+
========================
|
3
|
+
|
4
|
+
Nothing fancy, so if you're looking for more details on how to
|
5
|
+
actually generate a nice Torquebox project, there is a wealth
|
6
|
+
of good information to be found in the Torquebox documentation:
|
7
|
+
|
8
|
+
http://torquebox.org/documentation/1.0.0
|
9
|
+
|
10
|
+
What's in this project?
|
11
|
+
-----------------------
|
12
|
+
|
13
|
+
Here are currently a handful of base files to make your first
|
14
|
+
Torquebox app:
|
15
|
+
|
16
|
+
- app.rb Your Application
|
17
|
+
- config.ru Your Rackup file (see http://m.onkey.org/ruby-on-rack-1-hello-rack)
|
18
|
+
- Gemfile include the torquebox and torquebox-rake-support gems
|
19
|
+
- Rakefile See http://torquebox.org/documentation/1.0.0/deployment.html#deploy-using-rake
|
20
|
+
- torquebox.yml Your Torquebox YAML file for configuring all the fancy Torquebox-y things
|
21
|
+
- README This file
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'torquebox/rake/tasks'
|
@@ -0,0 +1,106 @@
|
|
1
|
+
application:
|
2
|
+
root: /path/to/myapp
|
3
|
+
env: development
|
4
|
+
|
5
|
+
web:
|
6
|
+
rackup: alternative/path/to/my_config.ru
|
7
|
+
context: /app-one
|
8
|
+
static: public
|
9
|
+
host: www.host-one.com
|
10
|
+
|
11
|
+
ruby:
|
12
|
+
version: 1.9
|
13
|
+
compile_mode: off
|
14
|
+
|
15
|
+
environment:
|
16
|
+
MAIL_HOST: mail.yourhost.com
|
17
|
+
REPLY_TO: you@yourhost.com
|
18
|
+
|
19
|
+
queues:
|
20
|
+
/queues/my_app_queue:
|
21
|
+
|
22
|
+
topics:
|
23
|
+
/queues/my_app_topic:
|
24
|
+
|
25
|
+
messaging:
|
26
|
+
# Simple messaging:
|
27
|
+
/queues/my_app_queue: MyFooHandler
|
28
|
+
/topics/long_lived_topic: MyBazHandler
|
29
|
+
# Set options in messaging:
|
30
|
+
/queues/foo:
|
31
|
+
MyFooHandler:
|
32
|
+
filter: "cost > 30"
|
33
|
+
config:
|
34
|
+
type: "premium"
|
35
|
+
season: "fall"
|
36
|
+
concurrency: 2
|
37
|
+
/topics/bar:
|
38
|
+
MyBarHandler:
|
39
|
+
durable: true
|
40
|
+
# Advanced Setup
|
41
|
+
/topics/simple: SimpleHandler
|
42
|
+
|
43
|
+
/topics/popular:
|
44
|
+
- Handler
|
45
|
+
concurrency: 5
|
46
|
+
- Observer: &defaults
|
47
|
+
filter: "x > 18"
|
48
|
+
config:
|
49
|
+
x: ex
|
50
|
+
y: why
|
51
|
+
- Processor
|
52
|
+
|
53
|
+
/queues/students:
|
54
|
+
VerySimpleAnalyzer:
|
55
|
+
YouthMonitor:
|
56
|
+
filter: "y < 18"
|
57
|
+
config:
|
58
|
+
h: ache
|
59
|
+
i: eye
|
60
|
+
LookAndFeel:
|
61
|
+
<<: *defaults
|
62
|
+
|
63
|
+
|
64
|
+
tasks:
|
65
|
+
SomeTask:
|
66
|
+
concurrency: 2
|
67
|
+
SomeOtherTask:
|
68
|
+
concurrency: 5
|
69
|
+
|
70
|
+
jobs:
|
71
|
+
mail.notifier:
|
72
|
+
job: Mail::Notifier
|
73
|
+
cron: '0 */5 * * * ?'
|
74
|
+
description: Deliver queued mail notifications
|
75
|
+
|
76
|
+
services:
|
77
|
+
MyService:
|
78
|
+
name: TorqueBox User
|
79
|
+
|
80
|
+
AnotherService:
|
81
|
+
singleton: true # Enable High Availability
|
82
|
+
|
83
|
+
auth:
|
84
|
+
default:
|
85
|
+
domain: hornetq
|
86
|
+
jmx:
|
87
|
+
domain: jmx-console
|
88
|
+
|
89
|
+
pooling:
|
90
|
+
web: # Bounded pool with upper and lower limit
|
91
|
+
min: 3
|
92
|
+
max: 10
|
93
|
+
web: shared # A shared pool is also an option
|
94
|
+
web: global # A global pool
|
95
|
+
# Default pooling config for an app in development mode
|
96
|
+
jobs:
|
97
|
+
min: 1
|
98
|
+
max: 2
|
99
|
+
messaging:
|
100
|
+
min: 1
|
101
|
+
max: 2
|
102
|
+
web: shared
|
103
|
+
# Default pooling config for a non-development deployment
|
104
|
+
jobs: shared
|
105
|
+
messaging: shared
|
106
|
+
web: shared
|
@@ -0,0 +1,74 @@
|
|
1
|
+
if ( Rails::VERSION::MAJOR == 2 )
|
2
|
+
gem "activerecord-jdbc-adapter", :lib => "arjdbc"
|
3
|
+
else
|
4
|
+
text = File.read 'Gemfile'
|
5
|
+
File.open('Gemfile', 'w') {|f| f << text.gsub(/^(gem 'sqlite3)/, '# \1') }
|
6
|
+
gem "activerecord-jdbc-adapter", :require => "arjdbc"
|
7
|
+
gem "jdbc-sqlite3"
|
8
|
+
gem "jruby-openssl"
|
9
|
+
end
|
10
|
+
|
11
|
+
# gems defs common to v2 and v3
|
12
|
+
gem "torquebox-rake-support"
|
13
|
+
gem 'torquebox'
|
14
|
+
|
15
|
+
|
16
|
+
if ( Rails::VERSION::MAJOR == 2 )
|
17
|
+
initializer("session_store.rb") do
|
18
|
+
<<-INIT
|
19
|
+
# Configure the TorqueBox Servlet-based session store.
|
20
|
+
# Provides for server-based, in-memory, cluster-compatible sessions.
|
21
|
+
( ActionController::Base.session_store = TorqueBox::Session::ServletStore ) if defined?(TorqueBox::Session::ServletStore)
|
22
|
+
INIT
|
23
|
+
end
|
24
|
+
else
|
25
|
+
remove_file( 'config/initializers/session_store.rb' )
|
26
|
+
initializer("session_store.rb") do
|
27
|
+
<<-INIT
|
28
|
+
# Configure the TorqueBox Servlet-based session store.
|
29
|
+
# Provides for server-based, in-memory, cluster-compatible sessions
|
30
|
+
#{app_const}.config.session_store TorqueBox::Session::ServletStore if defined?(TorqueBox::Session::ServletStore)
|
31
|
+
INIT
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
initializer("active_record_backgroundable.rb") do
|
36
|
+
<<-INIT
|
37
|
+
# Enable backgroundable methods for ActiveRecord classes. Provides:
|
38
|
+
# class AModel < ActiveRecord::Base
|
39
|
+
# always_background :a_method
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# a_model_instance.background.another_method
|
43
|
+
if defined?(TorqueBox::Messaging::Backgroundable) && defined?(ActiveRecord::Base)
|
44
|
+
ActiveRecord::Base.send(:include, TorqueBox::Messaging::Backgroundable)
|
45
|
+
end
|
46
|
+
INIT
|
47
|
+
end
|
48
|
+
|
49
|
+
# Create app/tasks and app/jobs, just for fun
|
50
|
+
inside('app') {
|
51
|
+
FileUtils.mkdir %w( tasks jobs )
|
52
|
+
}
|
53
|
+
|
54
|
+
# We need the app to find the rake tasks
|
55
|
+
rakefile( 'torquebox.rake' ) do
|
56
|
+
<<-TASK
|
57
|
+
|
58
|
+
begin
|
59
|
+
require 'torquebox-rake-support'
|
60
|
+
rescue LoadError => ex
|
61
|
+
puts "Failed to load the TorqueBox rake gem (torquebox-rake-support). Make sure it is available in your environment."
|
62
|
+
end
|
63
|
+
|
64
|
+
# Patch db:load_config to make sure activerecord-jdbc-adapter gets loaded
|
65
|
+
namespace :db do
|
66
|
+
task :load_config => :rails_env do
|
67
|
+
require 'active_record'
|
68
|
+
require 'activerecord-jdbc-adapter'
|
69
|
+
ActiveRecord::Base.configurations = Rails::Application.config.database_configuration
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
TASK
|
74
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/tb-cli.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "tb-cli/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "tb-cli"
|
7
|
+
s.version = Tbox::Cli::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Nick Klauer"]
|
10
|
+
s.email = ["klauer@gmail.com"]
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = %q{Create simple Torquebox.yml templates for your Torquebox, Rack-based applications.}
|
13
|
+
s.description = %q{Torquebox (http://www.torquebox.org) is a JBoss Application Server that will run your
|
14
|
+
Rack and Rails apps in JRuby. Torquebox provides a number of additional functionality that you might find useful, such
|
15
|
+
as messaging, background services, and scheduled tasks. Configuring those is incredibly easy, since they all rely on
|
16
|
+
simple YAML file configs. This CLI application simplifies that further by lettnig you generate your applications and
|
17
|
+
application templates with simple command line executions.}
|
18
|
+
|
19
|
+
s.add_development_dependency "rspec"
|
20
|
+
s.add_development_dependency "sinatra"
|
21
|
+
s.add_dependency "thor"
|
22
|
+
|
23
|
+
s.executables << "tb"
|
24
|
+
|
25
|
+
s.rubyforge_project = "tb-cli"
|
26
|
+
|
27
|
+
s.files = `git ls-files`.split("\n")
|
28
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
29
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
30
|
+
s.require_paths = ["lib"]
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tb-cli
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Nick Klauer
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-05-29 00:00:00 -05:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rspec
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "0"
|
25
|
+
type: :development
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sinatra
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: "0"
|
36
|
+
type: :development
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: thor
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: *id003
|
49
|
+
description: |-
|
50
|
+
Torquebox (http://www.torquebox.org) is a JBoss Application Server that will run your
|
51
|
+
Rack and Rails apps in JRuby. Torquebox provides a number of additional functionality that you might find useful, such
|
52
|
+
as messaging, background services, and scheduled tasks. Configuring those is incredibly easy, since they all rely on
|
53
|
+
simple YAML file configs. This CLI application simplifies that further by lettnig you generate your applications and
|
54
|
+
application templates with simple command line executions.
|
55
|
+
email:
|
56
|
+
- klauer@gmail.com
|
57
|
+
executables:
|
58
|
+
- tb
|
59
|
+
extensions: []
|
60
|
+
|
61
|
+
extra_rdoc_files: []
|
62
|
+
|
63
|
+
files:
|
64
|
+
- .gitignore
|
65
|
+
- .yardopts
|
66
|
+
- Gemfile
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- bin/tb
|
70
|
+
- lib/tb-cli.rb
|
71
|
+
- lib/tb-cli/camel_case.rb
|
72
|
+
- lib/tb-cli/cli/add.rb
|
73
|
+
- lib/tb-cli/cli/rack.rb
|
74
|
+
- lib/tb-cli/config_file.rb
|
75
|
+
- lib/tb-cli/descriptions.rb
|
76
|
+
- lib/tb-cli/templates/Gemfile.tt
|
77
|
+
- lib/tb-cli/templates/README.tt
|
78
|
+
- lib/tb-cli/templates/Rakefile.tt
|
79
|
+
- lib/tb-cli/templates/app.rb.tt
|
80
|
+
- lib/tb-cli/templates/config.ru.tt
|
81
|
+
- lib/tb-cli/templates/fully-exploded-torquebox.yml.tt
|
82
|
+
- lib/tb-cli/templates/template.rb
|
83
|
+
- lib/tb-cli/templates/torquebox.yml.tt
|
84
|
+
- lib/tb-cli/version.rb
|
85
|
+
- spec/spec_helper.rb
|
86
|
+
- tb-cli.gemspec
|
87
|
+
has_rdoc: true
|
88
|
+
homepage: ""
|
89
|
+
licenses: []
|
90
|
+
|
91
|
+
post_install_message:
|
92
|
+
rdoc_options: []
|
93
|
+
|
94
|
+
require_paths:
|
95
|
+
- lib
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: "0"
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
none: false
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: "0"
|
108
|
+
requirements: []
|
109
|
+
|
110
|
+
rubyforge_project: tb-cli
|
111
|
+
rubygems_version: 1.6.1
|
112
|
+
signing_key:
|
113
|
+
specification_version: 3
|
114
|
+
summary: Create simple Torquebox.yml templates for your Torquebox, Rack-based applications.
|
115
|
+
test_files:
|
116
|
+
- spec/spec_helper.rb
|