Permalink
Browse files

Gave the Ramaze executable the much needed love.

A few things have changed to the executable so far. The biggest change is that
rather than using regular expressions to "parse" all given options it now uses
OptionParser. This comes with the added advantage of making it easy to set
banners, options, running commands and so on. Another big change is that rather
than dumping most of the code in a single file each command is located in it's
own file making it easier to maintain them.

Most of the code in this commit is still backwards compatible and should still
work on Windows based system (since I just used the code written by @bougyman for
that). There are however a few minor changes. Because OptionParser is used the
output displayed when specifying -h or --help has changed, this however is a
good thing as the output now follows the Unix standards of command line
executables.

Another thing that has changed in terms of command behavior is that most
commands related to managing applications either accept a directory or a file.
For example, the command $ ramaze start now allows you to specify a directory
(or file) that points to the location of a Rackup configuration file. This is
actually quite useful as it makes it possible to run the ramaze executable from
any given location.

In order to make it easier to spec the executable and it's commands (I have yet
to begin working on this) I decided to manually specify all the possible Rack
and Ruby options the command Ramaze::Bin::Start accepts. Before this commit
these were extracted by parsing the output of rackup -h, this however proved to
be quite annoying as with every change of this output our specs would break
(even if it would be something simple such as newlines being removed).

A few examples of the new executable setup:

    $ ramaze start
    $ ramaze start /home/someuser/ramaze/
    $ ramaze start /home/someuser/ramaze/config.ru

Debugging using IRB:

    $ ramaze console
    $ ramaze console /home/someuser/ramaze
    $ ramaze console /home/someuser/ramaze/start.rb

Or perhaps viewing the status of an application:

    $ ramaze status
    $ ramaze status /home/someuser/ramaze -P /home/someuser/ramaze/ramaze.pid

For more information see the files located in lib/ramaze/bin, the old files
located in lib/ramaze/tool will be removed in the next commit.
  • Loading branch information...
