What is the purpose of Rake? - ruby

I know Rake stands for Ruby Make, and I know Make is a unix build utility. Now, I come from working in Xcode building iPhone apps to Ruby, so I have never used Make before, and the only time I use rake is when in rails or installing some third party package and I type a command like rake db:migrate. The things I don't understand are ... What exactly is a build utility? What is the purpose of rake? What does it let me do? So if anyone can help answer any of these questions for me, it would be much appreciated.

Rake lets you script certain tasks on a per-project basis, much as a Makefile allows a Unix developer to script their compile and build process. The defined tasks you've used Rake with so far were included with the packages they came with (e.g. rake db:migrate comes with Rails, or at least with ActiveRecord) and automate certain tasks related to those packages (e.g. installing required gems for a Rails project).
If your project has certain tasks which are performed repeatedly, you can write a rake task to run those tasks which gets included in the SCM tree for the project and runs in the context of that project; in Rails they're in lib/tasks. You could write a Rake task to purge stale session records from your database, for example, and then set up a cron job to run it.

Related

How to run unit tests before building a ruby gem?

I am developing a gem and I have my unit tests in lib/spec directory. Currently I manually run unit tests using rspec lib/spec. And then I build gem using gem build mygem.gemspec (which builds a .gem file).
How can I run my unit tests along with gem build command? (Just like how we do production builds using npm)
If you have a build process that consists of multiple tasks (e.g. testing, creating a gem, publishing a gem), and has dependencies between those tasks (e.g. the gem should only be created if the tests are successful, in order to publish the gem, it needs to be created first), you can use a build tool to automate that.
Actually, build tools can be used for much more than just building, which is why some people prefer the term task-oriented programming or (my personal favority) dependency-oriented programming for that.
The most famous of such dependency-oriented programming tools is probably make. If you are familiar with the Java ecosystem, you probably know Apache Ant and Gradle. In the Microsoft world, there is the Microsoft Build Engine (MSBuild). From the ECMAScript ecosystem, you may know Grunt or Gulp. The hot new kid on the block is Google's Bazel.
Ruby also has its own share of such tools, the most widely-used one is Rake.
A lot of Ruby libraries and tools come with their own ready-made Rake Tasks, so that you don't have to write them yourself. For your particular use case, for example, there are ready-made tasks for building gems and for running RSpec tests.

Automatically test when building gem

I don't like to run my tests every time I build my code, since the code itself is slow to run. However, I semi-frequently package it into a gem so I can send it to my co-workers. Is there a nice way (ideally within the .gemspec file) to automatically run my tests?
I've seen the test_files attribute in some people's gemspec code, is this intended for use by the installer?

In order to get my Gem published, do I absolutely need to write tests?

I would like to publish a Gem I wrote so it can be installed by users via gem install my-gem. The RubyGems guide on how to Make Your Own Gem has a section on using Test::Unit and rake to test my code.
Writing tests is going to add significant development time to a Gem that (in this case) is somewhat trivial in nature. I'd like to avoid it if possible.
Is it necessary to write tests in order to publish a Gem or just a suggestion?
It is a (good) suggestion, and is in no way required to publish a gem.

When packaging gems with an application, can one run the application one another computer with only installing the correct ruby version?

I have a ruby application I would like to package and distribute. The application is dependent on a few gems. This is a question about user experience.
I want the user to be able to download a folder and run my application. At most, the user will have to download and install the correct version of Ruby as a requirement.
Will running 'bundle package' be enough to cover the gem dependencies?
I have also explored bundling the running environment with ocra but I think that is over kill and to much of a knock on performance.

How do I enable the asset pipeline in a Rails project I upgraded to 3.1 from an old version?

I assume this would be the same as enabling the asset pipeline in a project that was created --skip-sprockets - I could be mistaken.
I'm trying to run rake assets:precompile to test, and right now, since I've already added require 'sprockets/railtie' to my config/application.rb - it finds the task at least - but it says:
no such table: app_configs
Update: I've discovered that this error is coming from a model in our application called AppConfig - so I'm looking into that part. I don't know why it only happens when running this rake task...
Update: It seems that this particular rake task is assuming I'm in the production environment, even though I'm in my development environment. Other rake tasks don't seem to have this problem... ? It shows that the task it's actually running is: /home/.../bin/rake assets:precompile:all RAILS_ENV=production RAILS_GROUP=assets
So it makes sense that it's not finding the table, because it's looking in the wrong database (probably one that doesn't even exist). But how is it determining (incorrectly) that it's in a production environment?
As it turns out:
I did have the asset pipeline setup almost correctly: all you have to do is run rake rails:update to make sure your project files are all updated to be compatible with your current Rails gem (3.1.x). It will warn you when it's going to overwrite files and you can view the changes and edit the file yourself (there's no merge option unfortunately). These changes include several configuration directives specific to the asset pipeline (in the config directory).
One special problem I encountered is addressed by this post: How to build task 'assets:precompile'
- (I was not requiring rails/all, so I had to add the sprockets require)
After doing all this is when I ran into the production environment problem. The assets:precompile task intentionally uses the production environment so that it produces production-ready assets; if you use the development environment it compiles assets according to the configuration in environments/development.rb which generally doesn't include digest urls. So that's intentional - the problem then is that when it initializes the production environment, it's trying to access a database that doesn't exist in the dev environment. The way to get around that (for testing purposes) is to add this to your config/application.rb file:
config.assets.initialize_on_precompile = false
This prevents it from initializing the app and voila, no more initialization errors during asset pre-compilation :) However: There's no reason to leave this set to false, unless you intend to precompie all your assets in a non-production environment for some reason (like Heroku does) rather than allowing Capistrano or some other deployment tool to compile them in production when deploying the app. initialize_on_precompile actually lets you use models and other application resources in your asset templates, which can be a useful feature.
Another helpful post: Upgrading from Rails 3 to Rails 3.1

Resources