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?

···

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

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 11/11/2011 14:28, Chad Perrin wrote:

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?

?? 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 Nov 11, 2011, at 12:28 , Chad Perrin wrote:

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?

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

puts MyAwesomeTool::VERSION

···

On Fri, Nov 11, 2011 at 9:28 PM, Chad Perrin <code@apotheon.net> 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?

--
Phillip Gawlowski

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 Fri, Nov 11, 2011 at 12:28 PM, Chad Perrin <code@apotheon.net> wrote:

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?

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

--
Carina

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 Sat, Nov 12, 2011 at 05:28:15AM +0900, Chad Perrin wrote:

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?

--
Chad Perrin [ 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 Fri, Nov 11, 2011 at 2:28 PM, Chad Perrin <code@apotheon.net> wrote:

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?

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

Keep the data where ever you want, Rubygems has tossed the FHS out the
window so it doesn't really matter.

The common way that has sprouted up, popularized by Bundler, is rather ass
backwards from the developers point of view. So flip it:

    module MyShit
      VERSION = File.read(File.dirname(__FILE__)+'/../VERSION').strip
    end

Now that's a rather simplistic approach, I can show you much better, but it
conveys the idea.

Of course, it all sort of begs the question of why Ruby itself isn't
version aware and could just tell us the version of a library, without
developer's having to manually insert it.

-----Messaggio originale-----

Allegato senza titolo 17166.dat (196 Bytes)

···

Da: Chad Perrin [mailto:code@apotheon.net]
Inviato: venerdì 11 novembre 2011 21:28
A: ruby-talk ML
Oggetto: 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?

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

--
Caselle da 1GB, trasmetti allegati fino a 3GB e in piu' IMAP, POP3 e SMTP autenticato? GRATIS solo con Email.it http://www.email.it/f

Sponsor:
Riccione Hotel 3 stelle in centro: Pacchetto Capodanno mezza pensione, animazione bimbi, zona relax, parcheggio. Scopri l'offerta solo per oggi...
Clicca qui: http://adv.email.it/cgi-bin/foclick.cgi?mid=11982&d=29-12

Just Use Dots

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

···

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

On Fri, Nov 11, 2011 at 9:28 PM, Chad Perrin <code@apotheon.net> 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

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 Sat, Nov 12, 2011 at 05:53:46AM +0900, Jeremy Bopp wrote:

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

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: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

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

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 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

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?

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 Nov 11, 2011, at 14:04 , Chad Perrin wrote:

On Sat, Nov 12, 2011 at 05:28:15AM +0900, Chad Perrin 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

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

      VERSION =

···

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

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

What do you think is backwards? You obviously don't think it's
backwards to have a constant of Whatever::VERSION. And you obviously
don't think it's backwards to have the version contained in a separate
file.

Why not make it actually simple instead of just simplistic?

  module MyShit
    VERSION = 'whatever you were trying to store in a separate file
for no obvious reason goes here'
  end

···

On Nov 12, 5:31 pm, Intransition <transf...@gmail.com> wrote:

Keep the data where ever you want, Rubygems has tossed the FHS out the
window so it doesn't really matter.

The common way that has sprouted up, popularized by Bundler, is rather ass
backwards from the developers point of view. So flip it:

module MyShit
  VERSION = File\.read\(File\.dirname\(\_\_FILE\_\_\)\+&#39;/\.\./VERSION&#39;\)\.strip
end

Now that's a rather simplistic approach, I can show you much better, but it
conveys the idea.

--
-yossef

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:25:32AM +0900, Eric Hodel wrote:

Just Use Dots

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

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

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

···

On 11/11/2011 15:25, Chad Perrin wrote:

On Sat, Nov 12, 2011 at 05:53:46AM +0900, Jeremy Bopp 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?

Good point, Eric

···

On Fri, Nov 11, 2011 at 1:29 PM, Eric Hodel <drbrain@segment7.net> wrote:

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.

--
Carina

>
> 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)

···

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

On Nov 11, 2011, at 14:04 , Chad Perrin wrote:

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