version 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,21 @@
1
- === Version 0.8.0 / (unreleased)
1
+ === Version 0.9.0 / 2010-02-15
2
+
3
+ * bug fixes
4
+ * fixed project name in some areas
5
+ * ensure correct sorting of 1.9 <=> 1.10 (closes #3)
6
+ * ensure correct sorting of prerelease versions
7
+ * Version.current returns nil if no VERSION found (closes #4)
8
+
9
+ * enhancements
10
+ * Version#prerelease? to determine if it's a prerelease version
11
+ * Version#bump! now accepts symbolic indexes
12
+ * Version#inspect has slightly friendlier output
13
+ * VersionTask now correctly bumps prerelease versions
14
+ * VersionTask has new version:bump:pre task
15
+ * now properly MIT-licensed
16
+ * somewhat spec'd
17
+
18
+ === Version 0.8.0 / 2010-02-05
2
19
 
3
20
  * bug fixes
4
21
  * fixed README documentation to properly reflect is_versioned
@@ -6,7 +23,7 @@
6
23
  collisions with other gems
7
24
 
8
25
  * enhancements
9
- * Added Version.current method (closes #2)
26
+ * added Version.current method (closes #2)
10
27
 
11
28
  === Version 0.7.1 / 2010-02-05
12
29
 
@@ -56,4 +73,4 @@
56
73
 
57
74
  * todo for 1.0.0
58
75
  * full suite of specs
59
- * version-bumping rake tasks
76
+ * version-bumping rake tasks
@@ -0,0 +1,23 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2010-2010 Stephen Touset
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
@@ -3,6 +3,7 @@
3
3
  * http://github.com/stouset/version
4
4
  * http://rdoc.info/projects/stouset/version
5
5
  * http://getcaliper.com/caliper/project?repo=git%3A%2F%2Fgithub.com%2Fstouset%2Fversion.git
6
+ * http://atlruby.org/stouset/posts/138-version-task
6
7
 
7
8
  == Description
8
9
 
@@ -15,6 +16,12 @@ Version is a simple wrapper around the concept of version-numbering schemes.
15
16
 
16
17
  == Examples
17
18
 
19
+ === Screencast
20
+
21
+ For a quick introduction, watch the
22
+ screencast[http://blip.tv/file/get/Tkadom-ATLRUGSteveTousetPresentingVersion277.mov]
23
+ of my presentation[http://atlruby.org/stouset/posts/138-version-task] at the
24
+ {Atlanta Ruby Users' Group}[http://atlruby.org/].
18
25
 
19
26
  === Rake Tasks
20
27
 
@@ -31,6 +38,8 @@ You're all set up.
31
38
  $ rake version:bump # => 0.1.1
32
39
  $ rake version:bump:minor # => 0.2.0
33
40
  $ rake version:bump:revision # => 0.2.1
41
+ $ rake version:bump:pre # => 0.2.1a
42
+ $ rake version:bump # => 0.2.2
34
43
  $ rake version:bump:major # => 1.0.0
35
44
  $ rake version:bump:minor # => 1.0.1
36
45
  $ cat VERSION # => 1.0.1
@@ -55,8 +64,9 @@ class-level constant.
55
64
 
56
65
  Foo::VERSION # => 1.0.1
57
66
 
58
- The Class::Version method takes a filename parameter if you use a different
59
- location for the VERSION file. See the Class::Version rdoc for details.
67
+ The Version.current and Class::is_versioned methods both take a filename
68
+ parameter if you use a different location for the VERSION file. See the
69
+ Version.current rdoc for details.
60
70
 
61
71
  === Manipulation in Code
62
72
 
@@ -65,12 +75,12 @@ library. It's simple to use, but I'll be surprised if there's much point
65
75
  beyond doing the legwork for the Rake task and class versioning.
66
76
 
67
77
  v = "1.2.0".to_version
68
- v.to_s # => 1.2.0
69
- v.bump! # => 1.2.1
70
- v.bump!(1) # => 1.3.0
71
- v.bump!(1, true) # => 1.3
72
- v.major = 2 # => 2.0
73
- v.to_a # => ['2', '0']
78
+ v.to_s # => 1.2.0
79
+ v.bump! # => 1.2.1
80
+ v.bump!(:major) # => 1.3.0
81
+ v.bump!(:minor, true) # => 1.3
82
+ v.major = 2 # => 2.0
83
+ v.to_a # => ['2', '0']
74
84
 
75
85
  == Install
76
86
 
data/Rakefile CHANGED
@@ -1,6 +1,5 @@
1
1
  $: << 'lib'
2
2
 
3
- require 'version'
4
3
  require 'rake/version_task'
5
4
 
6
5
  require 'rubygems'
@@ -13,7 +12,7 @@ spec = Gem::Specification.new do |s|
13
12
  s.author = 'Stephen Touset'
14
13
  s.email = 'stephen@touset.org'
15
14
  s.summary = 'simple version-number encapsulation'
16
- s.version = Version::VERSION
15
+ s.version = Version.current
17
16
  s.files = FileList['[A-Z]*', 'lib/**/*.rb', 'spec/**/*']
18
17
 
19
18
  s.add_development_dependency 'rspec'
@@ -24,9 +23,10 @@ Rake::GemPackageTask.new(spec) do |gem|
24
23
  end
25
24
 
26
25
  Rake::RDocTask.new do |doc|
27
- doc.title = "emcien-engine #{Version::VERSION}"
26
+ doc.title = "version #{Version.current}"
28
27
  doc.rdoc_dir = 'doc'
29
- doc.rdoc_files.include('README*')
28
+ doc.main = 'README.rdoc'
29
+ doc.rdoc_files.include('*.rdoc')
30
30
  doc.rdoc_files.include('lib/**/*.rb')
31
31
  end
32
32
 
data/TODO.rdoc CHANGED
@@ -1,5 +1,4 @@
1
- * fully spec all functionality
2
- * remove file parsing duplication between Class::Version() and
1
+ * remove file parsing duplication between Version.current and
3
2
  Rake::VersionTask
4
3
  * get rid of gem task warnings
5
- * support prerelease versions like Gem::Version
4
+ * improved pre-bumping (version:bump:major:pre?)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.0
1
+ 0.9.0
@@ -66,13 +66,16 @@ class Rake::VersionTask < Rake::TaskLib
66
66
 
67
67
  namespace :bump do
68
68
  desc 'Bump the major version number'
69
- task(:major => filename) { puts write(read.bump!(0)) }
69
+ task(:major => filename) { puts write(read.bump!(:major)) }
70
70
 
71
71
  desc 'Bump the minor version number'
72
- task(:minor => filename) { puts write(read.bump!(1)) }
72
+ task(:minor => filename) { puts write(read.bump!(:minor)) }
73
73
 
74
74
  desc 'Bump the revision number'
75
- task(:revision => filename) { puts write(read.bump!(2)) }
75
+ task(:revision => filename) { puts write(read.bump!(:revision)) }
76
+
77
+ desc 'Bump to a prerelease version'
78
+ task(:pre => filename) { puts write(read.bump!(:pre)) }
76
79
  end
77
80
  end
78
81
  end
@@ -11,6 +11,8 @@ require 'pathname'
11
11
  class Version
12
12
  include Comparable
13
13
 
14
+ autoload :Component, 'version/component'
15
+
14
16
  #
15
17
  # Searches through the parent directories of the calling method and looks
16
18
  # for a VERSION or VERSION.yml file to parse out the current version. Pass
@@ -22,9 +24,9 @@ class Version
22
24
  # if path is nil, detect automatically; if path is a directory, detect
23
25
  # automatically in the directory; if path is a filename, use it directly
24
26
  path = path ? Pathname.new(path) : self.version_file(caller.first)
25
- path = self.version_file(path) unless path.file?
26
-
27
- raise 'no VERSION or VERSION.yml found' unless path
27
+ path = self.version_file(path) unless path.nil? or path.file?
28
+
29
+ return nil unless path
28
30
 
29
31
  case path.extname
30
32
  when '' then path.read.strip.to_version
@@ -39,8 +41,8 @@ class Version
39
41
  #
40
42
  def self.version_file(filename)
41
43
  Pathname(filename).dirname.expand_path.ascend do |d|
42
- break d.join('VERSION') if d.join('VERSION').exist?
43
- break d.join('VERSION.yml') if d.join('VERSION.yml').exist?
44
+ break d.join('VERSION') if d.join('VERSION').file?
45
+ break d.join('VERSION.yml') if d.join('VERSION.yml').file?
44
46
  end
45
47
  end
46
48
 
@@ -50,13 +52,7 @@ class Version
50
52
  # version components.
51
53
  #
52
54
  def initialize(major, minor = 0, revision = nil, *rest)
53
- self.components = []
54
-
55
- self.major = major
56
- self.minor = minor
57
- self.revision = revision
58
-
59
- rest.each.with_index {|v, i| self[3 + i] = v }
55
+ self.components = [ major, minor, revision, *rest ]
60
56
  end
61
57
 
62
58
  #
@@ -67,15 +63,15 @@ class Version
67
63
  #++
68
64
  #
69
65
  [ :major, :minor, :revision ].each.with_index do |component, i|
70
- define_method(:"#{component}") { self[i] }
71
- define_method(:"#{component}=") {|v| self[i] = v.to_s }
66
+ define_method(:"#{component}") { self[i] }
67
+ define_method(:"#{component}=") {|v| self[i] = v }
72
68
  end
73
69
 
74
70
  #
75
71
  # Retrieves the component of the Version at +index+.
76
72
  #
77
73
  def [](index)
78
- self.components[index]
74
+ self.components[index] ? self.components[index].to_s : nil
79
75
  end
80
76
 
81
77
  #
@@ -84,33 +80,34 @@ class Version
84
80
  #
85
81
  # If +index+ is greater than the length of the version number, pads the
86
82
  # version number with zeroes until +index+.
87
- #--
88
- # TODO: rewrite sanely
89
- #++
83
+ #
90
84
  def []=(index, value)
91
- self.resize!(index) and return if value.nil? || value.empty?
85
+ return self.resize!(index) if value.nil? || value.to_s.empty?
86
+ return self[self.length + index] = value if index < 0
87
+
88
+ length = self.length - index
89
+ zeroes = Array.new length.abs, Version::Component.new('0')
90
+ value = Version::Component.new(value.to_s)
92
91
 
93
- if index < self.length
94
- length = self.length - index
95
- zeroes = Array.new(length, '0')
96
-
92
+ if length >= 0
97
93
  self.components[index, length] = zeroes
98
94
  self.components[index] = value
99
95
  else
100
- length = index - self.length
101
- zeroes = Array.new(length, '0')
102
-
103
96
  self.components += zeroes
104
97
  self.components << value
105
98
  end
106
99
  end
107
100
 
101
+ def prerelease?
102
+ self.components.any? {|c| c.prerelease? }
103
+ end
104
+
108
105
  #
109
106
  # Resizes the Version to +length+, removing any trailing components. Is a
110
107
  # no-op if +length+ is greater than its current length.
111
108
  #
112
109
  def resize!(length)
113
- self.components = self.components[0, length]
110
+ self.components = self.components.take(length)
114
111
  self
115
112
  end
116
113
 
@@ -119,12 +116,21 @@ class Version
119
116
  # least-significant part. Set +trim+ to true if you want the version to be
120
117
  # resized to only large enough to contain the index.
121
118
  #
122
- # "1.0.4a".bump! # => "1.0.4b"
123
- # "1.0.4b".bump!(1, true) # => "1.2"
119
+ # "1.0.4a".bump! # => '1.0.5'
120
+ # "1.0.4a".bump!(:pre) # => '1.0.5b'
121
+ # "1.0.4a".bump!(:minor, true) # => '1.2'
124
122
  #
125
123
  def bump!(index = self.length - 1, trim = false)
126
- self.resize!(index + 1) if trim
127
- self[index] = (self[index] || -1).succ
124
+ case index
125
+ when :major then self.bump!(0, trim)
126
+ when :minor then self.bump!(1, trim)
127
+ when :revision then self.bump!(2, trim)
128
+ when :pre then self[-1] = self.components[-1].next(true)
129
+ else
130
+ self.resize!(index + 1) if (trim or index >= self.length)
131
+ self[index] = self.components[index].next
132
+ end
133
+
128
134
  self
129
135
  end
130
136
 
@@ -140,14 +146,14 @@ class Version
140
146
  # +to_version+.
141
147
  #
142
148
  def <=>(other)
143
- self.to_a <=> other.to_version.to_a
149
+ self.components <=> other.to_version.components
144
150
  end
145
151
 
146
152
  #
147
153
  # Converts the version number into an array of its components.
148
154
  #
149
155
  def to_a
150
- self.components
156
+ self.components.map {|c| c.to_s }
151
157
  end
152
158
 
153
159
  #
@@ -157,7 +163,7 @@ class Version
157
163
  { :major => self.major,
158
164
  :minor => self.minor,
159
165
  :revision => self.revision,
160
- :rest => self.length > 3 ? self.components.drop(3) : nil }.
166
+ :rest => self.length > 3 ? self.to_a.drop(3) : nil }.
161
167
  delete_if {|k,v| v.nil? }
162
168
  end
163
169
 
@@ -165,7 +171,7 @@ class Version
165
171
  # The canonical representation of a version number.
166
172
  #
167
173
  def to_s
168
- self.components.join('.')
174
+ self.to_a.join('.')
169
175
  end
170
176
 
171
177
  #
@@ -183,13 +189,21 @@ class Version
183
189
  end
184
190
 
185
191
  #
186
- # Aliased from +to_s+.
192
+ # Returns a human-friendly version format.
187
193
  #
188
- alias inspect to_s
194
+ def inspect
195
+ self.to_s.inspect
196
+ end
189
197
 
190
198
  protected
191
199
 
192
- attr_accessor :components
200
+ def components
201
+ @components ||= []
202
+ end
203
+
204
+ def components=(components)
205
+ components.each_with_index {|c, i| self[i] = c }
206
+ end
193
207
  end
194
208
 
195
209
  class Version
@@ -0,0 +1,65 @@
1
+ require 'version'
2
+
3
+ class Version::Component
4
+ attr_accessor :digits
5
+ attr_accessor :letter
6
+
7
+ #
8
+ # Creates a single Component of a version, consisting of digits and
9
+ # possibly a letter. For example, +1+, +3a+, +12+, or +0+.
10
+ #
11
+ def initialize(component)
12
+ parts = component.split /(?=\D)/
13
+
14
+ self.digits = parts[0].to_i
15
+ self.letter = parts[1].to_s.strip
16
+ end
17
+
18
+ def initialize_copy(other)
19
+ self.digits = other.digits
20
+ self.letter = other.letter.dup
21
+ end
22
+
23
+ def prerelease?
24
+ not self.letter.empty?
25
+ end
26
+
27
+ def next(pre = false)
28
+ self.dup.next!(pre)
29
+ end
30
+
31
+ def next!(pre = false)
32
+ case
33
+ when ( pre and self.prerelease?) then self.letter.next!
34
+ when ( pre and not self.prerelease?) then self.letter = 'a'
35
+ when (not pre and self.prerelease?) then self.letter = ''
36
+ when (not pre and not self.prerelease?) then self.digits = self.digits.next
37
+ end
38
+
39
+ self
40
+ end
41
+
42
+ def <=>(other)
43
+ self.to_sortable_a <=> other.to_sortable_a
44
+ end
45
+
46
+ def to_sortable_a
47
+ [ self.digits, self.prerelease? ? 0 : 1, self.letter ]
48
+ end
49
+
50
+ def to_a
51
+ [ self.digits, self.letter ]
52
+ end
53
+
54
+ def to_i
55
+ self.digits
56
+ end
57
+
58
+ def to_s
59
+ self.to_a.join
60
+ end
61
+
62
+ def inspect
63
+ self.to_s.inspect
64
+ end
65
+ end
@@ -1,7 +1,7 @@
1
1
  $:.unshift File.dirname(__FILE__)
2
2
  $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
3
3
 
4
- require 'emcien-engine'
4
+ require 'version'
5
5
  require 'spec'
6
6
  require 'spec/autorun'
7
7
 
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ module ImplicitVersion
4
+ def method_missing(name, *args, &block)
5
+ super unless args.empty?
6
+ super unless block.nil?
7
+ super unless name.to_s =~ /^v[\d\w_]+$/
8
+
9
+ name.to_s.gsub(/^v/, '').gsub(/_/, '.').to_version
10
+ end
11
+ end
12
+
13
+ describe Version do
14
+ include ImplicitVersion
15
+
16
+ subject { "1.6.3a".to_version }
17
+
18
+ its(:major) { should == '1' }
19
+ its(:minor) { should == '6' }
20
+ its(:revision) { should == '3a' }
21
+ its(:prerelease?) { should be_true }
22
+
23
+ it 'should allow indexed access to components' do
24
+ subject[0].should == '1'
25
+ subject[1].should == '6'
26
+ subject[2].should == '3a'
27
+ end
28
+
29
+ it 'should return nil for unset components' do
30
+ subject[3].should == nil
31
+ subject[4].should == nil
32
+ end
33
+
34
+ it 'should major-bump to 2.0.0' do
35
+ subject.bump!(:major).should == v2_0_0
36
+ end
37
+
38
+ it 'should minor-bump to 1.7.0' do
39
+ subject.bump!(:minor).should == v1_7_0
40
+ end
41
+
42
+ it 'should revision-bump to 1.6.3' do
43
+ subject.bump!(:revision).should == v1_6_3
44
+ end
45
+
46
+ it 'should prerelease-bump to 1.6.3b' do
47
+ subject.bump!(:pre).should == v1_6_3b
48
+ end
49
+ end
50
+
51
+ describe Version do
52
+ include ImplicitVersion
53
+
54
+ it 'should preserve equality' do
55
+ v0_0.should == v0_0
56
+ v0_1_1.should == v0_1_1
57
+ v0_4_alpha.should == v0_4_alpha
58
+ v1_0_2.should == v1_0_2
59
+ v1_0_2b.should == v1_0_2b
60
+ v1_01.should == v1_01
61
+ v1_10.should == v1_10
62
+ v2_0.should == v2_0
63
+ va.should == vb
64
+ end
65
+
66
+ it 'should order correctly' do
67
+ v0_0.should < v0_0_0_0_0_1
68
+ v0_0_0_1.should < v1
69
+ v0_1a.should < v0_1
70
+ v0_01.should < v0_10
71
+ v0_9.should < v0_10
72
+ end
73
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: version
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Touset
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-05 00:00:00 -05:00
12
+ date: 2010-02-15 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -32,11 +32,13 @@ extra_rdoc_files: []
32
32
 
33
33
  files:
34
34
  - History.rdoc
35
+ - License.txt
35
36
  - Rakefile
36
37
  - README.rdoc
37
38
  - TODO.rdoc
38
39
  - VERSION
39
40
  - lib/rake/version_task.rb
41
+ - lib/version/component.rb
40
42
  - lib/version/ext/array.rb
41
43
  - lib/version/ext/class.rb
42
44
  - lib/version/ext/hash.rb
@@ -44,6 +46,7 @@ files:
44
46
  - lib/version.rb
45
47
  - spec/spec.opts
46
48
  - spec/spec_helper.rb
49
+ - spec/version_spec.rb
47
50
  has_rdoc: true
48
51
  homepage:
49
52
  licenses: []