tumbler 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/CHANGELOG +10 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +51 -0
- data/README.rdoc +85 -0
- data/Rakefile +11 -0
- data/Tumbler +9 -0
- data/VERSION +1 -0
- data/bin/tumbler +8 -0
- data/lib/tumbler/changelog.rb +62 -0
- data/lib/tumbler/cli.rb +69 -0
- data/lib/tumbler/gem.rb +35 -0
- data/lib/tumbler/gemspec.rb +4 -0
- data/lib/tumbler/gemspec_helper.rb +38 -0
- data/lib/tumbler/generate.rb +137 -0
- data/lib/tumbler/rake_tasks.rb +81 -0
- data/lib/tumbler/runner.rb +26 -0
- data/lib/tumbler/updater.rb +87 -0
- data/lib/tumbler/version.rb +57 -0
- data/lib/tumbler.rb +178 -0
- data/spec/bin_bijou_spec.rb +67 -0
- data/spec/changelog_spec.rb +52 -0
- data/spec/gemspec_spec.rb +38 -0
- data/spec/generate_spec.rb +50 -0
- data/spec/spec.opts +7 -0
- data/spec/spec_helper.rb +49 -0
- data/spec/updater_spec.rb +54 -0
- data/spec/version_spec.rb +48 -0
- data/template/Gemfile +10 -0
- data/template/Rakefile +2 -0
- data/template/generic.Tumbler.erb +14 -0
- data/template/generic.gemspec.erb +29 -0
- data/thinking.txt +54 -0
- data/tumbler.gemspec +36 -0
- metadata +204 -0
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
class Tumbler
|
6
|
+
class Updater
|
7
|
+
|
8
|
+
def initialize(dir, opts = nil)
|
9
|
+
@dir = dir
|
10
|
+
@name = opts && opts[:name] || File.basename(File.expand_path(dir))
|
11
|
+
raise "Couldn't find #{gemspec_path}" unless File.exist?(gemspec_path)
|
12
|
+
end
|
13
|
+
|
14
|
+
def update
|
15
|
+
upgrade_deps
|
16
|
+
upgrade_version
|
17
|
+
upgrade_changelog
|
18
|
+
upgrade_rakefile
|
19
|
+
end
|
20
|
+
|
21
|
+
def upgrade_deps
|
22
|
+
if File.exist?(gemfile_path)
|
23
|
+
gemspec = File.read(gemspec_path)
|
24
|
+
unless gemspec[/add_bundler_dependencies/] || gemspec[/inject_dependencies/]
|
25
|
+
@tainted_gemspec = true
|
26
|
+
File.open(gemspec_path, 'a') do |g|
|
27
|
+
g << <<-HERE_DOC
|
28
|
+
raise # (see below)
|
29
|
+
|
30
|
+
# You probably want to use inject the dependencies using either
|
31
|
+
# add_bundler_depenedencies or Tumbler::Gemspec.inject_dependencies(spec) (where spec is your Gemspec)
|
32
|
+
HERE_DOC
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def upgrade_version
|
39
|
+
unless File.exists?(version_path)
|
40
|
+
# go to rubygems and get it
|
41
|
+
gem_data = JSON.parse(Net::HTTP.get(URI.parse("http://rubygems.org/api/v1/gems/#{URI.escape(@name)}.json")))
|
42
|
+
version = gem_data['version']
|
43
|
+
File.open(version_path, 'w') {|f| f << version}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def upgrade_changelog
|
48
|
+
unless File.exists?(changelog_path)
|
49
|
+
File.open(changelog_path, 'w'){ |f| f << '' }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def upgrade_rakefile
|
54
|
+
create_rakefile and return if !File.exist?(rakefile_path)
|
55
|
+
rakefile = File.read(rakefile_path)
|
56
|
+
if rakefile !~ /Tumbler.use_rake_tasks/
|
57
|
+
File.open(rakefile_path, 'a') {|f| f.puts "\n\n# automatically added Tumbler tasks\n\nrequire 'tumbler'\nTumbler.use_rake_tasks"}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def rakefile_path
|
62
|
+
File.join(@dir, 'Rakefile')
|
63
|
+
end
|
64
|
+
|
65
|
+
def create_rakefile
|
66
|
+
File.open(rakefile_path, 'w') { |f|
|
67
|
+
f.puts "require 'tumbler'\nnTumbler.use_rake_tasks"
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
def version_path
|
72
|
+
File.join(@dir, Version::DEFAULT_FILE)
|
73
|
+
end
|
74
|
+
|
75
|
+
def changelog_path
|
76
|
+
File.join(@dir, Changelog::DEFAULT_FILE)
|
77
|
+
end
|
78
|
+
|
79
|
+
def gemspec_path
|
80
|
+
File.join(@dir, "#{@name}.gemspec")
|
81
|
+
end
|
82
|
+
|
83
|
+
def gemfile_path
|
84
|
+
File.join(@dir, 'Gemfile')
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class Tumbler
|
2
|
+
class Version
|
3
|
+
include Runner
|
4
|
+
|
5
|
+
attr_reader :file, :basefile, :field_names
|
6
|
+
|
7
|
+
DEFAULT_FILE = 'VERSION'
|
8
|
+
DEFAULT_FIELD = [:major, :minor, :tiny]
|
9
|
+
INITIAL_VERSION = '0.0.0'
|
10
|
+
|
11
|
+
def initialize(manager, &block)
|
12
|
+
@manager = manager
|
13
|
+
filename(DEFAULT_FILE)
|
14
|
+
fields(DEFAULT_FIELD)
|
15
|
+
instance_eval(&block) if block
|
16
|
+
reload
|
17
|
+
end
|
18
|
+
|
19
|
+
def fields(f)
|
20
|
+
@field_names = (f == :all ? @version.field_names : f)
|
21
|
+
end
|
22
|
+
|
23
|
+
def reload
|
24
|
+
@version = Versionomy.parse(File.exist?(file) ? File.read(file).strip : '0.0.0')
|
25
|
+
end
|
26
|
+
|
27
|
+
def filename(file)
|
28
|
+
@basefile = file
|
29
|
+
@file = File.join(@manager.base, file)
|
30
|
+
end
|
31
|
+
|
32
|
+
def value
|
33
|
+
@version
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_s
|
37
|
+
value.to_s
|
38
|
+
end
|
39
|
+
|
40
|
+
def bump(level)
|
41
|
+
if @manager.noop
|
42
|
+
@manager.dry "Bumping version to #{bump(level).to_s}"
|
43
|
+
else
|
44
|
+
File.open(file, 'w') {|f| f << @version.bump(level).to_s}
|
45
|
+
reload
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def commit(from)
|
50
|
+
sh "git commit #{@basefile} -m'Bumped version from #{from} to #{to_s}'"
|
51
|
+
end
|
52
|
+
|
53
|
+
def base
|
54
|
+
@manager.base
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/tumbler.rb
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
require 'callsite'
|
2
|
+
require 'versionomy'
|
3
|
+
require 'bundler'
|
4
|
+
|
5
|
+
Callsite.activate_kernel_dir_methods
|
6
|
+
$LOAD_PATH << __DIR__
|
7
|
+
|
8
|
+
require 'tumbler/runner'
|
9
|
+
require 'tumbler/updater'
|
10
|
+
require 'tumbler/rake_tasks'
|
11
|
+
require 'tumbler/version'
|
12
|
+
require 'tumbler/gemspec_helper'
|
13
|
+
require 'tumbler/changelog'
|
14
|
+
require 'tumbler/generate'
|
15
|
+
require 'tumbler/gem'
|
16
|
+
require 'tumbler/cli'
|
17
|
+
|
18
|
+
class Tumbler
|
19
|
+
def self.load_version(filename = Version::DEFAULT_FILE)
|
20
|
+
File.read(File.join(__DIR__, '..', filename))
|
21
|
+
end
|
22
|
+
|
23
|
+
VERSION = Tumbler.load_version
|
24
|
+
|
25
|
+
include Runner
|
26
|
+
|
27
|
+
Change = Struct.new(:hash, :author, :summary)
|
28
|
+
|
29
|
+
attr_reader :base, :version, :changelog, :gem, :name
|
30
|
+
attr_accessor :noop
|
31
|
+
|
32
|
+
def self.use_rake_tasks(name = nil)
|
33
|
+
root = File.dirname(Callsite.parse(caller).find{|c| c.filename =~ /Rakefile/}.filename)
|
34
|
+
Tumbler::Raketasks.register(File.expand_path(root), name)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.load(base)
|
38
|
+
File.exist?(File.join(base, 'Tumbler')) ? new(base) : nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def set_version(version)
|
42
|
+
@version = Version.new
|
43
|
+
end
|
44
|
+
|
45
|
+
def gem_name(name)
|
46
|
+
@name = name
|
47
|
+
end
|
48
|
+
|
49
|
+
def bundler
|
50
|
+
@definition ||= Bundler::Dsl.evaluate(gemfile_path)
|
51
|
+
end
|
52
|
+
|
53
|
+
def config_path
|
54
|
+
File.join(@base, 'Tumbler')
|
55
|
+
end
|
56
|
+
|
57
|
+
def gemfile_path
|
58
|
+
File.join(@base, 'Gemfile')
|
59
|
+
end
|
60
|
+
|
61
|
+
def gemspec_path
|
62
|
+
File.join(@base, "#{@name}.gemspec")
|
63
|
+
end
|
64
|
+
|
65
|
+
def lockfile_path
|
66
|
+
File.join(@base, 'Gemfile.lock')
|
67
|
+
end
|
68
|
+
|
69
|
+
def use_version(&block)
|
70
|
+
@version = Version.new(self, &block)
|
71
|
+
end
|
72
|
+
|
73
|
+
def use_gem(&block)
|
74
|
+
@gem.instance_eval(block)
|
75
|
+
end
|
76
|
+
|
77
|
+
def use_changelog(&block)
|
78
|
+
@changelog = Changelog.new(self, &block)
|
79
|
+
end
|
80
|
+
|
81
|
+
def reset
|
82
|
+
@version = nil
|
83
|
+
@changelog = nil
|
84
|
+
end
|
85
|
+
|
86
|
+
def bump_and_commit(field)
|
87
|
+
guard_clean
|
88
|
+
@changelog.update if @changelog
|
89
|
+
bump(field)
|
90
|
+
if @changelog
|
91
|
+
@changelog.write_version_header
|
92
|
+
@changelog.commit
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def tag_and_push
|
97
|
+
guard_clean
|
98
|
+
guard_already_tagged
|
99
|
+
tag
|
100
|
+
push
|
101
|
+
end
|
102
|
+
|
103
|
+
def bump_and_push(field)
|
104
|
+
revert_on_error {
|
105
|
+
bump_and_commit(field)
|
106
|
+
tag_and_push
|
107
|
+
}
|
108
|
+
end
|
109
|
+
|
110
|
+
def current_revision
|
111
|
+
sh('git show --pretty=format:%H').split(/\n/)[0].strip
|
112
|
+
end
|
113
|
+
|
114
|
+
def revert_on_error
|
115
|
+
current_ref = current_revision
|
116
|
+
begin
|
117
|
+
yield
|
118
|
+
rescue
|
119
|
+
sh "git reset --hard #{current_ref}"
|
120
|
+
raise
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def guard_clean
|
125
|
+
clean? or raise("There are files that need to be committed first.")
|
126
|
+
end
|
127
|
+
|
128
|
+
def guard_already_tagged
|
129
|
+
sh('git tag').split(/\n/).include?(@version.to_s) and raise("This tag has already been committed to the repo.")
|
130
|
+
end
|
131
|
+
|
132
|
+
def bump(level)
|
133
|
+
from = @version.to_s
|
134
|
+
@version.bump(level)
|
135
|
+
@version.commit(from)
|
136
|
+
end
|
137
|
+
|
138
|
+
def clean?
|
139
|
+
sh("git ls-files -dm").split("\n").size.zero?
|
140
|
+
end
|
141
|
+
|
142
|
+
def push
|
143
|
+
sh "git push --all"
|
144
|
+
sh "git push --tags"
|
145
|
+
end
|
146
|
+
|
147
|
+
def tag
|
148
|
+
sh "git tag #{@version.to_s}"
|
149
|
+
end
|
150
|
+
|
151
|
+
def commit(msg)
|
152
|
+
sh "git commit #{@version.basefile} -m'#{msg}'"
|
153
|
+
end
|
154
|
+
|
155
|
+
def tags
|
156
|
+
sh('git tag').split(/\n/)
|
157
|
+
end
|
158
|
+
|
159
|
+
def reload
|
160
|
+
reset
|
161
|
+
@gem = Gem.new(self)
|
162
|
+
instance_eval(File.read(config_path), config_path, 1)
|
163
|
+
end
|
164
|
+
|
165
|
+
def latest_changes
|
166
|
+
changes = sh("git log --pretty=format:'%h (%aN) %s' --no-color #{@version}..HEAD").
|
167
|
+
scan(/([a-f0-9]{7}) \((.*?)\) (.*)$/).
|
168
|
+
map{|line| Change.new(line[0], line[1], line[2])}
|
169
|
+
end
|
170
|
+
|
171
|
+
private
|
172
|
+
def initialize(base)
|
173
|
+
@base = base
|
174
|
+
reload
|
175
|
+
@noop = true if ENV['DRY'] == '1'
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe 'bin/tumbler' do
|
4
|
+
before(:each) do
|
5
|
+
@bin = File.expand_path(File.join(File.dirname(__FILE__), '..', 'bin', 'tumbler'))
|
6
|
+
@target = temp_dir('tmp')
|
7
|
+
end
|
8
|
+
|
9
|
+
after(:each) do
|
10
|
+
FileUtils.rm_rf @target
|
11
|
+
$".delete "tumbler/gemspec.rb" # we need to delete this so each gemspec can be generated fresh
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'creation' do
|
15
|
+
it "should generate an app" do
|
16
|
+
Dir.chdir(@target) {`bundle exec ruby #{@bin} test_gem`}
|
17
|
+
$?.should == 0
|
18
|
+
tumbler = Tumbler.new(File.join(@target, 'test_gem'))
|
19
|
+
tumbler.version.to_s.should == '0.0.0'
|
20
|
+
tumbler.bundler.dependencies.first.name.should == 'tumbler'
|
21
|
+
tumbler.bundler.dependencies.first.requirements_list.should == ['>= 0']
|
22
|
+
tumbler.bundler.dependencies.first.groups.should == [:development]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'upgrading' do
|
27
|
+
before(:each) do
|
28
|
+
Dir.chdir(@target) {`bundle exec ruby #{@bin} rails`}
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should do nothing on a normal existing tumbler app" do
|
32
|
+
tumbler = Tumbler.new(File.join(@target, 'rails'))
|
33
|
+
version_file = File.read(tumbler.version.file)
|
34
|
+
changelog_file = File.read(tumbler.changelog.file)
|
35
|
+
gemfile_file = File.read(tumbler.gemfile_path)
|
36
|
+
gemspec_file = File.read(tumbler.gemspec_path)
|
37
|
+
Dir.chdir(@target) {`bundle exec ruby #{@bin} rails -u`}
|
38
|
+
$?.should == 0
|
39
|
+
version_file.should == File.read(tumbler.version.file)
|
40
|
+
changelog_file.should == File.read(tumbler.changelog.file)
|
41
|
+
gemfile_file.should == File.read(tumbler.gemfile_path)
|
42
|
+
gemspec_file.should == File.read(tumbler.gemspec_path)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should work from inside the directory" do
|
46
|
+
tumbler = Tumbler.new(File.join(@target, 'rails'))
|
47
|
+
version_file = File.read(tumbler.version.file)
|
48
|
+
changelog_file = File.read(tumbler.changelog.file)
|
49
|
+
gemfile_file = File.read(tumbler.gemfile_path)
|
50
|
+
gemspec_file = File.read(tumbler.gemspec_path)
|
51
|
+
Dir.chdir("#{@target}/rails") {`bundle exec ruby #{@bin} . -u --name rails`}
|
52
|
+
$?.should == 0
|
53
|
+
version_file.should == File.read(tumbler.version.file)
|
54
|
+
changelog_file.should == File.read(tumbler.changelog.file)
|
55
|
+
gemfile_file.should == File.read(tumbler.gemfile_path)
|
56
|
+
gemspec_file.should == File.read(tumbler.gemspec_path)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should not work if the directory and gemspec mismatch and you don't supply a name" do
|
60
|
+
tumbler = Tumbler.new(File.join(@target, 'rails'))
|
61
|
+
FileUtils.mv("#{@target}/rails/rails.gemspec", "#{@target}/rails/notrails.gemspec")
|
62
|
+
Dir.chdir(@target) {`bundle exec ruby #{@bin} rails -u`}
|
63
|
+
$?.exitstatus.should == 1
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe Tumbler::Changelog do
|
4
|
+
|
5
|
+
after(:each) do
|
6
|
+
$".delete "tumbler/gemspec.rb" # we need to delete this so each gemspec can be generated fresh
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should generate a changelog" do
|
10
|
+
create_app('test') { |tumbler|
|
11
|
+
tumbler.sh 'touch file1'
|
12
|
+
tumbler.sh 'git add file1'
|
13
|
+
tumbler.sh 'git commit file1 -m"added file1"'
|
14
|
+
tumbler.sh 'touch file2'
|
15
|
+
tumbler.sh 'git add file2'
|
16
|
+
tumbler.sh 'git commit file2 -m"added file2"'
|
17
|
+
tumbler.bump_and_push(:tiny)
|
18
|
+
tumbler.version.to_s.should == '0.0.1'
|
19
|
+
changelog = File.read(tumbler.changelog.file)
|
20
|
+
changelog.should match(/== 0\.0\.1\s+\* added file2 \(.*?, [a-f0-9]{7}\)\s+\* added file1 \(.*?, [a-f0-9]{7}\)/)
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should not perform any changelog activity when the option isn't specified" do
|
25
|
+
create_app('test', :changelog => nil) { |tumbler|
|
26
|
+
tumbler.sh 'touch file1'
|
27
|
+
tumbler.sh 'git add file1'
|
28
|
+
tumbler.sh 'git commit file1 -m"added file1"'
|
29
|
+
tumbler.sh 'touch file2'
|
30
|
+
tumbler.sh 'git add file2'
|
31
|
+
tumbler.sh 'git commit file2 -m"added file2"'
|
32
|
+
tumbler.bump_and_push(:tiny)
|
33
|
+
tumbler.version.to_s.should == '0.0.1'
|
34
|
+
File.exist?(File.join(tumbler.base, 'CHANGELOG')).should be_false
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should rollback the entire set of commits when the remote is unreachable" do
|
39
|
+
create_app('test', :changelog => nil, :remote => 'ssh://ijustmadethisupisadomain.com/what_you_say.git') { |tumbler|
|
40
|
+
tumbler.sh 'touch file1'
|
41
|
+
tumbler.sh 'git add file1'
|
42
|
+
tumbler.sh 'git commit file1 -m"added file1"'
|
43
|
+
tumbler.sh 'touch file2'
|
44
|
+
tumbler.sh 'git add file2'
|
45
|
+
tumbler.sh 'git commit file2 -m"added file2"'
|
46
|
+
current_rev = tumbler.current_revision
|
47
|
+
proc {tumbler.bump_and_push(:tiny)}.should raise_error
|
48
|
+
tumbler.sh('git log').split(/\n/)[0].should == "commit #{current_rev}"
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe Tumbler::GemspecHelper do
|
4
|
+
before(:each) do
|
5
|
+
@dir, @app = create_bare_app('test')
|
6
|
+
@helper = Tumbler::GemspecHelper.new(@app)
|
7
|
+
end
|
8
|
+
|
9
|
+
after(:each) do
|
10
|
+
FileUtils.rm_rf(@dir)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should have a name" do
|
14
|
+
@helper.name.should == 'test'
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should have a version number" do
|
18
|
+
@helper.version.should == '0.0.0'
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should have files" do
|
22
|
+
@helper.files.should == ["CHANGELOG", "Gemfile", "Rakefile", "Tumbler", "VERSION", "test.gemspec"]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should have a date" do
|
26
|
+
@helper.date.should == Time.new.strftime("%Y-%m-%d")
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should inject_dependencies" do
|
30
|
+
spec = Gem::Specification.new
|
31
|
+
File.open("#{@app.base}/Gemfile", 'a') {|f| f.puts "gem 'test', '>= 0.0.5'"}
|
32
|
+
@app.reload
|
33
|
+
@helper.inject_dependencies(spec)
|
34
|
+
spec.runtime_dependencies.should == [Gem::Dependency.new('test', '>= 0.0.5')]
|
35
|
+
spec.development_dependencies.should == [Gem::Dependency.new('tumbler', '>= 0', :development)]
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe Tumbler::Generate do
|
4
|
+
|
5
|
+
after(:each) do
|
6
|
+
$".delete "tumbler/gemspec.rb" # we need to delete this so each gemspec can be generated fresh
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should suppress changelog creation if disabled" do
|
10
|
+
temp_dir('test') do |test_dir|
|
11
|
+
Tumbler::Generate.app(test_dir, 'mygem', :changelog => nil).write
|
12
|
+
File.exist?(File.join(test_dir, "CHANGELOG")).should be_false
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should generate a gemspec" do
|
17
|
+
temp_dir('test') do |test_dir|
|
18
|
+
Tumbler::Generate.app(test_dir, 'mygem').write
|
19
|
+
spec = Gem::Specification.load("#{test_dir}/mygem.gemspec")
|
20
|
+
spec.dependencies.should == [Gem::Dependency.new('tumbler', '>=0', :development)]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should generate a Rakefile" do
|
25
|
+
temp_dir('test') do |test_dir|
|
26
|
+
Tumbler::Generate.app(test_dir, 'mygem').write
|
27
|
+
File.exist?("#{test_dir}/Rakefile").should be_true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should accept an extra dependency" do
|
32
|
+
temp_dir('test2') do |test_dir|
|
33
|
+
Tumbler::Generate.app(test_dir, 'mygem', :dependencies => 'eventmachine').write
|
34
|
+
spec = Gem::Specification.load("#{test_dir}/mygem.gemspec")
|
35
|
+
spec.dependencies.size.should == 2
|
36
|
+
spec.dependencies.should include(Gem::Dependency.new('tumbler', '>=0', :development))
|
37
|
+
spec.dependencies.should include(Gem::Dependency.new('eventmachine', '>=0', :runtime))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should accept an extra dependency with a version" do
|
42
|
+
temp_dir('test2') do |test_dir|
|
43
|
+
Tumbler::Generate.app(test_dir, 'mygem', :dependencies => [['eventmachine', '>=1.0.0']]).write
|
44
|
+
spec = Gem::Specification.load("#{test_dir}/mygem.gemspec")
|
45
|
+
spec.dependencies.size.should == 2
|
46
|
+
spec.dependencies.should include(Gem::Dependency.new('tumbler', '>=0', :development))
|
47
|
+
spec.dependencies.should include(Gem::Dependency.new('eventmachine', '>=1.0.0', :runtime))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
$LOAD_PATH << File.basename(__FILE__)
|
5
|
+
$LOAD_PATH << File.join(File.basename(__FILE__), '..', 'lib')
|
6
|
+
|
7
|
+
require 'tumbler'
|
8
|
+
|
9
|
+
def create_app(name, opts = {})
|
10
|
+
temp_dir(name) do |dir|
|
11
|
+
temp_dir("remote-#{name}.git") do |remote_dir|
|
12
|
+
Tumbler::Generate.app(dir, name, opts).write
|
13
|
+
tumbler = Tumbler.new(dir)
|
14
|
+
|
15
|
+
Dir.chdir(remote_dir) { `git --bare init` }
|
16
|
+
|
17
|
+
remote = opts[:remote] || "file://#{remote_dir}"
|
18
|
+
|
19
|
+
Dir.chdir(dir) {
|
20
|
+
`git remote add origin #{remote}`
|
21
|
+
`git push origin master`
|
22
|
+
}
|
23
|
+
|
24
|
+
yield tumbler
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def create_bare_app(name, opts = {})
|
30
|
+
dir = temp_dir(name)
|
31
|
+
Tumbler::Generate.app(dir, name, opts).write
|
32
|
+
tumbler = Tumbler.new(dir)
|
33
|
+
[dir, tumbler]
|
34
|
+
end
|
35
|
+
|
36
|
+
def temp_dir(name)
|
37
|
+
dir = File.join(Dir.tmpdir, rand(10000).to_s, "#{Process.pid}-#{name}")
|
38
|
+
FileUtils.rm_rf(dir)
|
39
|
+
FileUtils.mkdir_p(dir)
|
40
|
+
if block_given?
|
41
|
+
begin
|
42
|
+
yield dir
|
43
|
+
ensure
|
44
|
+
FileUtils.rm_rf(dir)
|
45
|
+
end
|
46
|
+
else
|
47
|
+
dir
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fakeweb'
|
3
|
+
|
4
|
+
describe Tumbler::Updater do
|
5
|
+
before(:each) do
|
6
|
+
@bin = File.expand_path(File.join(File.dirname(__FILE__), '..', 'bin', 'tumbler'))
|
7
|
+
@target = temp_dir('tmp')
|
8
|
+
Dir.chdir(@target) {`bundle exec ruby #{@bin} rails`}
|
9
|
+
end
|
10
|
+
|
11
|
+
after(:each) do
|
12
|
+
FileUtils.rm_rf @target
|
13
|
+
$".delete "tumbler/gemspec.rb" # we need to delete this so each gemspec can be generated fresh
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should fetch the version number" do
|
17
|
+
FakeWeb.allow_net_connect = false
|
18
|
+
FakeWeb.register_uri(:get, "http://rubygems.org/api/v1/gems/rails.json", :body => '{ "name": "rails", "info": "Rails is a framework for building web-application using CGI, FCGI, mod_ruby, or WEBrick on top of either MySQL, PostgreSQL, SQLite, DB2, SQL Server, or Oracle with eRuby- or Builder-based templates.", "version": "2.3.5", "version_downloads": 2451, "authors": "David Heinemeier Hansson", "downloads": 134451, "project_uri": "http://rubygems.org/gems/rails", "gem_uri": "http://rubygems.org/gems/rails-2.3.5.gem", "dependencies": { "runtime": [ { "name": "activesupport", "requirements": ">= 2.3.5" } ], "development": [ ] }}')
|
19
|
+
File.unlink("#{@target}/rails/VERSION")
|
20
|
+
Tumbler::Updater.new("#{@target}/rails", :name => 'rails').update
|
21
|
+
File.read("#{@target}/rails/VERSION").should == '2.3.5'
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should generate a CHANGELOG" do
|
25
|
+
File.unlink("#{@target}/rails/CHANGELOG")
|
26
|
+
Tumbler::Updater.new("#{@target}/rails", :name => 'rails').update
|
27
|
+
File.exist?("#{@target}/rails/CHANGELOG").should be_true
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should not append anything to the Rakefile as it already has the tumbler tasks in it" do
|
31
|
+
rakefile = File.read("#{@target}/rails/Rakefile")
|
32
|
+
Tumbler::Updater.new("#{@target}/rails", :name => 'rails').update
|
33
|
+
File.read("#{@target}/rails/Rakefile").should == rakefile
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should append the Tumbler tasks if they don't already exist" do
|
37
|
+
File.open("#{@target}/rails/Rakefile", 'w') {|f| f.puts '# Some other rake file'}
|
38
|
+
Tumbler::Updater.new("#{@target}/rails", :name => 'rails').update
|
39
|
+
File.read("#{@target}/rails/Rakefile").scan(/require 'tumbler'\nTumbler\.use_rake_tasks/).size.should == 1
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should not append anything to the gemspec if it already is using tumbler" do
|
43
|
+
gemspec = File.read("#{@target}/rails/rails.gemspec")
|
44
|
+
Tumbler::Updater.new("#{@target}/rails", :name => 'rails').update
|
45
|
+
File.read("#{@target}/rails/rails.gemspec").should == gemspec
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should append inject deps if its not there already" do
|
49
|
+
File.open("#{@target}/rails/Rakefile", 'w') {|f| f.puts '# Some other gemspec file'}
|
50
|
+
Tumbler::Updater.new("#{@target}/rails", :name => 'rails').update
|
51
|
+
File.read("#{@target}/rails/rails.gemspec").scan(/Tumbler::Gemspec.inject_dependencies/).size.should == 1
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe 'Tumbler#version' do
|
4
|
+
it "should read the current version" do
|
5
|
+
create_app('test', :version => '0.1.2') { |tumbler|
|
6
|
+
tumbler.version.to_s.should == '0.1.2'
|
7
|
+
}
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should bump the current version by minor" do
|
11
|
+
create_app('test', :version => '0.1.2') { |tumbler|
|
12
|
+
tumbler.bump_and_push(:minor)
|
13
|
+
tumbler.version.to_s.should == '0.2.0'
|
14
|
+
tumbler.tags.should include('0.2.0')
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should bump the current version by tiny" do
|
19
|
+
create_app('test', :version => '0.1.2') { |tumbler|
|
20
|
+
tumbler.bump_and_push(:tiny)
|
21
|
+
tumbler.version.to_s.should == '0.1.3'
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should bump the current version by major" do
|
26
|
+
create_app('test', :version => '0.1.2') { |tumbler|
|
27
|
+
tumbler.bump_and_push(:major)
|
28
|
+
tumbler.version.to_s.should == '1.0.0'
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should bump the current version by major" do
|
33
|
+
create_app('test', :version => '0.1.2') { |tumbler|
|
34
|
+
tumbler.bump_and_push(:major)
|
35
|
+
tumbler.version.to_s.should == '1.0.0'
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should not let you tag the same version twice" do
|
40
|
+
create_app('test', :version => '0.1.2') { |tumbler|
|
41
|
+
tumbler.bump_and_push(:major)
|
42
|
+
tumbler.version.to_s.should == '1.0.0'
|
43
|
+
proc {tumbler.tag_and_push(:major)}.should raise_error
|
44
|
+
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|