did_craken 0.0.1
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.rdoc +170 -0
 - data/lib/craken.rb +112 -0
 - data/lib/enumeration.rb +89 -0
 - data/lib/raketab.rb +104 -0
 - data/spec/craken_spec.rb +138 -0
 - data/spec/enumeration_spec.rb +136 -0
 - data/spec/raketab_spec.rb +171 -0
 - metadata +76 -0
 
    
        data/README.rdoc
    ADDED
    
    | 
         @@ -0,0 +1,170 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            = Craken
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Craken is a rails plugin for managing and installing rake-centric crontab files 
         
     | 
| 
      
 4 
     | 
    
         
            +
            over Capistrano.
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            What is a crontab?  A command list that cron will run at specified intervals.
         
     | 
| 
      
 7 
     | 
    
         
            +
            What is cron?  A daemon to execute scheduled commands.
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            If you don't know these things already you should probably do a little research
         
     | 
| 
      
 10 
     | 
    
         
            +
            before using this tool :) Begin here: http://en.wikipedia.org/wiki/Cron
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            Craken uses files called +raketab+s that are similar in every respect to crontab
         
     | 
| 
      
 13 
     | 
    
         
            +
            files except the commands are rake tasks instead of arbitrary unix commands.  The file
         
     | 
| 
      
 14 
     | 
    
         
            +
            goes in the craken directory inside config (i.e. #{RAILS_ROOT}/config/craken/raketab).
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            Why not just let it run arbitrary commands instead of limiting it to rake tasks?
         
     | 
| 
      
 17 
     | 
    
         
            +
            The main issue this plugin attempts to alleviate is having to manage the 
         
     | 
| 
      
 18 
     | 
    
         
            +
            rails environment configuration for multiple deployments.  Craken will set up the
         
     | 
| 
      
 19 
     | 
    
         
            +
            crontab to change into the application's current directory and set rake to run in
         
     | 
| 
      
 20 
     | 
    
         
            +
            the correct environment.
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            Raketab files can also handle ERB escaped text bound to the rake environment.
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            A Capistrano file is also included to make it easy to install cron jobs on multiple 
         
     | 
| 
      
 25 
     | 
    
         
            +
            hosts.  A new :cron capistrano role is necessary to define which machines to install to.
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            == Configuration
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            Command line configuration options to the rake task (defaults are in parens):
         
     | 
| 
      
 30 
     | 
    
         
            +
            [+deploy_path+]        Where the application is deployed (RAILS_ROOT)
         
     | 
| 
      
 31 
     | 
    
         
            +
            [+crontab_exe+]        Where to find the crontab excutable (/usr/bin/crontab)
         
     | 
| 
      
 32 
     | 
    
         
            +
            [+rake_exe+]           The rake executable (/usr/bin/rake)
         
     | 
| 
      
 33 
     | 
    
         
            +
            [+raketab_rails_env+]  Rails environment mode to set the cron jobs to run in (RAILS_ENV)
         
     | 
| 
      
 34 
     | 
    
         
            +
            [+app_name+]           Name of the application (tries to figure it out from the deploy path)
         
     | 
| 
      
 35 
     | 
    
         
            +
            [+raketab_file+]       Where the raketab file is:
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
              #{RAILS_ROOT}/config/craken/#{HOSTNAME}_raketab or 
         
     | 
| 
      
 38 
     | 
    
         
            +
              #{RAILS_ROOT}/config/craken/raketab if the first is not found
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            The +raketab_file+ can be a crontab file (no extension), a .yaml/.yml file or 
         
     | 
| 
      
 41 
     | 
    
         
            +
            an .rb file (see Other Formats below).
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            == Example
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            An example line from an example raketab file:
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              59 * * * * thing:to_do > /tmp/thing_to_do.log 2>&1
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            This will run the rake task thing:to_do every 59th minute after every hour.
         
     | 
| 
      
 50 
     | 
    
         
            +
            The little redirect thing is added for effect; otherwise output will be mailed
         
     | 
| 
      
 51 
     | 
    
         
            +
            to the user who the crontab is installed on.
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            When craken:install is run on the production box, the crontab will look like this:
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
              ### foo raketab
         
     | 
| 
      
 56 
     | 
    
         
            +
              59 * * * * cd /home/thatguy/u/apps/foo/current && /usr/bin/rake --silent RAILS_ENV=production thing:to_do > /tmp/thing_to_do.log 2>&1
         
     | 
| 
      
 57 
     | 
    
         
            +
              ### foo raketab end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            The "magic" part of craken is the bit that crontab added:
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
              cd /home/thatguy/u/apps/foo/current && /usr/bin/rake --silent RAILS_ENV=production
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
            === Special crontab string support
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
            An example line to add a rake task to be executed after reboot:
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
              @reboot thinking_sphinx:start > /tmp/ts_startup.log 2>&1
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
            All special strings and their effects:
         
     | 
| 
      
 70 
     | 
    
         
            +
            [<tt>@reboot</tt>]    execute after reboot
         
     | 
| 
      
 71 
     | 
    
         
            +
            [<tt>@yearly</tt>]    every year
         
     | 
| 
      
 72 
     | 
    
         
            +
            [<tt>@annually</tt>]  every year hipster version
         
     | 
| 
      
 73 
     | 
    
         
            +
            [<tt>@monthly</tt>]   every month, or better known as: <i>No roll in the hay for you this time honey!</i>
         
     | 
| 
      
 74 
     | 
    
         
            +
            [<tt>@weekly</tt>]    just like every month but weekly
         
     | 
| 
      
 75 
     | 
    
         
            +
            [<tt>@daily</tt>]     like brushing your teeth
         
     | 
| 
      
 76 
     | 
    
         
            +
            [<tt>@midnight</tt>]  when the ghosts come out
         
     | 
| 
      
 77 
     | 
    
         
            +
            [<tt>@hourly</tt>]    whenever the long hand of your watch is at 12
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
            Read more about crontab special strings here: http://unixhelp.ed.ac.uk/CGI/man-cgi?crontab+5
         
     | 
| 
      
 80 
     | 
    
         
            +
            == Other Formats
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
            You can also specify other types of files to describe +raketabs+.  You can have multiple formats and they 
         
     | 
| 
      
 83 
     | 
    
         
            +
            will be aggregated together.
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
            === YAML 
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
            You can specify it in YAML.  For instance in a +config/craken/raketab.yml+:
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
              my_command:
         
     | 
| 
      
 90 
     | 
    
         
            +
                hour: 5
         
     | 
| 
      
 91 
     | 
    
         
            +
                minute: 30
         
     | 
| 
      
 92 
     | 
    
         
            +
                day: 1
         
     | 
| 
      
 93 
     | 
    
         
            +
                month: September
         
     | 
| 
      
 94 
     | 
    
         
            +
                command: thing:to_do > /tmp/thing_to_do.log 2>&1
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
            Here we've specified my_command to run at 5:30 AM on September 1st.  Aside from the command to run, 
         
     | 
| 
      
 97 
     | 
    
         
            +
            the timings have the following defaults: 0 minute, 0 hour, every day, every month, every weekday. So 
         
     | 
| 
      
 98 
     | 
    
         
            +
            you could specify in your raketab.yml:
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
              my_other_command:
         
     | 
| 
      
 101 
     | 
    
         
            +
                command: other:thing:to_do > /tmp/thing_to_do.log 2>&1
         
     | 
| 
      
 102 
     | 
    
         
            +
                
         
     | 
| 
      
 103 
     | 
    
         
            +
            This will run at midnight of every day.  You can also specify weekday:
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
              my_third_command:
         
     | 
| 
      
 106 
     | 
    
         
            +
                weekday: thursday
         
     | 
| 
      
 107 
     | 
    
         
            +
                command: third:thing:to_do > /tmp/thing_to_do.log 2>&1
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
            You can also specify the month number or weekday number as you would in a crontab.  Lastly, you can specify ranges or full match strings and they will be passed on to the crontab directly:
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
              and_finally:
         
     | 
| 
      
 112 
     | 
    
         
            +
                hour: *
         
     | 
| 
      
 113 
     | 
    
         
            +
                weekday: 1-5
         
     | 
| 
      
 114 
     | 
    
         
            +
                command: last:thing:to_do > /tmp/thing_to_do.log 2>&1
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
            Here, the command will run every hour from Monday to Friday.  Month and Weekday names are not supported when doing ranges in this fashion.
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
            === Raketab DSL
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
            The other format is written in pure ruby using the +Raketab+ object.  In your +config/craken/raketab.rb+ file:
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
              Raketab.new do |cron|
         
     | 
| 
      
 123 
     | 
    
         
            +
                cron.schedule 'thing:to_do > /tmp/thing_to_do.log 2>&1', :every => :thursday
         
     | 
| 
      
 124 
     | 
    
         
            +
              end
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
            The defaults are like those for the YAML file, so in this case, thing to do will run at midnight on thursdays.
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
              Raketab.new do |cron|
         
     | 
| 
      
 129 
     | 
    
         
            +
                cron.schedule 'thing:to_do > /tmp/thing_to_do.log 2>&1', :on => :september, :the => '1st', :at => '5:30'    
         
     | 
| 
      
 130 
     | 
    
         
            +
              end
         
     | 
| 
      
 131 
     | 
    
         
            +
              
         
     | 
| 
      
 132 
     | 
    
         
            +
            Here it will run only on the first of september at 5:30 AM.  Month and weekday names are also supported, and
         
     | 
| 
      
 133 
     | 
    
         
            +
            also the named units (hour, minute, month, day, weekday):
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
              Raketab.new do |cron|
         
     | 
| 
      
 136 
     | 
    
         
            +
                cron.schedule 'thing:to_do > /tmp/thing_to_do.log 2>&1', :on => september, :every => thursday
         
     | 
| 
      
 137 
     | 
    
         
            +
              end
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
            Here it will run every Thursday in September.  Ranges (inclusive and exclusive), comma separated lists, in strings or using numbers or weekday and month names are also supported and their three letter abbreviations:
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
              Raketab.new do |cron|
         
     | 
| 
      
 142 
     | 
    
         
            +
                cron.schedule 'thing:to_do > /tmp/thing_to_do.log 2>&1',     :every => mon..fri
         
     | 
| 
      
 143 
     | 
    
         
            +
                cron.schedule 'first:five:days > /tmp/thing_to_do.log 2>&1', :days => [1,2,3,4,5]
         
     | 
| 
      
 144 
     | 
    
         
            +
                cron.schedule 'first:day:q1 > /tmp/thing_to_do.log 2>&1',    :the => '1st', :in => [jan,feb,mar]
         
     | 
| 
      
 145 
     | 
    
         
            +
                cron.schedule 'first:day:q4 > /tmp/thing_to_do.log 2>&1',    :the => '1st', :months => 'October,November,December'
         
     | 
| 
      
 146 
     | 
    
         
            +
              end
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
            You can find all the variants in the spec for Raketab and pick and choose which is most natural for you.
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
            = Running the Capistrano Script
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
              cap craken:install
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
            Deploying to someplace other than production?  Rails environment is important so rake 
         
     | 
| 
      
 155 
     | 
    
         
            +
            is set in the right mode when the cron job runs:
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
              cap -c rails_env=qa craken:install
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
            Different raketab files can be used to limit a subset of rake tasks to a particular 
         
     | 
| 
      
 160 
     | 
    
         
            +
            machine listed as a :cron role.  These files are prefixed with the name of the machine
         
     | 
| 
      
 161 
     | 
    
         
            +
            they need to be deployed to:
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
              foo_raketab  # goes on the "foo" machine
         
     | 
| 
      
 164 
     | 
    
         
            +
              bar_raketab  # goes on the "bar" machine
         
     | 
| 
      
 165 
     | 
    
         
            +
              raketab      # goes on all machines except "foo" and "bar"
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
            Doug McInnes <doug.mcinnes@latimes.com>
         
     | 
| 
      
 168 
     | 
    
         
            +
            John Dewey <john.dewey@latimes.com>
         
     | 
| 
      
 169 
     | 
    
         
            +
            Reid MacDonald <reid.macdonald@latimes.com>
         
     | 
| 
      
 170 
     | 
    
         
            +
            Copyright (c) 2008 Los Angeles Times, released under the MIT license
         
     | 
    
        data/lib/craken.rb
    ADDED
    
    | 
         @@ -0,0 +1,112 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'socket'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "#{File.dirname(__FILE__)}/raketab"
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module Craken
         
     | 
| 
      
 5 
     | 
    
         
            +
              def self.determine_raketab_files
         
     | 
| 
      
 6 
     | 
    
         
            +
                if File.directory?("#{DEPLOY_PATH}/config/craken/") # Use hostname specific raketab first.
         
     | 
| 
      
 7 
     | 
    
         
            +
                  raketabs = Dir["#{DEPLOY_PATH}/config/craken/*raketab*"].partition {|f| f =~ %r[/raketab.*$] }
         
     | 
| 
      
 8 
     | 
    
         
            +
                  raketabs.last.empty? ? raketabs.first : raketabs.last.grep(/#{HOSTNAME}_raketab/)
         
     | 
| 
      
 9 
     | 
    
         
            +
                else
         
     | 
| 
      
 10 
     | 
    
         
            +
                  Dir["#{DEPLOY_PATH}/config/raketab*"]
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              HOSTNAME          = Socket.gethostname.split('.').first.downcase.strip
         
     | 
| 
      
 15 
     | 
    
         
            +
              DEPLOY_PATH       = ENV['deploy_path'] || RAILS_ROOT
         
     | 
| 
      
 16 
     | 
    
         
            +
              RAKETAB_FILES     = ENV['raketab_files'].split(":") rescue determine_raketab_files
         
     | 
| 
      
 17 
     | 
    
         
            +
              CRONTAB_EXE       = ENV['crontab_exe'] || "/usr/bin/crontab"
         
     | 
| 
      
 18 
     | 
    
         
            +
              RAKE_EXE          = ENV['rake_exe'] || ((rake = `which rake`.strip and rake.empty?) ? "/usr/bin/rake" : rake)
         
     | 
| 
      
 19 
     | 
    
         
            +
              RAKETAB_RAILS_ENV = ENV['raketab_rails_env'] || RAILS_ENV
         
     | 
| 
      
 20 
     | 
    
         
            +
              # assumes root of app is name of app, also takes into account 
         
     | 
| 
      
 21 
     | 
    
         
            +
              # capistrano deployments
         
     | 
| 
      
 22 
     | 
    
         
            +
              APP_NAME          = ENV['app_name'] || (DEPLOY_PATH =~ /\/([^\/]*)\/releases\/\d*$/ ? $1 : File.basename(DEPLOY_PATH))
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              # see here: http://unixhelp.ed.ac.uk/CGI/man-cgi?crontab+5
         
     | 
| 
      
 25 
     | 
    
         
            +
              SPECIAL_STRINGS   = %w[@reboot @yearly @annually @monthly @weekly @daily @midnight @hourly]
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
              CRONTAB_MARKER_START = "### #{APP_NAME} #{RAKETAB_RAILS_ENV} raketab start"
         
     | 
| 
      
 28 
     | 
    
         
            +
              CRONTAB_MARKER_END = "### #{APP_NAME} #{RAKETAB_RAILS_ENV} raketab end"
         
     | 
| 
      
 29 
     | 
    
         
            +
              # strip out the existing raketab cron tasks for this project
         
     | 
| 
      
 30 
     | 
    
         
            +
              def load_and_strip
         
     | 
| 
      
 31 
     | 
    
         
            +
                crontab = ''
         
     | 
| 
      
 32 
     | 
    
         
            +
                old = false
         
     | 
| 
      
 33 
     | 
    
         
            +
                `#{CRONTAB_EXE} -l`.each_line do |line|
         
     | 
| 
      
 34 
     | 
    
         
            +
                  line.strip!
         
     | 
| 
      
 35 
     | 
    
         
            +
                  if old || line == CRONTAB_MARKER_START
         
     | 
| 
      
 36 
     | 
    
         
            +
                    old = line != CRONTAB_MARKER_END
         
     | 
| 
      
 37 
     | 
    
         
            +
                  else
         
     | 
| 
      
 38 
     | 
    
         
            +
                    crontab << line
         
     | 
| 
      
 39 
     | 
    
         
            +
                    crontab << "\n"
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
                crontab
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
              def append_tasks(crontab, raketab)
         
     | 
| 
      
 46 
     | 
    
         
            +
                crontab << "#{CRONTAB_MARKER_START}\n"
         
     | 
| 
      
 47 
     | 
    
         
            +
                raketab.each_line do |line|
         
     | 
| 
      
 48 
     | 
    
         
            +
                  line.strip!
         
     | 
| 
      
 49 
     | 
    
         
            +
                  unless line =~ /^#/ || line.empty? # ignore comments and blank lines
         
     | 
| 
      
 50 
     | 
    
         
            +
                    sp = line.split
         
     | 
| 
      
 51 
     | 
    
         
            +
                    if SPECIAL_STRINGS.include?(sp.first)
         
     | 
| 
      
 52 
     | 
    
         
            +
                      crontab << sp.shift
         
     | 
| 
      
 53 
     | 
    
         
            +
                      tasks = sp
         
     | 
| 
      
 54 
     | 
    
         
            +
                    else
         
     | 
| 
      
 55 
     | 
    
         
            +
                      crontab << sp[0,5].join(' ')
         
     | 
| 
      
 56 
     | 
    
         
            +
                      tasks = sp[5,sp.size]
         
     | 
| 
      
 57 
     | 
    
         
            +
                    end
         
     | 
| 
      
 58 
     | 
    
         
            +
                    crontab << " cd #{DEPLOY_PATH} && #{RAKE_EXE} --silent RAILS_ENV=#{RAKETAB_RAILS_ENV}"
         
     | 
| 
      
 59 
     | 
    
         
            +
                    tasks.each do |task|
         
     | 
| 
      
 60 
     | 
    
         
            +
                      crontab << " #{task}"
         
     | 
| 
      
 61 
     | 
    
         
            +
                    end
         
     | 
| 
      
 62 
     | 
    
         
            +
                    crontab << "\n"
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
                end
         
     | 
| 
      
 65 
     | 
    
         
            +
                crontab << "#{CRONTAB_MARKER_END}\n"
         
     | 
| 
      
 66 
     | 
    
         
            +
                crontab
         
     | 
| 
      
 67 
     | 
    
         
            +
              end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
              # install new crontab
         
     | 
| 
      
 70 
     | 
    
         
            +
              def install(crontab)
         
     | 
| 
      
 71 
     | 
    
         
            +
                filename = ".crontab#{rand(9999)}" 
         
     | 
| 
      
 72 
     | 
    
         
            +
                File.open(filename, 'w') { |f| f.write crontab }
         
     | 
| 
      
 73 
     | 
    
         
            +
                `#{CRONTAB_EXE} #{filename}`
         
     | 
| 
      
 74 
     | 
    
         
            +
                FileUtils.rm filename
         
     | 
| 
      
 75 
     | 
    
         
            +
              end
         
     | 
| 
      
 76 
     | 
    
         
            +
              
         
     | 
| 
      
 77 
     | 
    
         
            +
              def raketab(files=RAKETAB_FILES)    
         
     | 
| 
      
 78 
     | 
    
         
            +
                files.map do |file|
         
     | 
| 
      
 79 
     | 
    
         
            +
                  next unless File.exist?(file)
         
     | 
| 
      
 80 
     | 
    
         
            +
                  builder = file =~ /.(\w+)$/ ? "build_raketab_from_#{$1}" : "build_raketab"
         
     | 
| 
      
 81 
     | 
    
         
            +
                  send(builder.to_sym, file)
         
     | 
| 
      
 82 
     | 
    
         
            +
                end.join("\n")
         
     | 
| 
      
 83 
     | 
    
         
            +
              end
         
     | 
| 
      
 84 
     | 
    
         
            +
              
         
     | 
| 
      
 85 
     | 
    
         
            +
              private
         
     | 
| 
      
 86 
     | 
    
         
            +
                def build_raketab_from_rb(file)
         
     | 
| 
      
 87 
     | 
    
         
            +
                  eval(File.new(file).read).tabs
         
     | 
| 
      
 88 
     | 
    
         
            +
                end
         
     | 
| 
      
 89 
     | 
    
         
            +
              
         
     | 
| 
      
 90 
     | 
    
         
            +
                def build_raketab_from_yml(file)
         
     | 
| 
      
 91 
     | 
    
         
            +
                  yml = YAML::load(ERB.new(File.read(file)).result(binding))
         
     | 
| 
      
 92 
     | 
    
         
            +
                  yml.map do |name,tab|
         
     | 
| 
      
 93 
     | 
    
         
            +
                    format = []
         
     | 
| 
      
 94 
     | 
    
         
            +
                    format << (tab['min'] || tab['minute'] || '0')
         
     | 
| 
      
 95 
     | 
    
         
            +
                    format << (tab['hour'] || '0')
         
     | 
| 
      
 96 
     | 
    
         
            +
                    format << (tab['day'] || '*')
         
     | 
| 
      
 97 
     | 
    
         
            +
                    format << (tab['month'] =~ /^\d+$/ ? tab['month'] : Date._parse(tab['month'].to_s)[:mon] || '*')
         
     | 
| 
      
 98 
     | 
    
         
            +
                    format << ((day = tab['weekday'] || tab['wday'] and day =~ /^\d+$/ ? day : Date._parse(day.to_s)[:wday]) || '*')
         
     | 
| 
      
 99 
     | 
    
         
            +
                    format << tab['command']
         
     | 
| 
      
 100 
     | 
    
         
            +
                    format.join(' ')        
         
     | 
| 
      
 101 
     | 
    
         
            +
                  end.join("\n")
         
     | 
| 
      
 102 
     | 
    
         
            +
                end
         
     | 
| 
      
 103 
     | 
    
         
            +
                alias_method :build_raketab_from_yaml, :build_raketab_from_yml
         
     | 
| 
      
 104 
     | 
    
         
            +
                
         
     | 
| 
      
 105 
     | 
    
         
            +
                def build_raketab(file)
         
     | 
| 
      
 106 
     | 
    
         
            +
                  ERB.new(File.read(file)).result(binding)
         
     | 
| 
      
 107 
     | 
    
         
            +
                end
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                def method_missing(method, *args)
         
     | 
| 
      
 110 
     | 
    
         
            +
                  method.to_s =~ /^build_raketab/ ? build_raketab(*args) : super
         
     | 
| 
      
 111 
     | 
    
         
            +
                end
         
     | 
| 
      
 112 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/enumeration.rb
    ADDED
    
    | 
         @@ -0,0 +1,89 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Enumeration  
         
     | 
| 
      
 2 
     | 
    
         
            +
              include Comparable
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              def initialize(id)
         
     | 
| 
      
 5 
     | 
    
         
            +
                @unit_id = id % self.class.size
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
              private_class_method :new
         
     | 
| 
      
 8 
     | 
    
         
            +
              
         
     | 
| 
      
 9 
     | 
    
         
            +
              def self.for(var)
         
     | 
| 
      
 10 
     | 
    
         
            +
                units[var.to_s =~ /^\d+$/ ? var.to_i - offset : abbrs.index(var[0,3].downcase.capitalize)] 
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              def succ
         
     | 
| 
      
 14 
     | 
    
         
            +
                self.class.units[(@unit_id + 1) % self.class.size]
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              def between?(a,b)
         
     | 
| 
      
 18 
     | 
    
         
            +
                true # always in rings, change for non rings
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
              
         
     | 
| 
      
 21 
     | 
    
         
            +
              def <=>(o)
         
     | 
| 
      
 22 
     | 
    
         
            +
                @unit_id <=> o.instance_variable_get("@unit_id")
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
              
         
     | 
| 
      
 25 
     | 
    
         
            +
              def to_s
         
     | 
| 
      
 26 
     | 
    
         
            +
                self.class.names[@unit_id]
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
              
         
     | 
| 
      
 29 
     | 
    
         
            +
              def to_i
         
     | 
| 
      
 30 
     | 
    
         
            +
                @unit_id + self.class.offset
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
              
         
     | 
| 
      
 33 
     | 
    
         
            +
              def to_abbr
         
     | 
| 
      
 34 
     | 
    
         
            +
                to_s[0,3]
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
              
         
     | 
| 
      
 37 
     | 
    
         
            +
              def coerce(o)
         
     | 
| 
      
 38 
     | 
    
         
            +
                [self.class.for(o % self.class.size), self]
         
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
              def +(o)
         
     | 
| 
      
 42 
     | 
    
         
            +
                self.class.for((to_i + o.to_i) % self.class.size)
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
              def -(o)
         
     | 
| 
      
 46 
     | 
    
         
            +
                self.class.for((to_i - o.to_i) % self.class.size)
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
              def inspect
         
     | 
| 
      
 50 
     | 
    
         
            +
                "#<#{self.class.name.split("::").last}:#{to_s}>"
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
                  
         
     | 
| 
      
 53 
     | 
    
         
            +
              def self.generate(names, offset=0)
         
     | 
| 
      
 54 
     | 
    
         
            +
                klass = Class.new(self)
         
     | 
| 
      
 55 
     | 
    
         
            +
                klass.send(:build_from, names)
         
     | 
| 
      
 56 
     | 
    
         
            +
                klass.send(:offset=, offset)
         
     | 
| 
      
 57 
     | 
    
         
            +
                klass.instance_eval { undef generate } 
         
     | 
| 
      
 58 
     | 
    
         
            +
                klass
         
     | 
| 
      
 59 
     | 
    
         
            +
              end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
              class << self
         
     | 
| 
      
 62 
     | 
    
         
            +
                include Enumerable
         
     | 
| 
      
 63 
     | 
    
         
            +
                def each
         
     | 
| 
      
 64 
     | 
    
         
            +
                  units.each { |u| yield u }
         
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
      
 66 
     | 
    
         
            +
                
         
     | 
| 
      
 67 
     | 
    
         
            +
                attr_accessor :offset
         
     | 
| 
      
 68 
     | 
    
         
            +
                attr_reader :names, :abbrs, :units, :size
         
     | 
| 
      
 69 
     | 
    
         
            +
                def build_from(names)
         
     | 
| 
      
 70 
     | 
    
         
            +
                  @names = names.dup.freeze
         
     | 
| 
      
 71 
     | 
    
         
            +
                  @abbrs = names.map { |n| n[0,3] }.freeze
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                  @size  = @names.size
         
     | 
| 
      
 74 
     | 
    
         
            +
                  @units = (0...@size).map { |n| new(n) }.freeze
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                  @names.each_with_index do |c,i|
         
     | 
| 
      
 77 
     | 
    
         
            +
                    const = c.upcase
         
     | 
| 
      
 78 
     | 
    
         
            +
                    const_get(const)      rescue const_set(const, @units[i]) 
         
     | 
| 
      
 79 
     | 
    
         
            +
                    const_get(const[0,3]) rescue const_set(const[0,3], @units[i]) 
         
     | 
| 
      
 80 
     | 
    
         
            +
                  end
         
     | 
| 
      
 81 
     | 
    
         
            +
                end
         
     | 
| 
      
 82 
     | 
    
         
            +
                private :build_from
         
     | 
| 
      
 83 
     | 
    
         
            +
              end
         
     | 
| 
      
 84 
     | 
    
         
            +
            end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
            def Enumeration(*args)
         
     | 
| 
      
 87 
     | 
    
         
            +
              Enumeration.generate(*args)
         
     | 
| 
      
 88 
     | 
    
         
            +
            end
         
     | 
| 
      
 89 
     | 
    
         
            +
            alias enum Enumeration
         
     | 
    
        data/lib/raketab.rb
    ADDED
    
    | 
         @@ -0,0 +1,104 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "#{File.dirname(__FILE__)}/enumeration"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'date'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            class Raketab  
         
     | 
| 
      
 5 
     | 
    
         
            +
              Month   = enum %w[January February March April May June July August September October November December], 1
         
     | 
| 
      
 6 
     | 
    
         
            +
              Weekday = enum %w[Sunday Monday Tuesday Wednesday Thursday Friday Saturday]
         
     | 
| 
      
 7 
     | 
    
         
            +
                
         
     | 
| 
      
 8 
     | 
    
         
            +
              class << self
         
     | 
| 
      
 9 
     | 
    
         
            +
                def methodize_enum(enum)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  enum.each do |e| 
         
     | 
| 
      
 11 
     | 
    
         
            +
                    p = Proc.new { e }
         
     | 
| 
      
 12 
     | 
    
         
            +
                    define_method(e.to_s.downcase,    p) 
         
     | 
| 
      
 13 
     | 
    
         
            +
                    define_method(e.to_abbr.downcase, p) 
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
                private :methodize_enum
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                def schedule(&block)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  tab = Raketab.new
         
     | 
| 
      
 20 
     | 
    
         
            +
                  tab.instance_eval(&block)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  tab
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
              methodize_enum(Month)
         
     | 
| 
      
 25 
     | 
    
         
            +
              methodize_enum(Weekday)
         
     | 
| 
      
 26 
     | 
    
         
            +
              
         
     | 
| 
      
 27 
     | 
    
         
            +
              def initialize
         
     | 
| 
      
 28 
     | 
    
         
            +
                @tabs = []
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
              def run(command, options={})
         
     | 
| 
      
 32 
     | 
    
         
            +
                month, wday, mday, hour, min = options[:month]   || options[:months]   || options[:mon], 
         
     | 
| 
      
 33 
     | 
    
         
            +
                                               options[:weekday] || options[:weekdays] || options[:wday], 
         
     | 
| 
      
 34 
     | 
    
         
            +
                                               options[:day]     || options[:days]     || options[:mday],
         
     | 
| 
      
 35 
     | 
    
         
            +
                                               options[:hour]    || options[:hours],
         
     | 
| 
      
 36 
     | 
    
         
            +
                                               options[:minute]  || options[:minutes]  || options[:min]
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                # make sure we have ints instead of enums, yo
         
     | 
| 
      
 39 
     | 
    
         
            +
                month, wday = [[month, Month], [wday, Weekday]].map do |element,type| 
         
     | 
| 
      
 40 
     | 
    
         
            +
                  if element.kind_of?(Array) # just arrays for now
         
     | 
| 
      
 41 
     | 
    
         
            +
                   element.each_with_index { |e,i| element[i] = enum_to_i(e,type) } 
         
     | 
| 
      
 42 
     | 
    
         
            +
                  else
         
     | 
| 
      
 43 
     | 
    
         
            +
                   enum_to_i(element,type)
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                [:each, :every, :on, :in, :at, :the].each do |type|
         
     | 
| 
      
 48 
     | 
    
         
            +
                  if options[type]
         
     | 
| 
      
 49 
     | 
    
         
            +
                    if(options[type] =~ /:/)
         
     | 
| 
      
 50 
     | 
    
         
            +
                      from = options[type]
         
     | 
| 
      
 51 
     | 
    
         
            +
                    else
         
     | 
| 
      
 52 
     | 
    
         
            +
                      from, ignore, exclusive, to = options[type].to_s.match(/(\w+)(\.\.(\.?)(\w+))?/)[1..4].map { |m| m.gsub(/s$/i, '') if m } 
         
     | 
| 
      
 53 
     | 
    
         
            +
                    end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                    parse = Date._parse(from)
         
     | 
| 
      
 56 
     | 
    
         
            +
                    range = to ? Date._parse(to) : {}
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                    month ||= get_value(parse, range, exclusive == '.', :mon)
         
     | 
| 
      
 59 
     | 
    
         
            +
                    wday  ||= get_value(parse, range, exclusive == '.', :wday)
         
     | 
| 
      
 60 
     | 
    
         
            +
                    mday  ||= get_value(parse, range, exclusive == '.', :mday)
         
     | 
| 
      
 61 
     | 
    
         
            +
                    hour  ||= get_value(parse, range, exclusive == '.', :hour)
         
     | 
| 
      
 62 
     | 
    
         
            +
                    min   ||= get_value(parse, range, exclusive == '.', :min)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
                end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                # deal with any arrays and ranges
         
     | 
| 
      
 67 
     | 
    
         
            +
                min, hour, mday, wday, month = [min, hour, mday, wday, month].map do |type| 
         
     | 
| 
      
 68 
     | 
    
         
            +
                 type.respond_to?(:map) ? type.map.join(',') : type    
         
     | 
| 
      
 69 
     | 
    
         
            +
                end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                # special cases with hours
         
     | 
| 
      
 72 
     | 
    
         
            +
                hour ||= options[:at].to_i if options[:at] # :at => "5 o'clock" / "5" / 5
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                # fill missing items
         
     | 
| 
      
 75 
     | 
    
         
            +
                hour, min         = [hour, min].map { |t| t || '0' }
         
     | 
| 
      
 76 
     | 
    
         
            +
                month, wday, mday = [month, wday, mday].map { |t| t || '*' }    
         
     | 
| 
      
 77 
     | 
    
         
            +
                
         
     | 
| 
      
 78 
     | 
    
         
            +
                # put it together
         
     | 
| 
      
 79 
     | 
    
         
            +
                @tabs << "#{min} #{hour} #{mday} #{month} #{wday} #{command}"
         
     | 
| 
      
 80 
     | 
    
         
            +
              end  
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
              def tabs
         
     | 
| 
      
 83 
     | 
    
         
            +
                @tabs.join("\n")
         
     | 
| 
      
 84 
     | 
    
         
            +
              end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
              private
         
     | 
| 
      
 87 
     | 
    
         
            +
                def get_value(from, to, exclusive, on)
         
     | 
| 
      
 88 
     | 
    
         
            +
                  value = (from[on] and to[on]) ? Range.new(from[on], to[on], exclusive) : from[on]
         
     | 
| 
      
 89 
     | 
    
         
            +
                  if value.is_a?(Range) and value.first > value.last
         
     | 
| 
      
 90 
     | 
    
         
            +
                    reverse = (value.last.to_i+(exclusive ? 0 : 1)..(value.first.to_i-1))
         
     | 
| 
      
 91 
     | 
    
         
            +
                    range = case on
         
     | 
| 
      
 92 
     | 
    
         
            +
                      when :mon  then 1..12
         
     | 
| 
      
 93 
     | 
    
         
            +
                      when :wday then 0..6
         
     | 
| 
      
 94 
     | 
    
         
            +
                      when :mday then 1..31
         
     | 
| 
      
 95 
     | 
    
         
            +
                    end
         
     | 
| 
      
 96 
     | 
    
         
            +
                    value = range.map - reverse.map
         
     | 
| 
      
 97 
     | 
    
         
            +
                  end
         
     | 
| 
      
 98 
     | 
    
         
            +
                  value
         
     | 
| 
      
 99 
     | 
    
         
            +
                end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                def enum_to_i(element, type)
         
     | 
| 
      
 102 
     | 
    
         
            +
                  element.kind_of?(type) ? element.to_i : element
         
     | 
| 
      
 103 
     | 
    
         
            +
                end
         
     | 
| 
      
 104 
     | 
    
         
            +
            end  
         
     | 
    
        data/spec/craken_spec.rb
    ADDED
    
    | 
         @@ -0,0 +1,138 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            RAILS_ROOT = "foo/bar/baz"
         
     | 
| 
      
 2 
     | 
    
         
            +
            RAILS_ENV = "test"
         
     | 
| 
      
 3 
     | 
    
         
            +
            ENV['app_name'] = "craken_test"
         
     | 
| 
      
 4 
     | 
    
         
            +
            ENV['raketab_rails_env'] = "test"
         
     | 
| 
      
 5 
     | 
    
         
            +
            ENV['rake_exe'] = '/usr/bin/bundle exec rake'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            require File.dirname(__FILE__) + "/../lib/craken"
         
     | 
| 
      
 8 
     | 
    
         
            +
            require 'fileutils'
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            describe Craken do
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              include Craken
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              describe "load_and_strip" do
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                it "should load the user's installed crontab" do
         
     | 
| 
      
 17 
     | 
    
         
            +
                  # figured out how to do this from here:
         
     | 
| 
      
 18 
     | 
    
         
            +
                  # http://jakescruggs.blogspot.com/2007/11/mocking-backticks-and-other-kernel.html
         
     | 
| 
      
 19 
     | 
    
         
            +
                  self.should_receive(:`).with(/crontab -l/).and_return('')
         
     | 
| 
      
 20 
     | 
    
         
            +
                  load_and_strip
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                it "should strip out preinstalled raketab commands associated with the project" do
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            crontab = <<EOS
         
     | 
| 
      
 26 
     | 
    
         
            +
            ### craken_test test raketab start
         
     | 
| 
      
 27 
     | 
    
         
            +
            this is a test
         
     | 
| 
      
 28 
     | 
    
         
            +
            one more line
         
     | 
| 
      
 29 
     | 
    
         
            +
            ### craken_test test raketab end
         
     | 
| 
      
 30 
     | 
    
         
            +
            EOS
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  self.should_receive(:`).with(/crontab -l/).and_return(crontab)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  load_and_strip.should be_empty
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                it "should not strip out preinstalled raketab commands not associated with the project" do
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            crontab = <<EOS
         
     | 
| 
      
 39 
     | 
    
         
            +
            1 2 3 4 5 blah blah
         
     | 
| 
      
 40 
     | 
    
         
            +
            ### craken_test test raketab start
         
     | 
| 
      
 41 
     | 
    
         
            +
            this is a test
         
     | 
| 
      
 42 
     | 
    
         
            +
            one more line
         
     | 
| 
      
 43 
     | 
    
         
            +
            ### craken_test test raketab end
         
     | 
| 
      
 44 
     | 
    
         
            +
            6 7 8 9 10 foo bar
         
     | 
| 
      
 45 
     | 
    
         
            +
            EOS
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  self.should_receive(:`).with(/crontab -l/).and_return(crontab)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  load_and_strip.should == "1 2 3 4 5 blah blah\n6 7 8 9 10 foo bar\n"
         
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
              end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
              describe "append_tasks" do
         
     | 
| 
      
 53 
     | 
    
         
            +
                before(:each) do
         
     | 
| 
      
 54 
     | 
    
         
            +
                  @crontab = "1 2 3 4 5 blah blah\n6 7 8 9 10 foo bar\n"
         
     | 
| 
      
 55 
     | 
    
         
            +
                end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                it "should add comments to the beginning and end of the rake tasks it adds to crontab" do
         
     | 
| 
      
 58 
     | 
    
         
            +
                  raketab = "0 1 0 0 0 foo:bar"
         
     | 
| 
      
 59 
     | 
    
         
            +
                  cron = append_tasks(@crontab, raketab)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  cron.should match(/### craken_test test raketab start\n0 1 0 0 0 /)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  cron.should match(/### craken_test test raketab end\n$/)
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                it "should ignore comments in the raketab string" do
         
     | 
| 
      
 65 
     | 
    
         
            +
            raketab = <<EOS
         
     | 
| 
      
 66 
     | 
    
         
            +
            # comment to ignore
         
     | 
| 
      
 67 
     | 
    
         
            +
            0 1 0 0 0 foo:bar
         
     | 
| 
      
 68 
     | 
    
         
            +
            # another comment to ignore
         
     | 
| 
      
 69 
     | 
    
         
            +
            EOS
         
     | 
| 
      
 70 
     | 
    
         
            +
                  cron = append_tasks(@crontab, raketab)
         
     | 
| 
      
 71 
     | 
    
         
            +
                  cron.should_not match(/# comment to ignore/)
         
     | 
| 
      
 72 
     | 
    
         
            +
                  cron.should_not match(/# another comment to ignore/)
         
     | 
| 
      
 73 
     | 
    
         
            +
                end
         
     | 
| 
      
 74 
     | 
    
         
            +
                
         
     | 
| 
      
 75 
     | 
    
         
            +
                it "should not munge the eight crontab special strings" do
         
     | 
| 
      
 76 
     | 
    
         
            +
            raketab = <<EOS
         
     | 
| 
      
 77 
     | 
    
         
            +
            @reboot brush:teeth
         
     | 
| 
      
 78 
     | 
    
         
            +
            @yearly dont_forget_girlfriends:birthday
         
     | 
| 
      
 79 
     | 
    
         
            +
            @annually just_damn_remember:it
         
     | 
| 
      
 80 
     | 
    
         
            +
            @monthly do_some:sport
         
     | 
| 
      
 81 
     | 
    
         
            +
            @weekly get:stash
         
     | 
| 
      
 82 
     | 
    
         
            +
            @daily take:shower
         
     | 
| 
      
 83 
     | 
    
         
            +
            @midnight stop_working_on_os:projects
         
     | 
| 
      
 84 
     | 
    
         
            +
            @hourly drink:water
         
     | 
| 
      
 85 
     | 
    
         
            +
            EOS
         
     | 
| 
      
 86 
     | 
    
         
            +
                  cron = append_tasks(@crontab, raketab)
         
     | 
| 
      
 87 
     | 
    
         
            +
                  cron.should match(/@reboot (.*)/)
         
     | 
| 
      
 88 
     | 
    
         
            +
                  cron.should match(/@yearly (.*)/)
         
     | 
| 
      
 89 
     | 
    
         
            +
                  cron.should match(/@annually (.*)/)
         
     | 
| 
      
 90 
     | 
    
         
            +
                  cron.should match(/@monthly (.*)/)
         
     | 
| 
      
 91 
     | 
    
         
            +
                  cron.should match(/@weekly (.*)/)
         
     | 
| 
      
 92 
     | 
    
         
            +
                  cron.should match(/@daily (.*)/)
         
     | 
| 
      
 93 
     | 
    
         
            +
                  cron.should match(/@midnight (.*)/)
         
     | 
| 
      
 94 
     | 
    
         
            +
                  cron.should match(/@hourly (.*)/)
         
     | 
| 
      
 95 
     | 
    
         
            +
                end
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                it "should not munge the crontab time configuration" do
         
     | 
| 
      
 98 
     | 
    
         
            +
            raketab = <<EOS
         
     | 
| 
      
 99 
     | 
    
         
            +
            0 1 0 0 0 foo:bar
         
     | 
| 
      
 100 
     | 
    
         
            +
            1,2,3,4,5,6 0 7,8 4 5 baz:blarg
         
     | 
| 
      
 101 
     | 
    
         
            +
            EOS
         
     | 
| 
      
 102 
     | 
    
         
            +
                  cron = append_tasks(@crontab, raketab)
         
     | 
| 
      
 103 
     | 
    
         
            +
                  cron.should match(/0 1 0 0 0 [^\d]/)
         
     | 
| 
      
 104 
     | 
    
         
            +
                  cron.should match(/1,2,3,4,5,6 0 7,8 4 5 [^\d]/)
         
     | 
| 
      
 105 
     | 
    
         
            +
                end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                it "should add a cd command, rake command and environment variables" do
         
     | 
| 
      
 108 
     | 
    
         
            +
                  raketab = "0 1 0 0 0 foo:bar"
         
     | 
| 
      
 109 
     | 
    
         
            +
                  cron = append_tasks(@crontab, raketab)
         
     | 
| 
      
 110 
     | 
    
         
            +
                  cron.should match(/0 1 0 0 0 cd #{Craken::DEPLOY_PATH} && #{Craken::RAKE_EXE} --silent RAILS_ENV=#{Craken::RAKETAB_RAILS_ENV} foo:bar/)
         
     | 
| 
      
 111 
     | 
    
         
            +
                end
         
     | 
| 
      
 112 
     | 
    
         
            +
                
         
     | 
| 
      
 113 
     | 
    
         
            +
                it "should use the rake command given via ENV['rake_exe']" do
         
     | 
| 
      
 114 
     | 
    
         
            +
                  raketab = "0 1 0 0 0 foo:bar"
         
     | 
| 
      
 115 
     | 
    
         
            +
                  cron = append_tasks(@crontab, raketab)
         
     | 
| 
      
 116 
     | 
    
         
            +
                  cron.should include('/usr/bin/bundle exec rake')
         
     | 
| 
      
 117 
     | 
    
         
            +
                end
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
                it "should ignore additional data at the end of the configuration" do
         
     | 
| 
      
 120 
     | 
    
         
            +
                  raketab = "0 1 0 0 0 foo:bar >> /tmp/foobar.log 2>&1"
         
     | 
| 
      
 121 
     | 
    
         
            +
                  cron = append_tasks(@crontab, raketab)
         
     | 
| 
      
 122 
     | 
    
         
            +
                  cron.should match(/0 1 0 0 0 cd #{Craken::DEPLOY_PATH} && #{Craken::RAKE_EXE} --silent RAILS_ENV=#{Craken::RAKETAB_RAILS_ENV} foo:bar >> \/tmp\/foobar.log 2>&1/)
         
     | 
| 
      
 123 
     | 
    
         
            +
                end
         
     | 
| 
      
 124 
     | 
    
         
            +
              end
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
              describe "install" do
         
     | 
| 
      
 127 
     | 
    
         
            +
                it "should install crontab by creating a temporary file, running crontab, then deleting the temp file" do
         
     | 
| 
      
 128 
     | 
    
         
            +
                  crontab = "crontab"
         
     | 
| 
      
 129 
     | 
    
         
            +
                  file_handle = mock("file handle")
         
     | 
| 
      
 130 
     | 
    
         
            +
                  file_handle.should_receive(:write).with(crontab)
         
     | 
| 
      
 131 
     | 
    
         
            +
                  File.should_receive(:open).with(/.crontab[0-9]*/, 'w').and_yield(file_handle)
         
     | 
| 
      
 132 
     | 
    
         
            +
                  self.should_receive(:`).with(/crontab .crontab[0-9]*$/)
         
     | 
| 
      
 133 
     | 
    
         
            +
                  FileUtils.should_receive(:rm).with(/.crontab[0-9]*/)
         
     | 
| 
      
 134 
     | 
    
         
            +
                  install(crontab)
         
     | 
| 
      
 135 
     | 
    
         
            +
                end
         
     | 
| 
      
 136 
     | 
    
         
            +
              end
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,136 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            describe Enumeration do
         
     | 
| 
      
 2 
     | 
    
         
            +
              Weekday = enum %w[Sunday Monday Tuesday Wednesday Thursday Friday Saturday]
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              describe 'creation' do
         
     | 
| 
      
 5 
     | 
    
         
            +
                it "should create an enumeration by Enumeration.generate, Enumeration(), or enum" do
         
     | 
| 
      
 6 
     | 
    
         
            +
                  ABC1 = Enumeration.generate(%w[a b c])
         
     | 
| 
      
 7 
     | 
    
         
            +
                  ABC1.units.should == [ABC1::A, ABC1::B, ABC1::C]
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  ABC2 = Enumeration(%w[a b c])
         
     | 
| 
      
 10 
     | 
    
         
            +
                  ABC2.units.should == [ABC1::A, ABC1::B, ABC1::C]
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  ABC3 = enum %w[a b c]
         
     | 
| 
      
 13 
     | 
    
         
            +
                  ABC3.units.should == [ABC1::A, ABC1::B, ABC1::C]
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                it "should not generate an enumeration itself" do
         
     | 
| 
      
 17 
     | 
    
         
            +
                  ABC4 = enum %w[a b c]
         
     | 
| 
      
 18 
     | 
    
         
            +
                  ABC4.methods.grep(/generate/).should be_empty
         
     | 
| 
      
 19 
     | 
    
         
            +
                  lambda{ ABC4.generate(%w[a b c]) }.should raise_error(NoMethodError)
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                it "should allow an offset from zero to be specified" do
         
     | 
| 
      
 23 
     | 
    
         
            +
                  ABC = enum %w[a b c], 1
         
     | 
| 
      
 24 
     | 
    
         
            +
                  ABC.offset.should == 1
         
     | 
| 
      
 25 
     | 
    
         
            +
                  ABC.size.should == 3
         
     | 
| 
      
 26 
     | 
    
         
            +
                  ABC.units.map { |l| l.to_i }.should == [1,2,3]
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
              
         
     | 
| 
      
 30 
     | 
    
         
            +
              describe 'properties' do
         
     | 
| 
      
 31 
     | 
    
         
            +
                it "should generate the right size of elements" do
         
     | 
| 
      
 32 
     | 
    
         
            +
                  Weekday.units.size.should == 7
         
     | 
| 
      
 33 
     | 
    
         
            +
                  Weekday.size.should == Weekday.units.size      
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                it "should generate an enumeration based on an collection of names" do
         
     | 
| 
      
 37 
     | 
    
         
            +
                  # full names
         
     | 
| 
      
 38 
     | 
    
         
            +
                  Weekday.names.should == %w[Sunday Monday Tuesday Wednesday Thursday Friday Saturday]    
         
     | 
| 
      
 39 
     | 
    
         
            +
                  Weekday.units.should == 
         
     | 
| 
      
 40 
     | 
    
         
            +
                    [Weekday::SUNDAY, Weekday::MONDAY, Weekday::TUESDAY, Weekday::WEDNESDAY, Weekday::THURSDAY, Weekday::FRIDAY, Weekday::SATURDAY]
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  # abbreviationss
         
     | 
| 
      
 43 
     | 
    
         
            +
                  Weekday.abbrs.should == %w[Sun Mon Tue Wed Thu Fri Sat]
         
     | 
| 
      
 44 
     | 
    
         
            +
                  Weekday.units.should == 
         
     | 
| 
      
 45 
     | 
    
         
            +
                    [Weekday::SUN, Weekday::MON, Weekday::TUE, Weekday::WED, Weekday::THU, Weekday::FRI, Weekday::SAT]
         
     | 
| 
      
 46 
     | 
    
         
            +
                  Weekday.units.map { |w| w.to_i }.should == (0..6).map
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
                
         
     | 
| 
      
 49 
     | 
    
         
            +
                it "should get units based on integer value" do
         
     | 
| 
      
 50 
     | 
    
         
            +
                  (0..6).each do |value|
         
     | 
| 
      
 51 
     | 
    
         
            +
                    Weekday.for(value).should == Weekday.units[value]
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
                  
         
     | 
| 
      
 54 
     | 
    
         
            +
                  # and respect offsets
         
     | 
| 
      
 55 
     | 
    
         
            +
                  (1..3).each do |value|
         
     | 
| 
      
 56 
     | 
    
         
            +
                    ABC.for(value).should == ABC.units[value - ABC.offset]
         
     | 
| 
      
 57 
     | 
    
         
            +
                  end        
         
     | 
| 
      
 58 
     | 
    
         
            +
                end
         
     | 
| 
      
 59 
     | 
    
         
            +
                
         
     | 
| 
      
 60 
     | 
    
         
            +
                it "should be enumerable on the units" do
         
     | 
| 
      
 61 
     | 
    
         
            +
                  Weekday.methods.grep(/^each$/).should == %w[each]
         
     | 
| 
      
 62 
     | 
    
         
            +
                  Weekday.is_a?(Enumerable)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  Weekday.map {|x| x.to_i }.should == Weekday.units.map {|x| x.to_i }
         
     | 
| 
      
 64 
     | 
    
         
            +
                end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                it "should not be able to create new units" do
         
     | 
| 
      
 67 
     | 
    
         
            +
                  lambda { Weekday.new(7) }.should raise_error(NoMethodError)
         
     | 
| 
      
 68 
     | 
    
         
            +
                end
         
     | 
| 
      
 69 
     | 
    
         
            +
              end
         
     | 
| 
      
 70 
     | 
    
         
            +
              
         
     | 
| 
      
 71 
     | 
    
         
            +
              describe 'units' do
         
     | 
| 
      
 72 
     | 
    
         
            +
                it "should be comparable" do
         
     | 
| 
      
 73 
     | 
    
         
            +
                  Weekday::SUN.methods.grep(/^succ$/).should == %w[succ]
         
     | 
| 
      
 74 
     | 
    
         
            +
                  Weekday::SUN.is_a?(Comparable)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  Weekday::SUN.should < Weekday::MON
         
     | 
| 
      
 76 
     | 
    
         
            +
                  Weekday::SUN.should <= Weekday::MON
         
     | 
| 
      
 77 
     | 
    
         
            +
                  Weekday::MON.should > Weekday::SUN
         
     | 
| 
      
 78 
     | 
    
         
            +
                  Weekday::MON.should >= Weekday::SUN
         
     | 
| 
      
 79 
     | 
    
         
            +
                  Weekday::SUN.should == Weekday::SUN
         
     | 
| 
      
 80 
     | 
    
         
            +
                  Weekday::WED.between?(Weekday::MON, Weekday::FRI).should be_true
         
     | 
| 
      
 81 
     | 
    
         
            +
                  Weekday::FRI.between?(Weekday::THU, Weekday::SUN).should be_true # if a ring
         
     | 
| 
      
 82 
     | 
    
         
            +
                  
         
     | 
| 
      
 83 
     | 
    
         
            +
                end
         
     | 
| 
      
 84 
     | 
    
         
            +
                
         
     | 
| 
      
 85 
     | 
    
         
            +
                # this should be configurable!? is true for now!
         
     | 
| 
      
 86 
     | 
    
         
            +
                it "should be a ring of values (cross boundries)" do 
         
     | 
| 
      
 87 
     | 
    
         
            +
                  Weekday::SAT.succ.should == Weekday::SUN      
         
     | 
| 
      
 88 
     | 
    
         
            +
                  Weekday::SUN.succ.should == Weekday::MON
         
     | 
| 
      
 89 
     | 
    
         
            +
                end
         
     | 
| 
      
 90 
     | 
    
         
            +
                
         
     | 
| 
      
 91 
     | 
    
         
            +
                it "should work in a range" do
         
     | 
| 
      
 92 
     | 
    
         
            +
                  (Weekday::MON..Weekday::FRI).map.should == Weekday.units[1..5]
         
     | 
| 
      
 93 
     | 
    
         
            +
                end
         
     | 
| 
      
 94 
     | 
    
         
            +
                
         
     | 
| 
      
 95 
     | 
    
         
            +
                it "should have to_s be it's name" do
         
     | 
| 
      
 96 
     | 
    
         
            +
                  %w[Sunday Monday Tuesday Wednesday Thursday Friday Saturday].each do |name|
         
     | 
| 
      
 97 
     | 
    
         
            +
                    Weekday.for(name).to_s.should == name
         
     | 
| 
      
 98 
     | 
    
         
            +
                  end
         
     | 
| 
      
 99 
     | 
    
         
            +
                end
         
     | 
| 
      
 100 
     | 
    
         
            +
                
         
     | 
| 
      
 101 
     | 
    
         
            +
                it "should have to_abbr to get it's three letter abbreviation" do
         
     | 
| 
      
 102 
     | 
    
         
            +
                  %w[Sun Mon Tue Wed Thu Fri Sat].each do |abbr|
         
     | 
| 
      
 103 
     | 
    
         
            +
                    Weekday.for(abbr).to_abbr.should == abbr
         
     | 
| 
      
 104 
     | 
    
         
            +
                  end
         
     | 
| 
      
 105 
     | 
    
         
            +
                end
         
     | 
| 
      
 106 
     | 
    
         
            +
                
         
     | 
| 
      
 107 
     | 
    
         
            +
                it "should show the enumerable name and unit name in inspect" do
         
     | 
| 
      
 108 
     | 
    
         
            +
                  %w[Sunday Monday Tuesday Wednesday Thursday Friday Saturday].each do |name|
         
     | 
| 
      
 109 
     | 
    
         
            +
                    Weekday.for(name).inspect.should == "#<Weekday:#{name}>"
         
     | 
| 
      
 110 
     | 
    
         
            +
                  end
         
     | 
| 
      
 111 
     | 
    
         
            +
                end
         
     | 
| 
      
 112 
     | 
    
         
            +
                
         
     | 
| 
      
 113 
     | 
    
         
            +
                it "should use integer values in arithmatic (+/-) and return another unit" do
         
     | 
| 
      
 114 
     | 
    
         
            +
                  Weekday.each_with_index do |w,i|
         
     | 
| 
      
 115 
     | 
    
         
            +
                    (Weekday::SUN + i).should == w
         
     | 
| 
      
 116 
     | 
    
         
            +
                  end
         
     | 
| 
      
 117 
     | 
    
         
            +
                  Weekday.map.reverse.each_with_index do |w,i|
         
     | 
| 
      
 118 
     | 
    
         
            +
                    (Weekday::SUN - i - 1).should == w
         
     | 
| 
      
 119 
     | 
    
         
            +
                  end
         
     | 
| 
      
 120 
     | 
    
         
            +
                  # ring / identity
         
     | 
| 
      
 121 
     | 
    
         
            +
                  (Weekday::SUN + 7).should == Weekday::SUN 
         
     | 
| 
      
 122 
     | 
    
         
            +
                  (Weekday::SUN - 7).should == Weekday::SUN 
         
     | 
| 
      
 123 
     | 
    
         
            +
                end
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
                it "should use integer values in arithmatic (+/-) and return another unit with coersion to weekday on integer" do
         
     | 
| 
      
 126 
     | 
    
         
            +
                  Weekday.each_with_index do |w,i|
         
     | 
| 
      
 127 
     | 
    
         
            +
                    (1 + w).should == Weekday.map[(i+1) % Weekday.size]
         
     | 
| 
      
 128 
     | 
    
         
            +
                  end
         
     | 
| 
      
 129 
     | 
    
         
            +
                  Weekday.each_with_index do |w,i|
         
     | 
| 
      
 130 
     | 
    
         
            +
                    (i - w).should == Weekday::SUN
         
     | 
| 
      
 131 
     | 
    
         
            +
                  end      
         
     | 
| 
      
 132 
     | 
    
         
            +
                  (0 + Weekday::MON).should == Weekday::MON
         
     | 
| 
      
 133 
     | 
    
         
            +
                  (2 - Weekday::MON).should == Weekday::MON 
         
     | 
| 
      
 134 
     | 
    
         
            +
                end
         
     | 
| 
      
 135 
     | 
    
         
            +
              end
         
     | 
| 
      
 136 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,171 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            describe Raketab do
         
     | 
| 
      
 2 
     | 
    
         
            +
              it "should have defaults (0 for hour, minutes and * for days and months)" do
         
     | 
| 
      
 3 
     | 
    
         
            +
               Raketab.schedule { run 'test' }.tabs.should == '0 0 * * * test'
         
     | 
| 
      
 4 
     | 
    
         
            +
              end
         
     | 
| 
      
 5 
     | 
    
         
            +
              
         
     | 
| 
      
 6 
     | 
    
         
            +
              it "should set all the fields by name" do
         
     | 
| 
      
 7 
     | 
    
         
            +
                Raketab.schedule { run 'test', :min => 1 }.tabs.should     == "1 0 * * * test"
         
     | 
| 
      
 8 
     | 
    
         
            +
                Raketab.schedule { run 'test', :minute => 1 }.tabs.should  == "1 0 * * * test"
         
     | 
| 
      
 9 
     | 
    
         
            +
                Raketab.schedule { run 'test', :hour => 1 }.tabs.should    == "0 1 * * * test"
         
     | 
| 
      
 10 
     | 
    
         
            +
                Raketab.schedule { run 'test', :day => 1 }.tabs.should     == "0 0 1 * * test"
         
     | 
| 
      
 11 
     | 
    
         
            +
                Raketab.schedule { run 'test', :mday => 1 }.tabs.should    == "0 0 1 * * test"
         
     | 
| 
      
 12 
     | 
    
         
            +
                Raketab.schedule { run 'test', :month => 1 }.tabs.should   == "0 0 * 1 * test"
         
     | 
| 
      
 13 
     | 
    
         
            +
                Raketab.schedule { run 'test', :mon => 1 }.tabs.should     == "0 0 * 1 * test"
         
     | 
| 
      
 14 
     | 
    
         
            +
                Raketab.schedule { run 'test', :wday => 1 }.tabs.should    == "0 0 * * 1 test"
         
     | 
| 
      
 15 
     | 
    
         
            +
                Raketab.schedule { run 'test', :weekday => 1 }.tabs.should == "0 0 * * 1 test"
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
              
         
     | 
| 
      
 18 
     | 
    
         
            +
              it "should set month and weekday fields by method name" do
         
     | 
| 
      
 19 
     | 
    
         
            +
                Raketab.schedule { run 'test', :month => january }.tabs.should == "0 0 * 1 * test"
         
     | 
| 
      
 20 
     | 
    
         
            +
                Raketab.schedule { run 'test', :mon => jan }.tabs.should       == "0 0 * 1 * test"
         
     | 
| 
      
 21 
     | 
    
         
            +
                Raketab.schedule { run 'test', :wday => monday }.tabs.should   == "0 0 * * 1 test"
         
     | 
| 
      
 22 
     | 
    
         
            +
                Raketab.schedule { run 'test', :weekday => mon }.tabs.should   == "0 0 * * 1 test"
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              it "should set the fields by comma string" do
         
     | 
| 
      
 26 
     | 
    
         
            +
                Raketab.schedule { run 'test', :minutes => '1,2,3' }.tabs.should  == "1,2,3 0 * * * test"
         
     | 
| 
      
 27 
     | 
    
         
            +
                Raketab.schedule { run 'test', :hours => '1,2,3' }.tabs.should    == "0 1,2,3 * * * test"
         
     | 
| 
      
 28 
     | 
    
         
            +
                Raketab.schedule { run 'test', :days => '1,2,3' }.tabs.should     == "0 0 1,2,3 * * test"
         
     | 
| 
      
 29 
     | 
    
         
            +
                Raketab.schedule { run 'test', :months => '1,2,3' }.tabs.should   == "0 0 * 1,2,3 * test"
         
     | 
| 
      
 30 
     | 
    
         
            +
                Raketab.schedule { run 'test', :weekdays => '1,2,3' }.tabs.should == "0 0 * * 1,2,3 test"
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
              
         
     | 
| 
      
 33 
     | 
    
         
            +
              it "should set the fields by array populated by method names" do
         
     | 
| 
      
 34 
     | 
    
         
            +
                Raketab.schedule { run 'test', :months => [jan,feb,mar] }.tabs.should   == "0 0 * 1,2,3 * test"
         
     | 
| 
      
 35 
     | 
    
         
            +
                Raketab.schedule { run 'test', :weekdays => [mon,tue,wed] }.tabs.should == "0 0 * * 1,2,3 test"
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
              
         
     | 
| 
      
 38 
     | 
    
         
            +
              it "should set the fields by array" do
         
     | 
| 
      
 39 
     | 
    
         
            +
                Raketab.schedule { run 'test', :minutes => [1,2,3] }.tabs.should  == "1,2,3 0 * * * test"
         
     | 
| 
      
 40 
     | 
    
         
            +
                Raketab.schedule { run 'test', :hours => [1,2,3] }.tabs.should    == "0 1,2,3 * * * test"
         
     | 
| 
      
 41 
     | 
    
         
            +
                Raketab.schedule { run 'test', :days => [1,2,3] }.tabs.should     == "0 0 1,2,3 * * test"
         
     | 
| 
      
 42 
     | 
    
         
            +
                Raketab.schedule { run 'test', :months => [1,2,3] }.tabs.should   == "0 0 * 1,2,3 * test"
         
     | 
| 
      
 43 
     | 
    
         
            +
                Raketab.schedule { run 'test', :weekdays => [1,2,3] }.tabs.should == "0 0 * * 1,2,3 test"
         
     | 
| 
      
 44 
     | 
    
         
            +
              end
         
     | 
| 
      
 45 
     | 
    
         
            +
              
         
     | 
| 
      
 46 
     | 
    
         
            +
              it "should set the fields by inclusive ranges" do
         
     | 
| 
      
 47 
     | 
    
         
            +
                Raketab.schedule { run 'test', :minutes => 1..3 }.tabs.should  == "1,2,3 0 * * * test"
         
     | 
| 
      
 48 
     | 
    
         
            +
                Raketab.schedule { run 'test', :hours => 1..3 }.tabs.should    == "0 1,2,3 * * * test"
         
     | 
| 
      
 49 
     | 
    
         
            +
                Raketab.schedule { run 'test', :days => 1..3 }.tabs.should     == "0 0 1,2,3 * * test"
         
     | 
| 
      
 50 
     | 
    
         
            +
                Raketab.schedule { run 'test', :months => 1..3 }.tabs.should   == "0 0 * 1,2,3 * test"
         
     | 
| 
      
 51 
     | 
    
         
            +
                Raketab.schedule { run 'test', :weekdays => 1..3 }.tabs.should == "0 0 * * 1,2,3 test"
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
              
         
     | 
| 
      
 54 
     | 
    
         
            +
              it "should set the fields by exclusive ranges" do
         
     | 
| 
      
 55 
     | 
    
         
            +
                Raketab.schedule { run 'test', :minutes => 1...4 }.tabs.should  == "1,2,3 0 * * * test"
         
     | 
| 
      
 56 
     | 
    
         
            +
                Raketab.schedule { run 'test', :hours => 1...4 }.tabs.should    == "0 1,2,3 * * * test"
         
     | 
| 
      
 57 
     | 
    
         
            +
                Raketab.schedule { run 'test', :days => 1...4 }.tabs.should     == "0 0 1,2,3 * * test"
         
     | 
| 
      
 58 
     | 
    
         
            +
                Raketab.schedule { run 'test', :months => 1...4 }.tabs.should   == "0 0 * 1,2,3 * test"
         
     | 
| 
      
 59 
     | 
    
         
            +
                Raketab.schedule { run 'test', :weekdays => 1...4 }.tabs.should == "0 0 * * 1,2,3 test"
         
     | 
| 
      
 60 
     | 
    
         
            +
              end
         
     | 
| 
      
 61 
     | 
    
         
            +
              
         
     | 
| 
      
 62 
     | 
    
         
            +
              it "should set weekday with symbol or string of the day name or abbreviation" do
         
     | 
| 
      
 63 
     | 
    
         
            +
                Raketab.schedule { run 'test', :on => :thursday }.tabs.should  == '0 0 * * 4 test'
         
     | 
| 
      
 64 
     | 
    
         
            +
                Raketab.schedule { run 'test', :on => 'Thursday' }.tabs.should == '0 0 * * 4 test'
         
     | 
| 
      
 65 
     | 
    
         
            +
                Raketab.schedule { run 'test', :on => :thu }.tabs.should       == '0 0 * * 4 test'
         
     | 
| 
      
 66 
     | 
    
         
            +
                Raketab.schedule { run 'test', :on => 'Thurs' }.tabs.should    == '0 0 * * 4 test'
         
     | 
| 
      
 67 
     | 
    
         
            +
              end
         
     | 
| 
      
 68 
     | 
    
         
            +
              
         
     | 
| 
      
 69 
     | 
    
         
            +
              
         
     | 
| 
      
 70 
     | 
    
         
            +
              it "should set month with symbol or string of the month name or abbreviation" do
         
     | 
| 
      
 71 
     | 
    
         
            +
                Raketab.schedule { run 'test', :on => :september }.tabs.should  == '0 0 * 9 * test'
         
     | 
| 
      
 72 
     | 
    
         
            +
                Raketab.schedule { run 'test', :on => 'September' }.tabs.should == '0 0 * 9 * test'
         
     | 
| 
      
 73 
     | 
    
         
            +
                Raketab.schedule { run 'test', :on => :sep }.tabs.should        == '0 0 * 9 * test'
         
     | 
| 
      
 74 
     | 
    
         
            +
                Raketab.schedule { run 'test', :on => 'Sep' }.tabs.should       == '0 0 * 9 * test'
         
     | 
| 
      
 75 
     | 
    
         
            +
              end
         
     | 
| 
      
 76 
     | 
    
         
            +
              
         
     | 
| 
      
 77 
     | 
    
         
            +
              it "should set month with any syntactic sugar" do
         
     | 
| 
      
 78 
     | 
    
         
            +
                Raketab.schedule { run 'test', :every => :september }.tabs.should == '0 0 * 9 * test'
         
     | 
| 
      
 79 
     | 
    
         
            +
                Raketab.schedule { run 'test', :each => :september }.tabs.should  == '0 0 * 9 * test'
         
     | 
| 
      
 80 
     | 
    
         
            +
                Raketab.schedule { run 'test', :on => :september }.tabs.should    == '0 0 * 9 * test'
         
     | 
| 
      
 81 
     | 
    
         
            +
                Raketab.schedule { run 'test', :in => :september }.tabs.should    == '0 0 * 9 * test'
         
     | 
| 
      
 82 
     | 
    
         
            +
              end
         
     | 
| 
      
 83 
     | 
    
         
            +
              
         
     | 
| 
      
 84 
     | 
    
         
            +
              it "should set day with any syntactic sugar" do
         
     | 
| 
      
 85 
     | 
    
         
            +
                Raketab.schedule { run 'test', :every => '1st' }.tabs.should == '0 0 1 * * test'
         
     | 
| 
      
 86 
     | 
    
         
            +
                Raketab.schedule { run 'test', :each => '2nd' }.tabs.should  == '0 0 2 * * test'
         
     | 
| 
      
 87 
     | 
    
         
            +
                Raketab.schedule { run 'test', :the => '3rd' }.tabs.should   == '0 0 3 * * test'
         
     | 
| 
      
 88 
     | 
    
         
            +
              end
         
     | 
| 
      
 89 
     | 
    
         
            +
              
         
     | 
| 
      
 90 
     | 
    
         
            +
              it "should set the time of day, with AM/PM or military time" do
         
     | 
| 
      
 91 
     | 
    
         
            +
                Raketab.schedule { run 'no meridiem', :at => '12:30' }.tabs.should   == '30 12 * * * no meridiem'
         
     | 
| 
      
 92 
     | 
    
         
            +
                Raketab.schedule { run 'am meridiem', :at => '12:30AM' }.tabs.should == '30 0 * * * am meridiem'
         
     | 
| 
      
 93 
     | 
    
         
            +
                Raketab.schedule { run 'pm meridiem', :at => '12:30PM' }.tabs.should == '30 12 * * * pm meridiem'
         
     | 
| 
      
 94 
     | 
    
         
            +
                Raketab.schedule { run 'military',    :at => '23:30' }.tabs.should   == '30 23 * * * military'
         
     | 
| 
      
 95 
     | 
    
         
            +
              end
         
     | 
| 
      
 96 
     | 
    
         
            +
              
         
     | 
| 
      
 97 
     | 
    
         
            +
              it "should set all the fields if they are all provided" do
         
     | 
| 
      
 98 
     | 
    
         
            +
                Raketab.schedule do |t| 
         
     | 
| 
      
 99 
     | 
    
         
            +
                  t.run 'test', :every => :sep, :the => '1st', :on => :thursdays, :at => "12:30" 
         
     | 
| 
      
 100 
     | 
    
         
            +
                end.tabs.should == "30 12 1 9 4 test"
         
     | 
| 
      
 101 
     | 
    
         
            +
              end
         
     | 
| 
      
 102 
     | 
    
         
            +
              
         
     | 
| 
      
 103 
     | 
    
         
            +
              it "should set the range of months" do
         
     | 
| 
      
 104 
     | 
    
         
            +
                Raketab.schedule { run 'inclusive full', :in => 'September..November' }.tabs.should  == '0 0 * 9,10,11 * inclusive full'
         
     | 
| 
      
 105 
     | 
    
         
            +
                Raketab.schedule { run 'exclusive full', :in => 'September...December' }.tabs.should == '0 0 * 9,10,11 * exclusive full'
         
     | 
| 
      
 106 
     | 
    
         
            +
                Raketab.schedule { run 'inclusive abbr', :in => 'Sep..Nov' }.tabs.should             == '0 0 * 9,10,11 * inclusive abbr'
         
     | 
| 
      
 107 
     | 
    
         
            +
                Raketab.schedule { run 'exclusive abbr', :in => 'Sep...Dec' }.tabs.should            == '0 0 * 9,10,11 * exclusive abbr'
         
     | 
| 
      
 108 
     | 
    
         
            +
              end
         
     | 
| 
      
 109 
     | 
    
         
            +
              
         
     | 
| 
      
 110 
     | 
    
         
            +
              it "should set the range of months across year boundry" do
         
     | 
| 
      
 111 
     | 
    
         
            +
                Raketab.schedule { run 'inclusive full reverse', :in => 'November..January' }.tabs.should    == '0 0 * 1,11,12 * inclusive full reverse'
         
     | 
| 
      
 112 
     | 
    
         
            +
                Raketab.schedule { run 'exclusive full reverse', :in => 'November...February' }.tabs.should  == '0 0 * 1,11,12 * exclusive full reverse'
         
     | 
| 
      
 113 
     | 
    
         
            +
                Raketab.schedule { run 'inclusive abbr reverse', :in => 'Nov..Jan' }.tabs.should             == '0 0 * 1,11,12 * inclusive abbr reverse'
         
     | 
| 
      
 114 
     | 
    
         
            +
                Raketab.schedule { run 'exclusive abbr reverse', :in => 'Nov...Feb' }.tabs.should            == '0 0 * 1,11,12 * exclusive abbr reverse'
         
     | 
| 
      
 115 
     | 
    
         
            +
              end
         
     | 
| 
      
 116 
     | 
    
         
            +
              
         
     | 
| 
      
 117 
     | 
    
         
            +
              it "should set the range of days" do
         
     | 
| 
      
 118 
     | 
    
         
            +
                Raketab.schedule { run 'inclusive full', :on => 'Monday..Thursday' }.tabs.should == '0 0 * * 1,2,3,4 inclusive full'
         
     | 
| 
      
 119 
     | 
    
         
            +
                Raketab.schedule { run 'exclusive full', :on => 'Monday...Friday' }.tabs.should  == '0 0 * * 1,2,3,4 exclusive full'
         
     | 
| 
      
 120 
     | 
    
         
            +
                Raketab.schedule { run 'inclusive abbr', :on => 'Mon..Thur' }.tabs.should        == '0 0 * * 1,2,3,4 inclusive abbr'
         
     | 
| 
      
 121 
     | 
    
         
            +
                Raketab.schedule { run 'exclusive abbr', :on => 'Mon...Fri' }.tabs.should        == '0 0 * * 1,2,3,4 exclusive abbr'
         
     | 
| 
      
 122 
     | 
    
         
            +
              end
         
     | 
| 
      
 123 
     | 
    
         
            +
              
         
     | 
| 
      
 124 
     | 
    
         
            +
              it "should set the range of days across week boundry" do
         
     | 
| 
      
 125 
     | 
    
         
            +
                Raketab.schedule { run 'inclusive full', :on => 'Thursday..Monday' }.tabs.should  == '0 0 * * 0,1,4,5,6 inclusive full'
         
     | 
| 
      
 126 
     | 
    
         
            +
                Raketab.schedule { run 'exclusive full', :on => 'Thursday...Monday' }.tabs.should == '0 0 * * 0,4,5,6 exclusive full'
         
     | 
| 
      
 127 
     | 
    
         
            +
                Raketab.schedule { run 'inclusive abbr', :on => 'Thu..Mon' }.tabs.should         == '0 0 * * 0,1,4,5,6 inclusive abbr'
         
     | 
| 
      
 128 
     | 
    
         
            +
                Raketab.schedule { run 'exclusive abbr', :on => 'Thu...Mon' }.tabs.should        == '0 0 * * 0,4,5,6 exclusive abbr'
         
     | 
| 
      
 129 
     | 
    
         
            +
              end
         
     | 
| 
      
 130 
     | 
    
         
            +
              
         
     | 
| 
      
 131 
     | 
    
         
            +
              it "should set the range of months using month name methods" do
         
     | 
| 
      
 132 
     | 
    
         
            +
                Raketab.schedule { run 'inclusive full', :in => september..november }.tabs.should  == '0 0 * 9,10,11 * inclusive full'
         
     | 
| 
      
 133 
     | 
    
         
            +
                Raketab.schedule { run 'exclusive full', :in => september...december }.tabs.should == '0 0 * 9,10,11 * exclusive full'
         
     | 
| 
      
 134 
     | 
    
         
            +
                Raketab.schedule { run 'inclusive abbr', :in => sep..nov }.tabs.should             == '0 0 * 9,10,11 * inclusive abbr'
         
     | 
| 
      
 135 
     | 
    
         
            +
                Raketab.schedule { run 'exclusive abbr', :in => sep...dec }.tabs.should            == '0 0 * 9,10,11 * exclusive abbr'
         
     | 
| 
      
 136 
     | 
    
         
            +
              end
         
     | 
| 
      
 137 
     | 
    
         
            +
              
         
     | 
| 
      
 138 
     | 
    
         
            +
              it "should set the range of months across year boundry using month name methods" do
         
     | 
| 
      
 139 
     | 
    
         
            +
                Raketab.schedule { run 'inclusive full reverse', :in => november..january }.tabs.should    == '0 0 * 1,11,12 * inclusive full reverse'
         
     | 
| 
      
 140 
     | 
    
         
            +
                Raketab.schedule { run 'exclusive full reverse', :in => november...february }.tabs.should  == '0 0 * 1,11,12 * exclusive full reverse'
         
     | 
| 
      
 141 
     | 
    
         
            +
                Raketab.schedule { run 'inclusive abbr reverse', :in => nov..jan }.tabs.should             == '0 0 * 1,11,12 * inclusive abbr reverse'
         
     | 
| 
      
 142 
     | 
    
         
            +
                Raketab.schedule { run 'exclusive abbr reverse', :in => nov...feb }.tabs.should            == '0 0 * 1,11,12 * exclusive abbr reverse'
         
     | 
| 
      
 143 
     | 
    
         
            +
              end
         
     | 
| 
      
 144 
     | 
    
         
            +
              
         
     | 
| 
      
 145 
     | 
    
         
            +
              it "should set the range of days using weekday name methods" do
         
     | 
| 
      
 146 
     | 
    
         
            +
                Raketab.schedule { run 'inclusive full', :on => monday..thursday }.tabs.should == '0 0 * * 1,2,3,4 inclusive full'
         
     | 
| 
      
 147 
     | 
    
         
            +
                Raketab.schedule { run 'exclusive full', :on => monday...friday }.tabs.should  == '0 0 * * 1,2,3,4 exclusive full'
         
     | 
| 
      
 148 
     | 
    
         
            +
                Raketab.schedule { run 'inclusive abbr', :on => mon..thu }.tabs.should         == '0 0 * * 1,2,3,4 inclusive abbr'
         
     | 
| 
      
 149 
     | 
    
         
            +
                Raketab.schedule { run 'exclusive abbr', :on => mon...fri }.tabs.should        == '0 0 * * 1,2,3,4 exclusive abbr'
         
     | 
| 
      
 150 
     | 
    
         
            +
              end
         
     | 
| 
      
 151 
     | 
    
         
            +
              
         
     | 
| 
      
 152 
     | 
    
         
            +
              it "should set the range of days across week boundry using weekday name methods" do
         
     | 
| 
      
 153 
     | 
    
         
            +
                Raketab.schedule { run 'inclusive full', :on => thursday..monday }.tabs.should  == '0 0 * * 0,1,4,5,6 inclusive full'
         
     | 
| 
      
 154 
     | 
    
         
            +
                Raketab.schedule { run 'exclusive full', :on => thursday...monday }.tabs.should == '0 0 * * 0,4,5,6 exclusive full'
         
     | 
| 
      
 155 
     | 
    
         
            +
                Raketab.schedule { run 'inclusive abbr', :on => thu..mon }.tabs.should          == '0 0 * * 0,1,4,5,6 inclusive abbr'
         
     | 
| 
      
 156 
     | 
    
         
            +
                Raketab.schedule { run 'exclusive abbr', :on => thu...mon }.tabs.should         == '0 0 * * 0,4,5,6 exclusive abbr'
         
     | 
| 
      
 157 
     | 
    
         
            +
              end
         
     | 
| 
      
 158 
     | 
    
         
            +
              
         
     | 
| 
      
 159 
     | 
    
         
            +
              it "should set the time with just a number on at" do
         
     | 
| 
      
 160 
     | 
    
         
            +
                Raketab.schedule { run 'test', :at => "5 o'clock" }.tabs.should == '0 5 * * * test'
         
     | 
| 
      
 161 
     | 
    
         
            +
                Raketab.schedule { run 'test', :at => "5" }.tabs.should         == '0 5 * * * test'
         
     | 
| 
      
 162 
     | 
    
         
            +
                Raketab.schedule { run 'test', :at => 5 }.tabs.should           == '0 5 * * * test'
         
     | 
| 
      
 163 
     | 
    
         
            +
              end
         
     | 
| 
      
 164 
     | 
    
         
            +
              
         
     | 
| 
      
 165 
     | 
    
         
            +
              it "should handle multiple cron jobs" do
         
     | 
| 
      
 166 
     | 
    
         
            +
                Raketab.schedule do
         
     | 
| 
      
 167 
     | 
    
         
            +
                   run '1st', :at => "5 o'clock" 
         
     | 
| 
      
 168 
     | 
    
         
            +
                   run '2nd', :on => :thursday
         
     | 
| 
      
 169 
     | 
    
         
            +
                end.tabs.should == "0 5 * * * 1st\n0 0 * * 4 2nd"
         
     | 
| 
      
 170 
     | 
    
         
            +
              end
         
     | 
| 
      
 171 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,76 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification 
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: did_craken
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version 
         
     | 
| 
      
 4 
     | 
    
         
            +
              hash: 29
         
     | 
| 
      
 5 
     | 
    
         
            +
              prerelease: 
         
     | 
| 
      
 6 
     | 
    
         
            +
              segments: 
         
     | 
| 
      
 7 
     | 
    
         
            +
              - 0
         
     | 
| 
      
 8 
     | 
    
         
            +
              - 0
         
     | 
| 
      
 9 
     | 
    
         
            +
              - 1
         
     | 
| 
      
 10 
     | 
    
         
            +
              version: 0.0.1
         
     | 
| 
      
 11 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 12 
     | 
    
         
            +
            authors: 
         
     | 
| 
      
 13 
     | 
    
         
            +
            - Doug McInnes
         
     | 
| 
      
 14 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 15 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 16 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            date: 2011-02-14 00:00:00 +01:00
         
     | 
| 
      
 19 
     | 
    
         
            +
            default_executable: 
         
     | 
| 
      
 20 
     | 
    
         
            +
            dependencies: []
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            description: Craken is a rails plugin for managing and installing rake-centric crontab files over Capistrano.
         
     | 
| 
      
 23 
     | 
    
         
            +
            email: 
         
     | 
| 
      
 24 
     | 
    
         
            +
            - didier@nocoffee.fr
         
     | 
| 
      
 25 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            extra_rdoc_files: 
         
     | 
| 
      
 30 
     | 
    
         
            +
            - README.rdoc
         
     | 
| 
      
 31 
     | 
    
         
            +
            files: 
         
     | 
| 
      
 32 
     | 
    
         
            +
            - lib/craken.rb
         
     | 
| 
      
 33 
     | 
    
         
            +
            - lib/enumeration.rb
         
     | 
| 
      
 34 
     | 
    
         
            +
            - lib/raketab.rb
         
     | 
| 
      
 35 
     | 
    
         
            +
            - README.rdoc
         
     | 
| 
      
 36 
     | 
    
         
            +
            - spec/craken_spec.rb
         
     | 
| 
      
 37 
     | 
    
         
            +
            - spec/enumeration_spec.rb
         
     | 
| 
      
 38 
     | 
    
         
            +
            - spec/raketab_spec.rb
         
     | 
| 
      
 39 
     | 
    
         
            +
            has_rdoc: true
         
     | 
| 
      
 40 
     | 
    
         
            +
            homepage: https://github.com/latimes/craken
         
     | 
| 
      
 41 
     | 
    
         
            +
            licenses: []
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 44 
     | 
    
         
            +
            rdoc_options: 
         
     | 
| 
      
 45 
     | 
    
         
            +
            - --charset=UTF-8
         
     | 
| 
      
 46 
     | 
    
         
            +
            require_paths: 
         
     | 
| 
      
 47 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 48 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 49 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 50 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 51 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 52 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 53 
     | 
    
         
            +
                  hash: 3
         
     | 
| 
      
 54 
     | 
    
         
            +
                  segments: 
         
     | 
| 
      
 55 
     | 
    
         
            +
                  - 0
         
     | 
| 
      
 56 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 57 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 58 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 59 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 60 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 61 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 62 
     | 
    
         
            +
                  hash: 3
         
     | 
| 
      
 63 
     | 
    
         
            +
                  segments: 
         
     | 
| 
      
 64 
     | 
    
         
            +
                  - 0
         
     | 
| 
      
 65 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 66 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
            rubyforge_project: 
         
     | 
| 
      
 69 
     | 
    
         
            +
            rubygems_version: 1.4.2
         
     | 
| 
      
 70 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 71 
     | 
    
         
            +
            specification_version: 3
         
     | 
| 
      
 72 
     | 
    
         
            +
            summary: A Rails plugin for managing and installing rake-centric crontab files.
         
     | 
| 
      
 73 
     | 
    
         
            +
            test_files: 
         
     | 
| 
      
 74 
     | 
    
         
            +
            - spec/craken_spec.rb
         
     | 
| 
      
 75 
     | 
    
         
            +
            - spec/enumeration_spec.rb
         
     | 
| 
      
 76 
     | 
    
         
            +
            - spec/raketab_spec.rb
         
     |