How to skip require in ruby? - ruby

Can I conditionally skip requiring a file in Ruby?
begin
require 'aws-sdk'
rescue LoadError
puts "aws-sdk gem not found"
end
namespace :db do
desc "import local postgres database to heroku. user and database name is hardcoded"
task :import_to_heroku => [:environment, "db:dump_for_heroku"] do
# code using aws-sdk gem
end
end
In the above code, can I ask Ruby not to read after rescue LoadError
I can wrap the whole code in an conditional but that is inelegant.
I tried next and return.
EDIT: added a new question at Can I conditionally skip loading "further" ruby code in the same file?. sorry. Did not ask this question properly

Maybe add an exit after the log:
begin
require 'aws-sdk'
rescue LoadError
puts "aws-sdk gem not found"
exit
end
namespace :db do
desc "import local postgres database to heroku. user and database name is hardcoded"
task :import_to_heroku => [:environment, "db:dump_for_heroku"] do
# code using aws-sdk gem
end
end
Also the abort function is to log and exit in the same call:
abort("aws-sdk gem not found")

i have rescued LoadError but i want that if LoadError is executed., further code should not be executed. In the example given, the rake task db:import_to_heroku should not be called
Then do:
begin
require 'aws-sdk'
namespace :db do
desc "import local postgres database to heroku. user and database name is hardcoded"
task :import_to_heroku => [:environment, "db:dump_for_heroku"] do
# code using aws-sdk gem
end
end
rescue LoadError
puts "aws-sdk gem not found"
end

The "top-level return" feature has been added.
It is now possible to use the return keyword at the top level, which as you say, did not work at the time the question was asked. Further discussion here.

Related

how to invoke bundler commands from within a Serverspec/RSpec test

I have a project to create a template ruby project.
I am using serverspec and want to verify the behaviour of the template.
However, using command(`rake -T`) fails. If I execute the command manually, it works as expected.
Debugging, when the test is running in Serverspec, it finds the wrong Gemfile - it is using the Gemfile from my project (.), not the generated directory (target/sample_project).
How can I invoke rake or bundler commands withing a Serverspec/Rspec test?
sample code:
require "spec_helper"
require 'serverspec'
require 'fileutils'
set :backend, :exec
set :login_shell, true
describe "Generated Template" do
output_dir='target'
project_dir="#{output_dir}/sample_project"
# Hooks omitted to create the sample_project
# and change working directory to `project_dir`
describe command('rake -T') do
its(:stdout) { should include "rake serverspec:localhost" }
its(:stdout) { should include "rake serverspec:my_app" }
end
end
Bundler has provision for running external shell commands documented here: http://bundler.io/v1.3/man/bundle-exec.1.html
Running bundler/rake tasks is possible using rspec using Bundler.with_clean_env, instead of Serverspec.
require 'bundler'
require 'rspec'
RSpec.describe "Generated Template" do
output_dir='target'
project_dir="#{output_dir}/sample_project"
around(:example) do |example|
#Change context, so we are in the generated project directory
orig_dir=Dir.pwd
Dir.chdir(project_dir)
example.run
Dir.chdir(orig_dir)
end
around(:example) do |example|
Bundler.with_clean_env do
example.run
end
end
it "should include localhost" do
expect(`rake -T 2>&1`).to include "rake serverspec:localhost"
end
end

createdb not recognized as a command when using ActiveRecord

