climax 0.0.2 → 0.0.3

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/README.markdown CHANGED
@@ -162,3 +162,51 @@ debugger will not begin until the current iteration of `main` has completed.
162
162
  This is excellent for stopping a long running process without interrupting its work. By sending an
163
163
  :exit or :quit event, whether through the Control DRb or from your application itself, your
164
164
  application will be allowed to finish processing its current unit of work before exiting.
165
+
166
+ Generating a New Application
167
+ ============================
168
+
169
+ To help you get started quickly, you can easily generate a new application using climax by running
170
+ the following command:
171
+
172
+ climax create <project-name>
173
+
174
+ Climax will then create a new project for you that is ready to rock and roll. Here is the file
175
+ structure generated for a new project named "my_project":
176
+
177
+ my_project/
178
+ Gemfile
179
+ LICENSE.txt
180
+ README.md
181
+ Rakefile
182
+ bin/
183
+ my_project*
184
+ features/
185
+ step_definitions/
186
+ support/
187
+ io.rb
188
+ env.rb
189
+ lib/
190
+ my_project.rb
191
+ my_project/
192
+ version.rb
193
+ my_project.gemspec
194
+ pkg
195
+
196
+ Your new application has the boilerplate code necessary to start running your application immediately:
197
+
198
+ cd my_project
199
+ ./bin/my_project --help
200
+ Usage: my_project [options]
201
+ -d, --daemon Fork application and run in background
202
+ --log_level Set to debug, info, warn, error, or fatal. Default: info.
203
+ --log_file File to log output to. By default logs to stdout.
204
+ --control_port Override the port for the control DRb to listen on. Default is 7249
205
+ -h, --help Display this help message.
206
+
207
+ Running the application will simply print `"Hello World"` until you hit `Ctrl-C`.
208
+
209
+ The three files you will want to modify are `README.md` (with info about your application),
210
+ `<project-name>.gemspec` and `lib/<project-name>.rb`.
211
+
212
+ You can bundle your application with `gem bundle *.gemspec`.
data/bin/climax ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
3
+ require 'rubygems' rescue nil
4
+ require 'climax/cli'
5
+ Climax::CLI::Application.new(ARGV)
data/lib/climax.rb CHANGED
@@ -1,218 +1 @@
1
- require "pry"
2
- require "slop"
3
- require "logger"
4
- require "pry-remote"
5
- require "climax/version"
6
- require "climax/control_drb"
7
-
8
- module Climax
9
- module Application
10
-
11
- def initialize(args=[])
12
- @args = args.dup
13
- options do
14
- on :d, :daemon, "Fork application and run in background"
15
- on :log_level=, "Set to debug, info, warn, error, or fatal. Default: info.", :default => "info"
16
- on :log_file=, "File to log output to. By default logs to stdout.", :default => nil
17
- on :control_port=, "Override the port for the control DRb to listen on. Default is 7249", :as => :int, :default => 7249
18
- end
19
- configure
20
- _parse_options
21
- end
22
-
23
- def _pre_main
24
- if daemonize?
25
- exit 0 if !Process.fork.nil?
26
- log.debug "Running in background (#{$$})"
27
- end
28
-
29
- log.debug "Starting Control DRb on port #{control_port}"
30
- @control_drb = Climax::ControlDRb.new(self, control_port)
31
- end
32
-
33
- def _post_main
34
- log.debug "Stopping Control DRb"
35
- @control_drb.stop_service
36
- end
37
-
38
- def _parse_options
39
- slop.parse!
40
- @opts = slop
41
- exit 0 if opts.help?
42
- rescue => e
43
- abort("#{e.message}\n#{slop.to_s}")
44
- end
45
-
46
- def daemonize?
47
- @daemonize = opts[:daemon]
48
- end
49
-
50
- def log
51
- if @log.nil?
52
- @log = Logger.new(log_file || $stdout, "daily")
53
- @log.level = log_level
54
- if log_file
55
- @log.formatter = proc do |severity, datetime, progname, msg|
56
- datetime = datetime.strftime("%Y-%m-%d %H:%M:%S")
57
- "[#{datetime}] #{$$} #{severity} -- #{msg}\n"
58
- end
59
- else
60
- # Give a more concise format when logging to STDOUT
61
- @log.formatter = proc do |severity, datetime, progname, msg|
62
- "#{severity}: #{msg}\n"
63
- end
64
- end
65
- end
66
- @log
67
- end
68
-
69
- def control_port
70
- @control_port ||= opts[:control_port]
71
- end
72
-
73
- def control_port= (port)
74
- raise "Cannot set control port to #{port}: ControlDRb is already running!" if @control_drb
75
- @control_port = port
76
- end
77
-
78
- def log_file
79
- @log_file ||= opts[:log_file]
80
- end
81
-
82
- def log_file= (path)
83
- if !@log.nil?
84
- warning = "Changing log path to #{path}!"
85
- $stderr.write(warning)
86
- log.warn(warning)
87
- @log = nil
88
- end
89
- @log_file = path
90
- end
91
-
92
- # Return current log_level
93
- def log_level
94
- @log_level ||= string_to_log_level opts[:log_level]
95
- end
96
-
97
- # Set log level to "debug", "warn", "info", etc. or use Logger::DEBUG, etc.
98
- def log_level= (level)
99
- log.level = @log_level = string_to_log_level(level)
100
- log.warn("Changed log level to #{level}")
101
- end
102
-
103
- # Example: "debug" => Logger::DEBUG
104
- def string_to_log_level (string)
105
- return string if string.is_a? Fixnum
106
- Logger.const_get(string.upcase)
107
- end
108
-
109
- # Raw command line arguments passed to application
110
- def args
111
- @args
112
- end
113
-
114
- # Return instance of Slop
115
- def slop
116
- @slop ||= Slop.new(:strict => true, :help => true)
117
- end
118
-
119
- # Method for wrapping calls to on() and banner(). Simply for readability.
120
- # Example:
121
- # options do
122
- # on 'v', 'verbose', 'More output'
123
- # end
124
- def options (&block)
125
- yield
126
- end
127
-
128
- # Run the application
129
- def run
130
- _pre_main
131
- pre_main
132
- @exit_status = _event_loop
133
- _post_main
134
- post_main
135
-
136
- exit exit_status if exit_status.is_a? Fixnum
137
- abort(exit_status.to_s)
138
- end
139
-
140
- def exit_status
141
- @exit_status
142
- end
143
-
144
- # Return current options. nil until ClimaxApplication::new has finished running
145
- def opts
146
- @opts
147
- end
148
-
149
- # Set a command line option ala Slop
150
- def on (*args)
151
- slop.on(*args)
152
- end
153
-
154
- # Set help banner output ala Slop
155
- def banner (*args)
156
- slop.banner(*args)
157
- end
158
-
159
- def command (cmd, &block)
160
- slop.command(cmd, block)
161
- end
162
-
163
- def _event_loop
164
- while true
165
-
166
- begin
167
- event = _next_event
168
-
169
- unless event.nil?
170
- case event.type
171
- when :set_log_level then log_level = event.payload
172
- when :stop_control_drb then @control_drb && @control_drb.stop_service
173
- when :start_remote_debugger then binding.remote_pry
174
- when :quit, :exit then return 0
175
- end
176
- end
177
- end while !event.nil?
178
-
179
- result = main
180
- return result if !result.nil?
181
- end
182
- end
183
-
184
- def send_event (type, payload=nil)
185
- events_mutex.synchronize {
186
- events.unshift OpenStruct.new(:type => type, :payload => payload)
187
- }
188
- end
189
-
190
- def events
191
- @events ||= []
192
- end
193
-
194
- def _next_event
195
- events_mutex.synchronize {
196
- events.pop
197
- }
198
- end
199
-
200
- def events_mutex
201
- @events_mutex ||= Mutex.new
202
- end
203
-
204
- def configure
205
- end
206
-
207
- def main
208
- raise "Please implement a main() method for your application."
209
- end
210
-
211
- def pre_main
212
- end
213
-
214
- def post_main
215
- end
216
-
217
- end
218
- end
1
+ require 'climax/application'
@@ -0,0 +1,218 @@
1
+ require "pry"
2
+ require "slop"
3
+ require "logger"
4
+ require "pry-remote"
5
+ require "climax/version"
6
+ require "climax/control_drb"
7
+
8
+ module Climax
9
+ module Application
10
+
11
+ def initialize(args=[])
12
+ @args = args.dup
13
+ options do
14
+ on :d, :daemon, "Fork application and run in background"
15
+ on :log_level=, "Set to debug, info, warn, error, or fatal. Default: info.", :default => "info"
16
+ on :log_file=, "File to log output to. By default logs to stdout.", :default => nil
17
+ on :control_port=, "Override the port for the control DRb to listen on. Default is 7249", :as => :int, :default => 7249
18
+ end
19
+ configure
20
+ _parse_options
21
+ end
22
+
23
+ def _pre_main
24
+ if daemonize?
25
+ exit 0 if !Process.fork.nil?
26
+ log.debug "Running in background (#{$$})"
27
+ end
28
+
29
+ log.debug "Starting Control DRb on port #{control_port}"
30
+ @control_drb = Climax::ControlDRb.new(self, control_port)
31
+ end
32
+
33
+ def _post_main
34
+ log.debug "Stopping Control DRb"
35
+ @control_drb.stop_service
36
+ end
37
+
38
+ def _parse_options
39
+ slop.parse!
40
+ @opts = slop
41
+ exit 0 if opts.help?
42
+ rescue => e
43
+ abort("#{e.message}\n#{slop.to_s}")
44
+ end
45
+
46
+ def daemonize?
47
+ @daemonize = opts[:daemon]
48
+ end
49
+
50
+ def log
51
+ if @log.nil?
52
+ @log = Logger.new(log_file || $stdout, "daily")
53
+ @log.level = log_level
54
+ if log_file
55
+ @log.formatter = proc do |severity, datetime, progname, msg|
56
+ datetime = datetime.strftime("%Y-%m-%d %H:%M:%S")
57
+ "[#{datetime}] #{$$} #{severity} -- #{msg}\n"
58
+ end
59
+ else
60
+ # Give a more concise format when logging to STDOUT
61
+ @log.formatter = proc do |severity, datetime, progname, msg|
62
+ "#{severity}: #{msg}\n"
63
+ end
64
+ end
65
+ end
66
+ @log
67
+ end
68
+
69
+ def control_port
70
+ @control_port ||= opts[:control_port]
71
+ end
72
+
73
+ def control_port= (port)
74
+ raise "Cannot set control port to #{port}: ControlDRb is already running!" if @control_drb
75
+ @control_port = port
76
+ end
77
+
78
+ def log_file
79
+ @log_file ||= opts[:log_file]
80
+ end
81
+
82
+ def log_file= (path)
83
+ if !@log.nil?
84
+ warning = "Changing log path to #{path}!"
85
+ $stderr.write(warning)
86
+ log.warn(warning)
87
+ @log = nil
88
+ end
89
+ @log_file = path
90
+ end
91
+
92
+ # Return current log_level
93
+ def log_level
94
+ @log_level ||= string_to_log_level opts[:log_level]
95
+ end
96
+
97
+ # Set log level to "debug", "warn", "info", etc. or use Logger::DEBUG, etc.
98
+ def log_level= (level)
99
+ log.level = @log_level = string_to_log_level(level)
100
+ log.warn("Changed log level to #{level}")
101
+ end
102
+
103
+ # Example: "debug" => Logger::DEBUG
104
+ def string_to_log_level (string)
105
+ return string if string.is_a? Fixnum
106
+ Logger.const_get(string.upcase)
107
+ end
108
+
109
+ # Raw command line arguments passed to application
110
+ def args
111
+ @args
112
+ end
113
+
114
+ # Return instance of Slop
115
+ def slop
116
+ @slop ||= Slop.new(:strict => true, :help => true)
117
+ end
118
+
119
+ # Method for wrapping calls to on() and banner(). Simply for readability.
120
+ # Example:
121
+ # options do
122
+ # on 'v', 'verbose', 'More output'
123
+ # end
124
+ def options (&block)
125
+ yield
126
+ end
127
+
128
+ # Run the application
129
+ def run
130
+ _pre_main
131
+ pre_main
132
+ @exit_status = _event_loop
133
+ _post_main
134
+ post_main
135
+
136
+ exit exit_status if exit_status.is_a? Fixnum
137
+ abort(exit_status.to_s)
138
+ end
139
+
140
+ def exit_status
141
+ @exit_status
142
+ end
143
+
144
+ # Return current options. nil until ClimaxApplication::new has finished running
145
+ def opts
146
+ @opts
147
+ end
148
+
149
+ # Set a command line option ala Slop
150
+ def on (*args)
151
+ slop.on(*args)
152
+ end
153
+
154
+ # Set help banner output ala Slop
155
+ def banner (*args)
156
+ slop.banner(*args)
157
+ end
158
+
159
+ def command (cmd, &block)
160
+ slop.command(cmd, block)
161
+ end
162
+
163
+ def _event_loop
164
+ while true
165
+
166
+ begin
167
+ event = _next_event
168
+
169
+ unless event.nil?
170
+ case event.type
171
+ when :set_log_level then log_level = event.payload
172
+ when :stop_control_drb then @control_drb && @control_drb.stop_service
173
+ when :start_remote_debugger then binding.remote_pry
174
+ when :quit, :exit then return 0
175
+ end
176
+ end
177
+ end while !event.nil?
178
+
179
+ result = main
180
+ return result if !result.nil?
181
+ end
182
+ end
183
+
184
+ def send_event (type, payload=nil)
185
+ _events_mutex.synchronize {
186
+ _events.unshift OpenStruct.new(:type => type, :payload => payload)
187
+ }
188
+ end
189
+
190
+ def _events
191
+ @_events ||= []
192
+ end
193
+
194
+ def _next_event
195
+ _events_mutex.synchronize {
196
+ _events.pop
197
+ }
198
+ end
199
+
200
+ def _events_mutex
201
+ @_events_mutex ||= Mutex.new
202
+ end
203
+
204
+ def configure
205
+ end
206
+
207
+ def main
208
+ raise "Please implement a main() method for your application."
209
+ end
210
+
211
+ def pre_main
212
+ end
213
+
214
+ def post_main
215
+ end
216
+
217
+ end
218
+ end
data/lib/climax/cli.rb ADDED
@@ -0,0 +1,34 @@
1
+ require 'slop'
2
+
3
+ require 'climax/commands/create'
4
+ require 'climax/commands/control'
5
+
6
+ module Climax
7
+ module CLI
8
+ class Application
9
+
10
+ def initialize (args)
11
+ @args = args.dup
12
+ @opts = Slop.parse(:strict => true, :help => true) do
13
+ command 'create' do
14
+ run do |options, args|
15
+ Climax::CLI::Command::Create.new(options, args).run
16
+ end
17
+ end
18
+
19
+ command 'control' do
20
+ on 'p', 'port=', 'Port of control drb to connect to. Default: 7249', :default => 7249, :as => :int
21
+ run do |options, args|
22
+ Climax::CLI::Command::Control.new(options, args).run
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ def opts
29
+ @opts
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,77 @@
1
+ require 'fileutils'
2
+ require 'erb'
3
+
4
+ module Climax
5
+ module CLI
6
+ module Command
7
+ class Create
8
+
9
+ def initialize (options, args)
10
+ @opts = options.dup
11
+ @args = args.dup
12
+ end
13
+
14
+ def run
15
+ raise "Too many arguments. Just pass name of new climax application" if args.length > 1
16
+ raise "Not enough arguments. Please pass name of new climax application" if args.length < 1
17
+ @full_path = args[0]
18
+ @name = File.basename(@full_path)
19
+ @dir = File.dirname(@full_path)
20
+
21
+ create_directory_structure @name, @dir
22
+ end
23
+
24
+ def in_directory (dir, &block)
25
+ cwd = FileUtils.pwd
26
+ FileUtils.mkpath(dir)
27
+ FileUtils.cd(dir)
28
+ begin
29
+ yield
30
+ ensure
31
+ FileUtils.cd(cwd)
32
+ end
33
+ end
34
+
35
+ def create_directory_structure (name, dir)
36
+ in_directory(dir) do
37
+ # Create standard bundler gem layout
38
+ %x[bundle gem #{name}]
39
+ # Add a couple extra directories
40
+ FileUtils.mkpath(["#{name}/bin", "#{name}/features", "#{name}/pkg"])
41
+
42
+ # Get bundler generated module path
43
+ gemspec = File.read("#{name}/#{name}.gemspec")
44
+ module_string = /gem.version\s+=\s+(.*)::VERSION/.match(gemspec)[1]
45
+ module_path = module_string.split("::")
46
+
47
+ template_dir = File.join(File.dirname(__FILE__), "..", "..", "..", "templates")
48
+
49
+ File.open("#{name}/bin/#{name}", "w") do |file|
50
+ file.write(ERB.new(File.read(File.join(template_dir, "application_wrapper.erb")), 0, '<>').result(binding))
51
+ end
52
+
53
+ FileUtils.chmod "+x", "#{name}/bin/#{name}"
54
+
55
+ File.open("#{name}/lib/#{name}.rb", "w") do |file|
56
+ file.write(ERB.new(File.read(File.join(template_dir, "application.rb.erb")), 0, '<>').result(binding))
57
+ end
58
+
59
+ gemspec.gsub!(/^end$/, " gem.add_development_dependency \"cucumber\"\n gem.add_runtime_dependency \"climax\"\nend")
60
+ File.open("#{name}/#{name}.gemspec", "w") do |file|
61
+ file.write(gemspec)
62
+ end
63
+
64
+ end
65
+ end
66
+
67
+ def opts
68
+ @opts
69
+ end
70
+
71
+ def args
72
+ @args
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -1,3 +1,3 @@
1
1
  module Climax
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -0,0 +1,37 @@
1
+ require "climax"
2
+ require "<%= name %>/version"
3
+
4
+ <% indent = 0 %>
5
+ <% module_path.each do |m| %>
6
+ <%= (" "*indent) + "module #{m}\n" %>
7
+ <% indent = indent + 2 %>
8
+ <% end %>
9
+
10
+ class Application
11
+ include Climax::Application
12
+
13
+ def configure
14
+ # options do
15
+ # on 'v', 'verbose', 'More verbose'
16
+ # end
17
+ end
18
+
19
+ def pre_main
20
+ # log.debug "Application has is about to run"
21
+ end
22
+
23
+ def main
24
+ log.info "Hello World!"
25
+ sleep 1
26
+ return nil
27
+ end
28
+
29
+ def post_main
30
+ # log.debug "Application is shutting down."
31
+ end
32
+ end
33
+
34
+ <% module_path.each do |_| %>
35
+ <% indent = indent - 2 %>
36
+ <%= (" "*indent) + "end\n" %>
37
+ <% end %>
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- mode: ruby -*-
3
+ $:.unshift File.expand_path("../../lib", __FILE__)
4
+ require "rubygems" rescue nil
5
+ require "<%= name %>"
6
+ <%= module_string %>::Application.new(ARGV).run
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: climax
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
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-02-21 00:00:00.000000000 Z
12
+ date: 2013-02-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: pry
@@ -96,7 +96,8 @@ description: Opinionated framework for Ruby CLI applications that provides loggi
96
96
  of long running processes
97
97
  email:
98
98
  - alfred.fazio@gmail.com
99
- executables: []
99
+ executables:
100
+ - climax
100
101
  extensions: []
101
102
  extra_rdoc_files: []
102
103
  files:
@@ -104,10 +105,17 @@ files:
104
105
  - Gemfile
105
106
  - README.markdown
106
107
  - Rakefile
108
+ - bin/climax
107
109
  - climax.gemspec
108
110
  - lib/climax.rb
111
+ - lib/climax/application.rb
112
+ - lib/climax/cli.rb
113
+ - lib/climax/commands/control.rb
114
+ - lib/climax/commands/create.rb
109
115
  - lib/climax/control_drb.rb
110
116
  - lib/climax/version.rb
117
+ - templates/application.rb.erb
118
+ - templates/application_wrapper.erb
111
119
  - test/bin/hello_world
112
120
  - test/lib/hello_world.rb
113
121
  homepage: https://github.com/appriss/climax