Why use GemSpec + GemFile when checking for dependencies? - ruby-on-rails

Whenever developing gems, I don't see any reasons why Gemfile is not directly inspected for dependencies.
Indeed, why use a .gemspec file in order to list them ? Is there a real benefit ?

Well that's because the Gemfile isn't a file from Rubygems, but a file from Bundler. So the Rubygem developers would have to extend their used files in order to support Gemfile. Since there already is the .gemspec file, there is no valid reason why they should. (there are enough gems which do well without a Gemfile)
In fact, it is recommended to use this as the only contents of the Gemfile of gems:
source 'https://rubygems.org'
gemspec
It will instruct bundler to use the .gemspec file as the authorative source of gems.

Related

What kind of dependencies must be in Gemfile and in gemspec?

Cant figure out where rails gem must specify its dependencies? In Gemfile on in gemspec? The generated Gemfile has these description:
# Declare your gem's dependencies in malibu.gemspec.
# Bundler will treat runtime dependencies like base dependencies, and
# development dependencies will be added by default to the :development group.
gemspec
# Declare any dependencies that are still in development here instead of in
# your gemspec. These might include edge Rails or gems from your path or
# Git. Remember to move these dependencies to your gemspec before releasing
# your gem to rubygems.org.
But I still can understand. Can you help me? My thanks
If you are developing a new gem, then you'll want to declare all of your production-ready gems in the .gemspec using add_dependency.
As for the Gemfile itself, as the comment states, it is used for adding dependencies which are still in development (i.e. not released). For example, if you want to use the latest edge version of Rails, you'd have to specify that dependency with the git or github option (e.g. gem "rails", github: "rails/rails"). These options are only available in the Gemfile, not the .gemspec.
In general you want to always put your dependencies in the .gemspec and only use the Gemfile if you need to.

How do you install gems from Gemfile.lock file?

I am trying to run an app taken off Github.
I have run bundle install to install required gems from the Gemfile. However when running the app, an error message tells me the gems installed are the wrong version.
On inspecting the Gemfile.lock I note that the versions are older than the gems installed. (i.e. I have newer versions of gems installed and the application requires older gems.)
Is there a quick way to install all the gems as per the versions described in the Gemfile.lock file? Alternatively is there a method to ignore that file?
Gemfile:
source 'http://rubygems.org'
gem 'rails', "3.0.9"
gem "sass"
..
Gemfile.lock:
sass (3.1.1)
..
In the above example, even though sass is installed the app specially requires version 3.1.1.
With a valid Gemfile.lock file, bundle install alone should be sufficient, unless some particular gem version has been yanked. In that case you would need to look for an alternative gem version that is still currently available (usually bundle update name_of_yanked_gem would suffice).
About the sass 3.1.1, it is not so much that the application requires that particular version, but rather, that was likely the newest version available when the Gemfile.lock was last generated/updated given the overall version constraints as specified in Gemfile. As you have listed, there is no version range specified for sass itself, but other gems may impose further constraints if they have sass as a dependency.
Outright ignoring Gemfile.lock is not a good idea as under normal circumstances it will be specifying the gem versions that were last known to be still usable with the application.
try this ..
bundle install --deployment
With above deployment option, bundle then reads from Gemfile.lock.
What's more, the gems are installed to directory vendor/bundle, with the bundle directory being auto created.
Also, new directory .bundle is created directly under the rails root directory, and has a file named config, whose content is as follows ...
BUNDLE_FROZEN: '1'
BUNDLE_PATH: vendor/bundle
BUNDLE_DISABLE_SHARED_GEMS: '1'
Hope the above works for you.
Make sure you're running the web server with bundle execute rails server

Could not find gem 'spree-paypal-express' with spree 1.1.1

Hi I have installed and working Spree 1.1.1. and want to integrate PayPal to the engine. and when i am trying to install 'spree_paypal_express' the console is showing the below message please help me out.
Could not find gem 'spree-paypal-express (>= 0) x86-mingw32' in the gems available on this machine.
There are a few possible issues with this.
First, there may be an issue with your Gemfile. For example,
-- the gem may not be in the gemfile,
-- you may have misspelled the name of the gem in your gemfile
-- you may have extra whitespace in the gem name (e.g., gem 'spree-paypal-express ' <- note extra space)
Here are some things you can try (after checking the above first to make sure your Gemfile is correct):
Remove all your gems (go to the gems folder of your ruby, remove the specifications folder and the gems folder -- or create a new gemset using rvm)
gem list should be more or less empty
gem install bundler
And try to bundle install again from scratch.
I have manually downloaded zip folder from github repository and extracted.
by going in to the directory run gem build spree_paypal_express.gemspec
then it will generate some files in which spree_paypal_express-1.1.0.gem will be one of them.
so later run gem install spree_paypal_express-1.1.0.gem
then you are ready to go... you can check by gem list

