Referring to version numbers in a gem

How do I specify and access a gem’s version number within the code of
the
gem itself? For example:

  1. I write a library.
  2. I write a command line utility that uses that library.
  3. The utility uses OptionParser, with a --version option.
  4. I package the things up inside a gem.

What’s the best way to specify the version number and give the code
executed when the --version argument is supplied the ability to access
that version number?

On 11/11/2011 14:28, Chad P. wrote:

that version number?
I don’t know about the best way, but I’ve seen a couple ways to handle
it. The easiest for your needs is to define a VERSION constant
somewhere in the namespace of the library that is set to a simple string
representing the version number. I’ve seen other libraries break the
version up into pieces and set those to individual constants rather than
a single VERSION constant.

The trick with both of these schemes is to keep the internal version
information in sync with the gem version. How you do that depends on
how you build your gem, but generally speaking, you have two fairly
decent options.

The first is to define your constant in a minimal version.rb file and
then load that to get the version when building your gem. The other is
to generate the version.rb file based on some other specification of the
version when you build the gem.

Of course, you could also manually define your version in multiple
places. That’s crazy talk though as far as I’m concerned.

-Jeremy

On Nov 11, 2011, at 12:28 , Chad P. wrote:

that version number?
?? I usually just use a constant (eg, Hoe::VERSION)… but I don’t think
that’s what you’re asking because that’s too obvious. Do you really need
to get “the gem’s version number”? If you’re looking to be able to
choose what version of the dependent library you want to load, look at
any and every gem wrapper (eg rake, sow, flog, etc). They all have that
built-in.

On Fri, Nov 11, 2011 at 9:28 PM, Chad P. [email protected] wrote:

What’s the best way to specify the version number and give the code
executed when the --version argument is supplied the ability to access
that version number?

module MyAwesomeTool
VERSION = “0.1.0-1” # Major, minor, tiny, patch-level
end

puts MyAwesomeTool::VERSION


Phillip G.

gplus.to/phgaw | twitter.com/phgaw

A method of solution is perfect if we can forsee from the start,
and even prove, that following that method we shall attain our aim.
– Leibniz

How about DRYing it up a by fetching the value from the version info
supplied by your gem’s specification?

http://rubygems.rubyforge.org/rubygems-update/Gem/Specification.html

On Nov 11, 2011, at 1:02 PM, Phillip G. wrote:

On Fri, Nov 11, 2011 at 9:28 PM, Chad P. [email protected] wrote:

What’s the best way to specify the version number and give the code
executed when the --version argument is supplied the ability to access
that version number?

module MyAwesomeTool
VERSION = “0.1.0-1” # Major, minor, tiny, patch-level
end

puts MyAwesomeTool::VERSION

Just Use Dots

Then Gem::Version can parse it and you can do comparisons without
funny-business.

On Sat, Nov 12, 2011 at 05:53:46AM +0900, Jeremy B. wrote:

The trick with both of these schemes is to keep the internal version
information in sync with the gem version. How you do that depends on
how you build your gem, but generally speaking, you have two fairly
decent options.

The first is to define your constant in a minimal version.rb file and
then load that to get the version when building your gem. The other is
to generate the version.rb file based on some other specification of the
version when you build the gem.

Do you have any specific examples in mind for how to accomplish each of
those approaches – something fairly standard or well-defined – so I
would not have to reinvent a wheel someone else has probably already
figured out?

Of course, you could also manually define your version in multiple
places. That’s crazy talk though as far as I’m concerned.

As things currently stand, I find myself specifying the version in the
gemspec file:

s.version = 'N.N.N'

. . . and in the library:

module Foo
  @version = Gem::Version.new 'N.N.N'
  def self.version; @version; end
end

Then, in the executable, I just call Foo.version when I want version
information. It seems like I’m missing some easy way to get the version
information into the gemspec (or out of the gemspec), to eliminate that
duplication, somehow.

I’m using the Gem::Version thing for now in part because I’ve seen cases
where for some reason a VERSION constant conflicts with something else
in
the Ruby environment. I haven’t seen it in quite a while, but I don’t
want to have to deal with that kind of issue.

On Nov 11, 2011, at 1:22 PM, Carina C. Zona wrote:

How about DRYing it up a by fetching the value from the version info
supplied by your gem’s specification?

http://rubygems.rubyforge.org/rubygems-update/Gem/Specification.html

When developing, the code I’m running may not be installed as a gem so
there’s nowhere to fetch the version from.

The authoritative source should be with the code so that the behavior is
consistent for gem users, gem packagers and people who unpack gems and
load them with -I.

On Sat, Nov 12, 2011 at 06:25:32AM +0900, Eric H. wrote:

Just Use Dots

Then Gem::Version can parse it and you can do comparisons without
funny-business.

I’m using Gem::Version at present to specify my version, but I’m not
entirely sure how Gem::Version is meant to be used. The documentation
I’ve found for it specifies its parts, but not its usage, so I’m left
trying to figure out all of this stuff on my own.

On Sat, Nov 12, 2011 at 06:22:37AM +0900, Carina C. Zona wrote:

How about DRYing it up a by fetching the value from the version info
supplied by your gem’s specification?

http://rubygems.rubyforge.org/rubygems-update/Gem/Specification.html

That’s the sort of thing I want to do. I’m just not sure how best to go
about doing it. I mean . . . should my library read stuff from my
gemspec file? That seems wrong somehow.

