automatically load project's environment to irb - ruby-on-rails

Rails has useful command rails console, which downloads all necessary data and then we can interact with rails project in irb. Is there the same technique for Ruby project (built on Ruby language)? By this trick I can play with Ruby project in the irb without concerning about loading libraries, modules, classes, files and so on.
Thanks

Your project should have one file which loads the environment. Assuming your project is in lib/project.rb then simply:
$ irb -Ilib -rproject

From one of my projects:
# Creates an IRB console useful for debugging experiments
# Loads up the environment for the condition passed
def console
File.open("./tmp/irb-setup.rb", 'w') do |f|
f.puts "# Initializes the environment for IRb."
f.puts "Code to initialize your project here"
f.puts "$: << '#{File.expand_path(".")}/'" #handle load path
end
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
# require your code
libs = " -r irb/completion"
libs << " -r #{File.dirname(__FILE__) + "/base"}"
libs << " -r ./tmp/irb-setup.rb" # require the config file you just wrote
puts "Loading #{#options.env} environment..."
exec "#{irb} #{libs} --simple-prompt"
end
The trick is that you construct the irb command to autorequire all the code you need. I also needed to set up some configuration so I add the magick of writing a file I then require in IRb.

In my case my initialization script was in the current working directory. The below worked for me.
irb -r ./setup.rb

Related

How add ruby file to Rails application and make it auto-loadable/executable on Rails app start?

I am trying to add some external non-rails services to my JRuby Rails application (from another framework).
I want to run a Ruby file in the context of my Rails Application and make it auto-loadable/executable on Rails app start.
I didn't find the answer on Stackoverflow yet, the closest I have found so far is the suggestion to use rake tasks.
But i want it to be something like this:
In my
/app
directory besides controllers, models, views folders
I want to have something like:
/app/services
and in this services folder to have some
service_a.rb
service_b.rb
service_c.rb
so that when I start the Rails application, RAILS autoload those files from /services folder and executes them.
I have read this http://guides.rubyonrails.org/autoloading_and_reloading_constants.html
But it didn't help, it was just naming conventions and name space constants.
I want to have in my rails app something like entrypoint (like in C / Java) from where I load and execute some additional logic, that doesn't belog to rails (Vertx.io verticles deployment)
or to have some app.rb "main Class, method" from where I would load my /services and execute them
# app.rb
require 'vertx/vertx'
vertx = Vertx::Vertx.vertx()
# deploy verticles or vertx.deploy_verticle("verticles/myverticle.js")
puts " ##### I am about to deploy verticles! "
vertx.deployVerticle("verticles/listener.rb")
puts " verticle listener.rb has been deployed i think"
vertx.deployVerticle("verticles/sender.rb")
puts " verticle sender.rb has been deployed i think"
UPDATE
thank you for suggesting the configs of application.rb
I have just configured it the way you suggested:
# /config/application.rb
require File.expand_path('../boot', __FILE__)
require 'rails/all'
Bundler.require(*Rails.groups)
module Workspace
class Application < Rails::Application
config.active_record.raise_in_transactional_callbacks = true
config.autoload_paths += Dir["#{config.root}/app/services/*"]
end
end
Then I have created the directory /app/services
Placed 2 files in there: service_a.rb and service_b.rb
I just want to make sure that the code in service_a.rb gets exectued.
So that I for example print stuff out to console.
My service_a.rb:
# service_a.rb
puts "Service A has been exectued FROM PUTS method from services/service_a.rb "
class ServiceA
def service_a_method
puts " Service_A_METHOD has been exectued from services/service_a.rb ServiceA CLASS "
end
end
def stand_alone_service_a_method
puts " stand_alone_service_a_method has been just exectued !!! "
end
stand_alone_service_a_method()
Then i go ahead and run bin/rails server
(I am using C9.IO cloud 9 web IDE and ubuntu container with rails 4.2)
javajedi:~/workspace $ bin/rails s
=> Booting WEBrick
=> Rails 4.2.5 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
[2017-03-25 16:07:25] INFO WEBrick 1.3.1
[2017-03-25 16:07:25] INFO ruby 2.3.0 (2015-12-25) [x86_64-linux]
[2017-03-25 16:07:25] INFO WEBrick::HTTPServer#start: pid=2413 port=3000
but as you see, nothing gets printed out to console. Is that that i haven't set up ENV to be DEV so that it allows that stuff to be printed in console?
I just wanna be sure that my code gets exectued.
Because I am gonna deploy Vertx.io Verticles via such small services files.
Please advice what do I do wrong?
You need to add the sub directory in application.rb
config.autoload_paths += Dir["#{config.root}/app/services/*"]

