How can I tell if a vendored gem is being used? - ruby-on-rails

I have inherited an old project that was previously passed on by multiple developers. It's in a bad shape so I'm trying to bring it back to life. I notice there are some gems and libs that have been vendored into the project but can't tell if they are being used or what!
How can I workout if some of those gems are no longer being used by the project?

A convenient way of checking this is by using a REPL. I would recommend installing the pry-rails gem, which will simply replace the default rails console (IRB) with the arguably more powerful Pry REPL.
#Gemfile
group :development do
pry-rails
end
Run bundle install, and than start the Rails console with bundle exec rails c. Once you are within Pry, you can use its built in show-source command to look up where a specific method has been implemented. Example:
>> show-source ActiveRecord::Base.establish_connection
From: /home/andrea/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_specification.rb # line 128:
Owner: #<Class:ActiveRecord::Base>
Visibility: public
Number of lines: 11
def self.establish_connection(spec = ENV["DATABASE_URL"])
resolver = ConnectionSpecification::Resolver.new spec, configurations
spec = resolver.spec
unless respond_to?(spec.adapter_method)
raise AdapterNotFound, "database configuration specifies nonexistent # {spec.config[:adapter]} adapter"
end
remove_connection
connection_handler.establish_connection name, spec
end
For more usage examples on how to use this specific built-in command, refer to Pry's inline help system:
help show-source
Or have a look at the Source browsing page, on Pry's wiki.

there are some simple tricks that help you do that. you could for example put an puts caller i the root files of the gems and see if they get called from somewhere.
you could also use tracing functionality built into ruby like: http://apidock.com/ruby/Kernel/set_trace_func
or use external tracing tools.

Related

Ruby on Rails: Difference between behaviour within the console / in a .rb file

I would like to use information stored within a the credentials.yml.enc file for a Rails 5.2 app. However, I am struggling to get a command which works perfectly within the console to behave in the same way when inserted into a .rb file.
In the Rails console (on my local development computer) Rails.application.credentials.username returns "my_username"
If I insert this line within a very simple db_backup.rb file as shown below, I get the error:
NameError: uninitialized constant #<Class:#<Backup::Config::DSL:0x00007fb0db941d10>>::Rails
db_backup.rb:
Model.new(:db_backup, 'Description for db_backup') do
##
# PostgreSQL [Database]
#
database PostgreSQL do |db|
db.username = Rails.application.credentials.username
end
end
Please could you explain why I get the different behaviour when using exactly the same line of code in the Rails console / within a .rb file?
The context in which the code is executed is not the same. One is the rails console and the other is the backup command
What happens when you load the Rails console
Launching the rails console means you launch all of the rails stack before executing your code against it. The Rack applications like Sinatra, Rails etc. use the config.ru file as a convention for which file should be run to boot. (You can explore the rabbit hole if you want to have a deep understanding of this)
It means that the vast majority of errors you can encounter when will occur during the console boot, preventing you from executing anything in the console (because boot failed). Instead it will print the stack trace errors for you to figure out what went wrong so you can correct and give it another try.
TL; DR Rails.application.credentials.username in console is executed after all of the Rails stack (models, dependencies, initializers) has loaded in a particular order
What happens when you run the backup command
The backup command is defined here in the bin repo of the backup repo
It goes like this
#!/usr/bin/env ruby
# encoding: utf-8
require File.expand_path("../../lib/backup", __FILE__)
Backup::CLI.start
If you open the required file lib/backup.rb and look around in the Gemfile, you won't fine a place where you have a dependency or a define for the Rails constant.
Thus when you run the backup command and execute your db_backup.rb, the constant Rails called here is ... not defined. Ruby being kind will try to find a nested version of this constant in the current scope which is the Model.new do; end block.
It is still not defined which ruby tells you about with NameError: uninitialized constant #<Class:#<Backup::Config::DSL:0x00007fb0db941d10>>::Rails.
#giglemad gives a great explanation of the issue of class resolution in the execution context (rails console vs. running of the backup ruby file).
To fix your error, just let the code know to use the top-level class lookup (::Rails):
Model.new(:db_backup, 'Description for db_backup') do
##
# PostgreSQL [Database]
#
database PostgreSQL do |db|
db.username = ::Rails.application.credentials.username
end
end
If you're still seeing the missing Rails constant, you'll need to put your script in either a rake task, or require your rails environment.
I ended up resolving this by simply adding the line below to the top of my db_backup.rb:
require './config/environment' # added to enable credentials to be read from Rails environment

Is there a way to ignore a couple lines in git?

