Meeting notes, August 2011

16 views
Skip to first unread message

Jesse Hallett

unread,
Aug 3, 2011, 3:35:53 AM8/3/11
to pdx...@googlegroups.com
Please post corrections if you notice that I got any details wrong.


## Bundler, by Igal Koshevoy

List project dependencies in a file called "Gemfile" in your project
root. Then you can use the bundle command to resolve any dependencies
and install the gems for you.

gem 'gemname', '4.2.3', :require => 'vpim/calendar'

group :development
# more gems here
end

You can specify the exact gem versions that you want. This helps
avoid a situation where another gem requires an older version than
would be loaded by default if you had not specified a version.

If you install graphviz and the ruby-graphviz gem you can get a visual
representation of your gem dependency graph:

bundle viz

You can use the `:require => false` option with Facets so that you can
load just the facets components that you need where you need them.
This helps to prevent Facets from clobbering ActiveSupport. Or you
can pass a path to a specific subcomponent of the gem instead of
`false`. The :require option is also necessary if the name of the gem
is not the same as the string that you have to give to `require` to
load the thing.

The Gemfile is itself a ruby script. You can do something like add
code to load more gem declarations from a "Gemfile.local" file that is
not checked into version control. Or you can sniff a database.yaml
file to determine which database gem to require.

Instead of referencing a gem repository, you can load a library from a
git repository or a filesystem path with thr :git => repo_url or :path
=> some_path options. With git you can add a :ref => committish
option to target a specific tag, branch, or commit hash.

Pessimistic version numbers, like '~> 3.1.2', indicate specific
requirements for the major and minor number and a minimum value for
the patch level. Similarly, '~> 2.0' fixes the major number but
allows any minor number and patch level to be used.

Markus Roberts asks, why is there no index that lets Bundler figure
out a working combination of version numbers on its own? So that you
don't have to pin an older version of some gem by hand just because
another gem you are using will not work with the latest version. Sam
Livingston-Gray suggests that not every gem lists all of its
dependecies with precise version numbers.

When Bundler runs it produces a "Gemfile.lock" file that lists the
specific version of of the listed gems and their dependencies that
Bundler has determined to be the latest version that matches your
specifications. Should you check Gemfile.lock into version control?
If your Gemfile does any dymanic calculation then different instances
of the project are likely to require different sets of gems - so don't
check it in in that case.

Reid Beels mentions a gem called bundle_outdated, which provides a
command that examines your Gemfile and suggests newer versions for
gems that have updates available.

Specify RAILS_ENV at the shell level in your build scripts if your
Gemfile references that value.

bundle check || bundle install --local || bundle install --without
development --without test

Igal recently updated the pdxruby website with a new Gemfile that you
can look at as an example. The code is at
https://github.com/igal/pdxruby2. Another example to look at is
https://github.com/reidab/citizenry.

RAILS_ENV = bundle exec rake # runs the version of rake specified
in Gemfile

Or you can run:

bundle install --binstubs

to install executables for the appropriate versions of each gem into a
bin/ directory in your project tree.

Do not list Bundler itself as a dependency in your Gemfile!

Kyle Drake mentions that it is possible to combine RVM with Bundler to
specify which Ruby version to use to run your project. You can create
a .rvmrc file in your project to do this. If you are working under a
directory that contains a .rvmrc file RVM will automatically switch
Ruby versions to match the settings in that file.

Kyle also tells us that Bundler can place gem code into a vendor/
directory. You can check this code into your project if you want to.
But this does not work with git sources. If you have proprietary code
to include in your project and you want to deploy to Heroku, or to a
similar platform, you pretty much have to vendorize that code.

You can specify that certain gems or versions should be conditionally
included depending on the specific Ruby platform that is being used to
run your application. For example:

gem 'some_gem', :platforms => [:ruby_18, :mri_19, :rbx]


## Cascadia Ruby Conf recap, by Sam Livingston-Gray

First talk on salad dressing ladels at a US Ruby conference.

The sessions were recorded and will be posted online eventually.
About five talks are available now.

One interesting talk was on continuous deployment at Github. Every
commit to the master branch is run through tests and is automatically
deployed if the tests pass. They do not have JavaScript tests or
tests run in remotely-controlled browsers.

The single-track structure made for a social atmosphere because
everybody was chatting about the same stuff between sessions.

The Unix Chainsaw was a talk on some intermediate *nix tricks for
stuff like running tests and verifying success during each of multiple
stages of a git rebase.


## Rants on upgrading old code

Markus warns that older verions of Awesome Nested Set have concurrency
problems and will corrupt data under heavy load. Markus submitted a
fix for this that uses strategic row locking.

Also, apparently in some versions of Rails if you are using an
ActiveRecord scope that specifies order you can override that order in
a composed scope - but in other versions of Rails you can't.

Reid adds that in Rails 2 `scope(:stuff)` returns a scope object for
an existing scope called "stuff". In Rails 3, however, the same
method creates a new scope called "stuff". This is particularly bad
if you are migrating old code that includes an invocation like,
`scope(:find)`. That effectively overrides the `find` method in Rails
3.

Do you have experience with perftools and profiling? Reid is
interested in giving a talk on the subject, but wants to make sure
that he is up-to-date on the details.

Brian Ford says that Rubinius has a -Xprofile command line option that
gives you fast profiling. Adding an additional -Xprofiler.graph
option gives graph-formatted output instead of a flat output.

rbx -Xprofile -Xprofiler.graph

Amy Woodward from Engine Yard came to Portland recently and is
recruiting for Engine Yard's Portland office.

Reid says that Paydici may be hiring at some point soonish.

John Wilger

unread,
Aug 3, 2011, 9:10:52 AM8/3/11
to pdx...@googlegroups.com
Thanks once more for the excellent notes, Jesse.

--
Regards,
John Wilger

> --
> You received this message because you are subscribed to the Google Groups "pdxruby" group.
> To post to this group, send email to pdx...@googlegroups.com.
> To unsubscribe from this group, send email to pdxruby+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/pdxruby?hl=en.
>

Chuck Vose

unread,
Aug 3, 2011, 11:21:50 AM8/3/11
to pdx...@googlegroups.com
Thank you Jesse, and thanks to all the people that gave talks.

Sam Livingston-Gray

unread,
Aug 3, 2011, 1:13:32 PM8/3/11
to pdx...@googlegroups.com
Cascadia RubyConf links!

Session videos (10 up as of this writing):
http://confreaks.net/events/cascadiaruby2011
Music played at the venue(s): https://gist.github.com/1112154

My five favorite talks (in approximately descending order) were:
- Corey Donohoe: Shipping at the Speed of Life
- You'll want to watch this one if you're interested in continuous
deployment strategies, GitHub, and adding ridiculous-but-cool features
to Campfire bots.
- Gary Bernhardt: The Unix Chainsaw
- Watch this if you want to be inspired to increase your command-line-fu.
- Ryan Davis: Size Doesn't Matter (the ins and outs of Minitest)
- I loved this, but I enjoy testing and testing libraries; this was
one of the most technical talks out there.
- Aja Hammerly: Powerful (but Easy) Data Visualization with the Graph Gem
- Accessible to a fairly broad range of developers. Newbies, check it out!
- Aaron Patterson's history of ladles (or the archaic "ladels") [a
lightning talk]
- The man will say anything for a laugh, and he gets them. Well
worth the few minutes.

If you're interested in code design, you might also enjoy Avdi Grimm's
"Confident Code" presentation. Personally, I felt I could've gotten
almost as much out of just reading the slides, which I found online
at: http://avdi.org/talks/confident-code-railsconf-2011/

In particular, I love this slide:
https://skitch.com/geeksam/fpks6/confident-code

Enjoy!
-Sam

Jesse Cooke

unread,
Aug 3, 2011, 7:48:40 PM8/3/11
to pdx...@googlegroups.com
Just happened across this RubySpec doc on Guards and Ruby versions/platforms
http://rubyspec.org/guards/

--------------------------------------------
Jesse Cooke :: N-tier Engineer
jc00ke.com / @jc00ke

Jesse Cooke

