tumbler 0.0.1
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.
- 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
|