Telling Bundler to exclude certain gems from a particular gem's installation

Within a gemfile, is there any way to tell Bundler something like:
gem 'twitter-bootstrap-rails', :exclude therubyracer
I need to install twitter-bootstrap-rails but it automatically pulls therubyracer in, so bundle install fails and bootstrap isn't included in the project since this is a Windows machine. I installed execjs to no avail.
I tried to list therubyracer under production, and bundle install --without production, also to no avail.
"therubyracer gem on windows" is also this problem, but none of the suggestions there change the error I'm getting.
My old thread was "When I do "bundle update", I get an error from a gem not in my gemfile. How do I ignore this dependency?".
There is no option for this in Bundler.
So you're left with these options:
Don't use twitter-bootstrap-rails. You can just copy the compiled css and js files into the proper directories under vendor/assets. You'll lose the ability to change less variables. Or you can use the compass_twitter_bootstrap gem, which uses sass instead of less.
Get the maintainer of the less gem to use execjs instead of commonjs and therubyracer. It would probably mean significant refactoring for the maintainer(s) if at all possible.
Use the :platform option in your Gemfile, to only install on OSX or Linux. Then require the parts you can use by hand, without loading less. This probably won't work.

How to use Bundler with offline .gem file?

For my application, I need to handle encrypted ZIP files. Despite their horrific looking site, it seems that Chilkat's commercial Zip gem is probably the best way to go to implement this.
Because this is a commercial gem, they don't have it in any of the typical gem sources that Bundler looks at. I was able to install the Linux 64-bit version of the gem under Mac OS X (though I haven't tried to run it yet, so no word yet on if that will actually work). However, I'm first trying to get Bundler to recognize and load the gem from the .gem file that I downloaded.
Bundler has a path attribute which I've tried to utilize in several ways, but I haven't gotten it to work yet:
I tried using path to point to the .gem file itself, but path expects a directory.
I tried adding .gz to the end of the .gem file and extracting it - I got a directory with a data.tar.gz and metadata.gz inside. path pointed to the extracted directory with these two files didn't work.
I tried extracting the data.tar.gz and metadata.gz and placing the extracted versions inside the directory that I pointed path to. This failed.
I noticed that the gem didn't have a gemspec file - I created one and placed it inside the directory. No luck.
This is the error that I get:
$ bundle install
Fetching source index for http://rubygems.org/
Fetching source index for http://gems.github.com/
Could not find gem 'chilkat (>= 0, runtime)' in source at /Users/username/appname/vendor/cache/chilkat-9.1.0-x86_64-linux.
Source does not contain any versions of 'chilkat (>= 0, runtime)'
Any ideas on how I can get Bundler to see that the gem is indeed in this directory? Any other options other than the path attribute which doesn't seem to be working?
Many thanks!
I'm using Rails 3.0.3, new to Rails 3 and bundler.
I got this same error with:
gem 'mygem', :path => '/path/to/gem'
Resolved by specifying the version number:
gem 'mygem', '0.0.1', :path => '/path/to/gem'
Using >=0.0.1 for the version reverted to the original error. I can't explain any of this, however.
Quoting JD's helpful commment, from the Gemfile man page: "Similar to the semantics of the :git option, the :path option requires that the directory in question either contains a .gemspec for the gem, or that you specify an explicit version that bundler should use."
Try unpacking the gem and then using the path in your Gemfile.
i.e.
gem unpack my-gem-file.gem /my-rails-app/vendor/gems/
then add a line like so to your Gemfile
gem 'my-gem', '0.0.1', :path => 'vendor/gems/my-gem'
Obviously paths and version numbers will vary. You also might need to make the vendor/gems directory in your app root if it doesn't already exist.
Copy the gem in to vendor/cache directory in your application's root folder.
bundle install --local
This will install the local gem.
Since this gem will be local to any machine you'll be running your app on, just specify the gem in the Gemfile, then manually install the gem. When you run "bundle install", bundler will see it's already installed and move on.
This worked for me when installing a version of ruby-debug-base19 that wasn't available on rubygems.org yet.
Another way would be to set up your own gem server that's accessible to all your app servers. See http://guides.rubygems.org/run-your-own-gem-server/
I've never done this myself but it looks very simple. Just make sure you don't violate any of the Chilkat terms of service if your gem server is going to be on the Internet.
First unpack the gem using the solution by semanticart. Then add a gemspec in the unpacked gem. Bundler will be able to run properly.
Gem::Specification.new do |s|
s.name = "chilkat"
s.version = "9.4.1"
s.platform = Gem::Platform::RUBY
s.required_rubygems_version = ">= 1.3.6"
s.files = Dir.glob("lib/**/*")
s.require_path = "lib"
s.summary = "Make do with a self written gemspec"
end

Resources