semver2 3.1.0 → 3.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.semver +1 -1
- data/README.md +2 -2
- data/lib/semver.rb +2 -136
- data/lib/xsemver.rb +143 -0
- data/semver2.gemspec +1 -0
- metadata +20 -3
data/.semver
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
SemVer2 3.
|
1
|
+
SemVer2 3.1.x gem, following semver.org 2.0.0-rc.1
|
2
2
|
======
|
3
3
|
|
4
4
|
quickstart on the command line
|
@@ -35,4 +35,4 @@ git integration
|
|
35
35
|
% git config --global alias.semtag '!git tag -a $(semver tag) -m "tagging $(semver tag)"'
|
36
36
|
|
37
37
|
[Franco Lazzarino](mailto:flazzarino@gmail.com)
|
38
|
-
[Henrik Feldt](mailto:henrik@haf.se)
|
38
|
+
[Henrik Feldt](mailto:henrik@haf.se)
|
data/lib/semver.rb
CHANGED
@@ -1,140 +1,6 @@
|
|
1
1
|
require 'yaml'
|
2
|
+
require 'xsemver'
|
2
3
|
require 'semver/semvermissingerror'
|
3
4
|
|
4
|
-
class SemVer
|
5
|
-
|
6
|
-
FILE_NAME = '.semver'
|
7
|
-
TAG_FORMAT = 'v%M.%m.%p%s'
|
8
|
-
|
9
|
-
def SemVer.find dir=nil
|
10
|
-
v = SemVer.new
|
11
|
-
f = SemVer.find_file dir
|
12
|
-
v.load f
|
13
|
-
v
|
14
|
-
end
|
15
|
-
|
16
|
-
def SemVer.find_file dir=nil
|
17
|
-
dir ||= Dir.pwd
|
18
|
-
raise "#{dir} is not a directory" unless File.directory? dir
|
19
|
-
path = File.join dir, FILE_NAME
|
20
|
-
|
21
|
-
Dir.chdir dir do
|
22
|
-
while !File.exists? path do
|
23
|
-
raise SemVerMissingError, "#{dir} is not semantic versioned", caller if File.dirname(path).match(/(\w:\/|\/)$/i)
|
24
|
-
path = File.join File.dirname(path), ".."
|
25
|
-
path = File.expand_path File.join(path, FILE_NAME)
|
26
|
-
puts "semver: looking at #{path}"
|
27
|
-
end
|
28
|
-
return path
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
attr_accessor :major, :minor, :patch, :special
|
34
|
-
|
35
|
-
def initialize major=0, minor=0, patch=0, special=''
|
36
|
-
major.kind_of? Integer or raise "invalid major: #{major}"
|
37
|
-
minor.kind_of? Integer or raise "invalid minor: #{minor}"
|
38
|
-
patch.kind_of? Integer or raise "invalid patch: #{patch}"
|
39
|
-
|
40
|
-
unless special.empty?
|
41
|
-
special =~ /[A-Za-z][0-9A-Za-z\.]+/ or raise "invalid special: #{special}"
|
42
|
-
end
|
43
|
-
|
44
|
-
@major, @minor, @patch, @special = major, minor, patch, special
|
45
|
-
end
|
46
|
-
|
47
|
-
def load file
|
48
|
-
@file = file
|
49
|
-
hash = YAML.load_file(file) || {}
|
50
|
-
@major = hash[:major] or raise "invalid semver file: #{file}"
|
51
|
-
@minor = hash[:minor] or raise "invalid semver file: #{file}"
|
52
|
-
@patch = hash[:patch] or raise "invalid semver file: #{file}"
|
53
|
-
@special = hash[:special] or raise "invalid semver file: #{file}"
|
54
|
-
end
|
55
|
-
|
56
|
-
def save file=nil
|
57
|
-
file ||= @file
|
58
|
-
|
59
|
-
hash = {
|
60
|
-
:major => @major,
|
61
|
-
:minor => @minor,
|
62
|
-
:patch => @patch,
|
63
|
-
:special => @special
|
64
|
-
}
|
65
|
-
|
66
|
-
yaml = YAML.dump hash
|
67
|
-
open(file, 'w') { |io| io.write yaml }
|
68
|
-
end
|
69
|
-
|
70
|
-
def format fmt
|
71
|
-
fmt = fmt.gsub '%M', @major.to_s
|
72
|
-
fmt = fmt.gsub '%m', @minor.to_s
|
73
|
-
fmt = fmt.gsub '%p', @patch.to_s
|
74
|
-
if @special.nil? or @special.length == 0 then
|
75
|
-
fmt = fmt.gsub '%s', ''
|
76
|
-
else
|
77
|
-
fmt = fmt.gsub '%s', "-" + @special.to_s
|
78
|
-
end
|
79
|
-
fmt
|
80
|
-
end
|
81
|
-
|
82
|
-
def to_s
|
83
|
-
format TAG_FORMAT
|
84
|
-
end
|
85
|
-
|
86
|
-
def <=> other
|
87
|
-
maj = major.to_i <=> other.major.to_i
|
88
|
-
return maj unless maj == 0
|
89
|
-
|
90
|
-
min = minor.to_i <=> other.minor.to_i
|
91
|
-
return min unless min == 0
|
92
|
-
|
93
|
-
pat = patch.to_i <=> other.patch.to_i
|
94
|
-
return pat unless pat == 0
|
95
|
-
|
96
|
-
spe = special <=> other.special
|
97
|
-
return spec unless spe == 0
|
98
|
-
|
99
|
-
0
|
100
|
-
end
|
101
|
-
|
102
|
-
include Comparable
|
103
|
-
|
104
|
-
# Parses a semver from a string and format.
|
105
|
-
def self.parse(version_string, format = nil, allow_missing = true)
|
106
|
-
format ||= TAG_FORMAT
|
107
|
-
regex_str = Regexp.escape format
|
108
|
-
|
109
|
-
# Convert all the format characters to named capture groups
|
110
|
-
regex_str = regex_str.gsub('%M', '(?<major>\d+)').
|
111
|
-
gsub('%m', '(?<minor>\d+)').
|
112
|
-
gsub('%p', '(?<patch>\d+)').
|
113
|
-
gsub('%s', '(?:-(?<special>[A-Za-z][0-9A-Za-z\.]+))?')
|
114
|
-
|
115
|
-
regex = Regexp.new(regex_str)
|
116
|
-
match = regex.match version_string
|
117
|
-
|
118
|
-
if match
|
119
|
-
major = minor = patch = nil
|
120
|
-
special = ''
|
121
|
-
|
122
|
-
# Extract out the version parts
|
123
|
-
major = match[:major].to_i if match.names.include? 'major'
|
124
|
-
minor = match[:minor].to_i if match.names.include? 'minor'
|
125
|
-
patch = match[:patch].to_i if match.names.include? 'patch'
|
126
|
-
special = match[:special] || '' if match.names.include? 'special'
|
127
|
-
|
128
|
-
# Failed parse if major, minor, or patch wasn't found
|
129
|
-
# and allow_missing is false
|
130
|
-
return nil if !allow_missing and [major, minor, patch].any? {|x| x.nil? }
|
131
|
-
|
132
|
-
# Otherwise, allow them to default to zero
|
133
|
-
major ||= 0
|
134
|
-
minor ||= 0
|
135
|
-
patch ||= 0
|
136
|
-
|
137
|
-
SemVer.new major, minor, patch, special
|
138
|
-
end
|
139
|
-
end
|
5
|
+
class SemVer < ::XSemVer::SemVer
|
140
6
|
end
|
data/lib/xsemver.rb
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'semver/semvermissingerror'
|
3
|
+
|
4
|
+
module XSemVer
|
5
|
+
# sometimes a library that you are using has already put the class
|
6
|
+
# 'SemVer' in global scope. Too Bad®. Use this symbol instead.
|
7
|
+
class SemVer
|
8
|
+
FILE_NAME = '.semver'
|
9
|
+
TAG_FORMAT = 'v%M.%m.%p%s'
|
10
|
+
|
11
|
+
def SemVer.find dir=nil
|
12
|
+
v = SemVer.new
|
13
|
+
f = SemVer.find_file dir
|
14
|
+
v.load f
|
15
|
+
v
|
16
|
+
end
|
17
|
+
|
18
|
+
def SemVer.find_file dir=nil
|
19
|
+
dir ||= Dir.pwd
|
20
|
+
raise "#{dir} is not a directory" unless File.directory? dir
|
21
|
+
path = File.join dir, FILE_NAME
|
22
|
+
|
23
|
+
Dir.chdir dir do
|
24
|
+
while !File.exists? path do
|
25
|
+
raise SemVerMissingError, "#{dir} is not semantic versioned", caller if File.dirname(path).match(/(\w:\/|\/)$/i)
|
26
|
+
path = File.join File.dirname(path), ".."
|
27
|
+
path = File.expand_path File.join(path, FILE_NAME)
|
28
|
+
puts "semver: looking at #{path}"
|
29
|
+
end
|
30
|
+
return path
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_accessor :major, :minor, :patch, :special
|
36
|
+
|
37
|
+
def initialize major=0, minor=0, patch=0, special=''
|
38
|
+
major.kind_of? Integer or raise "invalid major: #{major}"
|
39
|
+
minor.kind_of? Integer or raise "invalid minor: #{minor}"
|
40
|
+
patch.kind_of? Integer or raise "invalid patch: #{patch}"
|
41
|
+
|
42
|
+
unless special.empty?
|
43
|
+
special =~ /[A-Za-z][0-9A-Za-z\.]+/ or raise "invalid special: #{special}"
|
44
|
+
end
|
45
|
+
|
46
|
+
@major, @minor, @patch, @special = major, minor, patch, special
|
47
|
+
end
|
48
|
+
|
49
|
+
def load file
|
50
|
+
@file = file
|
51
|
+
hash = YAML.load_file(file) || {}
|
52
|
+
@major = hash[:major] or raise "invalid semver file: #{file}"
|
53
|
+
@minor = hash[:minor] or raise "invalid semver file: #{file}"
|
54
|
+
@patch = hash[:patch] or raise "invalid semver file: #{file}"
|
55
|
+
@special = hash[:special] or raise "invalid semver file: #{file}"
|
56
|
+
end
|
57
|
+
|
58
|
+
def save file=nil
|
59
|
+
file ||= @file
|
60
|
+
|
61
|
+
hash = {
|
62
|
+
:major => @major,
|
63
|
+
:minor => @minor,
|
64
|
+
:patch => @patch,
|
65
|
+
:special => @special
|
66
|
+
}
|
67
|
+
|
68
|
+
yaml = YAML.dump hash
|
69
|
+
open(file, 'w') { |io| io.write yaml }
|
70
|
+
end
|
71
|
+
|
72
|
+
def format fmt
|
73
|
+
fmt = fmt.gsub '%M', @major.to_s
|
74
|
+
fmt = fmt.gsub '%m', @minor.to_s
|
75
|
+
fmt = fmt.gsub '%p', @patch.to_s
|
76
|
+
if @special.nil? or @special.length == 0 then
|
77
|
+
fmt = fmt.gsub '%s', ''
|
78
|
+
else
|
79
|
+
fmt = fmt.gsub '%s', "-" + @special.to_s
|
80
|
+
end
|
81
|
+
fmt
|
82
|
+
end
|
83
|
+
|
84
|
+
def to_s
|
85
|
+
format TAG_FORMAT
|
86
|
+
end
|
87
|
+
|
88
|
+
def <=> other
|
89
|
+
maj = major.to_i <=> other.major.to_i
|
90
|
+
return maj unless maj == 0
|
91
|
+
|
92
|
+
min = minor.to_i <=> other.minor.to_i
|
93
|
+
return min unless min == 0
|
94
|
+
|
95
|
+
pat = patch.to_i <=> other.patch.to_i
|
96
|
+
return pat unless pat == 0
|
97
|
+
|
98
|
+
spe = special <=> other.special
|
99
|
+
return spec unless spe == 0
|
100
|
+
|
101
|
+
0
|
102
|
+
end
|
103
|
+
|
104
|
+
include Comparable
|
105
|
+
|
106
|
+
# Parses a semver from a string and format.
|
107
|
+
def self.parse(version_string, format = nil, allow_missing = true)
|
108
|
+
format ||= TAG_FORMAT
|
109
|
+
regex_str = Regexp.escape format
|
110
|
+
|
111
|
+
# Convert all the format characters to named capture groups
|
112
|
+
regex_str = regex_str.gsub('%M', '(?<major>\d+)').
|
113
|
+
gsub('%m', '(?<minor>\d+)').
|
114
|
+
gsub('%p', '(?<patch>\d+)').
|
115
|
+
gsub('%s', '(?:-(?<special>[A-Za-z][0-9A-Za-z\.]+))?')
|
116
|
+
|
117
|
+
regex = Regexp.new(regex_str)
|
118
|
+
match = regex.match version_string
|
119
|
+
|
120
|
+
if match
|
121
|
+
major = minor = patch = nil
|
122
|
+
special = ''
|
123
|
+
|
124
|
+
# Extract out the version parts
|
125
|
+
major = match[:major].to_i if match.names.include? 'major'
|
126
|
+
minor = match[:minor].to_i if match.names.include? 'minor'
|
127
|
+
patch = match[:patch].to_i if match.names.include? 'patch'
|
128
|
+
special = match[:special] || '' if match.names.include? 'special'
|
129
|
+
|
130
|
+
# Failed parse if major, minor, or patch wasn't found
|
131
|
+
# and allow_missing is false
|
132
|
+
return nil if !allow_missing and [major, minor, patch].any? {|x| x.nil? }
|
133
|
+
|
134
|
+
# Otherwise, allow them to default to zero
|
135
|
+
major ||= 0
|
136
|
+
minor ||= 0
|
137
|
+
patch ||= 0
|
138
|
+
|
139
|
+
SemVer.new major, minor, patch, special
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
data/semver2.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: semver2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.
|
4
|
+
version: 3.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,8 +10,24 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-02-
|
14
|
-
dependencies:
|
13
|
+
date: 2013-02-05 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ~>
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.12.0
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: 2.12.0
|
15
31
|
description: maintain versions as per http://semver.org
|
16
32
|
email: henrik@haf.se
|
17
33
|
executables:
|
@@ -24,6 +40,7 @@ files:
|
|
24
40
|
- README.md
|
25
41
|
- lib/semver/semvermissingerror.rb
|
26
42
|
- lib/semver.rb
|
43
|
+
- lib/xsemver.rb
|
27
44
|
- bin/semver
|
28
45
|
homepage: https://github.com/haf/semver
|
29
46
|
licenses: []
|