1 parent 241c233 commit cd9fa64138324a5af061daafbd8e7307726843ed @YorickPeterse YorickPeterse committed Jul 21, 2011
View
@@ -1,15 +1,18 @@
#!/usr/bin/env ruby
+
begin
- require "pathname"
- local_ramaze = Pathname.new(__FILE__).expand_path.dirname.join("..", "lib", "ramaze.rb")
- if local_ramaze.file?
- require local_ramaze.to_s
+ local_ramaze = File.expand_path('../../lib/ramaze', __FILE__)
+
+ if File.exist?(local_ramaze)
+ require local_ramaze
+ require File.join(local_ramaze, 'bin', 'runner')
else
- require "ramaze"
+ require 'ramaze'
+ require 'ramaze/bin/runner'
end
- require "ramaze/tool/bin"
-rescue LoadError
- require "rubygems"
- require "ramaze/tool/bin"
+rescue
+ require 'rubygems'
+ require 'ramaze/bin/runner'
end
-Ramaze::Tool::Bin::Cmd.run(ARGV)
+
+Ramaze::Bin::Runner.run
@@ -0,0 +1,87 @@
+require 'irb'
+require 'irb/completion'
+
+module Ramaze
+ #:nodoc:
+ module Bin
+ ##
+ # Allows the user to enter an IRB like session that takes advantage of
+ # everything provided by Ramaze.
+ #
+ # == Usage
+ #
+ # ramaze console
+ # ramaze console /path/to/app/start.rb
+ #
+ # @author Yorick Peterse
+ # @since 21-07-2011
+ #
+ class Console
+ # String containing the description of this command.
+ Description = 'Starts an IRB session with Ramaze loaded into the session'
+
+ # The banner that is displayed when the -h or --help option is specified.
+ Banner = <<-TXT.strip
+Starts an IRB session and loads Ramaze into the session. All specified Rack
+options are ignored and environment variables are passed to IRB.
+
+Usage:
+ ramaze console [DIR] [OPTIONS]
+
+Example:
+ ramaze console
+ ramaze console /home/foobar/ramaze/start.rb
+ TXT
+
+ ##
+ # Creates a new instance of the command and sets all the options.
+ #
+ # @author Yorick Peterse
+ # @since 21-07-2011
+ #
+ def initialize
+ @options = OptionParser.new do |opt|
+ opt.banner = Banner
+ opt.summary_indent = ' '
+
+ opt.separator "\nOptions:\n"
+
+ opt.on('-h', '--help', 'Shows this help message') do
+ puts @options
+ exit
+ end
+ end
+ end
+
+ ##
+ # Runs the command based on the given command line arguments.
+ #
+ # @author Yorick Peterse
+ # @since 21-07-2011
+ # @param [Array] argv An array of command line arguments.
+ #
+ def run(argv = [])
+ @options.parse!(argv)
+
+ start_file = argv.delete_at(0)
+ start_file = File.join(Dir.pwd, 'start.rb') if start_file.nil?
+
+ if File.directory?(start_file)
+ start_file = File.join(start_file, 'start.rb')
+ end
+
+ if !File.exist?(start_file)
+ abort "The file #{start_file} does not exist"
+ end
+
+ start_file = Pathname.new(start_file).realpath.to_s
+ Ramaze.options.started = true
+
+ require(start_file)
+
+ IRB.start
+ puts 'Ramazement has ended, go in peace.'
+ end
+ end # Console
+ end # Bin
+end # Ramaze
@@ -0,0 +1,91 @@
+require 'fileutils'
+
+module Ramaze
+ #:nodoc:
+ module Bin
+ ##
+ # Simple command that allows users to easily create a new application based
+ # on the prototype that ships with Ramaze.
+ #
+ # == Usage
+ #
+ # ramaze create blog
+ #
+ # @author Yorick Peterse
+ # @since 21-07-2011
+ #
+ class Create
+ # The description of this command as shown in the global help message.
+ Description = 'Allows developers to easily create new Ramaze applications.'
+
+ # The banner of this command.
+ Banner = <<-TXT.strip
+Allows developers to easily create new Ramaze applications based on the
+prototype that ships with Ramaze.
+
+Usage:
+ ramaze create [NAME] [OPTIONS]
+
+Example:
+ ramaze create blog
+ TXT
+
+ ##
+ # Creates a new instance of the command and sets the options for
+ # OptionParser.
+ #
+ # @author Yorick Peterse
+ # @since 21-07-2011
+ #
+ def initialize
+ @options = {
+ :force => false
+ }
+
+ @opts = OptionParser.new do |opt|
+ opt.banner = Banner
+ opt.summary_indent = ' '
+
+ opt.separator "\nOptions:\n"
+
+ opt.on('-f', '--force', 'Overwrites existing directories') do
+ @options[:force] = true
+ end
+
+ opt.on('-h', '--help', 'Shows this help message') do
+ puts @opts
+ exit
+ end
+ end
+ end
+
+ ##
+ # Runs the command based on the specified command line arguments.
+ #
+ # @author Yorick Peterse
+ # @since 21-07-2011
+ # @param [Array] argv Array containing all command line arguments.
+ #
+ def run(argv = [])
+ @opts.parse!(argv)
+
+ name = argv.delete_at(0)
+ proto = __DIR__('../../proto')
+
+ abort 'You need to specify a name for your application' if name.nil?
+
+ path = File.join(Dir.pwd, name)
+
+ if File.directory?(path) and @options[:force] === false
+ abort 'The specified application already exists, use -f to overwrite it'
+ end
+
+ if File.directory?(path) and @options[:force] === true
+ FileUtils.rm_rf(path)
+ end
+
+ FileUtils.cp_r(proto, path)
+ end
+ end # Create
+ end # Bin
+end # Ramaze
@@ -0,0 +1,107 @@
+module Ramaze
+ #:nodoc:
+ module Bin
+ ##
+ # Module containing various helper methods useful for most commands.
+ #
+ # @author Yorick Peterse
+ # @author TJ Vanderpoel
+ # @since 21-07-2011
+ #
+ module Helper
+ ##
+ # Checks if the specified PID points to a process that's already running.
+ #
+ # @author TJ Vanderpoel
+ # @since 21-07-2011
+ # @param [String] pid The path to the PID.
+ # @return [TrueClass|FalseClass]
+ #
+ def is_running?(pid)
+ return false if !File.exist?(pid)
+
+ pid = File.read(pid).to_i
+
+ if is_windows?
+ wmi = WIN32OLE.connect("winmgmts://")
+ processes, ours = wmi.ExecQuery(
+ "select * from win32_process where ProcessId = #{pid}"
+ ), []
+
+ processes.each { |process| ours << process.Name }
+
+ return ours.first.nil?
+ else
+ begin
+ prio = Process.getpriority(Process::PRIO_PROCESS, pid)
+ return true
+ rescue Errno::ESRCH
+ return false
+ end
+ end
+ end
+
+ ##
+ # Checks if the system the user is using is Windows.
+ #
+ # @author TJ Vanderpoel
+ # @since 21-07-2011
+ # @return [TrueClass|FalseClass]
+ #
+ def is_windows?
+ return @is_win if @is_win
+
+ begin; require "win32ole"; rescue LoadError; end
+
+ @is_win ||= Object.const_defined?("WIN32OLE")
+ end
+
+ ##
+ # Tries to extract the path to the Rackup executable.
+ #
+ # @author TJ Vanderpoel
+ # @since 21-07-2001
+ # @return [String]
+ #
+ def rackup_path
+ return @rackup_path if @rackup_path
+
+ # Check with 'which' on platforms which support it
+ unless is_windows?
+ @rackup_path = %x{which rackup}.to_s.chomp
+
+ if @rackup_path.size > 0 and File.file?(@rackup_path)
+ return @rackup_path
+ end
+ end
+
+ # check for rackup in RUBYLIB
+ libs = ENV["RUBYLIB"].to_s.split(is_windows? ? ";" : ":")
+
+ if rack_lib = libs.detect { |r| r.match %r<(\\|/)rack\1> }
+ require "pathname"
+ @rackup_path = Pathname.new(rack_lib).parent.join("bin").join(
+ "rackup"
+ ).expand_path
+
+ return @rackup_path if File.file?(@rackup_path)
+ end
+
+ begin
+ require "rubygems"
+ require "rack"
+ require "pathname"
+
+ @rackup_path = Pathname.new(Gem.bindir).join("rackup").to_s
+
+ return @rackup_path if File.file?(@rackup_path)
+ rescue LoadError
+ nil
+ end
+
+ @rackup_path = nil
+ abort "Cannot find the path to the Rackup executable"
+ end
+ end # Helper
+ end # Bin
+end # Ramaze
Oops, something went wrong.

0 comments on commit cd9fa64

Please sign in to comment.