My team and I are constantly updating our Gemfile and these 2 lines which are on line 60 and 61 in our app are constantly changing. We want them to stay the same. Is there any way we can make it so that these lines never change? but to still be able to check stuff into our Gemfile?
group :development do
gem 'ph_app', path: '/Users/joe12/Desktop/VBR/ph_app'
end
Another answer involving a separate file:
Use the contents of another file using eval. In your Gemfile, add these lines:
other_path = __dir__ + '/Gemfile.local'
eval File.read(other_path) if File.exists? other_path
A developer may create a Gemfile.local and add their custom gems there like so:
group :development do
gem 'ph_app', path: '/Users/joe12/Desktop/VBR/ph_app'
end
This version is not very intrusive (but for the extra lines in the Gemfile). It is very flexible since the local configuration is optional. No need to supply an empty file on production machines. This is a good solution if the gem 'ph_app' is optional in the development environment.
This solution is a bit similar to using a different Gemfile (see other answer) but configured with --local. But more flexible :)
Note that the entries for custom gems in Gemfile.lock will differ on a per developer basis. Developers will need to be careful when adding their changes to version control.
As requested, an answer involving an environment variable:
Use this in your Gemfile:
group :development do
gem 'ph_app', path: ENV['PH_APP_HOME']
end
And have every developer set up that environment variable in their environments. On a Linux or OSX that would typically go into ~/.bash_profile, e.g.:
export PH_APP_HOME='/Users/joe12/Desktop/VBR/ph_app'
If you run rails specific binaries from within your IDE, then you will probably have to set up the environment variable there, too.
This will not interfer on production and test environments since the :development group will not get bundled there. (You did set up those environments accordingly, right?)
Note that the respective entry in Gemfile.lock will differ on a per developer basis. Developers will need to be careful when adding their changes to version control.
As requested, an answer involving a separate file:
Use a non-default Gemfile as a developer. This is the least intrusive solution for the project but probably also the least convenient for the developers.
Create a Gemfile.custom alongside the Gemfile, containing developer specific gems:
eval File.read(__dir__ + '/Gemfile')
group :development do
gem 'ph_app', path: ENV['PH_APP_HOME']
end
The Gemfile.custom should be ignored by version control.
The eval is an ordinary Ruby instruction. Together with File.read it will cause the other file to be read and its contents be interpreted. You can use the bundler DSL in that other file without doing anything special.
Execute this from the project root to start using the alternate Gemfile:
bundle config --global gemfile Gemfile.custom
Using --global will set the value for all projects on the developer's machine (for that user). And here is why developers might not like this solution very much: Every bundled project on their machines will need a Gemfile.custom.
Alternatively, the custom Gemfile option can be supplied to a bundler command. That way, other projects will not be affected, but every bundler command will have to be amended with the option. Binstubs might make this more convenient, but I did not try that.
Note that the entries for custom gems in Gemfile.custom.lock will differ on a per developer basis. Developers will need to be careful when adding their changes to version control.
You need to use "git filters" and a combination of 'clean' and 'smudge'. The post here explains in greater detail:
How to tell git to ignore individual lines, i.e. gitignore for specific lines of code
An answer involving relative paths:
Do not let your developers decide where they want to put that other project ph_app but instead make them put it in the same directory as the host project. (Not nested but in the same parent directory.)
Then add this to the Gemfile:
group :development do
gem 'ph_app', version: '2.1.32', path: '../ph_app'
end
Note the added version string. Thanks to that, bundler will make sure that the local files actually provide the requested version of ph_app. Every developer will need to manually pull the most recent changes from version control. And they might also have to manually switch branches there as the host project switches branches. Maybe this could be alleviated by means of git triggers.
If needed in your production environment, you can supply ph_app in the same manner, there too. Then you will need to install the correct version of the gem with your deployment script. However, referring to your version control server (e.g. github) will be easier and also ensure that the two projects stay in sync.
The entry for the ph_app gem in the host project's Gemfile.lock will be the same for all developers. It will only include the version string, i.e. no commit hash. Nice and easy :)

How to deploy Rails 3 project using "Rake"?