How to set up a file that I can run through my command line?

I am using Sublime Text and Ruby on Rails. Everything is installed.
How do I set up a file like random.rb
that I can navigate to in my git bash and run its contents.
The main reason I want to do this is to play with classes, methods and functions and see their outputs. IRB is not enough for when I want to build entire functions, etc.
How would I go about achieving this?
First example: simply run your Ruby code from the IRB prompt:
$ irb
> puts 'playing in irb prompt'
Second example: write your Ruby code to a ".rb" file and run it by using ruby file_name.rb:
#test.rb
puts 'Hello World'
$ ruby test.rb
-> "Hello world"
Third example: from Rails' console, you can run your .rb file:
$ rails console
$ eval(File.read 'test.rb')
-> 'Hello world'
#make sure your test.rb file resides in your project root directory.
Fourth example: use rails console to interact with your application model:
$ rails console
$ User.all #depending on what model you have.

Rails + Capybara-webkit – javascript code coverage?

I am looking into using capybara-webkit to do somewhat close-to-reality tests of app. This is absolutely neccessary as the app features a very rich JS-based UI and the Rails part is mostly API calls.
The question is: is there any tools to integrate into testing pipeline which could instrument Javascript code and report its coverage? The key here is the ability to integrate into testing workflow (just like rcov/simplecov) easily – I don't like the idea do it myself with jscoverage or analogue :)
Many thanks in advance.
This has now been added to JSCover (in trunk) - the related thread at JSCover is here.
I managed to get JSCover working in the Rails + Capybara pipeline, but
it did take quite a bit of hacking to get it to work
These changes are now in JSCover's trunk and will be part of version 1.0.5. There's working examples (including a Selenium IDE recorded example) and documentation in there too.
There is some additional work needed to get the branch detection to
work since that uses objects that cannot be easily serialized to JSON
This is a function to do this which is used in the new code.
Anyway, the end result works nicely
I agree. This makes JSCover useable by higher level tools that don't work well with iFrames or multiple windows which are avoided by this approach. It also means code coverage can be added to existing Selenium tests with two adjustments:
Make the tests run through the JSCover proxy
Save the coverage report at the end of the test suite
See JSCover's documentation for more information. Version 1.0.5 containing these changes should be released in a few days.
Update: Starting from JSCover version 1.05 the hacks I outlined in my previous answer are no longer needed. I've updated my answer to reflect this.
I managed to get JSCover working in the Rails + Capybara pipeline, but it did take some hacking to get it to work. I built a little rake task that:
uses the rails asset pipeline to generate the scripts
calls the java jar to instrument all the files and generate an empty report into a temp dir
patches the jscover.js script to operate in "report mode" (simply add jscoverage_isReport=true at the end)
copies the result to /public/assets so the tests pick it up without needing any changes and so the coverage report can be opened automatically in the browser
Then I added a setup task to clear out the browser's localStorage at the start of the tests and a teardown task that writes out the completed report at the end.
def setup
unless $startup_once
$startup_once=true
puts 'Clearing localStorage'
visit('/')
page.execute_script('localStorage.removeItem("jscover");')
end
end
def teardown
out=page.evaluate_script("typeof(_$jscoverage)!='undefined' && jscoverage_serializeCoverageToJSON()")
unless out.blank? then
File.open(File.join(Rails.root,"public/assets/jscoverage.json"), 'w') {|f| f.write(out) }
end
end
Anyway, the end result works nicely, the advantage of doing it this way is that it also works on headless browsers so it can also be included in CI.
*** Update 2: Here is a rake task that automates the steps, drop this in /lib/tasks
# Coverage testing for JavaScript
#
# Usage:
# Download JSCover from: http://tntim96.github.io/JSCover/ and move it to
# ~/Applications/JSCover-1
# First instumentalize the javascript files:
# rake assets:coverage
# Then run browser tests
# rake test
# See the results in the browser
# http://localhost:3000/assets/jscoverage.html
# Don't forget to clean up instrumentalization afterwards:
# rake assets:clobber
# Also don't forget to re-do instrumentalization after changing a JS file
namespace :assets do
desc 'Instrument all the assets named in config.assets.precompile'
task :coverage do
Rake::Task["assets:coverage:primary"].execute
end
namespace :coverage do
def jscoverage_loc;Dir.home+'/Applications/JSCover-1/';end
def internal_instrumentalize
config = Rails.application.config
target=File.join(Rails.public_path,config.assets.prefix)
environment = Sprockets::Environment.new
environment.append_path 'app/assets/javascripts'
`rm -rf #{tmp=File.join(Rails.root,'tmp','jscover')}`
`mkdir #{tmp}`
`rm -rf #{target}`
`mkdir #{target}`
print 'Generating assets'
require File.join(Rails.root,'config','initializers','assets.rb')
(%w{application.js}+config.assets.precompile.select{|f| f.is_a?(String) && f =~ /\.js$/}).each do |f|
print '.';File.open(File.join(target,f), 'w') {|ff| ff.write(environment[f].to_s) }
end
puts "\nInstrumentalizing…"
`java -Dfile.encoding=UTF-8 -jar #{jscoverage_loc}target/dist/JSCover-all.jar -fs #{target} #{tmp} #{'--no-branch' unless ENV['C1']} --local-storage`
puts 'Copying into place…'
`cp -R #{tmp}/ #{target}`
`rm -rf #{tmp}`
File.open("#{target}/jscoverage.js",'a'){|f| f.puts 'jscoverage_isReport = true' }
end
task :primary => %w(assets:environment) do
unless Dir.exist?(jscoverage_loc)
abort "Cannot find JSCover! Download from: http://tntim96.github.io/JSCover/ and put in #{jscoverage_loc}"
end
internal_instrumentalize
end
end
end

