version 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []