semver 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.semver +5 -0
- data/README.md +28 -0
- data/bin/semver +67 -0
- data/lib/semver.rb +108 -0
- data/semver.gemspec +14 -0
- metadata +59 -0
data/.semver
ADDED
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
SemVer
|
2
|
+
======
|
3
|
+
|
4
|
+
quickstart on the command line
|
5
|
+
------------------------------
|
6
|
+
install it
|
7
|
+
|
8
|
+
% gem install semver
|
9
|
+
|
10
|
+
use it
|
11
|
+
|
12
|
+
% semver init
|
13
|
+
% semver tag # => v0.0.0
|
14
|
+
% semver inc minor # => v0.1.0
|
15
|
+
% git tag -a `semver tag`
|
16
|
+
% say 'that was easy'
|
17
|
+
|
18
|
+
quickstart for ruby
|
19
|
+
-------------------
|
20
|
+
require 'semver'
|
21
|
+
v = SemVer.find
|
22
|
+
v.major # => "0"
|
23
|
+
v.major.next!
|
24
|
+
v.major # => "1"
|
25
|
+
v.format "%M.%m.%p" # => "1.1.0"
|
26
|
+
v.save
|
27
|
+
|
28
|
+
[Franco Lazzarino](mailto:flazzarino@gmail.com)
|
data/bin/semver
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'semver'
|
4
|
+
|
5
|
+
begin
|
6
|
+
command = ARGV.shift or raise "no command given"
|
7
|
+
|
8
|
+
case command
|
9
|
+
when /^init(ialize)?$/
|
10
|
+
FileUtils.touch SemVer::FILE_NAME
|
11
|
+
version = SemVer.find
|
12
|
+
version
|
13
|
+
version.save
|
14
|
+
|
15
|
+
when /^inc(rement)?$/
|
16
|
+
version = SemVer.find
|
17
|
+
dimension = ARGV.shift or raise "required: major | minor | patch"
|
18
|
+
|
19
|
+
case dimension
|
20
|
+
when 'major' then version.major.next!
|
21
|
+
when 'minor' then version.minor.next!
|
22
|
+
when 'patch' then version.patch.next!
|
23
|
+
else raise "#{dimension} is invalid: major | minor | patch"
|
24
|
+
end
|
25
|
+
|
26
|
+
version.special = ''
|
27
|
+
version.save
|
28
|
+
|
29
|
+
when /^spe(cial)?$/
|
30
|
+
version = SemVer.find
|
31
|
+
special_str = ARGV.shift or raise "required: an arbitrary string (beta, alfa, romeo, etc)"
|
32
|
+
version.special = special_str
|
33
|
+
version.save
|
34
|
+
|
35
|
+
when 'format'
|
36
|
+
version = SemVer.find
|
37
|
+
format_str = ARGV.shift or raise "required: format string"
|
38
|
+
version.format format_str
|
39
|
+
|
40
|
+
when 'tag'
|
41
|
+
version = SemVer.find
|
42
|
+
puts version.format "v%M.%m.%p%s"
|
43
|
+
|
44
|
+
when 'help'
|
45
|
+
puts <<-HELP
|
46
|
+
semver commands
|
47
|
+
---------------
|
48
|
+
|
49
|
+
init[ialze] # initialize semantic version tracking
|
50
|
+
inc[rement] major | minor | patch # increment a specific version number
|
51
|
+
spe[cial] [STRING] # set a special version suffix
|
52
|
+
format # printf like format: %M, %m, %p, %s
|
53
|
+
tag # equivalenti to format 'v%M.%m.%p%s'
|
54
|
+
help
|
55
|
+
|
56
|
+
PLEASE READ http://semver.org
|
57
|
+
HELP
|
58
|
+
|
59
|
+
else raise "invalid command #{command}"
|
60
|
+
end
|
61
|
+
|
62
|
+
rescue => e
|
63
|
+
puts e.message
|
64
|
+
puts e.backtrace
|
65
|
+
puts "#{$0} help for more info"
|
66
|
+
exit 1
|
67
|
+
end
|
data/lib/semver.rb
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
class SemVer
|
2
|
+
|
3
|
+
FILE_NAME = '.semver'
|
4
|
+
|
5
|
+
def SemVer.find dir=nil
|
6
|
+
v = SemVer.new
|
7
|
+
v.load
|
8
|
+
v
|
9
|
+
end
|
10
|
+
|
11
|
+
def SemVer.find_file dir=nil
|
12
|
+
dir ||= Dir.pwd
|
13
|
+
raise "#{dir} is not a directory" unless File.directory? dir
|
14
|
+
path = FILE_NAME
|
15
|
+
|
16
|
+
Dir.chdir dir do
|
17
|
+
|
18
|
+
loop do
|
19
|
+
|
20
|
+
if Dir[FILE_NAME].empty?
|
21
|
+
return nil if File.expand_path(path) == '/'
|
22
|
+
path = File.join '..', path
|
23
|
+
next
|
24
|
+
else
|
25
|
+
path = File.expand_path path
|
26
|
+
return path
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class << self
|
35
|
+
|
36
|
+
def attr_writer_pattern pattern, symbol
|
37
|
+
|
38
|
+
define_method("#{symbol}=".to_sym) do |str|
|
39
|
+
|
40
|
+
if str =~ pattern || str.empty?
|
41
|
+
instance_variable_set "@#{symbol}".to_sym, str
|
42
|
+
else
|
43
|
+
raise "#{symbol}: #{str} does not match pattern #{pattern}"
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
attr_writer_pattern /\d+/, :major
|
53
|
+
attr_writer_pattern /\d+/, :minor
|
54
|
+
attr_writer_pattern /\d+/, :patch
|
55
|
+
attr_writer_pattern /[A-Za-z][0-9A-Za-z-]+/, :special
|
56
|
+
attr_reader :major, :minor, :patch, :special
|
57
|
+
|
58
|
+
def initialize major='0', minor='0', patch='0', special=''
|
59
|
+
self.major, self.minor, self.patch, self.special = major.to_s, minor.to_s, patch.to_s, special.to_s
|
60
|
+
end
|
61
|
+
|
62
|
+
def load file=SemVer.find_file
|
63
|
+
hash = open(file) { |io| YAML::load io.read } || {}
|
64
|
+
self.major = hash[:major] || '0'
|
65
|
+
self.minor = hash[:minor] || '0'
|
66
|
+
self.patch = hash[:patch] || '0'
|
67
|
+
self.special = hash[:special] || ''
|
68
|
+
end
|
69
|
+
|
70
|
+
def save file=SemVer.find_file
|
71
|
+
|
72
|
+
hash = {
|
73
|
+
:major => @major,
|
74
|
+
:minor => @minor,
|
75
|
+
:patch => @patch,
|
76
|
+
:special => @special
|
77
|
+
}
|
78
|
+
|
79
|
+
yaml = YAML::dump hash
|
80
|
+
open(file, 'w') { |io| io.write yaml }
|
81
|
+
end
|
82
|
+
|
83
|
+
def format fmt
|
84
|
+
fmt.gsub! '%M', @major
|
85
|
+
fmt.gsub! '%m', @minor
|
86
|
+
fmt.gsub! '%p', @patch
|
87
|
+
fmt.gsub! '%s', @special
|
88
|
+
fmt
|
89
|
+
end
|
90
|
+
|
91
|
+
def <=> other
|
92
|
+
maj = major.to_i <=> other.major.to_i
|
93
|
+
return maj unless maj == 0
|
94
|
+
|
95
|
+
min = minor.to_i <=> other.minor.to_i
|
96
|
+
return min unless min == 0
|
97
|
+
|
98
|
+
pat = patch.to_i <=> other.patch.to_i
|
99
|
+
return pat unless pat == 0
|
100
|
+
|
101
|
+
spe = special <=> other.special
|
102
|
+
return spec unless spe == 0
|
103
|
+
|
104
|
+
0
|
105
|
+
end
|
106
|
+
|
107
|
+
include Comparable
|
108
|
+
end
|
data/semver.gemspec
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'semver'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "semver"
|
5
|
+
spec.version = SemVer.find.format '%M.%m.%p'
|
6
|
+
spec.summary = "Semantic Versioning"
|
7
|
+
spec.description = "maintain versions as per http://semver.rog"
|
8
|
+
spec.email = "flazzarino@gmail.com"
|
9
|
+
spec.authors = ["Francesco Lazzarino"]
|
10
|
+
spec.homepage = 'http://github.com/flazz/semver'
|
11
|
+
spec.executables << 'semver'
|
12
|
+
spec.files = [".semver", "semver.gemspec", "README.md"] + Dir["lib/**/*.rb"] + Dir['bin/*']
|
13
|
+
spec.has_rdoc = true
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: semver
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Francesco Lazzarino
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-02-13 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: maintain versions as per http://semver.rog
|
17
|
+
email: flazzarino@gmail.com
|
18
|
+
executables:
|
19
|
+
- semver
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- .semver
|
26
|
+
- semver.gemspec
|
27
|
+
- README.md
|
28
|
+
- lib/semver.rb
|
29
|
+
- bin/semver
|
30
|
+
has_rdoc: true
|
31
|
+
homepage: http://github.com/flazz/semver
|
32
|
+
licenses: []
|
33
|
+
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
|
37
|
+
require_paths:
|
38
|
+
- lib
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0"
|
44
|
+
version:
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: "0"
|
50
|
+
version:
|
51
|
+
requirements: []
|
52
|
+
|
53
|
+
rubyforge_project:
|
54
|
+
rubygems_version: 1.3.5
|
55
|
+
signing_key:
|
56
|
+
specification_version: 3
|
57
|
+
summary: Semantic Versioning
|
58
|
+
test_files: []
|
59
|
+
|