Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Vendor CIJoe.

  • Loading branch information...
commit f26f93a9b9b5a0a10efffa4308f370a45208e04f 1 parent ff66603
@jbarnette authored
Showing with 11,248 additions and 1 deletion.
  1. +4 −1 config/config.ru
  2. +22 −0 vendor/choice-0.1.4/CHANGELOG
  3. +18 −0 vendor/choice-0.1.4/LICENSE
  4. +443 −0 vendor/choice-0.1.4/README
  5. +87 −0 vendor/choice-0.1.4/examples/ftpd.rb
  6. +42 −0 vendor/choice-0.1.4/examples/gamble.rb
  7. +166 −0 vendor/choice-0.1.4/lib/choice.rb
  8. +67 −0 vendor/choice-0.1.4/lib/choice/lazyhash.rb
  9. +90 −0 vendor/choice-0.1.4/lib/choice/option.rb
  10. +233 −0 vendor/choice-0.1.4/lib/choice/parser.rb
  11. +8 −0 vendor/choice-0.1.4/lib/choice/version.rb
  12. +187 −0 vendor/choice-0.1.4/lib/choice/writer.rb
  13. +234 −0 vendor/choice-0.1.4/test/test_choice.rb
  14. +76 −0 vendor/choice-0.1.4/test/test_lazyhash.rb
  15. +145 −0 vendor/choice-0.1.4/test/test_option.rb
  16. +389 −0 vendor/choice-0.1.4/test/test_parser.rb
  17. +103 −0 vendor/choice-0.1.4/test/test_writer.rb
  18. +20 −0 vendor/cijoe-0.7.0/LICENSE
  19. +170 −0 vendor/cijoe-0.7.0/README.md
  20. +33 −0 vendor/cijoe-0.7.0/Rakefile
  21. +51 −0 vendor/cijoe-0.7.0/bin/cijoe
  22. +235 −0 vendor/cijoe-0.7.0/lib/cijoe.rb
  23. +67 −0 vendor/cijoe-0.7.0/lib/cijoe/build.rb
  24. +72 −0 vendor/cijoe-0.7.0/lib/cijoe/campfire.rb
  25. +27 −0 vendor/cijoe-0.7.0/lib/cijoe/commit.rb
  26. +43 −0 vendor/cijoe-0.7.0/lib/cijoe/config.rb
  27. +91 −0 vendor/cijoe-0.7.0/lib/cijoe/server.rb
  28. +3 −0  vendor/cijoe-0.7.0/lib/cijoe/version.rb
  29. +74 −0 vendor/cijoe-0.7.0/lib/cijoe/views/template.erb
  30. +12 −0 vendor/cijoe-0.7.0/test/helper.rb
  31. +17 −0 vendor/cijoe-0.7.0/test/test_cijoe.rb
  32. +68 −0 vendor/cijoe-0.7.0/test/test_cijoe_server.rb
  33. +43 −0 vendor/sinatra-1.0/AUTHORS
  34. +511 −0 vendor/sinatra-1.0/CHANGES
  35. +22 −0 vendor/sinatra-1.0/LICENSE
  36. +552 −0 vendor/sinatra-1.0/README.jp.rdoc
  37. +636 −0 vendor/sinatra-1.0/README.rdoc
  38. +116 −0 vendor/sinatra-1.0/Rakefile
  39. +7 −0 vendor/sinatra-1.0/lib/sinatra.rb
  40. +1,167 −0 vendor/sinatra-1.0/lib/sinatra/base.rb
  41. BIN  vendor/sinatra-1.0/lib/sinatra/images/404.png
  42. BIN  vendor/sinatra-1.0/lib/sinatra/images/500.png
  43. +28 −0 vendor/sinatra-1.0/lib/sinatra/main.rb
  44. +307 −0 vendor/sinatra-1.0/lib/sinatra/showexceptions.rb
  45. +746 −0 vendor/sinatra-1.0/lib/sinatra/tilt.rb
  46. +94 −0 vendor/sinatra-1.0/sinatra.gemspec
  47. +160 −0 vendor/sinatra-1.0/test/base_test.rb
  48. +65 −0 vendor/sinatra-1.0/test/builder_test.rb
  49. +64 −0 vendor/sinatra-1.0/test/contest.rb
  50. +81 −0 vendor/sinatra-1.0/test/erb_test.rb
  51. +82 −0 vendor/sinatra-1.0/test/erubis_test.rb
  52. +100 −0 vendor/sinatra-1.0/test/extensions_test.rb
  53. +221 −0 vendor/sinatra-1.0/test/filter_test.rb
  54. +95 −0 vendor/sinatra-1.0/test/haml_test.rb
  55. +76 −0 vendor/sinatra-1.0/test/helper.rb
  56. +582 −0 vendor/sinatra-1.0/test/helpers_test.rb
  57. +37 −0 vendor/sinatra-1.0/test/less_test.rb
  58. +197 −0 vendor/sinatra-1.0/test/mapped_error_test.rb
  59. +68 −0 vendor/sinatra-1.0/test/middleware_test.rb
  60. +33 −0 vendor/sinatra-1.0/test/request_test.rb
  61. +42 −0 vendor/sinatra-1.0/test/response_test.rb
  62. +98 −0 vendor/sinatra-1.0/test/result_test.rb
  63. +59 −0 vendor/sinatra-1.0/test/route_added_hook_test.rb
  64. +860 −0 vendor/sinatra-1.0/test/routing_test.rb
  65. +85 −0 vendor/sinatra-1.0/test/sass_test.rb
  66. +47 −0 vendor/sinatra-1.0/test/server_test.rb
  67. +368 −0 vendor/sinatra-1.0/test/settings_test.rb
  68. +13 −0 vendor/sinatra-1.0/test/sinatra_test.rb
  69. +93 −0 vendor/sinatra-1.0/test/static_test.rb
  70. +159 −0 vendor/sinatra-1.0/test/templates_test.rb
  71. +3 −0  vendor/sinatra-1.0/test/views/error.builder
  72. +3 −0  vendor/sinatra-1.0/test/views/error.erb
  73. +3 −0  vendor/sinatra-1.0/test/views/error.erubis
  74. +3 −0  vendor/sinatra-1.0/test/views/error.haml
  75. +2 −0  vendor/sinatra-1.0/test/views/error.sass
  76. +1 −0  vendor/sinatra-1.0/test/views/foo/hello.test
  77. +1 −0  vendor/sinatra-1.0/test/views/hello.builder
  78. +1 −0  vendor/sinatra-1.0/test/views/hello.erb
  79. +1 −0  vendor/sinatra-1.0/test/views/hello.erubis
  80. +1 −0  vendor/sinatra-1.0/test/views/hello.haml
  81. +5 −0 vendor/sinatra-1.0/test/views/hello.less
  82. +2 −0  vendor/sinatra-1.0/test/views/hello.sass
  83. +1 −0  vendor/sinatra-1.0/test/views/hello.test
  84. +3 −0  vendor/sinatra-1.0/test/views/layout2.builder
  85. +2 −0  vendor/sinatra-1.0/test/views/layout2.erb
  86. +2 −0  vendor/sinatra-1.0/test/views/layout2.erubis
  87. +2 −0  vendor/sinatra-1.0/test/views/layout2.haml
  88. +1 −0  vendor/sinatra-1.0/test/views/layout2.test