On Sat, Nov 12, 2011 at 06:32:51AM +0900, Jeremy B. wrote:


s.version = MyLibrary::VERSION

Wow. That really should have been obvious to me. Thank you.

On Sat, Nov 12, 2011 at 05:28:15AM +0900, Chad P. wrote:

that version number?
For now, I’m going with the following.

lib/gem_name.rb:

module GemName
  @version = Gem::Version.new 'N.N.N'
  def self.version; @version; end

  . . .
end

gem_name.gemspec:

load 'lib/gem_name.rb'

Gem::Specification.new do |s|
  s.version = GemName.version.to_s
  . . .
end

bin/gemname:

#!/usr/bin/env ruby
require 'gem_name'
require 'optparse'

. . .

opts = OptionParser.new do |opts|
  . . .

  opts.on_tail('--version', help_text[:version]) do
    puts "#{0} #{GemName.version} . . ."
  end
end

If anyone sees any problems with that approach, I’d like to hear about
it, but it seems to be working well enough for the moment.

On 11/11/2011 15:25, Chad P. wrote:

version when you build the gem.

Do you have any specific examples in mind for how to accomplish each of
those approaches – something fairly standard or well-defined – so I
would not have to reinvent a wheel someone else has probably already
figured out?

In lib/my_library/version.rb or something similar:

module MyLibrary
VERSION = ‘1.2.3’
end

In mylibrary.gemspec:

$: << ‘lib’
require ‘my_library/version’


s.version = MyLibrary::VERSION

In your executable:

require ‘my_library/version’
puts MyLibrary::VERSION

-Jeremy

Good point, Eric

On 11/11/2011 15:39, Chad P. wrote:

On Sat, Nov 12, 2011 at 06:32:51AM +0900, Jeremy B. wrote:


s.version = MyLibrary::VERSION

Wow. That really should have been obvious to me. Thank you.

I wish I could remember where I originally read about that solution so
that I could give proper attribution, but I’m glad you found it helpful.

-Jeremy

On Nov 11, 2011, at 14:04 , Chad P. wrote:

executed when the --version argument is supplied the ability to access
that version number?

For now, I’m going with the following.

lib/gem_name.rb:

module GemName
@version = Gem::Version.new ‘N.N.N’

Just use a plain string here. No reason to drag in Gem::Version at this
point (rubygems is still pretty heavy). Also, a constant would be a
better fit.

 def self.version; @version; end

There’s no need for a class method here. Since the version string really
is constant (for a given install), and there isn’t any morphing you’re
going to do, stick with a const.

 . . .

end

gem_name.gemspec:

load ‘lib/gem_name.rb’

Gem::Specification.new do |s|
s.version = GemName.version.to_s

s.version = GemName::VERSION

 . . .

end

bin/gemname:

. . .

 opts.on_tail('--version', help_text[:version]) do
   puts "#{0} #{GemName.version} . . ."

puts “#{0} #{GemName::VERSION} . . .”

 end

end

If anyone sees any problems with that approach, I’d like to hear about
it, but it seems to be working well enough for the moment.

There’s nothing wrong with it, but it does do a bit more than it
needs. Using a constant in the main class/module (I don’t see the value
in separating out the version to it’s own file) and then referring to
that everywhere is the DRYest way we could come up with when we were
figuring this stuff out. It’s the pattern that hoe uses and what sow
spits out when you create a new project with it.

On Fri, Nov 11, 2011 at 2:28 PM, Chad P. [email protected] wrote:

that version number?


Chad P. [ original content licensed OWL: http://owl.apotheon.org ]

Just use your git hash:

assumes file is in root/lib/gem_name.rb

module GemName
VERSION = git --git-dir="#{File.dirname __FILE__}/../.git" rev-parse origin/master
end

;)~

On Sat, Nov 12, 2011 at 09:09:32AM +0900, Ryan D. wrote:

On Nov 11, 2011, at 14:04 , Chad P. wrote:

module GemName
@version = Gem::Version.new ‘N.N.N’

Just use a plain string here. No reason to drag in Gem::Version at this
point (rubygems is still pretty heavy). Also, a constant would be a
better fit.

Using a constant could prove problematic. As I said in an earlier
response:

I'm using the Gem::Version thing for now in part because I've seen
cases where for some reason a VERSION constant conflicts with
something else in the Ruby environment.  I haven't seen it in quite 

a
while, but I don’t want to have to deal with that kind of issue.

 def self.version; @version; end

There’s no need for a class method here. Since the version string
really is constant (for a given install), and there isn’t any morphing
you’re going to do, stick with a const.

See above.

(et cetera)

This is what namespaces are for. If a library’s constants are
colliding with the environment’s, one or the other is managing
namespace poorly.

http://ruby-doc.org/docs/ProgrammingRuby/html/tut_modules.html

On Sat, Nov 12, 2011 at 09:34:24AM +0900, Josh C. wrote:

Just use your git hash:

This is probably a joke, but . . .

  1. I’m using Mercurial, not Git.

  2. That wouldn’t be a very good idea for version numbers, in my opinion.

assumes file is in root/lib/gem_name.rb

module GemName
VERSION = git --git-dir="#{File.dirname __FILE__}/../.git" rev-parse origin/master
end

  1. The only part of this that actually answers my question is this:

    VERSION =