I'm developing a GEM that I've forked and I'm trying to modify it slightly for my app.
I'm finding it difficult and time consuming because for every change I make I have to
uninstall
build
re-install
run the app
Is there an easier way of which doesn't require repeating all steps above?
To use it in some app using bundler
If what you mean is for using it in a app to test it / use it, you can just specify a path for your gem or even point to a git repo in the Gemfile http://gembundler.com/gemfile.html
Like
gem "mygem", :path => "~/code/gems/mygem"
To use it as a standalone gem. i.e: like rspec or rake that can run outside of an app.
Just specify the path to your gem binary when running the gem command, like:
$ ~/path_to_my_gem/bin/mygem some args
If you can execute inside your gem directory (i.e: the command does not create files in the current directory, or needs any specific files from the current directory), just do this:
$ ./bin/mygem some args
Note that this last one is just for future reference, I think it's not applicable in the OP context.
use require_relative to include your files:
require_relative 'yourgem/yourclass'
This is the documentation for the function.
Related
I've been using a Ruby package which I installed as a gem. Now I'd like to modify the code, to try my hand at fixing bugs/adding features. I can download the source for the package from GitHub, however, I'm not sure what to do next.
Is there an easy way I can replace a particular gem with code from a local source directory? Ideally, the process would be simple enough that I'd be able to continuously update as I modify the code.
Also, this package is used as a dependency for other gems, and ideally the other packages which use this gem would then use the updated version. (As the program I'm ultimately running is from one of those other gems.) Is there a way to do the install without also installing those other packages from source?
(This would be on Linux, if it makes things easier.)
Assuming your using bundler you can set this in your Gemfile. If your not sure your using bundler look in the root of your project. There should be one file called Gemfile with no extension. The presence of this file will generally indicate that the project's author is using bundler. All changes described below should be made inside that file.
The :path and :git keys in the gem hashmap can be used to point rubygems to different locations. When I am using :path I will have two different ruby projects. The first project is the active project. The project that I am currently working on. This project requires the gem in question that I need to update. The second project will the the checked out source code of the gem I wish to change. With these two projects setup I can edit the Gemfile of the first project and point it at the second project. This is done using :path.
# The Gemfile of the first project
gem 'the_gem_in_question', :path => '/the/path/to/the/second/project'
There are two ways to modify these files and have the changes show up.
One is using the Gemfile to define a path. For example if you wanted the redis gem locally, you can git clone git#github.com:redis/redis-rb.git then as Stewart pointed above, put it into your Gemfile this line gem 'redis', :path => './pathtoredis/redis' instead of gem 'redis'
Another way, which is a little quicker but harder to track changes and stuff is to just gem open redis to open it in a text editor.
I want to ship a ruby script and not ask the end consumer to run gem install or some bundler command. I just wants him to open the zip and run my script.
I understand that I will need to bundle my gems inside my zip but I am not sure how it can be achieved.
Today I am using bundler with the following .bundle/config:
---
BUNDLE_PATH: lib/vendor/bundle
BUNDLE_DISABLE_SHARED_GEMS: '1'
BUNDLE_FROZEN: '1'
and I do some nasty manipulation on library search path, in the beginning of my script:
$:.unshift File.dirname(__FILE__) + "/vendor/bundle/ruby/2.0.0/gems/colored-1.2/lib"
To conclude, What is the right way to create a statically linked (without external dependencies) ruby shippable script?
You're on the right track. You might want to look at bundle install --standalone, which generates a file that does all of the necessary load path manipulation.
http://myronmars.to/n/dev-blog/2012/03/faster-test-boot-times-with-bundler-standalone
I am writing a Ruby script designed to run from the command line. The script has a corresponding RSpec file that verifies its functionality. The folder structure is:
./main_script.rb
./spec/main_script_spec.rb
Running rspec spec in the top level directory works as expected. Test results from the ./spec/main_script_spec.rb file are shown. I'd like to avoid running this manually every time I change either the main script file or the spec file. All my search results turn up things like guard which (as far as I can tell) are all designed for Rails apps.
How do I setup RSpec to watch for script or spec changes and run automatically with non-Rails Ruby code?
Like David said, Guard can be used to watch a wide variety of files and perform actions when those files are modified. It does not have to be used with a Rails app. I have set up something similar in the past using guard. Here is what I did:
Place the following in your Gemfile:
source 'https://rubygems.org'
gem 'guard'
gem 'guard-shell'
gem 'rspec'
gem 'rb-fsevent', '~> 0.9'
Then run:
$ bundle install
Create a Guardfile in your home directory with:
$ guard init
In the Guardfile, comment out the examples and add this:
guard :shell do
watch(%r{^*\.rb}) { `bundle exec rspec spec/` }
end
This tells guard to watch for modifications to any ruby files in the directory and execute the command bundle exec rspec spec/ when they change (the backticks are used to execute the command in the shell).
Then open up a new terminal window in your current directory and start a guard server to start watching the files:
$ bundle exec guard
Now your Rspec test suite should automatically run when you modify ruby files in the directory.
I used guard at the past, but now I'm using a combination of rspec focus feature and watch command.
It's very simple, just add an f before a describe of it block you want to run the test. So it would becomes fdescribe or fit block. This is the same as adding a tag :focus => true to your block.
We can then filter specs with the focus tag: rspec -t focus
Now, to keeping running theses specs (every 0.5 seconds) with focus tag we call it with watch command:
watch -n 0.5 rspec -t focus
But with that the output won't show colors. So, we need to use with unbuffer.
sudo apt-get install expect
With a little customization:
watch -n 0.5 --color 'unbuffer bundle exec rspec -t focus'
Since it's annoying to type this all, I made two alias at my ~/.bash_aliases file (your can use .bashrc as well):
alias focus="watch -n 0.5 --color 'unbuffer bundle exec rspec -t focus'"
alias focuss="bundle exec rspec -t focus"
Now I can type focus to keep running it, or for a single focus execution I type focuss
Guard can be used for plain old ruby. I generally have trouble with guard so I like to use watchr, another gem. With a few lines of code you can tell watchr to watch for changes to your files and run a command when they change.
For an example of guard with plain ruby, see the shuhari gem.
update on watchr gem: There appears to be an issue with this gem, perhaps with versions of ruby >= 2.0. The observr gem addresses this issue and works as expected in ruby 2.3.
I have used guard and the guard-rspec addition with great results, and I don't believe it to be Rails-specific. Other Ruby/RSpec projects should work equally well.
The guard documentation recommends the use of Bundler and to "always run Guard through Bundler to avoid errors". I.e. you install it through your Gemfile and always run it with bundle exec guard (or use rubygems-bundler to avoid the bundle exec part).
I'm working on a console ruby application (not rails!) I will be installing this application on several machines. I was wondering if there is a way i can build it so i dont have to install the gems i'm using for the app on each machine. I'd like to be able to just copy the directory to each machine and run it. Ideally, i'd like to put the gems in the lib folder or something and reference them from there, so i don't have to even install them on my dev machine. Is there a way to do this?
In .net, we call this the "spare tire" principle.
thanks,
Craig
How about using bundler?
Then you can include a Gemfile that specifies all the necssary gems and just run "bundle install" on each machine to pull them down.
If you really want to bundle them with the app run "bundle package" and the gems will be stored in vendor/cache.
You could take the same approach as rails allows and "vendor" your gems. This involves creating a new directory (rails uses vendor/gems) and unpack the gem into this directory, using gem unpack.
You then configure your load path to include all of the sub-folders below that.
Edit
You can configure your load path by doing something like this
Dir.glob(File.join("vendor", "gems", "*", "lib")).each do |lib|
$LOAD_PATH.unshift(File.expand_path(lib))
end
I am trying to hack through a forked gem (buildr). As such I cloned it from github and began to butcher the code. The official gem is installed on my system (under /usr/lib/ruby.../gems/buildr...). There is an executable which I need to use in my dev process - buildr.
Now I want the buildr executable and the library to point to my forked repo and not the default gem installation. This would be for this gem only. As such, the changes I make against the forked repo is usable directly for testing and so forth.
I would guess I need to load my library prior to the system gem loading. Can somebody recommend the best way to do so?
I did something similar for work when the Spreadsheet gem broke backward compatibility. I put the previous versions code in it's own module and just renamed the gem my-spreadsheet and installed that (I really wanted some of the features of the new gem but I also didn't want to rewrite all my previous code at that point).
If it's just a binary you want to override you could always do some PATH magic, setting the directory of your binary first and thus make sure you always override. But personally I'd prefer making my own copy with a new name and installing that.
you could bump the version in the gemspec for your fork. Then when you install your version of the gem, it will use your (newer) version by default.
change buildr.gemspec
#...
spec.version = '1.3.4.dev'
#...
Then
$ gem build buildr.gemspec
$ sudo gem install buildr-1.3.4.dev.gem
and it should work.