Executing a binary gem file with unpacked gems - ruby-on-rails

I am using the gem whenever
To update the crontab, it executes the whenever command in the root directory of my application.
The trouble is: my production environment doesn't have the gem installed, so I unpacked the whenever gem into my application and running 'whenever' from my application root directory fails to find the file
How do I run the frozen gem executable from the root directory of my application?
I found that
cd #{release_path} && /usr/bin/ruby #{release_path}/script/runner #{release_path}/vendor/gems/whenever-0.4.1/bin/whenever --update-crontab #{application}
works; but this seems like the 'wrong' answer

This has the answer you're looking for:
http://www.mail-archive.com/rubyonrails-talk#googlegroups.com/msg45169.html
Finally, you usually can add gems to
the load path by doing the following
within your environment.rb:
Option 1: add gems using less ruby
code within the environment.rb file
# Add additional load paths for your
own custom dirs config.load_paths +=
%W( #{RAILS_ROOT}/extras )
Option 2: add gems using more ruby
code within the environment.rb file
Dir.glob( File.expand_path(
"#{RAILS_ROOT}/vendor/gems/*",
FILE) ).each do | gem |
$:.unshift File.join( gem, 'lib' ) end
Option 3: using a combination of
Option (1) and (2).
Read the whole message, it's quite instructive.

Related

cannot create the rspec files on windows 'rails app"

I'm running on windows 7 and I cannot install/create the rspec files and capybara which is needed to work on the assignment .
If you could finish the simple setup steps listed below and give me a link to the empty app repository so I could download to finish the assignment , I will be so gratefull to you .
by the way , I 'm getting the following errors in step 4 if someone could help . I have asked before but no one have answered ;(
Steps needed :
Create a new Rails application called todolists
Add the following specification to your Gemfile
group :test do
gem 'rspec-rails', '~> 3.0'
gem 'capybara'
end
Run the bundle command to resolve new gems
From the todolists application root directory, initialize the rspec tests using the rails generate
rspec:install command
[todolists]$ rails generate rspec:install
create .rspec
create spec
create spec/spec_helper.rb
create spec/rails_helper.rb
Add the following line to .rspec to add verbose output to test results.
--format documentation
Download and extract the starter set of bootstrap files.
1
|-- Gemfile
|-- db
| ‘-- seed.rb
‘-- spec
‘-- features
‘-- module3_action_pack_spec.rb
• overwrite your existing Gemfile with the Gemfile from the bootstrap fileset. They should be nearly identical,
but this is done to make sure the gems and versions you use in your solution can be processed by the
automated Grader when you submit. Any submission should be tested with this version of the file.
• overwrite your existing db/seed.rb file using the seeds.rb provided with the bootstrap fileset. The
bootstrap seeds.rb file contains some test data that will be useful during development and unit tests.
• add the spec/features/module3_action_pack_spec.rb file provided with the bootstrap fileset to your
todolists application. Within your application root directory, you will first need to create a corresponding
spec/features sub-directory to place the module3_action_pack_spec.rb file. This file contains tests that
will help determine whether you have completed the assignment.
6-run rspec
The problem is that rspec versions > 2.8.0 don't go well with Windows. Can you try to install an older version of rspec-rails? Include this in your Gemfile.
gem 'rspec-rails', '~> 2.8'
Run bundle install and then try
rails g rspec:install

Load gems inside scripts run from the shell outside our Rails application directory?

We have a mail gem installed in our vendor/cache directory inside a Rails application.
The script is called "test" and is not inside the Rails application directory.
#! /usr/local/rvm/wrappers/ruby-1.9.3-p194/ruby
require 'date'
require 'fileutils'
require 'openssl'
require 'yaml'
require 'mail'
require 'dalli'
I get the following error when I execute this script from outside the Rails application.
/usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require': cannot load such file -- mail (LoadError)
from /usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
I simply re-installed these gems (mail, dalli) in the standard Ruby path and it worked, but that's not ideal.
What do we need to so that these installed gems are found when we try to run this script outside of a Rails app? In other words, how do we specify the path to these gems?
Be sure that your gem are all declared in your Gemfile:
gem 'mail'
If you don't want them to be loaded by default, and load them only when needed, you can use the require statement that you are already using, and in your Gemfile add :require => false:
gem 'mail', :require => false
When you call your script from outside your Rails environment, and want to load the gems, prefix your script by bundle exec:
bundle exec my_script.rb
If you need to run your script from another location than your rails's app root, you must run:
BUNDLE_GEMFILE=/path/to/your/app/Gemfile bundle exec your_script
Keep in mind though that this may cause path issues if your script or your gems are looking for file in the path of your rails app

Ruby Gem command line tool

I am trying to build a command line ruby gem. I am using bundler to create the gem and install the gem locally. It generated the needed directories. I also was able to test that if I require my Gem I can use methods inside of it. I am trying to get the command line piece working now and can't seem to get it working. I want to be able to do something like
gemname command
Similar to how rspec works:
rspec test/whatever.rb
Any help on how to be able to execute through the command line would be great.
In order to declared the executables you have to just make a proper line in your yourgem.gemspec:
`git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
This line, along with an other useful line is generated by bundle gem yourgem command. Just execute it, and then fix the yourgem.gemspec according your needs. Put executables into bin/ folder of your gem, and all libraries, including the version, into lib/ folder.
The next step is to use the binary. When you are installing the gem into a system, the binary folder is automatically included into binary search path. So your gem is avaiable to execute from anywere. But when your gem isn't installed you are still able to simelate the case with a bundler's exec as follows:
bundle exec bin/your_exec
It picks the require librarires up from lib/ folder, and the executable will work properly.
To make sure that the executable will work, build the gem with gem build yourgem.gemspec, then install it with gem install yourgem.gem, and try.
I think the problem is that you've not commited your code yet.
Check if git ls-files -- bin/* shows you the script you want to execute.
When you commit your file, then git ls-files will return it and the spec will be able to load the script.
Checkout these blog posts:
http://robdodson.me/blog/2012/06/14/how-to-write-a-command-line-ruby-gem/
http://rubylearning.com/blog/2011/01/03/how-do-i-make-a-command-line-tool-in-ruby/
I'm not really sure what you've built so far but here are a few points of interest:
#!/usr/bin/env ruby for first line in the executable file (in the /bin folder).
chmod +x filname to make it executable
ARGV[0] Variables passed in are retrieved from ARGV[0]
s.executables << 'your_file' Add executable to gemspec
I figured this out at least for my specific issue. I just need to call out the bin command directly instead of that git ls loop. The top one works the bottom one doesn't for some reason.
spec.executables = ["toolshed"]
vs
spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }

How to run a Rails application within a gem?

I'm not sure if this sort of thing is very common, but I keep finding myself trying to create gems that are just wrappers around a Rails application.
My gem will have a generator to create a config.ru but the Rails application will live inside the gem's lib directory. I need to know how to "embed" a Rails application and configure it so that it can be run inside the gem.
For example:
$ mygem new project
mygem created a directory called "project" with the following files:
project/config.ru
project/widgets/
project/foobars/
My gem will also generate some directories that will need to be added to Rails somehow so that I can access the code in those directories from the Rails app living inside the Gem.
Any help or advice you can give me would be appreciated.
To clarify, I'm not trying to create a Rails engine, or plugin to a Rails application. I'm trying to create a fully-fledged Rails application, but package it as a gem so that a user of my gem can run the gem (the rails app) without needing to know that it's using Rails behind the scenes.
Update: Okay, I've got a little bit working now. I've created the gem and generated the rails project inside the gem's lib directory.
$ bundle gem my_gem && cd my_gem/lib
$ rails new my_gem --skip-bundle
Which leaves me with:
my_gem/
my_gem.gemspec
bin/my_gem
lib/
my_gem.rb
my_gem/
version.rb # generated by bundler
# the rails app:
app/
config/
Gemfile
...etc
Since this gem requires Rails, I started adding the gems defined in the Rails Gemfile as dependencies in the gem's Gemspec, but I'm a little confused as to how to handle the assets group in the Gemfile.
# Rails Gemfile
group :assets do
gem 'sass-rails', '~> 3.2.3'
gem 'coffee-rails', '~> 3.2.1'
gem 'therubyracer', :platforms => :ruby
gem 'uglifier', '>= 1.0.3'
end
# gemspec
Gem::Specification.new do |gem|
gem.name = "my_gem"
# ...
gem.add_dependency 'rails', '3.2.8'
gem.add_dependency 'sqlite3'
gem.add_dependency 'jquery-rails'
# how to add the assets group gems?
end
Try this and see if it helps you make progress.
Gems are just directories of files, and you can put whatever files you want into a gem.
Create:
Create a blank gem full-blown Rails project:
$ bundle gem my_gem
Then a Rails app:
$ rails new my_app --skip-bundle
Copy the Rails files into the gem:
$ cp -R my_app/* my_gem
Bundle everything into your Rails app:
$ cd my_gem
$ bundle install --binstubs --path vendor/bundle
$ cd -
Make the Rakefile have the gem tasks and the Rails setup:
#!/usr/bin/env rake
require "bundler/gem_tasks"
require File.expand_path('../config/application', __FILE__)
MyApp::Application.load_tasks
Verify that it starts:
$ rails server
Load Path:
To control where Rails looks for files, such as "external" configuration files, you can use the file config/application.rb with any directory paths like this:
# Add additional load paths for your own custom dirs
# config.load_paths += %W( #{config.root}/../customdir )
Note the ".." which means go above the Rails directory. This gives you a path relative to the gem.
If you prefer you can specify an absolute path, for example if you know the user will always keep his external files in "~/myfiles/". You can also choose to use ENV vars to send in whatever directory you want.
If you read about load path capabilties, look for lines that are shorthand for adding a directory to the front of the load path because you may want to put your external diretories first:
$:.unshift File.dirname(__FILE__)
Gem Build:
Edit my_gem.gemspec to add your own description, homepage, summary, etc. then build:
$ gem build my_gem.gemspec
Successfully built RubyGem
Name: my_gem
Version: 0.0.1
File: my_gem-0.0.1.gem
Now your Rails app is packaged as a gem.
The config.ru should be a typical Rails one. No special changes AFAIK.
When your user wants to install your app:
$ gem install my_gem
The gem will install in the user's typical gem directory. If you want to adjust this, see this page on rubygems: http://docs.rubygems.org/read/chapter/3
Crate:
You may also want to investigate the Crate project:
Crate: Packaging Standalone Ruby Applications
http://www.slideshare.net/copiousfreetime/crate-packaging-standalone-ruby-applications
Rack:
To use config.ru here is the typical Rails setup:
# Rails.root/config.ru
require "config/environment"
use Rails::Rack::LogTailer
use ActionDispatch::Static
run ActionController::Dispatcher.new
For your project, you want to require some files before Rails. You'll want to learn about the Ruby "require" and how it finds files using LOAD_PATH.
The easy way:
# Rails.root/config.ru
require_relative 'filename'
require "config/environment"
Or to put the user's custom directory up couple directory levels:
require './../../filename' # not the best for security
Or to use an absolute path, read about File.expand_path:
File.expand_path(__FILE__)
Or to use the current directory and put it on the load path:
$LOAD_PATH.unshift(File.dirname(__FILE__))
require 'filename'
Lots of choices for you to consider. Hope this helps!
What about the question, "How am I going to run the Rails application inside the gem?".
A Rails application has controllers and views to run a web server. What you need are actions to create, list, update, and destroy. Exposing these actions without a web server is essentially having such methods in a class. That's a normal standard type of gem in the first place.
So maybe your questions is really, how do I write a gem where I have ActiveRecord, and the other Rails stuff.
First, you need to make your gem dependent on the Rails gems you need. You do this in the gemspec file for your gem.
Then it really is just a matter of your gem code doing a require of the right Rails gems you need.
I'm not sure if this will help, as I read through everything and I couldn't find the motivation behind why you were doing this. One of the reasons I came up with was making something that can be used on a desktop environment. In that case you could try using something like Bowline. If you just want to provide an application that others can download and use and install themselves, then you can probably assume they can follow at least basic developer kind of instructions and you could just provide the whole app on github or as a zip file. See an example of someone else doing something similar over on Fat Free CRM's github page.

How do you unpack gems using jruby on rails 2.3?

I'm trying to unpack all the system gems to end up with a standalone Rails directory including all the rails gems and all the system gems.
I'm starting with a bare rails setup; just did a jruby -S rails and a 'generate jdbc'. I then add a config.gem 'jdbc-mysql' to environment.rb and do the jruby -S rake gems:unpack:dependencies.
After unpacking, if I do a rake I get:
no such file to load -- jdbc-mysql
Is there something else you need to do to get the jdbc gem unpacked?
I'm using jruby 1.4.0 (and moving to 1.5 is on my todo list) and rails 2.3.8.
Here is what I do:
1) Install gems to a local repository
2) Set my load environment to use a gemrc.yml file from inside the local repository
To instal gems locally do this from your project folder:
gem install {gemname} -i gems
(the "-i gems" tells rubygems to install the gem in the folder gems and the {gemname} is a placeholder for the name of the gem you want to install.)
To set your gemrc.yml make a file in the newly created gems folder called gemrc.yml with something like the following content:
http://gist.github.com/430339
Then you need to tell your app to use your local gems at startup by adding the following to your config/boot.rb
http://gist.github.com/430343
Good luck... and for extra credit you could setup the ability to install a gem if it is needed. I did this through a method called dependency which is a helper method for the require command... This function receives a name and options... This way I simply say something like: (dependency 'extlib') and it does this if it cannot require the gem.
puts gem install --config-file gems/gemrc.yml #{'-v "'+options[:version].gsub(' ','')+'"' if options[:version]} #{options[:gem] || name}

Resources