rubycut-babushka 0.10.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +8 -0
- data/Gemfile.lock +31 -0
- data/README.markdown +246 -0
- data/Rakefile +26 -0
- data/bin/babushka +11 -0
- data/deps/babushka.rb +101 -0
- data/deps/dev.rb +12 -0
- data/deps/fhs.rb +31 -0
- data/deps/git.rb +29 -0
- data/deps/homebrew.rb +30 -0
- data/deps/os_x.rb +33 -0
- data/deps/packages.rb +22 -0
- data/deps/pkg_managers.rb +110 -0
- data/deps/ruby.rb +23 -0
- data/deps/rubygems.rb +24 -0
- data/deps/system.rb +10 -0
- data/deps/templates/app.rb +68 -0
- data/deps/templates/external.rb +12 -0
- data/deps/templates/installer.rb +31 -0
- data/deps/templates/managed.rb +105 -0
- data/deps/templates/ppa.rb +24 -0
- data/deps/templates/src.rb +42 -0
- data/deps/templates/tmbundle.rb +15 -0
- data/lib/babushka.rb +28 -0
- data/lib/babushka/accepts_block_for.rb +72 -0
- data/lib/babushka/accepts_list_for.rb +49 -0
- data/lib/babushka/accepts_value_for.rb +24 -0
- data/lib/babushka/base.rb +78 -0
- data/lib/babushka/bug_reporter.rb +55 -0
- data/lib/babushka/cmdline.rb +133 -0
- data/lib/babushka/cmdline/handler.rb +41 -0
- data/lib/babushka/cmdline/helpers.rb +127 -0
- data/lib/babushka/cmdline/parser.rb +69 -0
- data/lib/babushka/colorizer.rb +59 -0
- data/lib/babushka/core_patches/array.rb +171 -0
- data/lib/babushka/core_patches/blank.rb +22 -0
- data/lib/babushka/core_patches/bytes.rb +52 -0
- data/lib/babushka/core_patches/hash.rb +107 -0
- data/lib/babushka/core_patches/hashish.rb +14 -0
- data/lib/babushka/core_patches/integer.rb +25 -0
- data/lib/babushka/core_patches/io.rb +8 -0
- data/lib/babushka/core_patches/numeric.rb +16 -0
- data/lib/babushka/core_patches/object.rb +27 -0
- data/lib/babushka/core_patches/string.rb +116 -0
- data/lib/babushka/core_patches/symbol.rb +12 -0
- data/lib/babushka/core_patches/try.rb +15 -0
- data/lib/babushka/core_patches/uri.rb +24 -0
- data/lib/babushka/dep.rb +470 -0
- data/lib/babushka/dep_context.rb +18 -0
- data/lib/babushka/dep_definer.rb +115 -0
- data/lib/babushka/dep_pool.rb +49 -0
- data/lib/babushka/dep_runner.rb +85 -0
- data/lib/babushka/dsl.rb +26 -0
- data/lib/babushka/git_repo.rb +185 -0
- data/lib/babushka/helpers/git_helpers.rb +32 -0
- data/lib/babushka/helpers/log_helpers.rb +176 -0
- data/lib/babushka/helpers/path_helpers.rb +34 -0
- data/lib/babushka/helpers/run_helpers.rb +145 -0
- data/lib/babushka/helpers/shell_helpers.rb +229 -0
- data/lib/babushka/helpers/suggest_helpers.rb +16 -0
- data/lib/babushka/helpers/uri_helpers.rb +36 -0
- data/lib/babushka/ip.rb +160 -0
- data/lib/babushka/lambda_chooser.rb +40 -0
- data/lib/babushka/levenshtein.rb +125 -0
- data/lib/babushka/meta_dep.rb +65 -0
- data/lib/babushka/meta_dep_context.rb +15 -0
- data/lib/babushka/parameter.rb +143 -0
- data/lib/babushka/pkg_helper.rb +81 -0
- data/lib/babushka/pkg_helpers/apt_helper.rb +61 -0
- data/lib/babushka/pkg_helpers/base_helper.rb +19 -0
- data/lib/babushka/pkg_helpers/binpkgsrc_helper.rb +48 -0
- data/lib/babushka/pkg_helpers/binports_helper.rb +34 -0
- data/lib/babushka/pkg_helpers/brew_helper.rb +110 -0
- data/lib/babushka/pkg_helpers/gem_helper.rb +120 -0
- data/lib/babushka/pkg_helpers/macports_helper.rb +22 -0
- data/lib/babushka/pkg_helpers/npm_helper.rb +45 -0
- data/lib/babushka/pkg_helpers/pacman_helper.rb +27 -0
- data/lib/babushka/pkg_helpers/pip_helper.rb +45 -0
- data/lib/babushka/pkg_helpers/src_helper.rb +16 -0
- data/lib/babushka/pkg_helpers/yum_helper.rb +25 -0
- data/lib/babushka/popen.rb +40 -0
- data/lib/babushka/prompt.rb +176 -0
- data/lib/babushka/renderable.rb +67 -0
- data/lib/babushka/resource.rb +215 -0
- data/lib/babushka/run_reporter.rb +60 -0
- data/lib/babushka/shell.rb +108 -0
- data/lib/babushka/source.rb +216 -0
- data/lib/babushka/source_pool.rb +146 -0
- data/lib/babushka/system_definitions.rb +97 -0
- data/lib/babushka/system_profile.rb +210 -0
- data/lib/babushka/task.rb +142 -0
- data/lib/babushka/vars.rb +108 -0
- data/lib/babushka/version_of.rb +65 -0
- data/lib/babushka/version_str.rb +57 -0
- data/lib/babushka/xml_string.rb +28 -0
- data/lib/components.rb +82 -0
- data/lib/fancypath/fancypath.rb +200 -0
- data/lib/inkan/inkan.rb +76 -0
- data/spec/acceptance/acceptance.rb +43 -0
- data/spec/acceptance_helper.rb +113 -0
- data/spec/archives/Blah.app.zip +0 -0
- data/spec/archives/archive.tar +0 -0
- data/spec/archives/archive.tar.bz2 +0 -0
- data/spec/archives/archive.tar.gz +0 -0
- data/spec/archives/archive.tbz2 +0 -0
- data/spec/archives/archive.tgz +0 -0
- data/spec/archives/archive.zip +0 -0
- data/spec/archives/content.txt +5 -0
- data/spec/archives/invalid_archive +5 -0
- data/spec/archives/nested archive/content.txt +5 -0
- data/spec/archives/nested_archive.tar +0 -0
- data/spec/archives/really_a_gzip.zip +0 -0
- data/spec/archives/test-0.3.1.tgz +0 -0
- data/spec/archives/tgz_archive +0 -0
- data/spec/archives/zip_without_extension +0 -0
- data/spec/babushka/accepts_for_spec.rb +174 -0
- data/spec/babushka/accepts_for_support.rb +72 -0
- data/spec/babushka/cmdline/console_spec.rb +11 -0
- data/spec/babushka/cmdline/help_spec.rb +61 -0
- data/spec/babushka/cmdline/version_spec.rb +10 -0
- data/spec/babushka/core_patches_spec.rb +171 -0
- data/spec/babushka/dep_context_spec.rb +58 -0
- data/spec/babushka/dep_definer_spec.rb +152 -0
- data/spec/babushka/dep_definer_support.rb +36 -0
- data/spec/babushka/dep_spec.rb +567 -0
- data/spec/babushka/dep_support.rb +29 -0
- data/spec/babushka/deps_spec.rb +113 -0
- data/spec/babushka/gem_helper_spec.rb +90 -0
- data/spec/babushka/git_repo_spec.rb +396 -0
- data/spec/babushka/ip_spec.rb +131 -0
- data/spec/babushka/lambda_chooser_spec.rb +115 -0
- data/spec/babushka/meta_dep_definer_spec.rb +127 -0
- data/spec/babushka/meta_dep_wrapper_spec.rb +32 -0
- data/spec/babushka/parameter_spec.rb +135 -0
- data/spec/babushka/path_helpers_spec.rb +102 -0
- data/spec/babushka/prompt_spec.rb +188 -0
- data/spec/babushka/renderable_spec.rb +100 -0
- data/spec/babushka/resource_spec.rb +141 -0
- data/spec/babushka/run_helpers_spec.rb +26 -0
- data/spec/babushka/shell_helpers_spec.rb +244 -0
- data/spec/babushka/shell_spec.rb +19 -0
- data/spec/babushka/source_pool_spec.rb +320 -0
- data/spec/babushka/source_pool_support.rb +31 -0
- data/spec/babushka/source_spec.rb +382 -0
- data/spec/babushka/source_support.rb +17 -0
- data/spec/babushka/system_profile_spec.rb +61 -0
- data/spec/babushka/task_spec.rb +141 -0
- data/spec/babushka/uri_spec.rb +13 -0
- data/spec/babushka/vars_spec.rb +59 -0
- data/spec/babushka/version_of_spec.rb +110 -0
- data/spec/babushka/version_str_spec.rb +130 -0
- data/spec/babushka/version_str_support.rb +37 -0
- data/spec/babushka/xml_string_spec.rb +98 -0
- data/spec/deps/bad/broken.rb +7 -0
- data/spec/deps/bad/working.rb +3 -0
- data/spec/deps/good/meta.rb +14 -0
- data/spec/deps/good/test.rb +11 -0
- data/spec/deps/outer/deps.rb +19 -0
- data/spec/deps/outer/more deps.rb +11 -0
- data/spec/deps/params/params.rb +10 -0
- data/spec/fancypath/fancypath_spec.rb +272 -0
- data/spec/fancypath_support.rb +10 -0
- data/spec/inkan/inkan_spec.rb +217 -0
- data/spec/renderable/different_example.conf.erb +4 -0
- data/spec/renderable/example.conf.erb +3 -0
- data/spec/renderable/example.sh +6 -0
- data/spec/renderable/with_binding.conf.erb +4 -0
- data/spec/renderable/xml_example.conf.erb +8 -0
- data/spec/repos/remote.git.tgz +0 -0
- data/spec/spec_helper.rb +87 -0
- metadata +238 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
def setup_yield_counts
|
2
|
+
@yield_counts = Hash.new {|hsh,k| hsh[k] = Hash.new {|hsh,k| 0 } }
|
3
|
+
|
4
|
+
@yield_counts_none = {}
|
5
|
+
@yield_counts_met_run = {:setup => 1, :met? => 1}
|
6
|
+
@yield_counts_meet_run = {:setup => 1, :met? => 2, :prepare => 1, :before => 1, :meet => 1, :after => 1}
|
7
|
+
@yield_counts_dep_failed = {:setup => 1}
|
8
|
+
@yield_counts_failed_meet_run = {:setup => 1, :met? => 2, :prepare => 1, :before => 1, :meet => 1, :after => 1}
|
9
|
+
@yield_counts_early_exit_meet_run = {:setup => 1, :met? => 1, :prepare => 1, :before => 1, :meet => 1}
|
10
|
+
@yield_counts_already_met = {:setup => 1, :met? => 1}
|
11
|
+
@yield_counts_failed_at_before = {:setup => 1, :met? => 2, :prepare => 1, :before => 1}
|
12
|
+
end
|
13
|
+
|
14
|
+
def make_counter_dep opts = {}
|
15
|
+
incrementers = DepContext.accepted_blocks.inject({}) {|lambdas,key|
|
16
|
+
lambdas[key] = L{ @yield_counts[opts[:name]][key] += 1 }
|
17
|
+
lambdas
|
18
|
+
}
|
19
|
+
dep opts[:name] do
|
20
|
+
requires opts[:requires]
|
21
|
+
requires_when_unmet opts[:requires_when_unmet]
|
22
|
+
DepContext.accepted_blocks.each {|dep_method|
|
23
|
+
send dep_method do
|
24
|
+
incrementers[dep_method].call
|
25
|
+
(opts[dep_method] || default_block_for(dep_method)).call
|
26
|
+
end
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'dep_support'
|
3
|
+
|
4
|
+
shared_examples_for "met?" do
|
5
|
+
describe "met?" do
|
6
|
+
before { Dep('a').met? }
|
7
|
+
it "should met?-check each dep exactly once" do
|
8
|
+
%w[a b c d e f].each {|i| @yield_counts[i].should == @yield_counts_already_met }
|
9
|
+
end
|
10
|
+
it "shouldn't run the meet-only dep" do
|
11
|
+
@yield_counts['g'].should == @yield_counts_none
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "an already met dep tree" do
|
17
|
+
before {
|
18
|
+
setup_yield_counts
|
19
|
+
make_counter_dep :name => 'a', :requires => %w[b c]
|
20
|
+
make_counter_dep :name => 'b', :requires => %w[c d e]
|
21
|
+
make_counter_dep :name => 'c', :requires => %w[f]
|
22
|
+
make_counter_dep :name => 'd', :requires => %w[e f], :requires_when_unmet => %w[g]
|
23
|
+
make_counter_dep :name => 'e', :requires => %w[f]
|
24
|
+
make_counter_dep :name => 'f'
|
25
|
+
make_counter_dep :name => 'g'
|
26
|
+
}
|
27
|
+
it_should_behave_like "met?"
|
28
|
+
describe "meet" do
|
29
|
+
before { Dep('a').meet }
|
30
|
+
it "should meet no deps" do
|
31
|
+
%w[a b c d e f].each {|i| @yield_counts[i].should == @yield_counts_already_met }
|
32
|
+
end
|
33
|
+
it "shouldn't run the meet-only dep" do
|
34
|
+
@yield_counts['g'].should == @yield_counts_none
|
35
|
+
end
|
36
|
+
end
|
37
|
+
after { Base.sources.anonymous.deps.clear! }
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "an unmeetable dep tree" do
|
41
|
+
before {
|
42
|
+
setup_yield_counts
|
43
|
+
make_counter_dep :name => 'a', :met? => L{ false }, :requires => %w[b c]
|
44
|
+
make_counter_dep :name => 'b', :met? => L{ false }, :requires => %w[c d e]
|
45
|
+
make_counter_dep :name => 'c', :met? => L{ false }, :requires => %w[f], :requires_when_unmet => %w[g]
|
46
|
+
make_counter_dep :name => 'd', :met? => L{ false }, :requires => %w[e f]
|
47
|
+
make_counter_dep :name => 'e', :met? => L{ false }, :requires => %w[f]
|
48
|
+
make_counter_dep :name => 'f', :met? => L{ false }
|
49
|
+
make_counter_dep :name => 'g', :met? => L{ false }
|
50
|
+
}
|
51
|
+
it_should_behave_like "met?"
|
52
|
+
describe "meet" do
|
53
|
+
before { Dep('a').meet }
|
54
|
+
it "should fail on the bootom-most dep" do
|
55
|
+
%w[f].each {|i| @yield_counts[i].should == @yield_counts_failed_meet_run }
|
56
|
+
end
|
57
|
+
it "should bubble the fail back up" do
|
58
|
+
%w[a b c].each {|i| @yield_counts[i].should == @yield_counts_dep_failed }
|
59
|
+
end
|
60
|
+
it "shouldn't run any deps after the fail" do
|
61
|
+
%w[d e g].each {|i| @yield_counts[i].should == @yield_counts_none }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
after { Base.sources.anonymous.deps.clear! }
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "a meetable dep tree" do
|
68
|
+
before {
|
69
|
+
setup_yield_counts
|
70
|
+
make_counter_dep :name => 'a', :requires => %w[b c] , :met? => L{ @yield_counts['a'][:met?] > 1 }
|
71
|
+
make_counter_dep :name => 'b', :requires => %w[c d e], :met? => L{ @yield_counts['b'][:met?] > 1 }
|
72
|
+
make_counter_dep :name => 'c', :requires => %w[f] , :met? => L{ @yield_counts['c'][:met?] > 1 }, :requires_when_unmet => %w[g]
|
73
|
+
make_counter_dep :name => 'd', :requires => %w[e f] , :met? => L{ @yield_counts['d'][:met?] > 1 }
|
74
|
+
make_counter_dep :name => 'e', :requires => %w[f] , :met? => L{ @yield_counts['e'][:met?] > 1 }
|
75
|
+
make_counter_dep :name => 'f', :met? => L{ @yield_counts['f'][:met?] > 1 }
|
76
|
+
make_counter_dep :name => 'g', :met? => L{ @yield_counts['g'][:met?] > 1 }
|
77
|
+
}
|
78
|
+
it_should_behave_like "met?"
|
79
|
+
describe "meet" do
|
80
|
+
before { Dep('a').meet }
|
81
|
+
it "should meet each dep exactly once" do
|
82
|
+
Base.sources.anonymous.deps.names.each {|i| @yield_counts[i].should == @yield_counts_meet_run }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
after { Base.sources.anonymous.deps.clear! }
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "a partially meetable dep tree" do
|
89
|
+
before {
|
90
|
+
setup_yield_counts
|
91
|
+
make_counter_dep :name => 'a', :requires => %w[b c] , :met? => L{ @yield_counts['a'][:met?] > 1 }
|
92
|
+
make_counter_dep :name => 'b', :requires => %w[c d e], :met? => L{ @yield_counts['b'][:met?] > 1 }
|
93
|
+
make_counter_dep :name => 'c', :requires => %w[f] , :met? => L{ @yield_counts['c'][:met?] > 1 }, :requires_when_unmet => %w[g]
|
94
|
+
make_counter_dep :name => 'd', :requires => %w[e f] , :met? => L{ @yield_counts['d'][:met?] > 1 }
|
95
|
+
make_counter_dep :name => 'e', :requires => %w[f] , :met? => L{ false }
|
96
|
+
make_counter_dep :name => 'f', :met? => L{ @yield_counts['f'][:met?] > 1 }
|
97
|
+
make_counter_dep :name => 'g', :met? => L{ @yield_counts['g'][:met?] > 1 }
|
98
|
+
}
|
99
|
+
it_should_behave_like "met?"
|
100
|
+
describe "meet" do
|
101
|
+
before { Dep('a').meet }
|
102
|
+
it "should meet deps until one fails" do
|
103
|
+
%w[c f g].each {|i| @yield_counts[i].should == @yield_counts_meet_run }
|
104
|
+
end
|
105
|
+
it "should fail on the unmeetable dep" do
|
106
|
+
%w[e].each {|i| @yield_counts[i].should == @yield_counts_failed_meet_run }
|
107
|
+
end
|
108
|
+
it "should bubble the fail up" do
|
109
|
+
%w[a b d].each {|i| @yield_counts[i].should == @yield_counts_dep_failed }
|
110
|
+
end
|
111
|
+
end
|
112
|
+
after { Base.sources.anonymous.deps.clear! }
|
113
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
def stub_env_info
|
4
|
+
GemHelper.stub!(:env_info).and_return(%q{
|
5
|
+
RubyGems Environment:
|
6
|
+
- INSTALLATION DIRECTORY: /Library/Ruby/Gems/1.8
|
7
|
+
})
|
8
|
+
end
|
9
|
+
|
10
|
+
def stub_versions_of
|
11
|
+
GemHelper.stub!(:versions_of).and_return([
|
12
|
+
VersionStr.new('0.2.11'),
|
13
|
+
VersionStr.new('0.2.11.3'),
|
14
|
+
VersionStr.new('0.3.7'),
|
15
|
+
VersionStr.new('0.3.9')
|
16
|
+
])
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "has?" do
|
20
|
+
before {
|
21
|
+
stub_versions_of
|
22
|
+
}
|
23
|
+
it "should report installed gems correctly" do
|
24
|
+
GemHelper.has?('hammock 0.3.9').should == VersionStr.new('0.3.9')
|
25
|
+
end
|
26
|
+
it "should report missing gems correctly" do
|
27
|
+
GemHelper.has?('hammock 0.3.8').should be_nil
|
28
|
+
end
|
29
|
+
it "should report matching gems correctly" do
|
30
|
+
GemHelper.has?('hammock >= 0.3.10').should be_nil
|
31
|
+
GemHelper.has?('hammock >= 0.3.9').should == VersionStr.new('0.3.9')
|
32
|
+
GemHelper.has?('hammock >= 0.3.8').should == VersionStr.new('0.3.9')
|
33
|
+
GemHelper.has?('hammock >= 0.3.7').should == VersionStr.new('0.3.9')
|
34
|
+
GemHelper.has?('hammock ~> 0.2.7').should == VersionStr.new('0.2.11.3')
|
35
|
+
GemHelper.has?('hammock ~> 0.3.7').should == VersionStr.new('0.3.9')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "gem_path_for" do
|
40
|
+
before {
|
41
|
+
stub_env_info
|
42
|
+
stub_versions_of
|
43
|
+
@prefix = '/Library/Ruby/Gems/1.8/gems'
|
44
|
+
}
|
45
|
+
it "should return the correct path" do
|
46
|
+
GemHelper.gem_path_for('hammock').should == @prefix / 'hammock-0.3.9'
|
47
|
+
GemHelper.gem_path_for('hammock', '0.3.9').should == @prefix / 'hammock-0.3.9'
|
48
|
+
GemHelper.gem_path_for('hammock', '~> 0.3.7').should == @prefix / 'hammock-0.3.9'
|
49
|
+
GemHelper.gem_path_for('hammock', '0.3.8').should be_nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe Babushka::GemHelper do
|
54
|
+
describe '.should_sudo?' do
|
55
|
+
before :each do
|
56
|
+
Babushka::GemHelper.stub!(
|
57
|
+
:gem_root => '/path/to/gems'.p,
|
58
|
+
:bin_path => '/path/to/bins'.p
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should return true if the bin dir is not writeable" do
|
63
|
+
File.should_receive(:writable?).with('/path/to/bins').and_return(false)
|
64
|
+
Babushka::GemHelper.should_sudo?.should be_true
|
65
|
+
end
|
66
|
+
|
67
|
+
context "when the bin dir is writable" do
|
68
|
+
before {
|
69
|
+
File.should_receive(:writable?).with('/path/to/bins').and_return(true)
|
70
|
+
}
|
71
|
+
it "should return false if the gem dir does not exist" do
|
72
|
+
Babushka::GemHelper.gem_root.should_receive(:exists?).and_return(false)
|
73
|
+
Babushka::GemHelper.should_sudo?.should be_false
|
74
|
+
end
|
75
|
+
context "when the gem dir exists" do
|
76
|
+
before {
|
77
|
+
Babushka::GemHelper.gem_root.should_receive(:exists?).and_return(true)
|
78
|
+
}
|
79
|
+
it "should return true if the gem dir is not writeable" do
|
80
|
+
Babushka::GemHelper.gem_root.should_receive(:writable?).and_return(false)
|
81
|
+
Babushka::GemHelper.should_sudo?.should be_true
|
82
|
+
end
|
83
|
+
it "should return false if the gem dir is writeable" do
|
84
|
+
Babushka::GemHelper.gem_root.should_receive(:writable?).and_return(true)
|
85
|
+
Babushka::GemHelper.should_sudo?.should be_false
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,396 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
def stub_commitless_repo name
|
4
|
+
(tmp_prefix / 'repos' / name).rm
|
5
|
+
cd tmp_prefix / 'repos' / name, :create => true do
|
6
|
+
shell "git init"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def stub_repo name
|
11
|
+
(tmp_prefix / 'repos' / "#{name}_remote").rm
|
12
|
+
cd tmp_prefix / 'repos' / "#{name}_remote", :create => true do
|
13
|
+
shell "tar -zxvf #{File.dirname(__FILE__) / '../repos/remote.git.tgz'}"
|
14
|
+
end
|
15
|
+
|
16
|
+
(tmp_prefix / 'repos' / name).rm
|
17
|
+
cd tmp_prefix / 'repos' do
|
18
|
+
shell "git clone #{name}_remote/remote.git #{name}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def repo_context name, &block
|
23
|
+
cd(tmp_prefix / 'repos'/ name, &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
describe GitRepo, 'creation' do
|
27
|
+
before(:all) { stub_repo 'a' }
|
28
|
+
it "should return nil on nonexistent paths" do
|
29
|
+
Babushka::GitRepo.new(tmp_prefix / 'repos/nonexistent').root.should == nil
|
30
|
+
end
|
31
|
+
it "should return nil on non-repo paths" do
|
32
|
+
Babushka::GitRepo.new(tmp_prefix / 'repos').root.should == nil
|
33
|
+
end
|
34
|
+
it "should recognise the repo path as a string" do
|
35
|
+
Babushka::GitRepo.new((tmp_prefix / 'repos/a').to_s).root.should == tmp_prefix / 'repos/a'
|
36
|
+
end
|
37
|
+
it "should recognise the repo path as a Fancypath" do
|
38
|
+
Babushka::GitRepo.new(tmp_prefix / 'repos/a').root.should == tmp_prefix / 'repos/a'
|
39
|
+
end
|
40
|
+
it "should find the parent when called on the subdir" do
|
41
|
+
Babushka::GitRepo.new(tmp_prefix / 'repos/a/lib').root.should == tmp_prefix / 'repos/a'
|
42
|
+
end
|
43
|
+
it "should find the git dir within the repo" do
|
44
|
+
Babushka::GitRepo.new(tmp_prefix / 'repos/a').git_dir.should == tmp_prefix / 'repos/a/.git'
|
45
|
+
Babushka::GitRepo.new(tmp_prefix / 'repos/a/lib').git_dir.should == tmp_prefix / 'repos/a/.git'
|
46
|
+
end
|
47
|
+
it "should store path as a Fancypath" do
|
48
|
+
Babushka::GitRepo.new((tmp_prefix / 'repos/a').to_s).path.should be_an_instance_of(Fancypath)
|
49
|
+
Babushka::GitRepo.new(tmp_prefix / 'repos/a').path.should be_an_instance_of(Fancypath)
|
50
|
+
end
|
51
|
+
it "should return the repo path as a Fancypath" do
|
52
|
+
Babushka::GitRepo.new((tmp_prefix / 'repos/a').to_s).root.should be_an_instance_of(Fancypath)
|
53
|
+
Babushka::GitRepo.new(tmp_prefix / 'repos/a').root.should be_an_instance_of(Fancypath)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe GitRepo, 'without a repo' do
|
58
|
+
subject { Babushka::GitRepo.new(tmp_prefix / 'repos/nonexistent') }
|
59
|
+
it "should not exist" do
|
60
|
+
subject.exists?.should be_false
|
61
|
+
end
|
62
|
+
[:clean?, :dirty?, :current_branch, :current_head, :remote_branch_exists?, :ahead?].each {|method|
|
63
|
+
it "should raise on #{method}" do
|
64
|
+
L{ subject.send(method) }.should raise_error(Babushka::GitRepoError, "There is no repo at #{tmp_prefix / 'repos/nonexistent'}.")
|
65
|
+
end
|
66
|
+
}
|
67
|
+
context "with lazy eval" do
|
68
|
+
subject { Babushka::GitRepo.new(tmp_prefix / 'repos/lazy') }
|
69
|
+
it "should fail before the repo is created, but work afterwards" do
|
70
|
+
subject.exists?.should be_false
|
71
|
+
L{ subject.clean? }.should raise_error(Babushka::GitRepoError, "There is no repo at #{tmp_prefix / 'repos/lazy'}.")
|
72
|
+
stub_repo 'lazy'
|
73
|
+
subject.exists?.should be_true
|
74
|
+
subject.should be_clean
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe GitRepo, "with a repo" do
|
80
|
+
before(:all) { stub_repo 'a' }
|
81
|
+
it "should exist with string path" do
|
82
|
+
Babushka::GitRepo.new((tmp_prefix / 'repos/a').to_s).exists?.should be_true
|
83
|
+
end
|
84
|
+
it "should exist with Fancypath path" do
|
85
|
+
Babushka::GitRepo.new(tmp_prefix / 'repos/a').exists?.should be_true
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe GitRepo, '#clean? / #dirty?' do
|
90
|
+
context "on commitless repos" do
|
91
|
+
before(:all) { stub_commitless_repo 'a' }
|
92
|
+
subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
|
93
|
+
it "should be clean" do
|
94
|
+
subject.should be_clean
|
95
|
+
subject.should_not be_dirty
|
96
|
+
end
|
97
|
+
end
|
98
|
+
context "on normal repos" do
|
99
|
+
before(:all) { stub_repo 'a' }
|
100
|
+
subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
|
101
|
+
it "should be clean" do
|
102
|
+
subject.should be_clean
|
103
|
+
subject.should_not be_dirty
|
104
|
+
end
|
105
|
+
context "when there are changes" do
|
106
|
+
before {
|
107
|
+
cd(tmp_prefix / 'repos/a') { shell "echo dirt >> content.txt" }
|
108
|
+
}
|
109
|
+
it "should be dirty" do
|
110
|
+
subject.should_not be_clean
|
111
|
+
subject.should be_dirty
|
112
|
+
end
|
113
|
+
context "when the changes are staged" do
|
114
|
+
before {
|
115
|
+
cd(tmp_prefix / 'repos/a') { shell "git add --update ." }
|
116
|
+
}
|
117
|
+
it "should be dirty" do
|
118
|
+
subject.should_not be_clean
|
119
|
+
subject.should be_dirty
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe GitRepo, '#include?' do
|
127
|
+
before(:all) { stub_repo 'a' }
|
128
|
+
subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
|
129
|
+
it "should return true for valid commits" do
|
130
|
+
subject.include?('20758f2d9d696c51ac83a0fd36626d421057b24d').should be_true
|
131
|
+
subject.include?('20758f2').should be_true
|
132
|
+
end
|
133
|
+
it "should return false for nonexistent commits" do
|
134
|
+
subject.include?('20758f2d9d696c51ac83a0fd36626d421057b24e').should be_false
|
135
|
+
subject.include?('20758f3').should be_false
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe GitRepo, '#branches' do
|
140
|
+
subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
|
141
|
+
context "on a repo with commits" do
|
142
|
+
before(:all) { stub_repo 'a' }
|
143
|
+
it "should return the only branch in a list" do
|
144
|
+
subject.branches.should == ['master']
|
145
|
+
end
|
146
|
+
context "after creating another branch" do
|
147
|
+
before {
|
148
|
+
repo_context('a') { shell "git checkout -b next" }
|
149
|
+
}
|
150
|
+
it "should return both branches" do
|
151
|
+
subject.branches.should == ['master', 'next']
|
152
|
+
end
|
153
|
+
context "after changing back to master" do
|
154
|
+
before {
|
155
|
+
repo_context('a') { shell "git checkout master" }
|
156
|
+
}
|
157
|
+
it "should return both branches" do
|
158
|
+
subject.branches.should == ['master', 'next']
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
context "on a repo with no commits" do
|
164
|
+
before { stub_commitless_repo 'a' }
|
165
|
+
it "should return no branches" do
|
166
|
+
subject.branches.should == []
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe GitRepo, '#current_branch' do
|
172
|
+
before(:all) { stub_repo 'a' }
|
173
|
+
subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
|
174
|
+
it "should return 'master'" do
|
175
|
+
subject.current_branch.should == 'master'
|
176
|
+
end
|
177
|
+
context "after creating another branch" do
|
178
|
+
before {
|
179
|
+
repo_context('a') { shell "git checkout -b next" }
|
180
|
+
}
|
181
|
+
it "should return 'next'" do
|
182
|
+
subject.current_branch.should == 'next'
|
183
|
+
end
|
184
|
+
context "after changing back to master" do
|
185
|
+
before {
|
186
|
+
repo_context('a') { shell "git checkout master" }
|
187
|
+
}
|
188
|
+
it "should return 'next'" do
|
189
|
+
subject.current_branch.should == 'master'
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
describe GitRepo, '#current_head' do
|
196
|
+
before { stub_repo 'a' }
|
197
|
+
subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
|
198
|
+
it "should return a short commit id" do
|
199
|
+
subject.current_head.should =~ /^[0-9a-f]{7}$/
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe GitRepo, '#current_full_head' do
|
204
|
+
before { stub_repo 'a' }
|
205
|
+
subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
|
206
|
+
it "should return a full commit id" do
|
207
|
+
subject.current_full_head.should =~ /^[0-9a-f]{40}$/
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
describe GitRepo, '#ahead?' do
|
212
|
+
before(:all) {
|
213
|
+
stub_repo 'a'
|
214
|
+
cd(tmp_prefix / 'repos/a') {
|
215
|
+
shell "git checkout -b topic"
|
216
|
+
}
|
217
|
+
}
|
218
|
+
subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
|
219
|
+
it "should have a local topic branch" do
|
220
|
+
subject.current_branch.should == 'topic'
|
221
|
+
end
|
222
|
+
it "should return true if the current branch has no remote" do
|
223
|
+
subject.remote_branch_exists?.should be_false
|
224
|
+
subject.should be_ahead
|
225
|
+
end
|
226
|
+
context "when remote branch exists" do
|
227
|
+
before(:all) {
|
228
|
+
cd(tmp_prefix / 'repos/a') {
|
229
|
+
shell "git push origin topic"
|
230
|
+
shell 'echo "Ch-ch-ch-changes" >> content.txt'
|
231
|
+
shell 'git commit -a -m "Changes!"'
|
232
|
+
}
|
233
|
+
}
|
234
|
+
it "should have a local topic branch" do
|
235
|
+
subject.current_branch.should == 'topic'
|
236
|
+
end
|
237
|
+
it "should return true if there are unpushed commits on the current branch" do
|
238
|
+
subject.remote_branch_exists?.should be_true
|
239
|
+
subject.should be_ahead
|
240
|
+
end
|
241
|
+
context "when the branch is fully pushed" do
|
242
|
+
before {
|
243
|
+
cd(tmp_prefix / 'repos/a') {
|
244
|
+
shell "git push origin topic"
|
245
|
+
}
|
246
|
+
}
|
247
|
+
it "should not be ahead" do
|
248
|
+
subject.remote_branch_exists?.should be_true
|
249
|
+
subject.should_not be_ahead
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
describe GitRepo, '#behind?' do
|
256
|
+
before(:all) {
|
257
|
+
stub_repo 'a'
|
258
|
+
cd(tmp_prefix / 'repos/a') {
|
259
|
+
shell "git checkout -b next"
|
260
|
+
shell "git reset --hard origin/next^"
|
261
|
+
}
|
262
|
+
}
|
263
|
+
subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
|
264
|
+
it "should return true if there are new commits on the remote" do
|
265
|
+
subject.remote_branch_exists?.should be_true
|
266
|
+
subject.should be_behind
|
267
|
+
end
|
268
|
+
context "when the remote is merged" do
|
269
|
+
before {
|
270
|
+
cd(tmp_prefix / 'repos/a') {
|
271
|
+
shell "git merge origin/next"
|
272
|
+
}
|
273
|
+
}
|
274
|
+
it "should not be behind" do
|
275
|
+
subject.remote_branch_exists?.should be_true
|
276
|
+
subject.should_not be_behind
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
describe GitRepo, '#clone!' do
|
282
|
+
before(:all) { stub_repo 'a' }
|
283
|
+
context "for existing repos" do
|
284
|
+
subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
|
285
|
+
it "should raise" do
|
286
|
+
L{
|
287
|
+
subject.clone!('a_remote/remote.git')
|
288
|
+
}.should raise_error(GitRepoExists, "Can't clone a_remote/remote.git to existing path #{tmp_prefix / 'repos/a'}.")
|
289
|
+
end
|
290
|
+
end
|
291
|
+
context "for non-existent repos" do
|
292
|
+
subject { Babushka::GitRepo.new(tmp_prefix / 'repos/b') }
|
293
|
+
it "should not exist yet" do
|
294
|
+
subject.exists?.should be_false
|
295
|
+
end
|
296
|
+
context "when the clone fails" do
|
297
|
+
it "should raise" do
|
298
|
+
L{
|
299
|
+
subject.clone!(tmp_prefix / 'repos/a_remote/nonexistent.git')
|
300
|
+
}.should raise_error(GitRepoError)
|
301
|
+
end
|
302
|
+
end
|
303
|
+
context "after cloning" do
|
304
|
+
before { subject.clone! "a_remote/remote.git" }
|
305
|
+
it "should exist now" do
|
306
|
+
subject.exists?.should be_true
|
307
|
+
end
|
308
|
+
it "should have the correct remote" do
|
309
|
+
subject.repo_shell("git remote -v").should == %Q{
|
310
|
+
origin\t#{tmp_prefix / 'repos/a_remote/remote.git'} (fetch)
|
311
|
+
origin\t#{tmp_prefix / 'repos/a_remote/remote.git'} (push)
|
312
|
+
}.strip
|
313
|
+
end
|
314
|
+
it "should have the remote branch" do
|
315
|
+
subject.repo_shell("git branch -a").should == %Q{
|
316
|
+
* master
|
317
|
+
remotes/origin/HEAD -> origin/master
|
318
|
+
remotes/origin/master
|
319
|
+
remotes/origin/next
|
320
|
+
}.strip
|
321
|
+
end
|
322
|
+
end
|
323
|
+
after {
|
324
|
+
shell "rm -rf #{tmp_prefix / 'repos/b'}"
|
325
|
+
}
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
describe GitRepo, '#branch!' do
|
330
|
+
before(:all) { stub_repo 'a' }
|
331
|
+
subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
|
332
|
+
it "should not already have a next branch" do
|
333
|
+
subject.branches.should_not include('next')
|
334
|
+
end
|
335
|
+
context "after tracking" do
|
336
|
+
before { subject.branch! "next" }
|
337
|
+
it "should have created a next branch" do
|
338
|
+
subject.branches.should include('next')
|
339
|
+
end
|
340
|
+
it "should not be tracking anything" do
|
341
|
+
subject.repo_shell('git config branch.next.remote').should be_nil
|
342
|
+
end
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
describe GitRepo, '#track!' do
|
347
|
+
before(:all) { stub_repo 'a' }
|
348
|
+
subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
|
349
|
+
it "should not already have a next branch" do
|
350
|
+
subject.branches.should_not include('next')
|
351
|
+
end
|
352
|
+
context "after tracking" do
|
353
|
+
before { subject.track! "origin/next" }
|
354
|
+
it "should have created a next branch" do
|
355
|
+
subject.branches.should include('next')
|
356
|
+
end
|
357
|
+
it "should be tracking origin/next" do
|
358
|
+
subject.repo_shell('git config branch.next.remote').should == 'origin'
|
359
|
+
end
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
describe GitRepo, '#checkout!' do
|
364
|
+
before(:all) {
|
365
|
+
stub_repo 'a'
|
366
|
+
cd(tmp_prefix / 'repos/a') {
|
367
|
+
shell "git checkout -b next"
|
368
|
+
}
|
369
|
+
}
|
370
|
+
subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
|
371
|
+
it "should already have a next branch" do
|
372
|
+
subject.branches.should =~ %w[master next]
|
373
|
+
subject.current_branch.should == 'next'
|
374
|
+
end
|
375
|
+
context "after checking out" do
|
376
|
+
before { subject.checkout! "master" }
|
377
|
+
it "should be on the master branch now" do
|
378
|
+
subject.current_branch.should == 'master'
|
379
|
+
end
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
describe GitRepo, '#reset_hard!' do
|
384
|
+
before {
|
385
|
+
stub_repo 'a'
|
386
|
+
cd(tmp_prefix / 'repos/a') {
|
387
|
+
shell "echo 'more rubies' >> lib/rubies.rb"
|
388
|
+
}
|
389
|
+
}
|
390
|
+
subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
|
391
|
+
it "should make a dirty repo clean" do
|
392
|
+
subject.should be_dirty
|
393
|
+
subject.reset_hard!
|
394
|
+
subject.should be_clean
|
395
|
+
end
|
396
|
+
end
|