rubycut-babushka 0.10.6
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/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
|