How to deploy Rails project on live server using Rake task?
For other projects I used Capistrano deployment.But for this project I wish to use rake...if anybody guide me please ... What gem I will need to install or what is the procedure I should follow?
You already answered your question yourself:
Either you use capistrano (the recommended way) - or you write your own custom rake Tasks that do what you want.
Writing Rake tasks is nothing complicated, you simply define tasks that depend on each other for each step of your deployment and then run them.
Remember: Rake tasks are just plain Ruby and you therefore can use any Gem that suits your needs.
Only if you get a bit more detailed on what tasks you want to do during your deployment I can start recommending Gems or what Tasks you may need to write.
Article by Martin Fowler on Rake: http://martinfowler.com/articles/rake.html
Generally a Rake file looks pretty much like this:
task :default => [:test]
task :test do
# You can write regular ruby here and do anything you want
puts "Foo"
end
task :dependant => [:test] do
# This task will automatically make sure task test is run before running.
puts "Hello World"
end
Linux or windows? which is the os you are using?
you can follow this refeerence
http://guides.rubyonrails.org/command_line.html
http://www.tutorialspoint.com/ruby-on-rails/rails-and-rake.htm
Just guessing a bit.
You probably would need:
A command line options parser
A way to interact through ssh
Some linux command execution
Optionally a way to interact with git

Unable to generate rails footnote

I am trying to install debug tool called rails-footnotes on Rails 3.0 following instruction on GitHub. A check running bundle show rails-footnotes show that I got rails-footnotes-3.7.4 installed. However, when I run
rails generate rails_footnotese:install
>>Could not find generator rails_footnotese:install.
I hope someone experienced the same issue might help me out.
Thank you.
Version 3.7.4 doesn't use a generator, only the newer 3.7.5 (which hasn't been released yet) does. Also, the README has a typo; it should be rails_footnotes:install, not rails_footnotese:install (there is already a pull request to fix this).
If you want to stay on the stable 3.7.4, all the generator command does is add the config/initializers/rails_footnotes.rb file with the same content from the README:
if defined?(Footnotes) && Rails.env.development?
Footnotes.run! # first of all
# ... other init code
end
and a .rails_footnotes file with this:
#this code temporarily disables notes for all controllers
# Footnotes::Filter.notes = []
Otherwise, use the git version to make the generator work:
gem 'rails-footnotes', :git => "git://github.com/josevalim/rails-footnotes.git"

Install barista/coffeescript on Rails 2.3

I am trying to get barista up and running in a Rails 2.3 application (that may not be moved to a new version of rails for the time beeing..). I switched the app to bundle so I added the following gems to my Gemspec:
gem "barista"
gem "json"
Then executed bundle install which run through. Now as far as I understand to "compile" the coffeescript there is a rake task that comes with barista. But it doesn't seem to be installed properly so I can use it with rake. I.e. when I execute rake -T there is no barista:brew
I saw a pending pull request on git hub suggesting to add require 'barista/tasks' but that only resulted in rake not finding it. So what am I doing wrong or more general how do I get up and running with barista on Rails 2.3.x?
It has been some time ago since I used Barista and I have it not in use in any project, so I cannot verify it.
But I remember that one advantage of Barista is, that it waits serving a request until a modified CoffeeScript file is recompiled. This ensures that the browser doesn't request an outdated file.
So there is no need to compile the CoffeeScript files with a Rake task.
CoffeeScript itself comes also with a watch function, that compiles CoffeeScripts when a change is detected:
coffee -w /path/to/scripts
The reason why I stopped using Barista is simply that I discovered Guard. So I wrote guard-coffeescript to compile my CoffeeScripts in the same moment I save the file.
Guard-coffeescript has some advantages over Barista and CoffeeScript:
Fast and low CPU consumption because it relies on file system modification events.
Can be configured in many ways, e.g. multiple source folders and output folders.
Immediate feedback when an error occurs, even with system notifications like Growl.
Note that Rails 2 support for Barista is, according to Barista's README, "untested" (it was originally built for Rails 3 only), so there may be compatibility issues. Also note that you need either therubyracer gem, or the node binary on your system's PATH (or any of the other JS runtimes supported by ExecJS).
Try this:
Add a file named foo.coffee to the folder app/coffeescripts with the contents
alert 'Hello, Barista!'
Now add <%= javascript_include_tag "foo" %> to an ERB file and load that page.
You should get the alert, just as you would if the compiled foo.js were in public/javascripts.
I've successfully integrated barista and rails 2.3.14. In development, when I ask for a js file, the coffeescript file is found and compiled on the fly.
I also successfully ran the barista:brew rake task and the js files were generated.
I did notice that for production, unless I include an ExecJS compatible compiler, I need to precompile my js files before a push, which might be another +1 for the guard solution by #netzpirat.
For reference - I'm using Barista 1.3.0 and coffee-script 2.2. Not sure how that affects things, but thought it was noteworthy.
Also, I added a line to load the barista tasks in my Rakefile:
# in my Rakefile
load "barista/tasks/barista.rake"

Resources