crackin 0.0.1.rc0
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.
- checksums.yaml +15 -0
- data/.crackin.yml +14 -0
- data/.gitignore +17 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/bin/crackin +92 -0
- data/crackin.gemspec +27 -0
- data/lib/crackin/changelog.rb +152 -0
- data/lib/crackin/config.rb +63 -0
- data/lib/crackin/ext/core/hash.rb +13 -0
- data/lib/crackin/ext/git/base.rb +13 -0
- data/lib/crackin/ext/git/lib.rb +7 -0
- data/lib/crackin/release.rb +187 -0
- data/lib/crackin/scm/git.rb +111 -0
- data/lib/crackin/scm.rb +45 -0
- data/lib/crackin/status.rb +144 -0
- data/lib/crackin/version.rb +10 -0
- data/lib/crackin/version_file.rb +100 -0
- data/lib/crackin.rb +11 -0
- metadata +136 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
OWNmZTcwNTc3MmY2Yjc2NWQ2NDU0YTdmMWRlOTY3NWVjODhlNmM2ZA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
OTBmMmFlMDBlMWIyYjczNDQ0OTJmZDVjNWI3NmRkMjBjN2UyZTk4Zg==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NTRjYTI5MzAyZTRkMjlkZDkyZjY3ZWZjYjJjZTY4ZWVkMGQwYWU4MTZhZWU0
|
10
|
+
NTg5MzM1Yjk2MjVlMDMyNTAzOTQ1YWE5ZjI0Mzc2Y2IxZWVhZTE5MmM5NTEz
|
11
|
+
NWIzNTE0OTllNTRmMWIxYjI0YjZkZjdhMjcxNzI5YmM2ZDFhNjc=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NWUwNjYwYTU0NTkwNmUyNmZhNTk4NGIwZTIyMWM2M2ViNTViODkxYTFhNWMx
|
14
|
+
MjdjYWU5MzljZjIxNDhlYTY4MGE5M2E4Njg5NTViOWU5ZWQxY2M4ZmZkOTI3
|
15
|
+
MDBjY2Q4Nzk3MjMxNjYwNDBkODc1NDk5YWQ5ODM2NDhmYWEwMDE=
|
data/.crackin.yml
ADDED
data/.gitignore
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-1.9.3-p448@crackin
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Shawn Catanzarite
|
2
|
+
|
3
|
+
MIT License
|
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
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Crackin
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'crackin'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install crackin
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/crackin
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'clamp'
|
5
|
+
require 'crackin'
|
6
|
+
|
7
|
+
module Crackin
|
8
|
+
class Command < Clamp::Command
|
9
|
+
option %w{-c --config}, '[CONFIG]', 'configuration file', environment_variable: 'CRACKIN_CONFIG', default: './.crackin.yml' do |config|
|
10
|
+
Crackin::Config.load(config)
|
11
|
+
end
|
12
|
+
subcommand 'init', 'intialize a directory for use with crackin' do
|
13
|
+
def execute
|
14
|
+
data = {crackin: Crackin::Config.defaults}.deep_stringify_keys
|
15
|
+
File.open(".crackin.yml", "w+") {|f| f.write(data.to_yaml)}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
subcommand 'status', 'show status information' do
|
19
|
+
def execute
|
20
|
+
puts Crackin::Status.new
|
21
|
+
end
|
22
|
+
end
|
23
|
+
subcommand 'release', 'commands for doing releases' do
|
24
|
+
option %w{-n --dryrun}, :flag, 'mock commands', default: false
|
25
|
+
subcommand 'major', 'major release' do
|
26
|
+
def execute
|
27
|
+
release_start(:major, dryrun?)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
subcommand 'minor', 'minor release' do
|
31
|
+
def execute
|
32
|
+
release_start(:minor, dryrun?)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
subcommand 'tiny', 'tiny release' do
|
36
|
+
def execute
|
37
|
+
release_start(:tiny, dryrun?)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
subcommand 'rc', 'release candidate release' do
|
41
|
+
def execute
|
42
|
+
release_start(:rc, dryrun?)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
subcommand 'beta', 'beta release' do
|
46
|
+
def execute
|
47
|
+
release_start(:beta, dryrun?)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
subcommand 'alpha', 'alpha release' do
|
51
|
+
def execute
|
52
|
+
release_start(:alpha, dryrun?)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
subcommand 'rollback', 'rollback release changes' do
|
56
|
+
def execute
|
57
|
+
release_rollback(dryrun?)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
subcommand 'finish', 'complete release process' do
|
61
|
+
def execute
|
62
|
+
release_finish(dryrun?)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def state(wanted)
|
68
|
+
status = Crackin::Status.new
|
69
|
+
status.state == wanted
|
70
|
+
end
|
71
|
+
def release_start(type, real)
|
72
|
+
raise "cannot start release when you're not in state == development" unless state('development')
|
73
|
+
Crackin::Release.new(type).start(real: real)
|
74
|
+
end
|
75
|
+
def release_rollback(real)
|
76
|
+
raise "cannot rollback when you're not in state == releasing" unless state('releasing')
|
77
|
+
Crackin::Release.new(:none).rollback(real: real)
|
78
|
+
end
|
79
|
+
def release_finish(real)
|
80
|
+
raise "cannot finish when you're not in state == releasing" unless state('releasing')
|
81
|
+
Crackin::Release.new(:none).finish(real: real)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
begin
|
87
|
+
Crackin::Command.run
|
88
|
+
rescue => e
|
89
|
+
puts "error: #{e.message}"
|
90
|
+
e.backtrace.each {|l| puts " #{l}"}
|
91
|
+
exit 1
|
92
|
+
end
|
data/crackin.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'crackin/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "crackin"
|
8
|
+
spec.version = Crackin::Version::STRING
|
9
|
+
spec.authors = ["Shawn Catanzarite"]
|
10
|
+
spec.email = ["me@shawncatz.com"]
|
11
|
+
spec.description = %q{release the crackin - gem release management}
|
12
|
+
spec.summary = %q{release the crackin - gem release management}
|
13
|
+
spec.homepage = "http://github.com/shawncatz/crackin"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency 'git'
|
22
|
+
spec.add_dependency 'clamp'
|
23
|
+
spec.add_dependency 'activesupport'
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
26
|
+
spec.add_development_dependency "rake"
|
27
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
module Crackin
|
2
|
+
class Changelog
|
3
|
+
def initialize(file, version, options={})
|
4
|
+
@options = {
|
5
|
+
first: false
|
6
|
+
}.merge(options)
|
7
|
+
@output = file
|
8
|
+
@version = version
|
9
|
+
@config = Crackin.config
|
10
|
+
@source = @config.source
|
11
|
+
@data = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
tags = order_tags([@version, source_tags, @data.keys].flatten.uniq).reverse
|
16
|
+
out = "### Changelog\n\n"
|
17
|
+
tags.each do |section|
|
18
|
+
lines = @data[section]
|
19
|
+
out += "##### #{section}:\n"
|
20
|
+
out += lines.join("\n") if lines
|
21
|
+
out += "\n\n"
|
22
|
+
end
|
23
|
+
out
|
24
|
+
end
|
25
|
+
|
26
|
+
def update
|
27
|
+
tags = ordered_tags
|
28
|
+
load
|
29
|
+
@data[@version] = between(tags.last, 'HEAD').uniq
|
30
|
+
end
|
31
|
+
|
32
|
+
def full
|
33
|
+
tags = ordered_tags
|
34
|
+
to = 'HEAD'
|
35
|
+
name = @version
|
36
|
+
tags.reverse_each do |from|
|
37
|
+
@data[name] = between(from, to).uniq
|
38
|
+
to = from
|
39
|
+
name = from
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def save
|
44
|
+
File.open(@output, "w+") {|f| f.write(to_s)}
|
45
|
+
end
|
46
|
+
|
47
|
+
protected
|
48
|
+
|
49
|
+
def ordered_tags
|
50
|
+
order_tags(source_tags)
|
51
|
+
end
|
52
|
+
|
53
|
+
def order_tags(list)
|
54
|
+
ordered = list.sort_by { |e| tag_to_number(e) }
|
55
|
+
ordered #.reject { |e| (a, b, c, d) = e.split("."); !d.nil? }
|
56
|
+
end
|
57
|
+
|
58
|
+
def tag_to_number(tag)
|
59
|
+
(a, b, c, d) = tag.gsub(/^v/, "").split(".")
|
60
|
+
tags = {'rc' => 3, 'beta' => 2, 'alpha' => 1}
|
61
|
+
t = 4
|
62
|
+
n = 0
|
63
|
+
if d && d =~ /(\w+)(\d+)/
|
64
|
+
t = tags[$1]
|
65
|
+
n = $2
|
66
|
+
end
|
67
|
+
str = ("%03d%03d%03d%03d%03d" % [a, b, c, t, n])
|
68
|
+
number = str.to_i
|
69
|
+
#puts "## #{tag} => #{str} => #{number}"
|
70
|
+
number
|
71
|
+
end
|
72
|
+
|
73
|
+
def source_tags
|
74
|
+
@source.tags.all.map(&:name)
|
75
|
+
end
|
76
|
+
|
77
|
+
def load
|
78
|
+
return unless File.exists?(@output)
|
79
|
+
file = File.open(@output).read
|
80
|
+
section = nil
|
81
|
+
file.lines.each do |line|
|
82
|
+
next if line =~ /^$/
|
83
|
+
if line =~ /^#####\s+(.*):/
|
84
|
+
section = $1
|
85
|
+
next
|
86
|
+
end
|
87
|
+
if section
|
88
|
+
@data[section] ||= []
|
89
|
+
@data[section] << line.chomp
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def between(from, to)
|
95
|
+
log = @source.between(from, to)
|
96
|
+
out = []
|
97
|
+
log.each do |c|
|
98
|
+
m = message(c.message)
|
99
|
+
out << m if m
|
100
|
+
end
|
101
|
+
out
|
102
|
+
end
|
103
|
+
|
104
|
+
def message(m)
|
105
|
+
out = nil
|
106
|
+
if m !~ /^(merge|v|version|changelog|crackin)/i
|
107
|
+
out = "* #{m}"
|
108
|
+
end
|
109
|
+
out
|
110
|
+
end
|
111
|
+
|
112
|
+
#def changelog(last=nil, single=false)
|
113
|
+
# command="git --no-pager log --format='%an::::%h::::%s'"
|
114
|
+
#
|
115
|
+
# list = `git tag`
|
116
|
+
#
|
117
|
+
# puts "# Changelog"
|
118
|
+
# puts
|
119
|
+
#
|
120
|
+
# ordered = list.lines.sort_by { |e| (a, b, c) = e.gsub(/^v/, "").split("."); "%3d%3d%3d" % [a, b, c] }
|
121
|
+
#
|
122
|
+
# ordered.reject { |e| (a, b, c, d) = e.split("."); !d.nil? }.reverse_each do |t|
|
123
|
+
# tag = t.chomp
|
124
|
+
#
|
125
|
+
# if last
|
126
|
+
# check = {}
|
127
|
+
# out = []
|
128
|
+
# log = `#{command} #{last}...#{tag}`
|
129
|
+
# log.lines.each do |line|
|
130
|
+
# (who, hash, msg) = line.split('::::')
|
131
|
+
# unless check[msg]
|
132
|
+
# unless msg =~ /^Merge branch/ || msg =~ /CHANGELOG/ || msg =~ /^(v|version|changes for|preparing|ready for release|ready to release|bump version)*\s*(v|version)*\d+\.\d+\.\d+/
|
133
|
+
# msg.gsub(" *", "\n*").gsub(/^\*\*/, " *").lines.each do |l|
|
134
|
+
# line = l =~ /^(\s+)*\*/ ? l : "* #{l}"
|
135
|
+
# out << line
|
136
|
+
# end
|
137
|
+
# check[msg] = hash
|
138
|
+
# end
|
139
|
+
# end
|
140
|
+
# end
|
141
|
+
# puts "## #{last}:"
|
142
|
+
# out.each { |e| puts e }
|
143
|
+
# #puts log
|
144
|
+
# puts
|
145
|
+
# end
|
146
|
+
#
|
147
|
+
# last = tag
|
148
|
+
# exit if single
|
149
|
+
# end
|
150
|
+
#end
|
151
|
+
end
|
152
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'active_support/all'
|
3
|
+
|
4
|
+
module Crackin
|
5
|
+
class Config
|
6
|
+
attr_reader :source
|
7
|
+
|
8
|
+
def initialize(file="./.crackin.yml")
|
9
|
+
yaml = YAML.load_file(file)
|
10
|
+
@config = self.class.defaults.deep_merge(yaml['crackin']||{})
|
11
|
+
@source = Crackin::Scm.open(@config)
|
12
|
+
end
|
13
|
+
|
14
|
+
def [](key)
|
15
|
+
@config[key]
|
16
|
+
end
|
17
|
+
|
18
|
+
class << self
|
19
|
+
def load(file="./.crackin.yml")
|
20
|
+
@config = Crackin::Config.new(file)
|
21
|
+
end
|
22
|
+
|
23
|
+
def instance
|
24
|
+
@config || load
|
25
|
+
end
|
26
|
+
|
27
|
+
def defaults
|
28
|
+
{
|
29
|
+
name: '<app>',
|
30
|
+
scm: 'git',
|
31
|
+
changelog: 'CHANGELOG.md',
|
32
|
+
branch: {
|
33
|
+
production: 'master',
|
34
|
+
development: 'develop'
|
35
|
+
},
|
36
|
+
status: {
|
37
|
+
verbose: true
|
38
|
+
},
|
39
|
+
version: 'lib/<app>/version.rb',
|
40
|
+
build: {
|
41
|
+
command: 'rake build', # gem build :name.gemspec && mkdir -p pkg && mv :name.gem pkg
|
42
|
+
after: []
|
43
|
+
}
|
44
|
+
|
45
|
+
}.deep_stringify_keys
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class << self
|
51
|
+
def config
|
52
|
+
Crackin::Config.instance
|
53
|
+
end
|
54
|
+
|
55
|
+
def version
|
56
|
+
Crackin::VersionFile.new(config['version'])
|
57
|
+
end
|
58
|
+
|
59
|
+
def source
|
60
|
+
config.source
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Hash
|
2
|
+
def deep_transform_keys(&block)
|
3
|
+
result = {}
|
4
|
+
each do |key, value|
|
5
|
+
result[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys(&block) : value
|
6
|
+
end
|
7
|
+
result
|
8
|
+
end unless Hash.respond_to?(:deep_transform_keys)
|
9
|
+
|
10
|
+
def deep_stringify_keys
|
11
|
+
deep_transform_keys{ |key| key.to_s }
|
12
|
+
end unless Hash.respond_to?(:deep_stringify_keys)
|
13
|
+
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
module Crackin
|
2
|
+
class Release
|
3
|
+
def initialize(type)
|
4
|
+
@config = Crackin.config
|
5
|
+
@source = @config.source
|
6
|
+
@current = @source.current_branch
|
7
|
+
@type = type
|
8
|
+
@version = Crackin::VersionFile.new(@config['version'])
|
9
|
+
raise "unknown version type: #{type}" unless @version.respond_to?(type.to_sym)
|
10
|
+
@version.send(type.to_sym)
|
11
|
+
end
|
12
|
+
|
13
|
+
def start(options={})
|
14
|
+
o = {
|
15
|
+
real: true
|
16
|
+
}.merge(options)
|
17
|
+
# make sure no pending changes
|
18
|
+
raise "there are pending changes" if o[:real] && @source.pending?
|
19
|
+
|
20
|
+
puts "release: #{@version}"
|
21
|
+
run(start_actions)
|
22
|
+
end
|
23
|
+
|
24
|
+
def finish(options={})
|
25
|
+
o = {
|
26
|
+
real: true
|
27
|
+
}.merge(options)
|
28
|
+
run(finish_actions)
|
29
|
+
end
|
30
|
+
|
31
|
+
def rollback(options={})
|
32
|
+
puts "rolling back: #{@version}"
|
33
|
+
undo(start_actions)
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
|
38
|
+
def run(actions)
|
39
|
+
begin
|
40
|
+
actions.each do |action|
|
41
|
+
puts ".. #{action[:name]}"
|
42
|
+
if action.keys.include?(:if) && !action[:if]
|
43
|
+
raise action[:failed] || "if statement evaluated to false"
|
44
|
+
end
|
45
|
+
action[:do].call
|
46
|
+
action[:success] = true
|
47
|
+
end
|
48
|
+
rescue => e
|
49
|
+
puts "** action failed: #{e.message}"
|
50
|
+
puts "## rolling back"
|
51
|
+
undo(actions)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def undo(actions)
|
56
|
+
actions.reverse.each do |action|
|
57
|
+
puts ".. undo: #{action[:name]}"
|
58
|
+
begin
|
59
|
+
action[:undo].call if action[:undo] #&& (action.keys.include?(:success) && action[:success])
|
60
|
+
rescue => e
|
61
|
+
puts "** failed: #{e.message}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def start_actions
|
67
|
+
actions = []
|
68
|
+
# change branch
|
69
|
+
actions << {
|
70
|
+
name: "change to production branch",
|
71
|
+
do: -> { @source.change_branch(@config['branch']['production']) },
|
72
|
+
undo: -> { @source.change_branch(@config['branch']['development']) },
|
73
|
+
if: @current == @config['branch']['development']
|
74
|
+
}
|
75
|
+
# create release branch
|
76
|
+
actions << {
|
77
|
+
name: "create release branch",
|
78
|
+
do: -> { @source.create_branch("crackin_#{@version.name}") },
|
79
|
+
undo: -> { @source.delete_branch("crackin_#{@version.name}") },
|
80
|
+
}
|
81
|
+
# merge from develop
|
82
|
+
actions << {
|
83
|
+
name: "merge from develop",
|
84
|
+
do: -> { @source.merge_from(@config['branch']['development']) },
|
85
|
+
undo: -> { @source.uncommit },
|
86
|
+
}
|
87
|
+
# change version file
|
88
|
+
actions << {
|
89
|
+
name: "update version file",
|
90
|
+
do: -> { @version.save },
|
91
|
+
undo: -> { @source.reset },
|
92
|
+
}
|
93
|
+
# changelog
|
94
|
+
actions << {
|
95
|
+
name: "update changelog",
|
96
|
+
do: -> {
|
97
|
+
changelog = Crackin::Changelog.new(@config['changelog'], @version.name)
|
98
|
+
changelog.update
|
99
|
+
changelog.save
|
100
|
+
},
|
101
|
+
undo: -> { @source.reset },
|
102
|
+
}
|
103
|
+
actions
|
104
|
+
end
|
105
|
+
|
106
|
+
def finish_actions
|
107
|
+
actions = []
|
108
|
+
unless File.exist?(File.expand_path('~/.gem/credentials'))
|
109
|
+
puts "gem credentials are not saved, you must run 'gem push pkg/#{@config['name']}-#{@version.name}.gem' to set them"
|
110
|
+
return
|
111
|
+
end
|
112
|
+
# commit
|
113
|
+
actions << {
|
114
|
+
name: "commit version and changelog",
|
115
|
+
do: -> { @source.commit(@version.name) },
|
116
|
+
undo: -> { @source.uncommit },
|
117
|
+
}
|
118
|
+
# change branch
|
119
|
+
actions << {
|
120
|
+
name: "change to production branch",
|
121
|
+
do: -> { @source.change_branch(@config['branch']['production']) },
|
122
|
+
undo: -> { @source.change_branch(@config['branch']['development']) },
|
123
|
+
#if: -> { @current != @config['branch']['production'] }
|
124
|
+
}
|
125
|
+
# merge from crackin branch
|
126
|
+
actions << {
|
127
|
+
name: "merge from crackin release branch",
|
128
|
+
do: -> { @source.merge_from(@current) },
|
129
|
+
undo: -> { @source.uncommit },
|
130
|
+
}
|
131
|
+
# tag
|
132
|
+
actions << {
|
133
|
+
name: "create tag",
|
134
|
+
do: -> { @source.tags.create(@version.name) },
|
135
|
+
undo: -> { @source.tags.delete(@version.name) },
|
136
|
+
}
|
137
|
+
# build
|
138
|
+
actions << {
|
139
|
+
name: "run build",
|
140
|
+
do: -> { raise "system command failed" unless system(@config['build']['command']) },
|
141
|
+
}
|
142
|
+
# push
|
143
|
+
actions << {
|
144
|
+
name: "source push",
|
145
|
+
do: -> { @source.push },
|
146
|
+
}
|
147
|
+
# push tags
|
148
|
+
actions << {
|
149
|
+
name: "tags push",
|
150
|
+
do: -> { @source.push_tags('origin', @config['branch']['production']) },
|
151
|
+
}
|
152
|
+
# gem push
|
153
|
+
actions << {
|
154
|
+
name: "gem push 'pkg/#{@config['name']}-#{@version.number}.gem'",
|
155
|
+
do: -> {
|
156
|
+
raise "system command failed" unless system("gem push pkg/#{@config['name']}-#{@version.number}.gem")
|
157
|
+
},
|
158
|
+
undo: -> {
|
159
|
+
puts "** You will need to manually yank the gem that was pushed."
|
160
|
+
}
|
161
|
+
}
|
162
|
+
# change branch
|
163
|
+
actions << {
|
164
|
+
name: "change to development branch",
|
165
|
+
do: -> { @source.change_branch(@config['branch']['development']) },
|
166
|
+
undo: -> { @source.change_branch(@config['branch']['production']) },
|
167
|
+
}
|
168
|
+
# merge from production
|
169
|
+
actions << {
|
170
|
+
name: "merge from production",
|
171
|
+
do: -> { @source.merge_from(@config['branch']['production']) },
|
172
|
+
undo: -> { @source.uncommit },
|
173
|
+
}
|
174
|
+
# delete release branch
|
175
|
+
actions << {
|
176
|
+
name: "delete release branch",
|
177
|
+
do: -> { @source.delete_branch("crackin_#{@version.name}") },
|
178
|
+
}
|
179
|
+
# push
|
180
|
+
actions << {
|
181
|
+
name: "source push",
|
182
|
+
do: -> { @source.push },
|
183
|
+
}
|
184
|
+
actions
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'git'
|
2
|
+
require 'shellwords'
|
3
|
+
|
4
|
+
module Crackin
|
5
|
+
module Scm
|
6
|
+
class Git < Base
|
7
|
+
attr_reader :git
|
8
|
+
def initialize(config={})
|
9
|
+
super
|
10
|
+
#@git = ::Git.open(@options[:working], log: Logger.new(STDOUT))
|
11
|
+
@git = ::Git.open(@options[:working])
|
12
|
+
end
|
13
|
+
|
14
|
+
def log
|
15
|
+
@git.log
|
16
|
+
end
|
17
|
+
|
18
|
+
def between(from, to)
|
19
|
+
@git.log.between(from, to)
|
20
|
+
end
|
21
|
+
|
22
|
+
def tags
|
23
|
+
Tags.new(@git)
|
24
|
+
end
|
25
|
+
|
26
|
+
def commit(message)
|
27
|
+
@git.commit_all(message)
|
28
|
+
end
|
29
|
+
|
30
|
+
def uncommit
|
31
|
+
@git.reset_hard('HEAD^')
|
32
|
+
end
|
33
|
+
|
34
|
+
def reset
|
35
|
+
@git.checkout_file('--', '.')
|
36
|
+
@git.clean(d: true, force: true)
|
37
|
+
#pending.keys.each do |p|
|
38
|
+
# puts "pending: #{p}"
|
39
|
+
# @git.checkout_file('--', p)
|
40
|
+
#end
|
41
|
+
end
|
42
|
+
|
43
|
+
def merge_from(from)
|
44
|
+
@git.branch(from).merge
|
45
|
+
end
|
46
|
+
|
47
|
+
def current_branch
|
48
|
+
@git.branch_current
|
49
|
+
end
|
50
|
+
|
51
|
+
def change_branch(to)
|
52
|
+
@git.checkout(to)
|
53
|
+
end
|
54
|
+
|
55
|
+
def create_branch(name)
|
56
|
+
branch = @git.branch(Shellwords.escape(name))
|
57
|
+
branch.create
|
58
|
+
branch.checkout
|
59
|
+
end
|
60
|
+
|
61
|
+
def delete_branch(name)
|
62
|
+
@git.checkout
|
63
|
+
@git.branch(Shellwords.escape(name)).delete
|
64
|
+
end
|
65
|
+
|
66
|
+
def push
|
67
|
+
@git.push
|
68
|
+
end
|
69
|
+
|
70
|
+
def push_tags(remote=@git.remote, branch=current_branch)
|
71
|
+
@git.push(remote, branch, true)
|
72
|
+
end
|
73
|
+
|
74
|
+
def pending
|
75
|
+
s = @git.status
|
76
|
+
d = {}
|
77
|
+
d.merge! s.changed
|
78
|
+
d.merge! s.added
|
79
|
+
d.merge! s.deleted
|
80
|
+
d.merge! s.untracked
|
81
|
+
d
|
82
|
+
end
|
83
|
+
|
84
|
+
def pending?
|
85
|
+
pending.count > 0
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
class Tags < Git
|
90
|
+
def initialize(git)
|
91
|
+
@git = git
|
92
|
+
end
|
93
|
+
|
94
|
+
def find(name)
|
95
|
+
@git.tag(name)
|
96
|
+
end
|
97
|
+
|
98
|
+
def create(name)
|
99
|
+
@git.add_tag(name)
|
100
|
+
end
|
101
|
+
|
102
|
+
def all
|
103
|
+
@git.tags
|
104
|
+
end
|
105
|
+
|
106
|
+
def destroy(name)
|
107
|
+
@git.tag_delete(name)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
data/lib/crackin/scm.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
module Crackin
|
2
|
+
module Scm
|
3
|
+
class Base
|
4
|
+
def initialize(config={})
|
5
|
+
@options = {
|
6
|
+
production: 'master',
|
7
|
+
working: File.expand_path('.')
|
8
|
+
}.merge(config)
|
9
|
+
end
|
10
|
+
|
11
|
+
def commit(message)
|
12
|
+
raise "not implemented"
|
13
|
+
end
|
14
|
+
|
15
|
+
def change_branch
|
16
|
+
raise "not implemented"
|
17
|
+
end
|
18
|
+
|
19
|
+
def push
|
20
|
+
raise "not implemented"
|
21
|
+
end
|
22
|
+
|
23
|
+
def tag
|
24
|
+
raise "not implemented"
|
25
|
+
end
|
26
|
+
|
27
|
+
def push_tags
|
28
|
+
raise "not implemented"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class << self
|
33
|
+
def open(options)
|
34
|
+
name = options['scm'] || 'git'
|
35
|
+
klass = "Crackin::Scm::#{name.capitalize}".constantize
|
36
|
+
#puts "loading: #{klass}"
|
37
|
+
klass.new(options)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
Dir["#{File.dirname(__FILE__)}/scm/*.rb"].each do |file|
|
44
|
+
require "#{file.gsub(/\.rb/, '')}"
|
45
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
module Crackin
|
2
|
+
class Status
|
3
|
+
attr_reader :state
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@config = Crackin.config
|
7
|
+
@source = @config.source
|
8
|
+
@verbose = @config['status']['verbose']
|
9
|
+
@version = Crackin::VersionFile.new(@config['version'])
|
10
|
+
@notices = []
|
11
|
+
|
12
|
+
process
|
13
|
+
end
|
14
|
+
|
15
|
+
def process
|
16
|
+
if (@source.current_branch =~ /^crackin_/) == 0
|
17
|
+
# we're releasing
|
18
|
+
@state = 'releasing'
|
19
|
+
@notices << notice_releasing
|
20
|
+
@notices << notice_releasing_pending if @source.pending
|
21
|
+
@notices << notice_releasing_finish
|
22
|
+
elsif @source.current_branch == @config['branch']['development']
|
23
|
+
@state = 'development'
|
24
|
+
@notices << notice_development
|
25
|
+
elsif @source.current_branch == @config['branch']['production']
|
26
|
+
@state = 'production'
|
27
|
+
@notices << notice_production
|
28
|
+
else
|
29
|
+
@state = 'unknown'
|
30
|
+
@notices << notice_unknown
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def releasing?
|
35
|
+
@state == 'releasing'
|
36
|
+
end
|
37
|
+
|
38
|
+
def production?
|
39
|
+
@state == 'production'
|
40
|
+
end
|
41
|
+
|
42
|
+
def development?
|
43
|
+
@state == 'development'
|
44
|
+
end
|
45
|
+
|
46
|
+
def unknown?
|
47
|
+
@state == 'unknown'
|
48
|
+
end
|
49
|
+
|
50
|
+
def status_line
|
51
|
+
"crackin # '#{@version}' # on branch: '#{@source.current_branch}' ('#{@state}') # pending changes: '#{@source.pending?}'"
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_s
|
55
|
+
out = []
|
56
|
+
out += @notices if @verbose
|
57
|
+
out << status_line
|
58
|
+
out.join("\n")
|
59
|
+
end
|
60
|
+
|
61
|
+
protected
|
62
|
+
|
63
|
+
def notice_releasing
|
64
|
+
<<-RELEASING
|
65
|
+
You are in the midst of a release.
|
66
|
+
RELEASING
|
67
|
+
end
|
68
|
+
|
69
|
+
def notice_releasing_pending
|
70
|
+
<<-PENDING
|
71
|
+
There are pending changes.
|
72
|
+
Most likely, these are the changes made for you by Crackin.
|
73
|
+
The changes include updating your version file and change log.
|
74
|
+
Verify the changes and add any additional comments to the change log.
|
75
|
+
PENDING
|
76
|
+
end
|
77
|
+
|
78
|
+
def notice_releasing_finish
|
79
|
+
<<-FINISH
|
80
|
+
To continue run the following command:
|
81
|
+
crackin release finish
|
82
|
+
|
83
|
+
To abort - if you've changed your mind - run the following command:
|
84
|
+
crackin release rollback
|
85
|
+
FINISH
|
86
|
+
end
|
87
|
+
|
88
|
+
def notice_development
|
89
|
+
<<-DEV
|
90
|
+
You are ready for development. Make changes to the develop branch, or merge
|
91
|
+
features from feature branches.
|
92
|
+
Commit and push your changes.
|
93
|
+
|
94
|
+
When you wish to start a release, run the following command:
|
95
|
+
crackin release <type>
|
96
|
+
|
97
|
+
Crackin uses semantic versioning, for more information see: http://semver.org
|
98
|
+
<type> can be one of the following:
|
99
|
+
|
100
|
+
crackin release major # => release #{@version.dup.major}
|
101
|
+
crackin release minor # => release #{@version.dup.minor}
|
102
|
+
crackin release tiny # => release #{@version.dup.tiny}
|
103
|
+
crackin release rc # => release #{@version.dup.rc} # tag type
|
104
|
+
crackin release beta # => release #{@version.dup.beta} # tag type
|
105
|
+
crackin release alpha # => release #{@version.dup.alpha} # tag type
|
106
|
+
|
107
|
+
subsequent tag type releases increment the tag number rc1, beta1, alpha1.
|
108
|
+
you can release a main type release which will clear the tag.
|
109
|
+
An example timeline of releases:
|
110
|
+
|
111
|
+
start v0.4.0
|
112
|
+
alpha release v0.4.1.alpha0
|
113
|
+
alpha release v0.4.1.alpha1
|
114
|
+
beta release v0.4.1.beta0
|
115
|
+
rc release v0.4.1.rc0
|
116
|
+
rc release v0.4.1.rc1
|
117
|
+
tiny release v0.4.1
|
118
|
+
DEV
|
119
|
+
end
|
120
|
+
|
121
|
+
def notice_production
|
122
|
+
<<-PRODUCTION
|
123
|
+
You are on the production branch. Normal work will happen on development branches.
|
124
|
+
For now, Crackin does not support any other process than the default:
|
125
|
+
1. make changes to development branch, or merge changes there from feature branches.
|
126
|
+
2. crackin release <type> - merge development and production, update version and change log.
|
127
|
+
|
128
|
+
*** HOT FIX RELEASES ARE NOT YET SUPPORTED ***
|
129
|
+
PRODUCTION
|
130
|
+
end
|
131
|
+
|
132
|
+
def notice_unknown
|
133
|
+
<<-UNKNOWN
|
134
|
+
You are in an unknown state. Normally this happens for one of two reasons:
|
135
|
+
|
136
|
+
1. There is a problem with your configuration.
|
137
|
+
Make sure that you have the branch values configured correctly
|
138
|
+
2. You are doing feature development on a feature branch.
|
139
|
+
This is ok, you just need to merge your changes to your development branch
|
140
|
+
Then you can use crackin to do releases.
|
141
|
+
UNKNOWN
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module Crackin
|
2
|
+
class VersionFile
|
3
|
+
def initialize(path)
|
4
|
+
@path = path
|
5
|
+
load
|
6
|
+
end
|
7
|
+
|
8
|
+
def load
|
9
|
+
File.read(@path).lines.each do |line|
|
10
|
+
@major = $1.to_i if line =~ /MAJOR\s+=\s+(\d+)/
|
11
|
+
@minor = $1.to_i if line =~ /MINOR\s+=\s+(\d+)/
|
12
|
+
@tiny = $1.to_i if line =~ /TINY\s+=\s+(\d+)/
|
13
|
+
if line =~ /TAG\s+=\s+(.*)/
|
14
|
+
@tag = $1
|
15
|
+
@tag.gsub!(/['"]/, '')
|
16
|
+
@tag = nil if @tag == 'nil'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def save
|
22
|
+
out = []
|
23
|
+
tag = @tag ? "'#{@tag}'" : "nil"
|
24
|
+
File.open(@path).lines.each do |line|; line.chomp!
|
25
|
+
line.gsub!(/(\s+)MAJOR\s+=\s+\d+/, "\\1MAJOR = #{@major}")
|
26
|
+
line.gsub!(/(\s+)MINOR\s+=\s+\d+/, "\\1MINOR = #{@minor}")
|
27
|
+
line.gsub!(/(\s+)TINY\s+=\s+\d+/, "\\1TINY = #{@tiny}")
|
28
|
+
line.gsub!(/(\s+)TAG\s+=\s+(nil|['"].*['"])/, "\\1TAG = #{tag}")
|
29
|
+
out << line
|
30
|
+
end
|
31
|
+
File.open(@path, "w+") {|f| f.write(out.join("\n"))}
|
32
|
+
end
|
33
|
+
|
34
|
+
def name
|
35
|
+
"v#{number}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_s
|
39
|
+
name
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_a
|
43
|
+
[@major, @minor, @tiny, @tag].compact
|
44
|
+
end
|
45
|
+
|
46
|
+
def number
|
47
|
+
to_a.join('.')
|
48
|
+
end
|
49
|
+
|
50
|
+
def major
|
51
|
+
@major += 1
|
52
|
+
@minor = 0
|
53
|
+
@tiny = 0
|
54
|
+
@tag = nil
|
55
|
+
name
|
56
|
+
end
|
57
|
+
|
58
|
+
def minor
|
59
|
+
@minor += 1
|
60
|
+
@tiny = 0
|
61
|
+
@tag = nil
|
62
|
+
name
|
63
|
+
end
|
64
|
+
|
65
|
+
def tiny
|
66
|
+
@tiny += 1 unless @tag
|
67
|
+
@tag = nil
|
68
|
+
name
|
69
|
+
end
|
70
|
+
|
71
|
+
def rc
|
72
|
+
tag('rc')
|
73
|
+
name
|
74
|
+
end
|
75
|
+
|
76
|
+
def beta
|
77
|
+
tag('beta')
|
78
|
+
name
|
79
|
+
end
|
80
|
+
|
81
|
+
def alpha
|
82
|
+
tag('alpha')
|
83
|
+
name
|
84
|
+
end
|
85
|
+
|
86
|
+
def tag(type)
|
87
|
+
if @tag =~ /#{type}(\d+)/
|
88
|
+
num = $1.to_i + 1
|
89
|
+
@tag = "#{type}#{num}"
|
90
|
+
else
|
91
|
+
@tiny += 1
|
92
|
+
@tag = "#{type}0"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def none
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/lib/crackin.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'crackin/version'
|
2
|
+
require 'crackin/scm'
|
3
|
+
require 'crackin/config'
|
4
|
+
require 'crackin/status'
|
5
|
+
require 'crackin/version_file'
|
6
|
+
require 'crackin/changelog'
|
7
|
+
require 'crackin/release'
|
8
|
+
|
9
|
+
require 'crackin/ext/git/base'
|
10
|
+
require 'crackin/ext/git/lib'
|
11
|
+
require 'crackin/ext/core/hash'
|
metadata
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: crackin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.rc0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Shawn Catanzarite
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-11-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: git
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ! '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: clamp
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: activesupport
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.3'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.3'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ! '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: release the crackin - gem release management
|
84
|
+
email:
|
85
|
+
- me@shawncatz.com
|
86
|
+
executables:
|
87
|
+
- crackin
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- .crackin.yml
|
92
|
+
- .gitignore
|
93
|
+
- .ruby-version
|
94
|
+
- Gemfile
|
95
|
+
- LICENSE.txt
|
96
|
+
- README.md
|
97
|
+
- Rakefile
|
98
|
+
- bin/crackin
|
99
|
+
- crackin.gemspec
|
100
|
+
- lib/crackin.rb
|
101
|
+
- lib/crackin/changelog.rb
|
102
|
+
- lib/crackin/config.rb
|
103
|
+
- lib/crackin/ext/core/hash.rb
|
104
|
+
- lib/crackin/ext/git/base.rb
|
105
|
+
- lib/crackin/ext/git/lib.rb
|
106
|
+
- lib/crackin/release.rb
|
107
|
+
- lib/crackin/scm.rb
|
108
|
+
- lib/crackin/scm/git.rb
|
109
|
+
- lib/crackin/status.rb
|
110
|
+
- lib/crackin/version.rb
|
111
|
+
- lib/crackin/version_file.rb
|
112
|
+
homepage: http://github.com/shawncatz/crackin
|
113
|
+
licenses:
|
114
|
+
- MIT
|
115
|
+
metadata: {}
|
116
|
+
post_install_message:
|
117
|
+
rdoc_options: []
|
118
|
+
require_paths:
|
119
|
+
- lib
|
120
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ! '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - ! '>'
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: 1.3.1
|
130
|
+
requirements: []
|
131
|
+
rubyforge_project:
|
132
|
+
rubygems_version: 2.1.10
|
133
|
+
signing_key:
|
134
|
+
specification_version: 4
|
135
|
+
summary: release the crackin - gem release management
|
136
|
+
test_files: []
|