mguymon-whenever 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +138 -0
- data/README.md +163 -0
- data/Rakefile +35 -0
- data/bin/whenever +38 -0
- data/bin/wheneverize +69 -0
- data/lib/whenever.rb +21 -0
- data/lib/whenever/capistrano.rb +33 -0
- data/lib/whenever/command_line.rb +125 -0
- data/lib/whenever/cron.rb +132 -0
- data/lib/whenever/job.rb +47 -0
- data/lib/whenever/job_list.rb +148 -0
- data/lib/whenever/output_redirection.rb +58 -0
- data/lib/whenever/setup.rb +18 -0
- data/lib/whenever/version.rb +3 -0
- data/mguymon-whenever.gemspec +83 -0
- data/test/functional/command_line_test.rb +310 -0
- data/test/functional/output_at_test.rb +251 -0
- data/test/functional/output_default_defined_jobs_test.rb +164 -0
- data/test/functional/output_defined_job_test.rb +111 -0
- data/test/functional/output_env_test.rb +23 -0
- data/test/functional/output_redirection_test.rb +307 -0
- data/test/test_helper.rb +20 -0
- data/test/unit/cron_test.rb +226 -0
- data/test/unit/job_test.rb +77 -0
- data/whenever.gemspec +85 -0
- metadata +132 -0
data/CHANGELOG.md
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
### 0.6.2 / October 26th, 2010
|
2
|
+
|
3
|
+
* --clear-crontab option completely removes entries. #63 [Javan Makhmali]
|
4
|
+
|
5
|
+
* Set default :environment and :path earlier in the new setup.rb (formerly job_types/default.rb). [Javan Makhmali]
|
6
|
+
|
7
|
+
* Converted README and CHANGELOG to markdown. [Javan Makhmali]
|
8
|
+
|
9
|
+
|
10
|
+
### 0.6.1 / October 20th, 2010
|
11
|
+
|
12
|
+
* Detect script/rails file and change runner to Rails 3 style if found. [Javan Makhmali]
|
13
|
+
|
14
|
+
* Created a new :job_template system that can be applied to all commands. Wraps all in bash -l -c 'command..' by default now for better RVM support. Stopped automatically setting the PATH too. [Javan Makhmali]
|
15
|
+
|
16
|
+
* Added a built-in Capistrano recipe. [Javan Makhmali]
|
17
|
+
|
18
|
+
|
19
|
+
### 0.5.3 / September 24th, 2010
|
20
|
+
|
21
|
+
* Better regexes for replacing Whenever blocks in the crontab. #45 [Javan Makhmali]
|
22
|
+
|
23
|
+
* Preserving backslashes when updating existing crontab. #82 [Javan Makhmali]
|
24
|
+
|
25
|
+
|
26
|
+
### 0.5.2 / September 15th, 2010
|
27
|
+
|
28
|
+
* Quotes automatically escaped in jobs. [Jay Adkisson]
|
29
|
+
|
30
|
+
* Added --cut option to the command line to allow pruning of the crontab. [Peer Allan]
|
31
|
+
|
32
|
+
* Switched to aaronh-chronic which is ruby 1.9.2 compatible. [Aaron Hurley, Javan Makhmali]
|
33
|
+
|
34
|
+
* Lots of internal reorganizing; tests broken into unit and functional. [Javan Makhmali]
|
35
|
+
|
36
|
+
|
37
|
+
### 0.5.0 / June 28th, 2010
|
38
|
+
|
39
|
+
* New job_type API for writing custom jobs. Internals use this to define command, runner, and rake. [Javan Makhmali - inspired by idlefingers (Damien)]
|
40
|
+
|
41
|
+
* Jobs < 1.hour can specify an :at. [gorenje]
|
42
|
+
|
43
|
+
* --clear option to remove crontab entries for a specific [identifier]. [mraidel (Michael Raidel)]
|
44
|
+
|
45
|
+
|
46
|
+
### 0.4.2 / April 26th, 2010
|
47
|
+
|
48
|
+
* runners now cd into the app's directory and then execute. [Michael Guterl]
|
49
|
+
|
50
|
+
* Fix STDERR output redirection to file to append instead of overwrite. [weplay]
|
51
|
+
|
52
|
+
* Move require of tempfile lib to file that actually uses it. [Finn Smith]
|
53
|
+
|
54
|
+
* bugfix: comparison Time with 0 failed. #32 [Dan Hixon]
|
55
|
+
|
56
|
+
|
57
|
+
### 0.4.1 / November 30th, 2009
|
58
|
+
|
59
|
+
* exit(0) instead of just exit to make JRuby happy. [Elan Meng]
|
60
|
+
|
61
|
+
* Fixed activesupport deprecation warning by requiring active_support. #37 [Andrew Nesbitt]
|
62
|
+
|
63
|
+
|
64
|
+
### 0.4.0 / October 20th, 2009
|
65
|
+
|
66
|
+
* New output option replaces the old cron_log option for output redirection and is much more flexible. #31 [Peer Allan]
|
67
|
+
|
68
|
+
* Reorganized the lib files (http://weblog.rubyonrails.org/2009/9/1/gem-packaging-best-practices) and switched to Jeweler from Echoe.
|
69
|
+
|
70
|
+
|
71
|
+
### 0.3.7 / September 4th, 2009
|
72
|
+
|
73
|
+
* No longer tries (and fails) to combine @shortcut jobs. #20 [Javan Makhmali]
|
74
|
+
|
75
|
+
|
76
|
+
### 0.3.6 / June 15th, 2009
|
77
|
+
|
78
|
+
* Setting a PATH in the crontab automatically based on the user's PATH. [Javan Makhmali]
|
79
|
+
|
80
|
+
|
81
|
+
### 0.3.5 / June 13th, 2009
|
82
|
+
|
83
|
+
* Added ability to accept lists of every's and at's and intelligently group them. (ex: every 'monday, wednesday', :at => ['3pm', '6am']). [Sam Ruby]
|
84
|
+
|
85
|
+
* Fixed issue with new lines. #18 [Javan Makhmali]
|
86
|
+
|
87
|
+
### 0.3.1 / June 25th, 2009
|
88
|
+
|
89
|
+
* Removed activesupport gem dependency. #1 [Javan Makhmali]
|
90
|
+
|
91
|
+
* Switched to numeric days of the week for Solaris support (and probably others). #8 [Roger Ertesvåg]
|
92
|
+
|
93
|
+
|
94
|
+
### 0.3.0 / June 2nd, 2009
|
95
|
+
|
96
|
+
* Added ability to set variables on the fly from the command line (ex: whenever --set environment=staging). [Javan Makhmali]
|
97
|
+
|
98
|
+
|
99
|
+
### 0.2.2 / April 30th, 2009
|
100
|
+
|
101
|
+
* Days of week jobs can now accept an :at directive (ex: every :monday, :at => '5pm'). [David Eisinger]
|
102
|
+
|
103
|
+
* Fixed command line test so it runs without a config/schedule.rb present. [Javan Makhmali]
|
104
|
+
|
105
|
+
* Raising an exception if someone tries to specify an :at with a cron shortcut (:day, :reboot, etc) so there are no false hopes. [Javan Makhmali]
|
106
|
+
|
107
|
+
|
108
|
+
### 0.1.7 / March 5th, 2009
|
109
|
+
|
110
|
+
* Added ability to update the crontab file non-destuctively instead of only overwriting it. [Javan Makhmali -- Inspired by code submitted individually from: Tien Dung (tiendung), Tom Lea (cwninja), Kyle Maxwell (fizx), and Andrew Timberlake (andrewtimberlake) on github]
|
111
|
+
|
112
|
+
|
113
|
+
### 0.1.5 / February 19th, 2009
|
114
|
+
|
115
|
+
* Fixed load path so Whenever's files don't conflict with anything in Rails. Thanks Ryan Koopmans. [Javan Makhmali]
|
116
|
+
|
117
|
+
|
118
|
+
### 0.1.4 / February 17th, 2009
|
119
|
+
|
120
|
+
* Added --load-file and --user opts to whenever binary. [Javan Makhmali]
|
121
|
+
|
122
|
+
|
123
|
+
### 0.1.3 / February 16th, 2009
|
124
|
+
|
125
|
+
* Added 'rake' helper for defining scheduled rake tasks. [Javan Makhmali]
|
126
|
+
|
127
|
+
* Renamed :cron_environment and :cron_path to :enviroment and :path for better (word) compatibility with rake tasks. [Javan Makhmali]
|
128
|
+
|
129
|
+
* Improved test load paths so tests can be run individually. [Javan Makhmali]
|
130
|
+
|
131
|
+
* Got rid of already initialized constant warning. [Javan Makhmali]
|
132
|
+
|
133
|
+
* Requiring specific gem versions: Chronic >=0.2.3 and activesupport >= 1.3.0 [Javan Makhmali]
|
134
|
+
|
135
|
+
|
136
|
+
### 0.1.0 / February 15th, 2009
|
137
|
+
|
138
|
+
* Initial release [Javan Makhmali]
|
data/README.md
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
### Introduction
|
2
|
+
|
3
|
+
Whenever is a Ruby gem that provides a clear syntax for writing and deploying cron jobs.
|
4
|
+
|
5
|
+
### Installation
|
6
|
+
|
7
|
+
$ gem install whenever
|
8
|
+
|
9
|
+
Or with Bundler in your Gemfile.
|
10
|
+
|
11
|
+
gem 'whenever', :require => false
|
12
|
+
|
13
|
+
### Getting started
|
14
|
+
|
15
|
+
$ cd /my/rails/app
|
16
|
+
$ wheneverize .
|
17
|
+
|
18
|
+
This will create an initial "config/schedule.rb" file you.
|
19
|
+
|
20
|
+
### Example schedule.rb file
|
21
|
+
|
22
|
+
every 3.hours do
|
23
|
+
runner "MyModel.some_process"
|
24
|
+
rake "my:rake:task"
|
25
|
+
command "/usr/bin/my_great_command"
|
26
|
+
end
|
27
|
+
|
28
|
+
every 1.day, :at => '4:30 am' do
|
29
|
+
runner "MyModel.task_to_run_at_four_thirty_in_the_morning"
|
30
|
+
end
|
31
|
+
|
32
|
+
every :hour do # Many shortcuts available: :hour, :day, :month, :year, :reboot
|
33
|
+
runner "SomeModel.ladeeda"
|
34
|
+
end
|
35
|
+
|
36
|
+
every :sunday, :at => '12pm' do # Use any day of the week or :weekend, :weekday
|
37
|
+
runner "Task.do_something_great"
|
38
|
+
end
|
39
|
+
|
40
|
+
More examples on the wiki: <http://wiki.github.com/javan/whenever/instructions-and-examples>
|
41
|
+
|
42
|
+
### Define your own job types
|
43
|
+
|
44
|
+
Whenever ships with three pre-defined job types: command, runner, and rake. You can define your own with `job_type`.
|
45
|
+
|
46
|
+
For example:
|
47
|
+
|
48
|
+
job_type :awesome, '/usr/local/bin/awesome :task :fun_level'
|
49
|
+
|
50
|
+
every 2.hours do
|
51
|
+
awesome "party", :fun_level => "extreme"
|
52
|
+
end
|
53
|
+
|
54
|
+
Would run `/usr/local/bin/awesome party extreme` every two hours. `:task` is always replaced with the first argument, and any additional `:whatevers` are replaced with the options passed in or by variables that have been defined with `set`.
|
55
|
+
|
56
|
+
The default job types that ship with Whenever are defined like so:
|
57
|
+
|
58
|
+
job_type :command, ":task :output"
|
59
|
+
job_type :rake, "cd :path && RAILS_ENV=:environment rake :task :output"
|
60
|
+
job_type :runner, "cd :path && script/runner -e :environment ':task' :output"
|
61
|
+
|
62
|
+
If a script/rails file is detected (like in a Rails 3 app), runner will be defined to fit:
|
63
|
+
|
64
|
+
job_type :runner, "cd :path && script/rails runner -e :environment ':task' :output"
|
65
|
+
|
66
|
+
If a `:path` is not set it will default to the directory in which `whenever` was executed. `:environment` will default to 'production'. `:output` will be replaced with your output redirection settings which you can read more about here: <http://github.com/javan/whenever/wiki/Output-redirection-aka-logging-your-cron-jobs>
|
67
|
+
|
68
|
+
All jobs are by default run with `bash -l -c 'command...'`. Among other things, this allows your cron jobs to play nice with RVM by loading the entire environment instead of cron's somewhat limited environment. Read more: <http://blog.scoutapp.com/articles/2010/09/07/rvm-and-cron-in-production>
|
69
|
+
|
70
|
+
You can change this by setting your own `:job_template`.
|
71
|
+
|
72
|
+
set :job_template, "bash -l -c ':job'"
|
73
|
+
|
74
|
+
Or set the job_template to nil to have your jobs execute normally.
|
75
|
+
|
76
|
+
set :job_template, nil
|
77
|
+
|
78
|
+
And you'll see your schedule.rb converted to cron sytax. Note: running `whenever` with no options does not display your current crontab file, it simply shows you the output of converting your schedule.rb file.
|
79
|
+
|
80
|
+
### Capistrano integration
|
81
|
+
|
82
|
+
Use the built-in Capistrano recipe for easy crontab updates with deploys.
|
83
|
+
|
84
|
+
In your "config/deploy.rb" file:
|
85
|
+
|
86
|
+
require "whenever/capistrano"
|
87
|
+
|
88
|
+
Take a look at the recipe for options you can set. <http://github.com/javan/whenever/blob/master/lib/whenever/capistrano.rb>
|
89
|
+
For example, if you're using bundler do this:
|
90
|
+
|
91
|
+
set :whenever_command, "bundle exec whenever"
|
92
|
+
require "whenever/capistrano"
|
93
|
+
|
94
|
+
By default, whenever runs jobs in the production environment. You can specify an environment to use in your deploy.rb file using:
|
95
|
+
|
96
|
+
set :whenever_environment, "dev"
|
97
|
+
|
98
|
+
If you are using capistrano multi-stage, and you have a rails environment for each stage, you might consider using:
|
99
|
+
|
100
|
+
set :whenever_environment do
|
101
|
+
stage
|
102
|
+
end
|
103
|
+
|
104
|
+
To configure jobs that should only run in one of your environments, you can add them in your schedule.rb like so:
|
105
|
+
|
106
|
+
case environment
|
107
|
+
when "production"
|
108
|
+
every 15.minutes do
|
109
|
+
runner "Session.expire"
|
110
|
+
end
|
111
|
+
when "staging"
|
112
|
+
every 30.minutes do
|
113
|
+
runner "Session.expire"
|
114
|
+
end
|
115
|
+
when "qa"
|
116
|
+
end
|
117
|
+
|
118
|
+
### The `whenever` command
|
119
|
+
|
120
|
+
$ cd /my/rails/app
|
121
|
+
$ whenever
|
122
|
+
|
123
|
+
This will simply show you your schedule.rb file converted to cron syntax. It does not read or write your crontab file. Run `whenever --help` for a complete list of options.
|
124
|
+
|
125
|
+
### Credit
|
126
|
+
|
127
|
+
Whenever was created for use at Inkling (<http://inklingmarkets.com>) where I work. Their take on it: <http://blog.inklingmarkets.com/2009/02/whenever-easy-way-to-do-cron-jobs-from.html>
|
128
|
+
|
129
|
+
Thanks to all the contributors who have made it even better: <http://github.com/javan/whenever/contributors>
|
130
|
+
|
131
|
+
### Discussion / Feedback / Issues / Bugs
|
132
|
+
|
133
|
+
For general discussion and questions, please use the google group: <http://groups.google.com/group/whenever-gem>
|
134
|
+
|
135
|
+
If you've found a genuine bug or issue, please use the Issues section on github: <http://github.com/javan/whenever/issues>
|
136
|
+
|
137
|
+
Ryan Bates created a great Railscast about Whenever: <http://railscasts.com/episodes/164-cron-in-ruby>
|
138
|
+
It's a little bit dated now, but remains a good introduction.
|
139
|
+
|
140
|
+
### License
|
141
|
+
|
142
|
+
Copyright (c) 2009+ Javan Makhmali
|
143
|
+
|
144
|
+
Permission is hereby granted, free of charge, to any person
|
145
|
+
obtaining a copy of this software and associated documentation
|
146
|
+
files (the "Software"), to deal in the Software without
|
147
|
+
restriction, including without limitation the rights to use,
|
148
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
149
|
+
copies of the Software, and to permit persons to whom the
|
150
|
+
Software is furnished to do so, subject to the following
|
151
|
+
conditions:
|
152
|
+
|
153
|
+
The above copyright notice and this permission notice shall be
|
154
|
+
included in all copies or substantial portions of the Software.
|
155
|
+
|
156
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
157
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
158
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
159
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
160
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
161
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
162
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
163
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
require File.expand_path(File.dirname(__FILE__) + "/lib/whenever/version")
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'jeweler'
|
8
|
+
Jeweler::Tasks.new do |gemspec|
|
9
|
+
gemspec.name = "mguymon-whenever"
|
10
|
+
gemspec.version = Whenever::VERSION
|
11
|
+
gemspec.summary = "Write your cron jobs in ruby."
|
12
|
+
gemspec.description = "Clean ruby syntax for writing and deploying cron jobs."
|
13
|
+
gemspec.email = "javan@javan.us"
|
14
|
+
gemspec.homepage = "http://github.com/mguymon/whenever"
|
15
|
+
gemspec.authors = ["Javan Makhmali"]
|
16
|
+
gemspec.add_dependency 'aaronh-chronic', '>= 0.3.9'
|
17
|
+
gemspec.add_dependency 'activesupport', '>= 2.3.4'
|
18
|
+
gemspec.add_development_dependency 'shoulda', '>= 2.1.1'
|
19
|
+
gemspec.add_development_dependency 'mocha', '>= 0.9.5'
|
20
|
+
end
|
21
|
+
Jeweler::GemcutterTasks.new
|
22
|
+
rescue LoadError
|
23
|
+
puts "Jeweler not available. Install it with: sudo gem install jeweler -s http://gemcutter.org"
|
24
|
+
end
|
25
|
+
|
26
|
+
require 'rake/testtask'
|
27
|
+
Rake::TestTask.new(:test) do |test|
|
28
|
+
test.libs << 'lib' << 'test'
|
29
|
+
test.pattern = 'test/{functional,unit}/**/*_test.rb'
|
30
|
+
test.verbose = true
|
31
|
+
end
|
32
|
+
|
33
|
+
task :test => :check_dependencies
|
34
|
+
|
35
|
+
task :default => :test
|
data/bin/whenever
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'optparse'
|
5
|
+
require 'whenever'
|
6
|
+
|
7
|
+
options = {}
|
8
|
+
|
9
|
+
OptionParser.new do |opts|
|
10
|
+
opts.banner = "Usage: whenever [options]"
|
11
|
+
opts.on('-i', '--update-crontab [identifier]', 'Default: full path to schedule.rb file') do |identifier|
|
12
|
+
options[:update] = true
|
13
|
+
options[:identifier] = identifier if identifier
|
14
|
+
end
|
15
|
+
opts.on('-w', '--write-crontab [identifier]', 'Default: full path to schedule.rb file') do |identifier|
|
16
|
+
options[:write] = true
|
17
|
+
options[:identifier] = identifier if identifier
|
18
|
+
end
|
19
|
+
opts.on('-c', '--clear-crontab [identifier]') do |identifier|
|
20
|
+
options[:clear] = true
|
21
|
+
options[:identifier] = identifier if identifier
|
22
|
+
end
|
23
|
+
opts.on('-s', '--set [variables]', 'Example: --set environment=staging&path=/my/sweet/path') do |set|
|
24
|
+
options[:set] = set if set
|
25
|
+
end
|
26
|
+
opts.on('-f', '--load-file [schedule file]', 'Default: config/schedule.rb') do |file|
|
27
|
+
options[:file] = file if file
|
28
|
+
end
|
29
|
+
opts.on('-u', '--user [user]', 'Default: current user') do |user|
|
30
|
+
options[:user] = user if user
|
31
|
+
end
|
32
|
+
opts.on('-k', '--cut [lines]', 'Cut lines from the top of the cronfile') do |lines|
|
33
|
+
options[:cut] = lines.to_i if lines
|
34
|
+
end
|
35
|
+
opts.on('-v', '--version') { puts "Whenever v#{Whenever::VERSION}"; exit(0) }
|
36
|
+
end.parse!
|
37
|
+
|
38
|
+
Whenever::CommandLine.execute(options)
|
data/bin/wheneverize
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# This file is based heavily on Capistrano's `capify` command
|
4
|
+
|
5
|
+
require 'optparse'
|
6
|
+
require 'fileutils'
|
7
|
+
|
8
|
+
OptionParser.new do |opts|
|
9
|
+
opts.banner = "Usage: #{File.basename($0)} [path]"
|
10
|
+
|
11
|
+
begin
|
12
|
+
opts.parse!(ARGV)
|
13
|
+
rescue OptionParser::ParseError => e
|
14
|
+
warn e.message
|
15
|
+
puts opts
|
16
|
+
exit 1
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
if ARGV.empty?
|
21
|
+
abort "Please specify the directory to wheneverize, e.g. `#{File.basename($0)} .'"
|
22
|
+
elsif !File.exists?(ARGV.first)
|
23
|
+
abort "`#{ARGV.first}' does not exist."
|
24
|
+
elsif !File.directory?(ARGV.first)
|
25
|
+
abort "`#{ARGV.first}' is not a directory."
|
26
|
+
elsif ARGV.length > 1
|
27
|
+
abort "Too many arguments; please specify only the directory to wheneverize."
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
content = <<-FILE
|
32
|
+
# Use this file to easily define all of your cron jobs.
|
33
|
+
#
|
34
|
+
# It's helpful, but not entirely necessary to understand cron before proceeding.
|
35
|
+
# http://en.wikipedia.org/wiki/Cron
|
36
|
+
|
37
|
+
# Example:
|
38
|
+
#
|
39
|
+
# set :output, "/path/to/my/cron_log.log"
|
40
|
+
#
|
41
|
+
# every 2.hours do
|
42
|
+
# command "/usr/bin/some_great_command"
|
43
|
+
# runner "MyModel.some_method"
|
44
|
+
# rake "some:great:rake:task"
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# every 4.days do
|
48
|
+
# runner "AnotherModel.prune_old_records"
|
49
|
+
# end
|
50
|
+
|
51
|
+
# Learn more: http://github.com/javan/whenever
|
52
|
+
FILE
|
53
|
+
|
54
|
+
file = 'config/schedule.rb'
|
55
|
+
base = ARGV.shift
|
56
|
+
|
57
|
+
file = File.join(base, file)
|
58
|
+
if File.exists?(file)
|
59
|
+
warn "[skip] `#{file}' already exists"
|
60
|
+
elsif File.exists?(file.downcase)
|
61
|
+
warn "[skip] `#{file.downcase}' exists, which could conflict with `#{file}'"
|
62
|
+
elsif !File.exists?(File.dirname(file))
|
63
|
+
warn "[skip] directory `#{File.dirname(file)}' does not exist"
|
64
|
+
else
|
65
|
+
puts "[add] writing `#{file}'"
|
66
|
+
File.open(file, "w") { |f| f.write(content) }
|
67
|
+
end
|
68
|
+
|
69
|
+
puts "[done] wheneverized!"
|