Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Improves detection of whether a Rake task is defined or not #34

Closed
wants to merge 1 commit into from

4 participants

@gabrielg

We ran into this earlier today. A Rails 3 application with a Rakefile that isn't broken gives the following output during a push:

...
       Cleaning up the bundler cache.
-----> Writing config/database.yml to read from DATABASE_URL
-----> Preparing app for Rails asset pipeline
       Running: rake assets:precompile
       Asset precompilation completed (14.48s)
-----> Rails plugin injection
       Injecting rails_log_stdout
...

However, a Rails 3 app with a Rakefile that raises an exception on load causes the asset precompilation to silently fail:

...
       Cleaning up the bundler cache.
-----> Writing config/database.yml to read from DATABASE_URL
-----> Rails plugin injection
       Injecting rails_log_stdout
...

I've patched the buildpack to check for defined Rake tasks in a different manner. If checking for a Rake task fails because of an exception, and not because the task is undefined, the push is aborted (I raised "Bad Rakefile" in this instance):


       Cleaning up the bundler cache.
-----> Writing config/database.yml to read from DATABASE_URL
 !
 !     rake aborted!
 !     Bad Rakefile
 !     
 !     (See full trace by running task with --trace)
 !
 !     Heroku push rejected, failed to compile Ruby/rails app
@gabrielg gabrielg Better checking for existence of Rake tasks
With the current setup, a broken Rakefile will cause all tasks to be
considered undefined. This silently fails under most situations, for
example, pushing a Rails 3 app with a broken Rakefile will cause
asset precompilation to not work, with no error during the push.
a37a82a
@jodell jodell referenced this pull request
Closed

No indicator that Rake failed #9

@schneems
Owner

From the Rake docs

    -P, --prereqs                    Display the tasks and dependencies, then exit.

Seems good. Though I would probably want to generalize that call so that it stored all rake tasks available much like the gem_bundled? method works. This way there would be no additional time penalty for checking the existence of rake tasks, should we add some later down the road. This would also assume that all rake tasks would be available after running the initial bundle install

I like the idea of using -p was --dry-run incorrectly reporting that a task was present in a Rakefile with errors?

@gabrielg

Close. Using --dry-run reports tasks aren't present in a Rakefile with errors, versus indicating that the Rakefile itself is broken. A symptom of this is that things like asset precompilation just silently fail, leading to a broken deploy, when the desired behaviour is likely to just halt the deploy entirely.

@hone
Owner

Had to fix a few things around Ruby 1.8.7, but looks good. Thanks and merged!

@hone hone closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Aug 30, 2012
  1. @gabrielg

    Better checking for existence of Rake tasks

    gabrielg authored
    With the current setup, a broken Rakefile will cause all tasks to be
    considered undefined. This silently fails under most situations, for
    example, pushing a Rails 3 app with a broken Rakefile will cause
    asset precompilation to not work, with no error during the push.
This page is out of date. Refresh to see the latest.
Showing with 7 additions and 1 deletion.
  1. +7 −1 lib/language_pack/ruby.rb
View
8 lib/language_pack/ruby.rb
@@ -538,7 +538,13 @@ def lockfile_parser
# @param [String] the task in question
# @return [Boolean] true if the rake task is defined in the app
def rake_task_defined?(task)
- run("env PATH=$PATH bundle exec rake #{task} --dry-run") && $?.success?
+ task_check = "rake -p 'Rake.application.load_rakefile; Rake::Task.task_defined?(ARGV[0])' #{task}"
+ out = run("env PATH=$PATH bundle exec #{task_check}")
+ if $?.success?
+ out.strip == "true"
+ else
+ error(out)
+ end
end
# executes the block with GIT_DIR environment variable removed since it can mess with the current working directory git thinks it's in
Something went wrong with that request. Please try again.