unread,
Aug 28, 2011, 2:02:36 PM8/28/11
to pdx...@googlegroups.com
I ran into a problem with using Gemfile.local: Your Gemfile.lock will be updated with the gems you specify in your local Gemfile. So if you commit your Gemfile.lock (which Yehuda says you're supposed to) you'll get bundler errors when say, pushing to Heroku. It'll complain that you have gems in your lock file but the were removed from your main Gemfile.

So, maybe instead of using a Gemfile.local, more detection in the main Gemfile would be better. In my case, I'm on linux but the designer I'm working with is on OS X, so detecting platform/OS or hell, username on small teams, would work. It's too bad there is a mismatch between what Bundler calls platforms and what RubySpec/MSpec calls platforms.

--------------------------------------------
Jesse Cooke :: N-tier Engineer
jc00ke.com / @jc00ke


Igal Koshevoy

unread,
Sep 2, 2011, 5:01:56 PM9/2/11
to pdx...@googlegroups.com
On Sun, Aug 28, 2011 at 11:02 AM, Jesse Cooke <je...@jc00ke.com> wrote:
> I ran into a problem with using Gemfile.local: Your Gemfile.lock will be
> updated with the gems you specify in your local Gemfile. So if you commit
> your Gemfile.lock (which Yehuda says you're supposed to) you'll get bundler
> errors when say, pushing to Heroku. It'll complain that you have gems in
> your lock file but the were removed from your main Gemfile.

In short, don't do that.

You have three options for managing your Gemfile* files in your
repository, but only two of them make sense:
1. Include the Gemfile and Gemfile.lock only when the Gemfile has no
conditional logic, which is okay for very simple Ruby apps.
2. Include the Gemfile, but exclude the Gemfile.lock if the Gemfile
has any conditional logic for loading gems, such as interpreter type
or version blocks, or code that loads a Gemfile.local. This is the
most common case.
3. Include the Gemfile and Gemfile.lock when the Gemfile has any
conditional logic, which is a bad idea because your Gemfile.lock will
not work on different systems.

> which Yehuda says you're supposed to

He says that, but that doesn't mean he's right. Bundler's poor design
is heavily biased towards unrealistically simplistic use cases where
the Gemfile is so simple that a Gemfile.lock can be the same between
systems. However, few projects are that simple and this bias causes
much frustration, particularly because Bundler provides an awkward CLI
for creating/updating the Gemfile.lock and this CLI has broken
backwards compatibility at least half a dozen times since I started
using Bundler.

> So, maybe instead of using a Gemfile.local, more detection in the main
> Gemfile would be better. In my case, I'm on linux but the designer I'm
> working with is on OS X, so detecting platform/OS or hell, username on small
> teams, would work. It's too bad there is a mismatch between what Bundler
> calls platforms and what RubySpec/MSpec calls platforms.

Unless I'm misunderstanding your comment, the Gemfile* files don't
work this way. The Gemfile.lock is a static, compiled list of the
exact gems that should be loaded -- there's no logic in there at all.
If you check-in the Gemfile.lock, you're forcing everyone to use the
exact same gems.

For example, if I include the following line in my Gemfile or Gemfile.local:
gem "ruby-debug", :platforms => :mri_18
and run `bundle` on a MRI 1.8 interpreter, then the Gemfile.lock will
force everyone to use the "ruby-debug" gem, even if their platform
can't (e.g. Windows, Ruby 1.9, JRuby, etc).

-igal

PS: Sorry for not responding to your message sooner.

Igal Koshevoy

unread,
Sep 2, 2011, 5:15:36 PM9/2/11
to pdx...@googlegroups.com
On Fri, Sep 2, 2011 at 2:01 PM, Igal Koshevoy <ig...@pragmaticraft.com> wrote:
> However, few projects are that simple and this bias causes
> much frustration, particularly because Bundler provides an awkward CLI
> for creating/updating the Gemfile.lock and this CLI has broken
> backwards compatibility at least half a dozen times since I started
> using Bundler.

For example, I'm currently using the following Capistrano deployment
rule to invoke the Bundler CLI to create/update the Gemfile.lock and
associated gems:

run "export RAILS_ENV=production; cd #{release_path} && (bundle
check || bundle --local || bundle --without test --without development
--path #{release_path}/tmp/bundler)"

I'm frustrated by how often the Bundler CLI changes and annoyed that I
have to write such convoluted commands for performing very common
actions.

-igal

Reply all
Reply to author
Forward
0 new messages