How to run a .rb file from IRB?

I am starting out with Ruby on Rails. I am currently going through a tutorial where it says that I have to run a .rb file from IRB and that that will create a .xml file in my current directory.
My question is how do I run a .rb file in IRB?
And do I have to be in the directory where this .rb file lives when I run it in IRB?
I tried the following: just typing irb on the command line in the directory of the file. That starts an IRB session as far as I understand.
Then I typed irb "filename.rb" which went through but didn't create anything in the current directory but at least it didn't give any errors.
I also tried a whole bunch of other stuff that plain gave me errors. So I don't think I can solve this myself and googling the matter didn't help at all.
I am running Leopard.
You can "run" a file in irb by just requiring or loading it.
$ irb
>> load './filename.rb'
To change your current working directory within irb, you can use FileUtils:
>> require 'fileutils'
>> FileUtils.pwd # prints working directory
>> FileUtils.cd '/path/to/somewhere' # changes the directory
In case you want to have your file loaded in the irb session and you are using Ruby 2+ you can load a file in irb like this:
irb -r ./the_name_of_your_file.rb
This opens an irb session with the given file loaded.
Imagine you have file with a class like this:
class Example
def initialize(name)
#name = name
end
def print__example
p name
end
end
You will be able to use the Example class in the irb session.
We can just create a .rb file in the directory which you are currently working in using any text editor and type all the code in that and then use the command ruby filename.rb in the terminal, not in the irb, then it shows the output in irb.

Executing Ruby script in an Rails application

I can run the following commands in the console for my Rails application and import CSV file into my database.
require 'csv'
# row will be an array with the fields in the order they appear in the file
CSV.open('myfile.csv', 'r') do |row|
# assuming the fields in the CSV file are in order npa, nxxFrom, nxxTo, trnk
# create and save a Trunk model for each row
Trunk.create!(:npa => row[0], :nxxFrom => row[1], :nxxTo => row[2], :trnk => row[3])
end
However I'd like to facilitate the process by just creating a script for it. The problem is I don't know how to write a script that is application specific. In order for the above commands to run, I need to launch console in the application folder by the following:
ruby script/console
So simply copy/pasting the commands into an .rb file and executing won't work.
Any help will always be appreciated :)
Why not use script/runner "<code or filename here>? to run the script? The runner script executes the script in the give application context without having a console.
You could make it a rake task which inherits from environment. Place it into lib/tasks/your_task.rake:
task :your_task => :environment do
# code goes here
end
Then run it using rake your_task. It can be called anything you want.
You need to invoke the rails environment in the script.
Try adding this at the top of you file:
RAILS_ENV = ARGV[0] || "production"
require File.join(File.dirname(__FILE__), *%w[.. config environment])
# assumes script is placed one level below the root of the application
# second parameter is the relative path to the environment directory of your rails app

Resources