View
5 config/config.ru
@@ -1,4 +1,7 @@
-require "rubygems"
+Dir["../../vendor/*/lib"].each do |path|
+ $:.unshift File.expand_path(path)
+end
+
require "cijoe"
use Rack::CommonLogger
View
22 vendor/choice-0.1.4/CHANGELOG
@@ -0,0 +1,22 @@
+0.1.3:
+ - Added args_of method to retrieve the arguments of an option
+
+0.1.2:
+ - Made validate directive accept block and validate against its boolean value.
+ - Created shorthand format for defining options directly with a hash.
+
+0.1.1:
+ - Fixed test_option.rb to be self sufficient.
+ - Fix so that long argument with equals sign in it will parse correctly [Justin Bailey]
+ - Added 'defaultize' deprecation warning. Too much magic can be harmful.
+ - Made Choice::Writer::puts, print, and printf public, can now possibly be used by other Choice classes.
+ - Changed UnknownArgument to UnknownOption (more descriptive)
+ - Added a 'valid' option as per bugtracker request for 'enum.' [Alexis Li]
+ - Change --long=[ARG] optional format to --long[=ARG] but keep around old format just in case.
+ - Added list format to options as per bug tracker suggestion in the format of --long=*LONG [Alexis Li]
+ - Added --long ARG format. Works with --long [ARG] and --long *ARG and --long [*ARG]
+ - Added :required option which insists an option is present.
+ - Added gamble.rb card game example.
+
+0.1.0:
+ - First release
View
18 vendor/choice-0.1.4/LICENSE
@@ -0,0 +1,18 @@
+Copyright (c) 2006 Chris Wanstrath
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
443 vendor/choice-0.1.4/README
@@ -0,0 +1,443 @@
+= Welcome to Choice
+
+Choice is a small library for defining and parsing command line options. It
+works awesomely with Highline[http://highline.rubyforge.org/] or other command
+line interface libraries.
+
+Choice was written by Chris Wanstrath as an exercise in test driving development
+of a DSL. This project is still an infant: bugs are expected and tattling on them
+is appreciated.
+
+Installing is easy, with RubyGems. Give it a shot:
+ $ gem install choice
+
+If you are lost, you can find Choice at http://choice.rubyforge.org or
+http://rubyforge.org/projects/choice/. E-mail inquiries can be directed to
+mailto:chris[at]ozmm[dot]org.
+
+Of course, Choice is licensed under the MIT License, which you can find included
+in the LICENSE file or by surfing your World Wide Web browser of choice towards
+http://www.opensource.org/licenses/mit-license.php.
+
+== Using Choice
+
+An +examples+ directory is included with Choice, in which some contrived Ruby
+programs utilizing the library have been placed. Here's a snippet:
+
+=== ftpd.rb
+
+ require 'choice'
+
+ PROGRAM_VERSION = 4
+
+ Choice.options do
+ header ''
+ header 'Specific options:'
+
+ option :host do
+ short '-h'
+ long '--host=HOST'
+ desc 'The hostname or ip of the host to bind to (default 127.0.0.1)'
+ default '127.0.0.1'
+ end
+
+ option :port do
+ short '-p'
+ long '--port=PORT'
+ desc 'The port to listen on (default 21)'
+ cast Integer
+ default 21
+ end
+
+ separator ''
+ separator 'Common options: '
+
+ option :help do
+ long '--help'
+ desc 'Show this message'
+ end
+
+ option :version do
+ short '-v'
+ long '--version'
+ desc 'Show version'
+ action do
+ puts "ftpd.rb FTP server v#{PROGRAM_VERSION}"
+ exit
+ end
+ end
+ end
+
+ puts 'port: ' + Choice[:port]
+
+Notice the last line. For free, you will be given a <tt>Choice.choices</tt>
+hash which contain, at runtime, the options found and their values.
+
+<tt>Choice[:key]</tt> is a shortcut for <tt>Choice.choices[:key]</tt>.
+
+Because we gave option <tt>:port</tt> a default of 21,
+<tt>Choice[:port]</tt> should be 21 if we run ftpd.rb with no options.
+Let's see.
+
+ $ ruby ftpd.rb
+ port: 21
+
+Cool. On our system, port 21 is reserved. Let's use another port.
+
+ $ ruby ftpd.rb -p 2100
+ port: 2100
+
+Alright. And, of course, there is the hard way of doing things.
+
+ $ ruby ftpd.rb --port=2100
+ port: 2100
+
+That <tt>:version</tt> option looks pretty interesting, huh? I wonder what it
+does...
+
+ $ ruby ftpd.rb -v
+ ftpd.rb FTP server v4
+
+That's not all, though. We also get a <tt>--help</tt> option for free.
+
+ $ ruby ftpd.rb --help
+ Usage: ftpd.rb [-hpv]
+
+ Specific options:
+ -h, --host=HOST The hostname or ip of the host to bind to (default 127.0.0.1)
+ -p, --port=PORT The port to listen on (default 21)
+
+ Common options:
+ --help Show this message
+ -v, --version Show version
+
+
+== The Choice.choices hash
+
+For better or worse, the <tt>Choice.choices</tt> hash is a bit lazy. It does
+not care how you access it. Using the above example, assume we have a
+<tt>:port</tt> option and we replace the last line of our program with the
+following three lines:
+
+ puts 'port: ' + Choice.choices[:port]
+ puts 'port: ' + Choice.choices['port']
+ puts 'port: ' + Choice.choices.port
+
+Now, run it.
+
+ $ ftpd.rb -p 2100
+ port: 2100
+ port: 2100
+ port: 2100
+
+Lazy, huh?
+
+Keep in mind that your option's key in the <tt>Choice.choices</tt> hash is
+defined by the first parameter passed to option statement. This is perfectly
+legit, albeit somewhat confusing:
+
+ option :name do
+ short '-h'
+ long '--handle=NAME'
+ desc "Your handle."
+ end
+
+You can access this option by using <tt>Choice.choices[:name]</tt>, not
+<tt>:handle</tt>.
+
+== Option options
+
+Obviously, Choice revolves around the <tt>option</tt> statement, which receives
+a block. Here are all the, er, options +option+ accepts. None of them are
+required but +short+ or +long+ must be present for Choice to know what to do.
+
+Options must be defined in the context of a <tt>Choice.options</tt> block, as
+seen above. This context is assumed for the following explanations.
+
+For the quick learners, here's the list:
+* short
+* long
+* default
+* desc
+* cast
+* valid (takes array)
+* validate (takes regex)
+* filter (takes a block)
+* action (ditto)
+
+You can define these within your option in any order which pleases you.
+
+=== short
+
+Defines the short switch for an option. Expected to be a dash and a single
+character.
+
+ short '-s'
+
+=== long
+
+Defines the long switch for an option. Expected to be a double dash followed by
+a string, an equal sign (or a space), and another string.
+
+There are two variants: longs where a parameter is required and longs where a
+parameter is optional, in which case the value will be +true+ if the option is
+present.
+
+*Optional*:
+ long '--debug=[LEVEL]'
+
+Assuming our program defines Choices and ends with this line:
+ puts 'debug: ' + Choice.choices[:debug]
+
+we can do this:
+
+ $ ruby ftpd.rb --debug
+ debug: true
+
+ $ ruby ftpd.rb --debug=1
+ debug: 1
+
+ $ ruby ftpd.rb --debug 1
+ debug: 1
+
+*Required*:
+ long '--debug=LEVEL'
+
+Assuming the same as above:
+
+ $ ruby ftpd.rb --debug 1
+ debug: 1
+
+ $ ruby ftpd.rb --debug
+ <help screen printed>
+
+=== long as array
+
+Often you may wish to allow users the ability to pass in multiple arguments and have
+them all combined into an array. You can accomplish this by defining a +long+ and
+setting the caps-argument to *ARG. Like this:
+
+ long '--suit *SUITS'
+
+<tt>Choice.choices.suits</tt> will now return an array. Here's an example of usage:
+
+ $ ruby --suit hearts clubs
+ suit: ['hearts', 'clubs']
+
+Check out <tt>examples/gamble.rb</tt> for more information on this cool feature.
+
+=== default
+
+You can define a default value for your option, if you'd like. If the option
+is not present in the argument list, the default will be returned when trying
+to access that element of the <tt>Choice.choices</tt> hash.
+
+As with the above, assume our program prints <tt>Choice.choices[:debug]</tt>:
+
+ default 'info'
+
+If we don't pass in <tt>--debug</tt>, the <tt>:debug</tt> element of our hash
+will be 'info.'
+
+ $ ftpd.rb
+ debug: info
+
+ $ ftpd.rb --debug warn
+ debug: warn
+
+=== desc
+
+The description of this option. Fairly straightforward, with one little trick:
+multiple +desc+ statements in a single option will be considered new desc lines.
+The desc lines will be printed in the order they are defined. Like this:
+
+ desc "Your hostname."
+ desc "(default 'localhost')"
+
+A snippet from your <tt>--help</tt> might then look like this:
+
+ -h, --host=HOST Your hostname.
+ (default 127.0.0.1)
+
+
+=== cast
+
+By default, all members of the <tt>Choice.choices</tt> hash are strings. If
+you want something different, like an Integer for a port number, you can use
+the +cast+ statement.
+
+ cast Integer
+
+Currently support +cast+ options:
+
+* Integer
+* String
+* Float
+* Symbol
+
+We'll probably add Date, Time, and DateTime in the future, if people want them.
+
+=== valid
+
+Giving +valid+ an array creates a whitelist of acceptable arguments.
+
+ valid %w[clubs hearts spades diamonds]
+
+If our option is passed anything other than one of the four card suits, the help
+screen will be printed. It might be a good idea to include acceptable arguments in
+your option's "desc" value.
+
+ $ ruby gamble.rb -s clubs
+ suit: clubs
+
+ $ ruby gamble.rb -s joker
+ <help screen printed>
+
+=== validate
+
+The +validate+ statement accepts a regular expression which it will test
+against the value passed. If the test fails, the <tt>--help</tt> screen will
+be printed. I love ports, so let's stick with that example:
+
+ validate /^\d+$/
+
+Of course, 2100 matches this:
+
+ $ ruby ftpd.rb -p 2100
+ port: 2100
+
+I like dogs. I wish dogs could be ports. Alas, Choice knows better (once
+I've told it so):
+
+ $ ruby ftpd.rb -p labradoodle
+ <help screen printed>
+
+=== filter
+
+The +filter+ statement lets you play with a value before it goes into the
+<tt>Choice.choices</tt> hash. If you use +cast+, this will occur post-casting.
+
+In this program we're defining a :name option and saying we don't want any
+crazy characters in it, then printing that element of the
+<tt>Choice.choices</tt>+ hash:
+
+ filter do |value|
+ value = value.gsub(/[^\w]/, '')
+ end
+
+Now:
+
+ $ ruby ftpd.rb --name=c.hr.is
+ name: chris
+
+You can probably think of better uses.
+
+=== action
+
+A block passed to the +action+ statement will be run if that particular option
+is passed. See the <tt>--version</tt> example earlier.
+
+=== required options
+
+You can specify an option as being required by passing :required => true to the
+option definition. Choice will then print the help screen if this option is
+not present. Please let your dear users know which options are required.
+
+For example:
+
+ option :card, :required => true do
+ short '-c'
+ long '--card CARD'
+ desc "The card you wish to gamble on. Required. Only one, please."
+ end
+
+Then:
+
+ $ ruby gamble.rb
+ <help screen, -c or --card wasn't passed>
+
+== Other options
+
+These statements are purely aesthetic, used to help make your <tt>--help</tt>
+screen a little more digestible.
+
+Passing an empty string to any of these options will print a newline.
+
+=== banner
+
+The banner is the first line printed when your program is called with
+<tt>--help</tt>. By default, it will be something like this, based on the
+options defined:
+
+ Usage: ftpd.rb [-hpv]
+
+You can pass any string to the +banner+ statement to override what prints. This
+might be useful if you're into ascii art.
+
+ banner "Usage: ftpd.rb"
+
+=== header
+
+The header is what shows up after the banner but before your option definitions
+are printed. Each header call is a newline. Check out the example above.
+
+ header "ftp is a harsh and unforgiving protocol."
+
+=== separator
+
+As in the example above, you can put separators between options to help display
+the logical groupings of your options. Or whatever.
+
+ separator "----"
+
+To get a blank line, rock an empty string:
+
+ separator ''
+
+=== footer
+
+The footer is displayed after all your options are displayed. Nothing new
+here, works like the other options above.
+
+ footer "That's all there is to it!"
+
+== Shorthand
+
+Now that you've gone through all the hard stuff, here's the easy stuff: Choice
+options can be defined with a simple hash if you'd like. Here's an example,
+from the tests:
+
+ Choice.options do
+ header "Tell me about yourself?"
+ header ""
+ options :band => { :short => "-b", :long => "--band=BAND", :cast => String, :desc => "Your favorite band.",
+ :validate => /\w+/ },
+ :animal => { :short => "-a", :long => "--animal=ANIMAL", :cast => String, :desc => "Your favorite animal." }
+
+ footer ""
+ footer "--help This message"
+ end
+
+How's that tickle you? Real nice.
+
+== It looks like poetry
+
+That's it. Not much, I know. Maybe this will make handling your command
+line options a bit easier. You can always use the option parser in the standard
+Ruby library, but DSLs are just so cool. As one of my non-programmer friends
+said of a Ruby DSL: "It looks like poetry."
+
+== It's totally broken
+
+Okay, I knew this would happen. Do me a favor, if you have time: run +rake+
+from the Choice directory and send me the output (mailto:chris[at]ozmm[dot]org).
+This'll run the unit tests. Also, if you would, send me a bit of information
+on your platform. Choice was tested on OS X and RHEL with a 2.4 kernel but who
+knows. Thanks a lot.
+
+== Thanks to
+
+For bug reports, patches, and ideas I'd be honored to thank the following:
+
+- Justin Bailey
+- Alexis Li
View
87 vendor/choice-0.1.4/examples/ftpd.rb
@@ -0,0 +1,87 @@
+$:.unshift "../lib"
+$:.unshift "lib"
+require 'choice'
+
+port = 21
+PROGRAM_VERSION = 4
+
+Choice.options do
+ #banner "Usage: ftpd.rb [options]"
+
+ header ""
+ header "Specific options:"
+
+ option :host do
+ short '-h'
+ long '--host=HOST'
+ desc "The hostname or ip of the host to bind to"
+ desc "(default 127.0.0.1)"
+ default '127.0.0.1'
+ end
+
+ option :port do
+ short '-p'
+ long '--port=PORT'
+ desc "The port to listen on (default 21)"
+ cast Integer
+ default port
+ end
+
+ option :clients do
+ short '-c'
+ long '--clients=NUM'
+ cast Integer
+ desc "The number of connections to allow at once (default 5)"
+ default 5
+ end
+
+ option :protocol do
+ short '-l'
+ long '--protocol=PROTOCOL'
+ desc "The protocol to use (default ftp)"
+ valid %w[ftp sftp]
+ default 'ftp'
+ end
+
+ option :yaml_cfg do
+ long '--config=FILE'
+ desc 'Load configuration from YAML file'
+ end
+
+ option :sample do
+ long '--sample'
+ desc "See a sample YAML config file"
+ action do
+ puts "See!"
+ exit
+ end
+ end
+
+ option :debug do
+ short '-d'
+ long '--debug[=LEVEL]'
+ desc 'Turn on debugging mode'
+ end
+
+ separator ''
+ separator 'Common options: '
+
+ option :help do
+ long '--help'
+ desc 'Show this message'
+ end
+
+ option :version do
+ short '-v'
+ long '--version'
+ desc 'Show version'
+ action do
+ puts "ftpd.rb FTP server v#{PROGRAM_VERSION}"
+ exit
+ end
+ end
+
+end
+
+print "Choices: "
+puts Choice.choices.inspect
View
42 vendor/choice-0.1.4/examples/gamble.rb
@@ -0,0 +1,42 @@
+$:.unshift "../lib"
+$:.unshift "lib"
+require 'choice'
+
+suits = %w[clubs diamonds spades hearts]
+stringed_numerics = (1..13).to_a.map { |a| a.to_s }
+valid_cards = stringed_numerics + %w[jack queen king ace]
+cards = {}
+stringed_numerics.each { |n| cards[n] = n }
+cards.merge!('1' => 'ace', '11' => 'jack', '12' => 'queen', '13' => 'king')
+
+Choice.options do
+ header "Gambling is fun again! Pick a card and a suit (or two), then see if you win!"
+ header ""
+ header "Options:"
+
+ option :suit, :required => true do
+ short '-s'
+ long '--suit *SUITS'
+ desc "The suit you wish to choose. Required. You can pass in more than one, even."
+ desc " Valid suits: #{suits * ' '}"
+ valid suits
+ end
+
+ separator ''
+
+ option :card, :required => true do
+ short '-c'
+ long '--card CARD'
+ desc "The card you wish to gamble on. Required. Only one, please."
+ desc " Valid cards: 1 - 13, jack, queen, king, ace"
+ valid valid_cards
+ cast String
+ end
+end
+
+suit = suits[rand(suits.size)]
+card = cards[(rand(13)+1).to_s]
+
+puts "I drew the #{card} of #{suit}."
+puts "You picked the #{Choice.choices.card} of #{Choice.choices.suit * ' or '}."
+puts "You " << (Choice.choices.suit.include?(suit) && card == cards[Choice.choices.card] ? 'win!' : 'lose :(')
View
166 vendor/choice-0.1.4/lib/choice.rb
@@ -0,0 +1,166 @@
+$:.unshift File.dirname(__FILE__)
+require 'choice/option'
+require 'choice/parser'
+require 'choice/writer'
+require 'choice/lazyhash'
+
+#
+# Usage of this module is lovingly detailed in the README file.
+#
+module Choice
+ extend self
+
+ # The main method, which defines the options
+ def options(hash = {}, &block)
+ # if we are passing in a hash to define our options, use that straight
+ options_from_hash(hash) unless hash.empty?
+
+ # Setup all instance variables
+ reset! if hash.empty?
+ @@args ||= ARGV
+
+ # Eval the passed block to define the options.
+ instance_eval(&block) if block_given?
+
+ # Parse what we've got.
+ parse unless parsed?
+ end
+
+ # Set options from a hash, shorthand style
+ def options_from_hash(options_hash)
+ options_hash.each do |name, definition|
+ option = Option.new
+ definition.each do |key, value|
+ Array(value).each { |hit| option.send(key, hit) }
+ end
+ @@options << [name.to_s, option]
+ end
+ end
+
+ # Return an array representing the rest of the command line arguments
+ def rest
+ @@rest
+ end
+
+ # Returns a hash representing options passed in via the command line.
+ def choices
+ @@choices
+ end
+
+ # Shortcut access to Choice.choices
+ def [](choice)
+ choices[choice]
+ end
+
+ # Defines an option.
+ def option(opt, options = {}, &block)
+ # Notice: options is maintained as an array of arrays, the first element
+ # the option name and the second the option object.
+ @@options << [opt.to_s, Option.new(options, &block)]
+ end
+
+ # Separators are text displayed by --help within the options block.
+ def separator(str)
+ # We store separators as simple strings in the options array to maintain
+ # order. They are ignored by the parser.
+ @@options << str
+ end
+
+ # Define the banner, header, footer methods. All are just getters/setters
+ # of class variables.
+ %w[banner header footer].each do |method|
+ define_method(method) do |string|
+ variable = "@@#{method}"
+ return class_variable_get(variable) if string.nil?
+ val = class_variable_get(variable) || ''
+ class_variable_set(variable, val << string)
+ end
+ end
+
+
+ # Parse the provided args against the defined options.
+ def parse #:nodoc:
+ # Do nothing if options are not defined.
+ return unless @@options.size > 0
+
+ # Show help if it's anywhere in the argument list.
+ if @@args.include?('--help')
+ help
+ else
+ begin
+ # Delegate parsing to our parser class, passing it our defined
+ # options and the passed arguments.
+ @@choices, @@rest = Parser.parse(@@options, @@args)
+ @@choices = LazyHash.new(@@choices)
+ rescue Choice::Parser::ParseError
+ # If we get an expected exception, show the help file.
+ help
+ end
+ end
+ end
+
+ # Did we already parse the arguments?
+ def parsed? #:nodoc:
+ @@choices ||= false
+ end
+
+ # Print the help screen by calling our Writer object
+ def help #:nodoc:
+ Writer.help( { :banner => @@banner, :header => @@header,
+ :options => @@options, :footer => @@footer },
+ output_to, exit_on_help? )
+ end
+
+ # Set the args, potentially to something other than ARGV.
+ def args=(args) #:nodoc:
+ @@args = args.dup.map { |a| a + '' }
+ parse if parsed?
+ end
+
+ # Return the args.
+ def args #:nodoc:
+ @@args
+ end
+
+ # Returns the arguments that follow an argument
+ def args_of(opt)
+ args_of_opt = []
+
+ # Return an array of the arguments between opt and the next option,
+ # which all start with "-"
+ @@args.slice(@@args.index(opt)+1, @@args.length).select do |arg|
+ if arg[0].chr != "-"
+ args_of_opt << arg
+ else
+ break
+ end
+ end
+ args_of_opt
+ end
+
+ # You can choose to not kill the script after the help screen is printed.
+ def dont_exit_on_help=(val) #:nodoc:
+ @@exit = true
+ end
+
+ # Do we want to exit on help?
+ def exit_on_help? #:nodoc:
+ @@exit rescue false
+ end
+
+ # If we want to write to somewhere other than STDOUT.
+ def output_to(target = nil) #:nodoc:
+ @@output_to ||= STDOUT
+ return @@output_to if target.nil?
+ @@output_to = target
+ end
+
+ # Reset all the class variables.
+ def reset! #:nodoc:
+ @@args = false
+ @@banner = false
+ @@header = Array.new
+ @@options = Array.new
+ @@footer = Array.new
+ end
+end
View
67 vendor/choice-0.1.4/lib/choice/lazyhash.rb
@@ -0,0 +1,67 @@
+module Choice
+
+ # This class lets us get away with really bad, horrible, lazy hash accessing.
+ # Like so:
+ # hash = LazyHash.new
+ # hash[:someplace] = "somewhere"
+ # puts hash[:someplace]
+ # puts hash['someplace']
+ # puts hash.someplace
+ #
+ # If you'd like, you can pass in a current hash when initializing to convert
+ # it into a lazyhash. Or you can use the .to_lazyhash method attached to the
+ # Hash object (evil!).
+ class LazyHash < Hash
+
+ # Keep the old methods around.
+ alias_method :old_store, :store
+ alias_method :old_fetch, :fetch
+
+ # You can pass in a normal hash to convert it to a LazyHash.
+ def initialize(hash = nil)
+ hash.each { |key, value| self[key] = value } if !hash.nil? && hash.is_a?(Hash)
+ end
+
+ # Wrapper for []
+ def store(key, value)
+ self[key] = value
+ end
+
+ # Wrapper for []=
+ def fetch(key)
+ self[key]
+ end
+
+ # Store every key as a string.
+ def []=(key, value)
+ key = key.to_s if key.is_a? Symbol
+ self.old_store(key, value)
+ end
+
+ # Every key is stored as a string. Like a normal hash, nil is returned if
+ # the key does not exist.
+ def [](key)
+ key = key.to_s if key.is_a? Symbol
+ self.old_fetch(key) rescue return nil
+ end
+
+ # You can use hash.something or hash.something = 'thing' since this is
+ # truly a lazy hash.
+ def method_missing(meth, *args)
+ meth = meth.to_s
+ if meth =~ /=/
+ self[meth.sub('=','')] = args.first
+ else
+ self[meth]
+ end
+ end
+
+ end
+end
+
+# Really ugly, horrible, extremely fun hack.
+class Hash #:nodoc:
+ def to_lazyhash
+ return Choice::LazyHash.new(self)
+ end
+end
View
90 vendor/choice-0.1.4/lib/choice/option.rb
@@ -0,0 +1,90 @@
+module Choice
+
+ # The Option class parses and stores all the information about a specific
+ # option.
+ class Option #:nodoc: all
+
+ # Since we define getters/setters on the fly, we need a white list of
+ # which to accept. Here's the list.
+ CHOICES = %w[short long desc default filter action cast validate valid]
+
+ # You can instantiate an option on its own or by passing it a name and
+ # a block. If you give it a block, it will eval() the block and set itself
+ # up nicely.
+ def initialize(options = {}, &block)
+ # Here we store the definitions this option contains, to make to_a and
+ # to_h easier.
+ @choices = []
+
+ # If we got a block, eval it and set everything up.
+ instance_eval(&block) if block_given?
+
+ # Is this option required?
+ @required = options[:required] || false
+ @choices << 'required'
+ end
+
+ # This is the catch all for the getter/setter choices defined in CHOICES.
+ # It also gives us choice? methods.
+ def method_missing(method, *args, &block)
+ # Get the name of the choice we want, as a class variable string.
+ var = "@#{method.to_s.sub('?','')}"
+
+ # To string, for regex purposes.
+ method = method.to_s
+
+ # Don't let in any choices not defined in our white list array.
+ raise ParseError, "I don't know `#{method}'" unless CHOICES.include? method.sub('?','')
+
+ # If we're asking a question, give an answer. Like 'short?'.
+ return !!instance_variable_get(var) if method =~ /\?/
+
+ # If we were called with no arguments, we want a get.
+ return instance_variable_get(var) unless args[0] || block_given?
+
+ # If we were given a block or an argument, save it.
+ instance_variable_set(var, args[0]) if args[0]
+ instance_variable_set(var, block) if block_given?
+
+ # Add the choice to the @choices array if we're setting it for the first
+ # time.
+ @choices << method if args[0] || block_given? unless @choices.index(method)
+ end
+
+ # The desc method is slightly special: it stores itself as an array and
+ # each subsequent call adds to that array, rather than overwriting it.
+ # This is so we can do multi-line descriptions easily.
+ def desc(string = nil)
+ return @desc if string.nil?
+
+ @desc ||= []
+ @desc.push(string)
+
+ # Only add to @choices array if it's not already present.
+ @choices << 'desc' unless @choices.index('desc')
+ end
+
+ # Simple, desc question method.
+ def desc?() !!@desc end
+
+ # Returns Option converted to an array.
+ def to_a
+ @choices.inject([]) do |array, choice|
+ return array unless @choices.include? choice
+ array + [instance_variable_get("@#{choice}")]
+ end
+ end
+
+ # Returns Option converted to a hash.
+ def to_h
+ @choices.inject({}) do |hash, choice|
+ return hash unless @choices.include? choice
+ hash.merge choice => instance_variable_get("@#{choice}")
+ end
+ end
+
+ # In case someone tries to use a method we don't know about in their
+ # option block.
+ class ParseError < Exception; end
+ end
+end
View
233 vendor/choice-0.1.4/lib/choice/parser.rb
@@ -0,0 +1,233 @@
+module Choice
+
+ # The parser takes our option definitions and our arguments and produces
+ # a hash of values.
+ module Parser #:nodoc: all
+ extend self
+
+ # What method to call on an object for each given 'cast' value.
+ CAST_METHODS = { Integer => :to_i, String => :to_s, Float => :to_f,
+ Symbol => :to_sym }
+
+ # Perhaps this method does too much. It is, however, a parser.
+ # You pass it an array of arrays, the first element of each element being
+ # the option's name and the second element being a hash of the option's
+ # info. You also pass in your current arguments, so it knows what to
+ # check against.
+ def parse(options, args)
+ # Return empty hash if the parsing adventure would be fruitless.
+ return {} if options.nil? || !options || args.nil? || !args.is_a?(Array)
+
+ # Operate on a copy of the inputs
+ args = args.dup
+
+ # If we are passed an array, make the best of it by converting it
+ # to a hash.
+ options = options.inject({}) do |hash, value|
+ value.is_a?(Array) ? hash.merge(value.first => value[1]) : hash
+ end if options.is_a? Array
+
+ # Define local hashes we're going to use. choices is where we store
+ # the actual values we've pulled from the argument list.
+ hashes, longs, required, validators, choices, arrayed = {}, {}, {}, {}, {}, {}
+ hard_required = {}
+
+ # We can define these on the fly because they are all so similar.
+ params = %w[short cast filter action default valid]
+ params.each { |param| hashes["#{param}s"] = {} }
+
+ # Inspect each option and move its info into our local hashes.
+ options.each do |name, obj|
+ name = name.to_s
+
+ # Only take hashes or hash-like duck objects.
+ raise HashExpectedForOption unless obj.respond_to? :to_h
+ obj = obj.to_h
+
+ # Is this option required?
+ hard_required[name] = true if obj['required']
+
+ # Set the local hashes if the value exists on this option object.
+ params.each { |param| hashes["#{param}s"][name] = obj[param] if obj[param] }
+
+ # If there is a validate statement, make it a regex or proc.
+ validators[name] = make_validation(obj['validate']) if obj['validate']
+
+ # Parse the long option. If it contains a =, figure out if the
+ # argument is required or optional. Optional arguments are formed
+ # like [=ARG], whereas required are just ARG (in --long=ARG style).
+ if obj['long'] && obj['long'] =~ /(=|\[| )/
+ # Save the separator we used, as we're gonna need it, then split
+ sep = $1
+ option, *argument = obj['long'].split(sep)
+
+ # The actual name of the long switch
+ longs[name] = option
+
+ # Preserve the original argument, as it may contain [ or =,
+ # by joining with the character we split on. Add a [ in front if
+ # we split on that.
+ argument = (sep == '[' ? '[' : '') << Array(argument).join(sep)
+
+ # Do we expect multiple arguments which get turned into an array?
+ arrayed[name] = true if argument =~ /^\[?=?\*(.+)\]?$/
+
+ # Is this long required or optional?
+ required[name] = true unless argument =~ /^\[=?\*?(.+)\]$/
+ elsif obj['long']
+ # We can't have a long as a switch when valid is set -- die.
+ raise ArgumentRequiredWithValid if obj['valid']
+
+ # Set without any checking if it's just --long
+ longs[name] = obj['long']
+ end
+
+ # If we were given a list of valid arguments with 'valid,' this option
+ # is definitely required.
+ required[name] = true if obj['valid']
+ end
+
+ rest = []
+
+ # Go through the arguments and try to figure out whom they belong to
+ # at this point.
+ while arg = args.shift
+ if hashes['shorts'].value?(arg)
+ # Set the value to the next element in the args array since
+ # this is a short.
+
+ # If the next argument isn't a value, set this value to true
+ if args.empty? || args.first.match(/^-/)
+ value = true
+ else
+ value = args.shift
+ end
+
+ # Add this value to the choices hash with the key of the option's
+ # name. If we expect an array, tack this argument on.
+ name = hashes['shorts'].index(arg)
+ if arrayed[name]
+ choices[name] ||= []
+ choices[name] << value unless value.nil?
+ choices[name] += arrayize_arguments(args)
+ else
+ choices[name] = value
+ end
+
+ elsif (m = arg.match(/^(--[^=]+)=?/)) && longs.value?(m[1])
+ # The joke here is we always accept both --long=VALUE and --long VALUE.
+
+ # Grab values from --long=VALUE format
+ name, value = arg.split('=', 2)
+ name = longs.index(name)
+
+ if value.nil? && args.first !~ /^-/
+ # Grab value otherwise if not in --long=VALUE format. Assume --long VALUE.
+ # Value is nil if we don't have a = and the next argument is no good
+ value = args.shift
+ end
+
+ # If we expect an array, tack this argument on.
+ if arrayed[name]
+ # If this is arrayed and the value isn't nil, set it.
+ choices[name] ||= []
+ choices[name] << value unless value.nil?
+ choices[name] += arrayize_arguments(args)
+ else
+ # If we set the value to nil, that means nothing was set and we
+ # need to set the value to true. We'll find out later if that's
+ # acceptable or not.
+ choices[name] = value.nil? ? true : value
+ end
+
+ else
+ # If we're here, we have no idea what the passed argument is. Die.
+ if arg =~ /^-/
+ raise UnknownOption
+ else
+ rest << arg
+ end
+ end
+ end
+
+ # Okay, we got all the choices. Now go through and run any filters or
+ # whatever on them.
+ choices.each do |name, value|
+ # Check to make sure we have all the required arguments.
+ raise ArgumentRequired if required[name] && value === true
+
+ # Validate the argument if we need to, against a regexp or a block.
+ if validators[name]
+ if validators[name].is_a?(Regexp) && validators[name] =~ value
+ elsif validators[name].is_a?(Proc) && validators[name].call(value)
+ else raise ArgumentValidationFails
+ end
+ end
+
+ # Make sure the argument is valid
+ raise InvalidArgument unless value.to_a.all? { |v| hashes['valids'][name].include?(v) } if hashes['valids'][name]
+
+ # Cast the argument using the method defined in the constant hash.
+ value = value.send(CAST_METHODS[hashes['casts'][name]]) if hashes['casts'].include?(name)
+
+ # Run the value through a filter and re-set it with the return.
+ value = hashes['filters'][name].call(value) if hashes['filters'].include?(name)
+
+ # Run an action block if there is one associated.
+ hashes['actions'][name].call(value) if hashes['actions'].include?(name)
+
+ # Now that we've done all that, re-set the element of the choice hash
+ # with the (potentially) new value.
+ choices[name] = value
+ end
+
+ # Die if we're missing any required arguments
+ hard_required.each do |name, value|
+ raise ArgumentRequired unless choices[name]
+ end
+
+ # Home stretch. Go through all the defaults defined and if a choice
+ # does not exist in our choices hash, set its value to the requested
+ # default.
+ hashes['defaults'].each do |name, value|
+ choices[name] = value unless choices[name]
+ end
+
+ # Return the choices hash and the rest of the args
+ [ choices, rest ]
+ end
+
+ private
+ # Turns trailing command line arguments into an array for an arrayed value
+ def arrayize_arguments(args)
+ # Go through trailing arguments and suck them in if they don't seem
+ # to have an owner.
+ array = []
+ until args.empty? || args.first.match(/^-/)
+ array << args.shift
+ end
+ array
+ end
+
+ def make_validation(validation)
+ case validation
+ when Proc then
+ validation
+ when Regexp, String then
+ Regexp.new(validation.to_s)
+ else
+ raise ValidateExpectsRegexpOrBlock
+ end
+ end
+
+ # All the possible exceptions this module can raise.
+ class ParseError < Exception; end
+ class HashExpectedForOption < Exception; end
+ class UnknownOption < ParseError; end
+ class ArgumentRequired < ParseError; end
+ class ValidateExpectsRegexpOrBlock < ParseError; end
+ class ArgumentValidationFails < ParseError; end
+ class InvalidArgument < ParseError; end
+ class ArgumentRequiredWithValid < ParseError; end
+ end
+end
View
8 vendor/choice-0.1.4/lib/choice/version.rb
@@ -0,0 +1,8 @@
+module Choice
+ module Version #:nodoc:
+ MAJOR = 0
+ MINOR = 1
+ TINY = 4
+ STRING = [MAJOR, MINOR, TINY] * '.'
+ end
+end
View
187 vendor/choice-0.1.4/lib/choice/writer.rb
@@ -0,0 +1,187 @@
+module Choice
+ # This module writes to the screen. As of now, its only real use is writing
+ # the help screen.
+ module Writer #:nodoc: all
+
+ # Some constants used for printing and line widths
+ SHORT_LENGTH = 6
+ SHORT_BREAK_LENGTH = 2
+ LONG_LENGTH = 29
+ PRE_DESC_LENGTH = SHORT_LENGTH + SHORT_BREAK_LENGTH + LONG_LENGTH
+
+
+ # The main method. Takes a hash of arguments with the following possible
+ # keys, running them through the appropriate method:
+ # banner, header, options, footer
+ #
+ # Can also be told where to print (default STDOUT) and not to exit after
+ # printing the help screen, which it does by default.
+ def self.help(args, target = STDOUT, dont_exit = false)
+ # Set our printing target.
+ self.target = target
+
+ # The banner method needs to know about the passed options if it's going
+ # to do its magic. Only really needs :options if :banner is nil.
+ banner(args[:banner], args[:options])
+
+ # Run these three methods, passing in the appropriate hash element.
+ %w[header options footer].each do |meth|
+ send(meth, args[meth.to_sym])
+ end
+
+ # Exit. Unless you don't want to.
+ exit unless dont_exit
+ end
+
+ class <<self
+ private
+
+ # Print a passed banner or assemble the default banner, which is usage.
+ def banner(banner, options)
+ if banner
+ puts banner
+ else
+ # Usage needs to know about the defined options.
+ usage(options)
+ end
+ end
+
+ # Print our header, which is just lines after the banner and before the
+ # options block. Needs an array, prints each element as a line.
+ def header(header)
+ if header.is_a?(Array) and header.size > 0
+ header.each { |line| puts line }
+ end
+ end
+
+ # Print out the options block by going through each option and printing
+ # it as a line (or more). Expects an array.
+ def options(options)
+ # Do nothing if there's nothing to do.
+ return if options.nil? || !options.size
+
+ # If the option is a hash, run it through option_line. Otherwise
+ # just print it out as is.
+ options.each do |name, option|
+ if option.respond_to?(:to_h)
+ option_line(option.to_h)
+ else
+ puts name
+ end
+ end
+ end
+
+ # The heavy lifting: print a line for an option. Has intimate knowledge
+ # of what keys are expected.
+ def option_line(option)
+ # Expect a hash
+ return unless option.is_a?(Hash)
+
+ # Make this easier on us
+ short = option['short']
+ long = option['long']
+ line = ''
+
+ # Get the short part.
+ line << sprintf("%#{SHORT_LENGTH}s", short)
+ line << sprintf("%-#{SHORT_BREAK_LENGTH}s", (',' if short && long))
+
+ # Get the long part.
+ line << sprintf("%-#{LONG_LENGTH}s", long)
+
+ # Print what we have so far
+ print line
+
+ # If there's a desc, print it.
+ if option['desc']
+ # If the line is too long, spill over to the next line
+ if line.length > PRE_DESC_LENGTH
+ puts
+ print " " * PRE_DESC_LENGTH
+ end
+
+ puts option['desc'].shift
+
+ # If there is more than one desc line, print each one in succession
+ # as separate lines.
+ option['desc'].each do |desc|
+ puts ' '*37 + desc
+ end
+
+ else
+ # No desc, just print a newline.
+ puts
+
+ end
+ end
+
+ # Expects an array, prints each element as a line.
+ def footer(footer)
+ footer.each { |line| puts line } unless footer.nil?
+ end
+
+ # Prints the usage statement, e.g. Usage prog.rb [-abc]
+ # Expects an array.
+ def usage(options)
+ # Really we just need an enumerable.
+ return unless options.respond_to?(:each)
+
+ # Start off the options with a dash.
+ opts = '-'
+
+ # Figure out the option shorts.
+ options.dup.each do |option|
+ # We really need an array here.
+ next unless option.is_a?(Array)
+
+ # Grab the hash of the last element, which should be the second
+ # element.
+ option = option.last.to_h
+
+ # Add the short to the options string.
+ opts << option['short'].sub('-','') if option['short']
+ end
+
+ # Figure out if we actually got any options.
+ opts = if opts =~ /^-(.+)/
+ " [#{opts}]"
+ end.to_s
+
+ # Print it out, with our newly aquired options string.
+ puts "Usage: #{program}" << opts
+ end
+
+ # Figure out the name of this program based on what was run.
+ def program
+ (/(\/|\\)/ =~ $0) ? File.basename($0) : $0
+ end
+
+ # Set where we print.
+ def target=(target)
+ @@target = target
+ end
+
+ # Where do we print?
+ def target
+ @@target
+ end
+
+ public
+ # Fake puts
+ def puts(str = nil)
+ str = '' if str.nil?
+ print(str + "\n")
+ end
+
+ # Fake printf
+ def printf(format, *args)
+ print(sprintf(format, *args))
+ end
+
+ # Fake print -- just add to target, which may not be STDOUT.
+ def print(str)
+ target << str
+ end
+ end
+ end
+end
View
234 vendor/choice-0.1.4/test/test_choice.rb
@@ -0,0 +1,234 @@
+$:.unshift "../lib:lib"
+require 'test/unit'
+require 'choice'
+
+$VERBOSE = nil
+
+class TestChoice < Test::Unit::TestCase
+
+ def setup
+ Choice.reset!
+ Choice.dont_exit_on_help = true
+ Choice.send(:class_variable_set, '@@choices', true)
+ end
+
+ def test_choices
+ Choice.options do
+ header "Tell me about yourself?"
+ header ""
+ option :band do
+ short "-b"
+ long "--band=BAND"
+ cast String
+ desc "Your favorite band."
+ validate /\w+/
+ end
+ option :animal do
+ short "-a"
+ long "--animal=ANIMAL"
+ cast String
+ desc "Your favorite animal."
+ end
+ footer ""
+ footer "--help This message"
+ end
+
+ band = 'LedZeppelin'
+ animal = 'Reindeer'
+
+ args = ['-b', band, "--animal=#{animal}"]
+ Choice.args = args
+
+ assert_equal band, Choice.choices['band']
+ assert_equal animal, Choice.choices[:animal]
+ assert_equal ["Tell me about yourself?", ""], Choice.header
+ assert_equal ["", "--help This message"], Choice.footer
+
+ assert_equal Choice.choices['band'], Choice['band']
+ assert_equal Choice.choices[:animal], Choice[:animal]
+ end
+
+ def test_failed_parse
+ assert Hash.new, Choice.parse
+ end
+
+ HELP_STRING = ''
+ def test_help
+ Choice.output_to(HELP_STRING)
+
+ Choice.options do
+ banner "Usage: choice [-mu]"
+ header ""
+ option :meal do
+ short '-m'
+ desc 'Your favorite meal.'
+ end
+
+ separator ""
+ separator "And you eat it with..."
+
+ option :utencil do
+ short "-u"
+ long "--utencil[=UTENCIL]"
+ desc "Your favorite eating utencil."
+ end
+ end
+
+ Choice.args = ['-m', 'lunch', '--help']
+
+ help_string = <<-HELP
+Usage: choice [-mu]
+
+ -m Your favorite meal.
+
+And you eat it with...
+ -u, --utencil[=UTENCIL] Your favorite eating utencil.
+HELP
+
+ assert_equal help_string, HELP_STRING
+ end
+
+ UNKNOWN_STRING = ''
+ def test_unknown_argument
+ Choice.output_to(UNKNOWN_STRING)
+
+ Choice.options do
+ banner "Usage: choice [-mu]"
+ header ""
+ option :meal do
+ short '-m'
+ desc 'Your favorite meal.'
+ end
+
+ separator ""
+ separator "And you eat it with..."
+
+ option :utencil do
+ short "-u"
+ long "--utencil[=UTENCIL]"
+ desc "Your favorite eating utencil."
+ end
+ end
+
+ Choice.args = ['-m', 'lunch', '--motorcycles']
+
+ help_string = <<-HELP
+Usage: choice [-mu]
+
+ -m Your favorite meal.
+
+And you eat it with...
+ -u, --utencil[=UTENCIL] Your favorite eating utencil.
+HELP
+
+ assert_equal help_string, UNKNOWN_STRING
+ end
+
+ REQUIRED_STRING = ''
+ def test_required_argument
+ Choice.output_to(REQUIRED_STRING)
+
+ Choice.options do
+ banner "Usage: choice [-mu]"
+ header ""
+ option :meal, :required => true do
+ short '-m'
+ desc 'Your favorite meal.'
+ end
+
+ separator ""
+ separator "And you eat it with..."
+
+ option :utencil do
+ short "-u"
+ long "--utencil[=UTENCIL]"
+ desc "Your favorite eating utencil."
+ end
+ end
+
+ Choice.args = ['-u', 'spork']
+
+ help_string = <<-HELP
+Usage: choice [-mu]
+
+ -m Your favorite meal.
+
+And you eat it with...
+ -u, --utencil[=UTENCIL] Your favorite eating utencil.
+HELP
+
+ assert_equal help_string, REQUIRED_STRING
+ end
+
+ def test_shorthand_choices
+ Choice.options do
+ header "Tell me about yourself?"
+ header ""
+ options :band => { :short => "-b", :long => "--band=BAND", :cast => String, :desc => ["Your favorite band.", "Something cool."],
+ :validate => /\w+/ },
+ :animal => { :short => "-a", :long => "--animal=ANIMAL", :cast => String, :desc => "Your favorite animal." }
+
+ footer ""
+ footer "--help This message"
+ end
+
+ band = 'LedZeppelin'
+ animal = 'Reindeer'
+
+ args = ['-b', band, "--animal=#{animal}"]
+ Choice.args = args
+
+ assert_equal band, Choice.choices['band']
+ assert_equal animal, Choice.choices[:animal]
+ assert_equal ["Tell me about yourself?", ""], Choice.header
+ assert_equal ["", "--help This message"], Choice.footer
+ end
+
+ def test_args_of
+ suits = %w[clubs diamonds spades hearts]
+ stringed_numerics = (1..13).to_a.map { |a| a.to_s }
+ valid_cards = stringed_numerics + %w[jack queen king ace]
+ cards = {}
+ stringed_numerics.each { |n| cards[n] = n }
+ cards.merge!('1' => 'ace', '11' => 'jack', '12' => 'queen', '13' => 'king')
+
+ Choice.options do
+ header "Gambling is fun again! Pick a card and a suit (or two), then see if you win!"
+ header ""
+ header "Options:"
+
+ option :suit, :required => true do
+ short '-s'
+ long '--suit *SUITS'
+ desc "The suit you wish to choose. Required. You can pass in more than one, even."
+ desc " Valid suits: #{suits * ' '}"
+ valid suits
+ end
+
+ separator ''
+
+ option :card, :required => true do
+ short '-c'
+ long '--card CARD'
+ desc "The card you wish to gamble on. Required. Only one, please."
+ desc " Valid cards: 1 - 13, jack, queen, king, ace"
+ valid valid_cards
+ cast String
+ end
+
+ #cheat! to test --option=
+ option :autowin do
+ short '-a'
+ long '--autowin=PLAYER'
+ desc 'The person who should automatically win every time'
+ desc 'Beware: raises the suspitions of other players'
+ end
+ end
+
+ args = ["-c", "king", "--suit", "clubs", "diamonds", "spades", "hearts", "--autowin", "Grant"]
+ Choice.args = args
+ assert_equal ["king"], Choice.args_of("-c")
+ assert_equal ["clubs", "diamonds", "spades", "hearts"], Choice.args_of("--suit")
+ assert_equal ["Grant"], Choice.args_of("--autowin")
+ end
+end
View
76 vendor/choice-0.1.4/test/test_lazyhash.rb
@@ -0,0 +1,76 @@
+$:.unshift "../lib:lib"
+require 'test/unit'
+require 'choice/lazyhash'
+
+class TestLazyHash < Test::Unit::TestCase
+
+ def test_symbol
+ name = 'Igor'
+ age = 41
+
+ hash = Choice::LazyHash.new
+ hash['name'] = name
+ hash[:age] = age
+
+ assert_equal name, hash[:name]
+ assert_equal age, hash[:age]
+ end
+
+ def test_string
+ name = "Frank Stein"
+ age = 30
+
+ hash = Choice::LazyHash.new
+ hash[:name] = name
+ hash['age'] = age
+
+ assert_equal name, hash['name']
+ assert_equal age, hash['age']
+ end
+
+ def test_store_and_fetch
+ name = 'Jimini Jeremiah'
+ job = 'Interior Decorator'
+
+ hash = Choice::LazyHash.new
+ hash.store('name', name)
+ hash.store(:job, job)
+
+ assert_equal name, hash.fetch(:name)
+ assert_equal job, hash.fetch('job')
+ end
+
+ def test_messages
+ star = 'Sol'
+ planet = 'Mars'
+
+ hash = Choice::LazyHash.new
+ hash.star = star
+ hash.planet = planet
+
+ assert_equal star, hash.star
+ assert_equal planet, hash.planet
+ end
+
+ def test_from_hash
+ state = 'Nebraska'
+ country = 'Mexico'
+
+ hash = { :state => state, :country => country }
+ lazy = Choice::LazyHash.new(hash)
+
+ assert_equal state, lazy['state']
+ assert_equal country, lazy[:country]
+ end
+
+ def test_to_lazyhash
+ hash = { :name => 'Jimmy', :age => 25 }
+ lazy = hash.to_lazyhash
+
+ assert_equal hash[:name], lazy.name
+ assert_equal hash[:name], lazy[:name]
+ assert_equal hash[:age], lazy.age
+ assert_equal hash[:age], lazy[:age]
+ end
+
+end
View
145 vendor/choice-0.1.4/test/test_option.rb
@@ -0,0 +1,145 @@
+$:.unshift "../lib:lib"
+require 'test/unit'
+require 'choice'
+require 'choice/option'
+
+class TestOption < Test::Unit::TestCase
+ def setup
+ Choice.reset!
+ @option = Choice::Option.new
+ end
+
+ def test_desc
+ line_one = "This is a description."
+ line_two = "I can add many lines."
+ line_three = "There is no limit."
+
+ assert_equal false, @option.desc?
+
+ @option.desc line_one
+ @option.desc line_two
+
+ assert @option.desc?
+ assert_equal [line_one, line_two], @option.desc
+
+ @option.desc line_three
+ assert @option.desc?
+ assert_equal [line_one, line_two, line_three], @option.desc
+ end
+
+ def test_choice
+ short = "-p"
+
+ assert_equal false, @option.short?
+
+ @option.short short
+
+ assert @option.short?
+ assert_equal short, @option.short
+ end
+
+ def test_no_choice
+ default = 42
+
+ assert_raise(Choice::Option::ParseError) do
+ @option.defaut?
+ end
+
+ assert_raise(Choice::Option::ParseError) do
+ @option.defaut default
+ end
+
+ assert_raise(Choice::Option::ParseError) do
+ @option.defaut
+ end
+
+ end
+
+ def test_block_choice
+ assert_equal false, @option.action?
+
+ @option.action do
+ 1 + 1
+ end
+
+ assert @option.action?
+ assert_block(&@option.action)
+ end
+
+ def test_format
+ @option = Choice::Option.new do
+ validate /^\w+$/
+ end
+
+ assert_equal /^\w+$/, @option.validate
+
+ block = proc { |f| File.exists? f }
+ @option = Choice::Option.new do
+ validate &block
+ end
+
+ assert_equal block, @option.validate
+ end
+
+ def test_dsl
+ @option = Choice::Option.new do
+ short "-h"
+ long "--host=HOST"
+ cast String
+ desc "The hostname."
+ desc "(Alphanumeric only)"
+ filter do
+ 5 * 10
+ end
+ end
+
+ assert_equal "-h", @option.short
+ assert_equal "--host=HOST", @option.long
+ assert_equal String, @option.cast
+ assert_equal ["The hostname.", "(Alphanumeric only)"], @option.desc
+ assert_equal proc { 5 * 10 }.call, @option.filter.call
+ end
+
+ def test_to_a
+ desc = "This is your description."
+ short = "-t"
+ long = "--test=METHOD"
+ default = :to_a
+
+ @option.desc desc
+ @option.short short
+ @option.long long
+ @option.default default
+ @option.action { 1 + 1 }
+ array = @option.to_a
+
+ assert_equal Choice::Option, @option.class
+ assert_equal Array, array.class
+ assert array.include? [desc]
+ assert array.include? short
+ assert array.include? long
+ assert array.include? default
+ assert_equal proc { 1 + 1 }.call, array.select { |a| a.is_a? Proc }.first.call
+ end
+
+ def test_to_h
+ desc = "This is your description."
+ short = "-t"
+ long = "--test=METHOD"
+ cast = Integer
+
+ @option.desc desc
+ @option.short short
+ @option.long long
+ @option.cast cast
+ @option.filter { 2 + 2 }
+ hash = @option.to_h
+
+ assert_equal Choice::Option, @option.class
+ assert_equal Hash, hash.class
+ assert_equal [desc], hash['desc']
+ assert_equal short, hash['short']
+ assert_equal cast, hash['cast']
+ assert_equal proc { 2 + 2 }.call, hash['filter'].call
+ end
+end
View
389 vendor/choice-0.1.4/test/test_parser.rb
@@ -0,0 +1,389 @@
+$:.unshift "../lib:lib"
+require 'test/unit'
+require 'choice/option'
+require 'choice/parser'
+
+class TestParser < Test::Unit::TestCase
+ def setup
+ @options = {}
+ end
+
+ def test_parse_options
+ @options['band'] = Choice::Option.new do
+ short '-b'
+ long '--band=BAND'
+ cast String
+ desc 'Your favorite band.'
+ end
+ @options['animal'] = Choice::Option.new do
+ short '-a'
+ long '--animal=ANIMAL'
+ cast String
+ desc 'Your favorite animal.'
+ end
+ band = 'Led Zeppelin'
+ animal = 'Reindeer'
+
+ args = ['-b', band, "--animal=#{animal}"]
+
+ choices, rest = Choice::Parser.parse(@options, args)
+
+ assert_equal band, choices['band']
+ assert_equal animal, choices['animal']
+ end
+
+ def test_parse_no_options
+ assert_equal Hash.new, Choice::Parser.parse(nil, nil)
+ end
+
+ def test_parse_default
+ @options['soda'] = Choice::Option.new do
+ short '-s'
+ long '--soda=SODA'
+ default 'PibbJr'
+ end
+
+ args = []
+
+ choices, rest = Choice::Parser.parse(@options, args)
+
+ assert_equal 'PibbJr', choices['soda']
+ end
+
+ def test_parse_options_with_filters
+ @options['host'] = Choice::Option.new do
+ short '-h'
+ filter do |opt|
+ opt.gsub!(/[^\w]/, '')
+ opt = opt.sub(/k/, 'c')
+ end
+ end
+ host = 'de.fun.kt'
+ args = ['-h', host]
+ choices, rest = Choice::Parser.parse(@options, args)
+
+ assert_equal 'defunct', choices['host']
+ end
+
+ def test_casting
+ @options['port'] = Choice::Option.new do
+ short '-p'
+ cast Integer
+ end
+
+ port = '3000'
+ args = ['-p', port]
+ choices, rest = Choice::Parser.parse(@options, args)
+
+ assert_equal port.to_i, choices['port']
+ end
+
+ def test_text_required
+ @options['name'] = Choice::Option.new do
+ short '-n'
+ long '--name=NAME'
+ end
+ @options['age'] = Choice::Option.new do
+ short '-a'
+ long 'age[=AGE]'
+ cast Integer
+ end
+
+ args = ['-n', '-a', '21']
+
+ assert_raise(Choice::Parser::ArgumentRequired) do
+ choices, rest = Choice::Parser.parse(@options, args)
+ end
+ end
+
+ def test_text_optional
+ @options['color'] = Choice::Option.new do
+ short '-c'
+ long '--color[=COLOR]'
+ end
+
+ args = ['-c']
+ choices, rest = Choice::Parser.parse(@options, args)
+
+ assert choices['color']
+
+ color = 'ladyblue'
+ args = ['-c', color]
+ choices, rest = Choice::Parser.parse(@options, args)
+
+ assert_equal color, choices['color']
+ end
+
+ def test_text_optional_deprecated
+ @options['color'] = Choice::Option.new do
+ short '-c'
+ long '--color=[COLOR]'
+ end
+
+ args = ['-c']
+ choices, rest = Choice::Parser.parse(@options, args)
+
+ assert choices['color']
+
+ color = 'ladyblue'
+ args = ['-c', color]
+ choices, rest = Choice::Parser.parse(@options, args)
+
+ assert_equal color, choices['color']
+ end
+
+ def test_ignore_separator
+ options = []
+ options << ['keyboard', Choice::Option.new do
+ short '-k'
+ long '--keyboard=BOARD'
+ end]
+
+ options << ['mouse', Choice::Option.new do
+ short '-m'
+ long '--mouse=MOUSE'
+ end]
+
+ args = ['-m', 'onebutton']
+ choices, rest = Choice::Parser.parse([options.first, '----', options.last], args)
+
+ assert choices['mouse']
+ assert_equal 1, choices.size
+ end
+
+ def test_long_as_switch
+ @options['chunky'] = Choice::Option.new do
+ short '-b'
+ long '--bacon'
+ end
+
+ args = ['--bacon']
+ choices, rest = Choice::Parser.parse(@options, args)
+
+ assert choices['chunky']
+ end
+
+ def test_validate_regexp
+ @options['email'] = Choice::Option.new do
+ short '-e'
+ long '--email=EMAIL'
+ desc 'Your valid email addy.'
+ validate /^[a-z0-9_.-]+@[a-z0-9_.-]+\.[a-z]{2,4}$/i
+ end
+
+ email_bad = 'this will@neverwork'
+ email_good = 'chris@ozmm.org'
+
+ args = ['-e', email_bad]
+ assert_raise(Choice::Parser::ArgumentValidationFails) do
+ choices, rest = Choice::Parser.parse(@options, args)
+ end
+
+ args = ['-e', email_good]
+ choices, rest = Choice::Parser.parse(@options, args)
+
+ assert_equal email_good, choices['email']
+ end
+
+ def test_validate_block
+ @options['file'] = Choice::Option.new do
+ short '-f'
+ long '--file=FILE'
+ desc 'Your valid email addy.'
+ validate do |arg|
+ File.exists? arg
+ end
+ end
+
+ file_bad = 'not_a_file.rb'
+ file_good = __FILE__
+
+ args = ['-f', file_bad]
+ assert_raise(Choice::Parser::ArgumentValidationFails) do
+ choices, rest = Choice::Parser.parse(@options, args)
+ end
+
+ args = ['-f', file_good]
+ choices, rest = Choice::Parser.parse(@options, args)
+
+ assert_equal file_good, choices['file']
+ end
+
+ def test_unknown_argument
+ @options['cd'] = Choice::Option.new do
+ short '-c'
+ long '--cd=CD'
+ desc 'A CD you like.'
+ end
+
+ args = ['-c', 'BestOfYanni', '--grace']
+ assert_raise(Choice::Parser::UnknownOption) do
+ choices, rest = Choice::Parser.parse(@options, args)
+ end
+ end
+
+ def test_valid
+ @options['suit'] = Choice::Option.new do
+ short '-s'
+ long '--suit=SUIT'
+ valid %w[club diamond spade heart]
+ desc "The suit of your card, sir."
+ end
+
+ suit_good = 'club'
+ suit_bad = 'joker'
+
+ args = ['-s', suit_bad]
+ assert_raise(Choice::Parser::InvalidArgument) do
+ choices, rest = Choice::Parser.parse(@options, args)
+ end
+
+ args = ['-s', suit_good]
+ choices, rest = Choice::Parser.parse(@options, args)
+
+ assert_equal suit_good, choices['suit']
+ end
+
+ def test_valid_needs_argument
+ @options['pants'] = Choice::Option.new do
+ short '-p'
+ long '--pants'
+ valid %w[jeans slacks trunks boxers]
+ desc "Your preferred type of pants."
+ end
+
+ args = ['-p']
+ assert_raise(Choice::Parser::ArgumentRequiredWithValid) do
+ choices, rest = Choice::Parser.parse(@options, args)
+ end
+ end
+
+ def test_long_as_array
+ @options['medium'] = Choice::Option.new do
+ short '-m'
+ long '--medium=*MEDIUM'
+ desc "The medium(s) you like best."
+ end
+
+ mediums = %w[canvas stone steel]
+
+ args = ['-m', mediums.first, '-m', mediums[1], '-m', mediums.last]
+ choices, rest = Choice::Parser.parse(@options, args)
+ assert_equal mediums, choices['medium']
+
+ args = ['-m', mediums.first, mediums[1], mediums.last]
+ choices, rest = Choice::Parser.parse(@options, args)
+ assert_equal mediums, choices['medium']
+
+ args = ["--medium=#{mediums.first}", "--medium=#{mediums[1]}", "--medium=#{mediums.last}"]
+ choices, rest = Choice::Parser.parse(@options, args)
+ assert_equal mediums, choices['medium']
+
+ args = ["--medium=#{mediums.first}", mediums[1], mediums.last]
+ choices, rest = Choice::Parser.parse(@options, args)
+ assert_equal mediums, choices['medium']
+ end
+
+ def test_long_as_array_optional
+ @options['instruments'] = Choice::Option.new do
+ short '-i'
+ long '--instruments[=*INSTRUMENTS]'
+ desc "Do you like instruments? Which ones do you like best?"
+ end
+
+ instruments = %w[xylophone guitar piano]
+
+ args = ["--instruments=#{instruments.first}",
+ "--instruments=#{instruments[1]}",
+ "--instruments=#{instruments.last}"]
+ choices, rest = Choice::Parser.parse(@options, args)
+ assert_equal instruments, choices['instruments']
+
+ args = %w[--instruments]
+ choices, rest = Choice::Parser.parse(@options, args)
+ assert_equal [], choices['instruments']
+ end
+
+ def test_long_as_array_with_valid
+ @options['suits'] = Choice::Option.new do
+ short '-s'
+ long '--suits=*SUITS'
+ valid %w[club diamond spade heart]
+ desc "The suits of your deck, sir."
+ end
+
+ suits = %w[spade heart]
+
+ args = ['-s', suits.first, suits.last]
+ choices, rest = Choice::Parser.parse(@options, args)
+
+ assert_equal suits, choices['suits']
+
+ args = ['-s', suits.first, 'notasuit']
+ assert_raise(Choice::Parser::InvalidArgument) do
+ choices, rest = Choice::Parser.parse(@options, args)
+ end
+ end
+
+ def test_long_with_spaces
+ @options['donut'] = Choice::Option.new do
+ short '-d'
+ long '--donut DONUT'
+ desc "Your favorite donut style."
+ end
+
+ donut = 'long-john'
+
+ args = ['--donut', donut]
+ choices, rest = Choice::Parser.parse(@options, args)
+
+ assert_equal donut, choices['donut']
+ end
+
+ def test_optional_long_with_spaces
+ @options['donut'] = Choice::Option.new do
+ short '-d'
+ long '--donut [DONUT]'
+ desc "Your favorite donut style."
+ end
+
+ donut = 'chocolate'
+
+ args = ['--donut', donut]
+ choices, rest = Choice::Parser.parse(@options, args)
+ assert_equal donut, choices['donut']
+
+ args = ['--donut']
+ choices, rest = Choice::Parser.parse(@options, args)
+ assert_equal true, choices['donut']
+ end
+
+ def test_long_with_spaces_arrayed
+ @options['donuts'] = Choice::Option.new do
+ short '-d'
+ long '--donuts *DONUTS'
+ desc "Your favorite donut styles."
+ end
+
+ donuts = %w[glazed cream-filled]
+
+ args = ['--donuts', donuts.first, donuts.last]
+ choices, rest = Choice::Parser.parse(@options, args)
+ assert_equal donuts, choices['donuts']
+ end
+
+ def test_long_with_rest
+ @options['donut'] = Choice::Option.new do
+ short '-d'
+ long '--donut [DONUT]'
+ desc "Your favorite donut style."
+ end
+
+ donut = 'chocolate'
+
+ args = ['eat', '--donut', donut]
+ choices, rest = Choice::Parser.parse(@options, args)
+ assert_equal donut, choices['donut']
+ assert_equal ['eat'], rest
+ end
+end
View
103 vendor/choice-0.1.4/test/test_writer.rb
@@ -0,0 +1,103 @@
+$:.unshift "../lib:lib"
+require 'test/unit'
+require 'choice'
+
+class TestWriter < Test::Unit::TestCase
+
+ def setup
+ Choice.reset!
+ end
+
+ HELP_OUT = ''
+ def test_help
+ song = Choice::Option.new do
+ short '-s'
+ long '--song=SONG'
+ cast String
+ desc 'Your favorite GNR song.'
+ desc '(Default: MyMichelle)'
+ default 'MyMichelle'
+ end
+ dude = Choice::Option.new do
+ short '-d'
+ long '--dude=DUDE'
+ cast String
+ desc 'Your favorite GNR dude.'
+ desc '(Default: Slash)'
+ default 'Slash'
+ end
+
+ options = [[:song, song], [:dude, dude]]
+ args = { :banner => "Welcome to the jungle",
+ :header => [""],
+ :options => options,
+ :footer => ["", "Wake up."] }
+
+ help_string = <<-HELP
+Welcome to the jungle
+
+ -s, --song=SONG Your favorite GNR song.
+ (Default: MyMichelle)
+ -d, --dude=DUDE Your favorite GNR dude.
+ (Default: Slash)
+
+Wake up.
+HELP
+
+ Choice::Writer.help(args, HELP_OUT, true)
+
+ assert_equal help_string, HELP_OUT
+ end
+
+ BANNER_OUT = ''
+ def test_banner
+ media = Choice::Option.new do
+ short '-m'
+ long '--media=MEDIA'
+ end
+ rom = Choice::Option.new do
+ short '-r'
+ long '--rom=ROM'
+ end
+
+ options = [[:media, media], [:rom, rom]]
+ args = { :header => [""],
+ :options => options }
+
+ help_string = <<-HELP
+Usage: #{program} [-mr]
+
+ -m, --media=MEDIA
+ -r, --rom=ROM
+HELP
+
+ Choice::Writer.help(args, BANNER_OUT, true)
+
+ assert_equal help_string, BANNER_OUT
+ end
+
+ SPILLOVER_OUT = ''
+ def test_desc_spillover
+ toolong = Choice::Option.new do
+ long '--thisisgonnabewaytoolongiswear=STRING'
+ desc 'Way too long, boy wonder.'
+ end
+
+ options = [[:toolong, toolong]]
+
+ help_string = <<-HELP
+Usage: #{program}
+ --thisisgonnabewaytoolongiswear=STRING
+ Way too long, boy wonder.
+HELP
+
+
+ Choice::Writer.help({:options => options}, SPILLOVER_OUT, true)
+
+ assert_equal help_string, SPILLOVER_OUT
+ end
+
+ def program
+ if (/(\/|\\)/ =~ $0) then File.basename($0) else $0 end
+ end
+end
View
20 vendor/cijoe-0.7.0/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2009 Chris Wanstrath
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
170 vendor/cijoe-0.7.0/README.md
@@ -0,0 +1,170 @@
+CI Joe
+======
+
+Joe is a [Continuous
+Integration](http://en.wikipedia.org/wiki/Continuous_integration)
+server that'll run your tests on demand and report their pass/fail status.
+
+Because knowing is half the battle.
+
+![The Battle](http://img.skitch.com/20090805-g4a2qhttwij8n2jr9t552efn3k.png)
+
+Quickstart
+----------
+
+RubyGems:
+
+ $ gem install cijoe
+ $ git clone git://github.com/you/yourrepo.git
+ $ cijoe yourrepo
+
+Boom. Navigate to <http://localhost:4567> to see Joe in action.
+Check `cijoe -h` for other options.
+
+Basically you need to run `cijoe` and hand it the path to a git
+repo. Make sure this isn't a shared repo: Joe needs to own it.
+
+Joe looks for various git config settings in the repo you hand it. For
+instance, you can tell Joe what command to run by setting
+`cijoe.runner`:
+
+ $ git config --add cijoe.runner "rake -s test:units"
+
+Joe doesn't care about Ruby, Python, or whatever. As long as the
+runner returns a non-zero exit status on fail and a zero on success,
+everyone is happy.
+
+Need to do some massaging of your repo before the tests run, like
+maybe swapping in a new database.yml? No problem - Joe will try to
+run `.git/hooks/after-reset` if it exists before each build phase.
+Do it in there. Just make sure it's executable.
+
+Want to notify IRC or email on test pass or failure? Joe will run
+`.git/hooks/build-failed` or `.git/hooks/build-worked` if they exist
+and are executable on build pass / fail. They're just shell scripts -
+put whatever you want in there.
+
+Tip: your repo's `HEAD` will point to the commit used to run the
+build. Pull any metadata you want out of that scro.
+
+
+Other Branches
+----------------------
+
+Want joe to run against a branch other than `master`? No problem:
+
+ $ git config --add cijoe.branch deploy
+
+
+Concurrent Push's - a kind of "queueing"
+----------------------------------------
+
+Joe runs just one build at the time. If you expect concurrent push's
+to your repo and want joe to build each in a kind of queue, just set:
+
+ $ git config --add cijoe.buildallfile tmp/cijoe.txt
+
+Joe will save requests while another build runs. If more than one push
+hits joe, he just picks the last after finishing the prior.
+
+
+Campfire
+-------------
+
+Campfire notification is included, because it's what we use. Want Joe
+notify your Campfire? Put this in your repo's `.git/config`:
+
+ [campfire]
+ token = your_api_token
+ subdomain = whatever
+ room = Awesomeness
+ ssl = false
+
+Note: your API token may differ between subdomains!
+
+Or do it the old fashion way:
+
+ $ cd yourrepo
+ $ git config --add campfire.token 98ADFLKJSDOIU7BLAH
+ $ git config --add campfire.subdomain github
+ etc.
+
+
+Checkin' Status
+----------------------
+
+Want to see how your build's doing without any of this fancy UI crap?
+Ping Joe for the lowdown:
+
+ curl http://localhost:4567/ping
+
+Joe will return `200 OK` if all is quiet on the Western Front. If
+Joe's busy building or your last build failed, you'll get `412
+PRECONDITION FAILED`.
+
+
+Multiple Projects
+------------------------
+
+Want CI for multiple projects? Just start multiple instances of Joe!
+He can run on any port - try `cijoe -h` for more options.
+
+If you're using Passenger, see [this blog post](http://chrismdp.github.com/2010/03/multiple-ci-joes-with-rack-and-passenger/).
+
+
+HTTP Auth
+----------------
+
+Worried about people triggering your builds? Setup HTTP auth:
+
+ $ git config --add cijoe.user chris
+ $ git config --add cijoe.pass secret
+
+
+GitHub Integration
+--------------------------
+
+Any POST to Joe will trigger a build. If you are hiding Joe behind
+HTTP auth, that's okay - GitHub knows how to authenticate properly.
+
+![Post-Receive URL](http://img.skitch.com/20090806-d2bxrk733gqu8m11tf4kyir5d8.png)
+
+You can find the Post-Receive option under the 'Service Hooks' subtab
+of your project's "Admin" tab.
+
+