I'm a newbie to Ruby and web development. I'm using Windows 7 64-bit with Ruby 2.0 and I have PostgreSQL 9.4 installed.
I'm trying to use ActiveRecord to create a database. I checked that my postgresql server is running and I did bundle install to make sure I had all the required gems. However, when I try to do the terminal command "bundle exec rake create:db" it tells me that "'createdb' is not recognized as an internal or external command, operable program or batch file." I also did the command with --trace but it did not provide more helpful output on what the issue is. The terminal just shows this:
C:\Users\MH\Desktop\activerecord-template> bundle exec rake db:create
Creating activerecord-template development and test databases if they don't exist...
'createdb' is not recognized as an internal or external command, operable program or batch file.
C:\Users\MH\Desktop\activerecord-template> bundle exec rake db:create --trace
**Invoke db:create (first_time)
**Execute db:create
'createdb' is not recognized as an internal or external command, operable program or batch file.
The closest thing I have found regarding this issue is located at this link: http://bobbyong.com/blog/installing-postgresql-on-windoes/. I did adjust the path of PostGreSQL as described in the link, but I still get the same createdb issue. I also uninstalled/reinstalled PostGreSQL. I can see a createdb file in the PostGreSQL directory and createdb works as a command when I use psql so I'm not sure exactly what the issue is with ActiveRecord.
This is what is in my Gemfile:
source 'https://rubygems.org'
gem 'activerecord'
gem 'pg'
gem 'rspec'
gem 'faker'
gem 'rake'
This is what is inside my Rakefile:
require 'rake'
require 'rspec/core/rake_task'
require 'active_support'
require 'active_support/core_ext'
require_relative 'config'
namespace :db do
desc "Drop, create, and migrate the database"
task :reset => [:drop, :create, :migrate]
desc "Create #{APP_NAME} databases"
task "create" do
puts "Creating #{APP_NAME} development and test databases if they don't exist..."
system("createdb #{DB_NAME} --username #{DB_USERNAME} -w --no-password && createdb #{TEST_DB_NAME} --username #{DB_USERNAME} -w --no-password")
end
desc "Drop #{APP_NAME} databases"
task "drop" do
puts "Dropping #{APP_NAME} development and test databases..."
system("dropdb #{DB_NAME} && dropdb #{TEST_DB_NAME}_test")
end
desc "Migrate the database"
task "migrate" do
ActiveRecord::Migrator.migrations_paths << File.dirname(__FILE__) + 'db/migrate'
ActiveRecord::Migration.verbose = true
ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths, nil)
end
desc "Populate the database with sample data"
task "seed" do
require APP_ROOT.join('db', 'seeds.rb')
end
end
namespace :generate do
desc "Create a database migration\n rake generate:migration NAME=create_people"
task :migration do
unless ENV.has_key?('NAME')
raise "Must specify NAME for migration, e.g. rake generate:migration NAME=create_people"
end
migration_name = ENV['NAME']
class_name = migration_name.camelize
timestamp = Time.now.strftime('%Y%m%d%H%M%S')
filename = "#{timestamp}_#{migration_name}.rb"
path = APP_ROOT.join('db', 'migrate', filename)
if File.exist?(path)
raise "ERROR! File '#{path}' already exists"
end
puts "Creating migration at #{path}"
File.open(path, 'w+') do |f|
f.write("class #{class_name} < ActiveRecord::Migration\n\tdef change\n\n\tend\nend")
end
end
end
desc 'Start IRB with application environment loaded'
task "console" do
exec "irb -r./config"
end
desc "Run the specs"
RSpec::Core::RakeTask.new(:spec)
task :default => :specs
# Will this not work?
#desc "Run the specs"
#task 'specs' do
# exec "rspec spec"
#end
This is what is inside my config.rb file:
require 'pathname'
require 'pg'
require 'active_record'
require 'logger'
## Load all files and configure the db
APP_ROOT = Pathname.new(File.expand_path(File.dirname(__FILE__)))
APP_NAME = APP_ROOT.basename.to_s
DB_PATH = APP_ROOT.join('db', APP_NAME + "_development.db").to_s
DB_NAME = APP_NAME + "_development.db"
TEST_DB_NAME = APP_NAME + "_test.db"
DB_USERNAME = 'postgres'
DB_PASSWORD =
if ENV['DEBUG']
ActiveRecord::Base.logger = Logger.new(STDOUT)
end
Dir[APP_ROOT.join('models', '*.rb')].each do |model_file|
filename = File.basename(model_file).gsub('.rb', '')
autoload ActiveSupport::Inflector.camelize(filename), model_file
end
ActiveRecord::Base.establish_connection :adapter => 'postgresql',
:database => DB_NAME,
:host => 'localhost',
:username => DB_USERNAME,
:password => DB_PASSWORD
If the terminal command "bundle exec rake create:db" produces the error "'createdb' is not recognized as an internal or external command, operable program or batch file.", this means that ActiveRecord is not able to find createdb.exe in the PostgreSQL directory.
You must append the PostgreSQL bin and lib folders to your path environment variable as described here: http://bobbyong.com/blog/installing-postgresql-on-windoes/
Do note it is important to put the bin path before the lib path or ActiveRecord will still not be able to find createdb.exe in the bin path. Also be sure to restart your command terminal so that any changes to the environment variables can take effect.

require ruby library in serverspec

