How do I specify and access a gem’s version number within the code of
the
gem itself? For example:
I write a library.
I write a command line utility that uses that library.
The utility uses OptionParser, with a --version option.
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?
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.
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.
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
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.
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.
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.
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:
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.
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.