I am a newbie in ruby and trying to get my hands dirty in chef. I have written a wrapper cookbook on postgresql community cookbook and wish to test it using test kitchen. Following is the spec.rb file I have written:
require 'serverspec'
require 'pg'
include Serverspec::Helper::Exec
include Serverspec::Helper::DetectOS
RSpec.configure do |c|
c.before :all do
c.path = '/sbin:/usr/sbin'
c.os = backend(Serverspec::Commands::Base).check_os
end
end
describe "Postgresql server" do
it "should connect to database" do
conn = PG::Connection.open(:dbname => "db",:user => "user1",:password => "password")
conn.status == "CONNECTION_OK"
end
end
Through this test I wish to check if the user and database have been created properly.
However this test is unable to resolve the dependency of "pg". Where do I mention this dependency in serverspec?
I have used kitchen verify [node name] to run the test.
Create the Ruby code necessary to install the gem prior to requiring it in your spec_helper.rb file (or on the top of the spec file if it makes more sense):
begin
Gem::Specification.find_by_name('pg')
rescue Gem::LoadError
require 'rubygems/dependency_installer'
Gem::DependencyInstaller.new(Gem::DependencyInstaller::DEFAULT_OPTIONS).install('pg')
end
require 'pg'

'cannot load such file -- mongoid' with rspec with ruby 2

Getting this error
cannot load such file -- mongoid
when trying to run RSpec tests.
I have mongo running in another terminal (mongod)
with ruby 2.0
I've trying including gem 'moped' and bundled but got the same error.
Trying to find out how to fix this error and run my tests.
This is for an open-source project that I've forked and am trying to update.
The test starts with:
require 'spec_helper'
begin
require 'will_paginate/mongoid' # <-- this is the issue
rescue LoadError => error
warn "Error running Sequel specs: #{error.message}"
mongoid_loaded = false
else
Mongoid.database = Mongo::Connection.new.db('will_paginate_test')
class MongoidModel
include Mongoid::Document
end
mongoid_loaded = true
end
describe...
I commented out require 'will_paginate/mongoid' but I then got uninitialized constant Mongoid (NameError)

Using raad and eventmachine in cli gem

I followed this tutorial to create a simple command-line gem and now I want to extend functionality with raad. Currently I have made the following changes after following the tutorial:
bin/zerp:
#!/usr/bin/env ruby
require 'zerp'
class Zerp
def start
Raad::Logger.debug 'zerp started'
EventMachine.run do
EventMachine.add_periodic_timer(1) do
Raad::Logger.info 'zerp is running'
end
end
end
def stop
EventMachine.stop
Raad::Logger.debug 'zerp stopped'
end
end
lib/zerp.rb:
require 'zerp/version'
require 'eventmachine'
require 'raad'
module Zerp
end
When I run the client from commandline I get the following error.
user#zenbook:~/git/zerp :) zerp
/home/user/.local/lib/ry/rubies/1.9.3-p194/lib/ruby/gems/1.9.1/gems/zerp-0.0.1/bin/zerp:5:in `<top (required)>': Zerp is not a class (TypeError)
from /home/user/.local/lib/ry/current/bin/zerp:23:in `load'
from /home/user/.local/lib/ry/current/bin/zerp:23:in `<main>'
user#zenbook:~/git/zerp :(
What is the proper approach to get this working?
This is a use-case I did not really look into when making Raad and only minor modifications will make it better integrate within a "executable" gem context. In the meantime you can use this workaround:
bin/zerp
#!/usr/bin/env ruby
begin
require 'zerp'
rescue LoadError
$:.unshift 'zerp/lib'
require 'zerp'
end
# raad must be required after the Zerp class definition
require 'raad'
zerp/lib/zerp.rb
require "zerp/version"
require "zerp/service"
zerp/lib/service.rb
require 'eventmachine'
class Zerp
def start
Raad::Logger.debug 'zerp started'
EventMachine.run do
EventMachine.add_periodic_timer(1) do
Raad::Logger.info 'zerp is running'
end
end
end
def stop
EventMachine.stop
Raad::Logger.debug 'zerp stopped'
end
end
zerp/lib/version
module ZerpModule
VERSION = "0.0.1"
end
The way Raad works right now is that since the file requiring the raad gem is "zerp" then Raad tries to bootstrap using the "Zerp" class. To avoid conflicts you should use another module name than "Zerp" - I just picked "ZerpModule".
I'll try to make a fix shortly to have Raad integrate better in a gem context.
In zerp.rb, you declare Zerp as a module, but in bin/zerp, you declare it as a class. Since it's already a module, you cannot do what you are trying to do.
I would just remove the module Zerp stuff. I would also put class Zerp etc. into zerp.rb.
Finally, in bin/zerp you need to actually call some methods. Something like this:
zerp = Zerp.new
Process.signal('SIGINT') do
zerp.stop
end
zerp.start
Not knowing what you are trying to do, that's just a guess…

Resources