rubycut-babushka 0.10.8 → 0.15.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. data/Gemfile +1 -0
  2. data/Gemfile.lock +17 -15
  3. data/README.markdown +163 -41
  4. data/Rakefile +1 -1
  5. data/bin/babushka +1 -1
  6. data/deps/apt.rb +44 -0
  7. data/deps/babushka.rb +54 -42
  8. data/deps/deprecated.rb +16 -0
  9. data/deps/dev.rb +28 -3
  10. data/deps/git.rb +27 -12
  11. data/deps/homebrew.rb +2 -2
  12. data/deps/packages.rb +14 -15
  13. data/deps/pkg_managers.rb +21 -75
  14. data/deps/ruby.rb +5 -19
  15. data/deps/rubygems.rb +3 -3
  16. data/deps/system.rb +2 -2
  17. data/deps/templates/app.rb +60 -41
  18. data/deps/templates/bin.rb +16 -0
  19. data/deps/templates/installer.rb +9 -9
  20. data/deps/templates/lib.rb +17 -0
  21. data/deps/templates/managed.rb +1 -38
  22. data/deps/templates/src.rb +16 -8
  23. data/deps/templates/task.rb +11 -0
  24. data/deps/templates/tmbundle.rb +16 -2
  25. data/lib/babushka.rb +2 -3
  26. data/lib/babushka/accepts_block_for.rb +5 -3
  27. data/lib/babushka/asset.rb +172 -0
  28. data/lib/babushka/base.rb +37 -8
  29. data/lib/babushka/bug_reporter.rb +6 -6
  30. data/lib/babushka/cmdline.rb +11 -10
  31. data/lib/babushka/cmdline/handler.rb +7 -3
  32. data/lib/babushka/cmdline/helpers.rb +15 -23
  33. data/lib/babushka/cmdline/parser.rb +1 -1
  34. data/lib/babushka/core_patches/object.rb +1 -1
  35. data/lib/babushka/core_patches/string.rb +8 -3
  36. data/lib/babushka/current_ruby.rb +44 -0
  37. data/lib/babushka/dep.rb +111 -185
  38. data/lib/babushka/dep_context.rb +8 -3
  39. data/lib/babushka/dep_definer.rb +45 -15
  40. data/lib/babushka/dep_pool.rb +5 -8
  41. data/lib/babushka/{meta_dep.rb → dep_template.rb} +21 -2
  42. data/lib/babushka/dsl.rb +3 -0
  43. data/lib/babushka/git_repo.rb +143 -49
  44. data/lib/babushka/helpers/git_helpers.rb +7 -6
  45. data/lib/babushka/helpers/log_helpers.rb +51 -13
  46. data/lib/babushka/helpers/path_helpers.rb +5 -7
  47. data/lib/babushka/helpers/run_helpers.rb +15 -55
  48. data/lib/babushka/helpers/shell_helpers.rb +18 -26
  49. data/lib/babushka/helpers/uri_helpers.rb +9 -18
  50. data/lib/babushka/lambda_chooser.rb +20 -13
  51. data/lib/babushka/parameter.rb +20 -4
  52. data/lib/babushka/path_checker.rb +72 -0
  53. data/lib/babushka/pkg_helper.rb +38 -13
  54. data/lib/babushka/pkg_helpers/apt_helper.rb +15 -8
  55. data/lib/babushka/pkg_helpers/binpkgsrc_helper.rb +15 -14
  56. data/lib/babushka/pkg_helpers/binports_helper.rb +7 -7
  57. data/lib/babushka/pkg_helpers/brew_helper.rb +17 -25
  58. data/lib/babushka/pkg_helpers/gem_helper.rb +36 -27
  59. data/lib/babushka/pkg_helpers/npm_helper.rb +9 -9
  60. data/lib/babushka/pkg_helpers/pacman_helper.rb +5 -4
  61. data/lib/babushka/pkg_helpers/pip_helper.rb +14 -10
  62. data/lib/babushka/pkg_helpers/unknown_pkg_helper.rb +19 -0
  63. data/lib/babushka/pkg_helpers/yum_helper.rb +1 -1
  64. data/lib/babushka/popen.rb +13 -10
  65. data/lib/babushka/prompt.rb +14 -1
  66. data/lib/babushka/renderable.rb +11 -9
  67. data/lib/babushka/resource.rb +5 -166
  68. data/lib/babushka/run_reporter.rb +12 -3
  69. data/lib/babushka/shell.rb +54 -44
  70. data/lib/babushka/source.rb +41 -20
  71. data/lib/babushka/source_pool.rb +20 -13
  72. data/lib/babushka/system_definitions.rb +11 -3
  73. data/lib/babushka/system_detector.rb +31 -0
  74. data/lib/babushka/system_matcher.rb +53 -0
  75. data/lib/babushka/system_profile.rb +67 -89
  76. data/lib/babushka/task.rb +36 -8
  77. data/lib/babushka/{meta_dep_context.rb → templated_dep_context.rb} +1 -1
  78. data/lib/babushka/vars.rb +46 -4
  79. data/lib/babushka/version_of.rb +35 -17
  80. data/lib/babushka/version_str.rb +12 -8
  81. data/lib/components.rb +9 -8
  82. data/lib/fancypath/fancypath.rb +109 -83
  83. data/lib/inkan/inkan.rb +14 -14
  84. data/lib/{babushka → levenshtein}/levenshtein.rb +0 -0
  85. data/spec/acceptance/acceptance.rb +4 -4
  86. data/spec/acceptance_helper.rb +10 -6
  87. data/spec/babushka/accepts_for_spec.rb +137 -142
  88. data/spec/babushka/accepts_for_support.rb +13 -6
  89. data/spec/babushka/asset_spec.rb +165 -0
  90. data/spec/babushka/cmdline/help_spec.rb +11 -9
  91. data/spec/babushka/cmdline/meet_spec.rb +15 -0
  92. data/spec/babushka/cmdline/version_spec.rb +1 -1
  93. data/spec/babushka/core_patches_spec.rb +9 -0
  94. data/spec/babushka/current_ruby_spec.rb +73 -0
  95. data/spec/babushka/dep_context_spec.rb +27 -13
  96. data/spec/babushka/dep_definer_spec.rb +108 -16
  97. data/spec/babushka/dep_spec.rb +87 -104
  98. data/spec/babushka/dep_template_spec.rb +176 -0
  99. data/spec/babushka/deps_spec.rb +48 -19
  100. data/spec/babushka/gem_helper_spec.rb +46 -59
  101. data/spec/babushka/git_repo_spec.rb +242 -51
  102. data/spec/babushka/ip_spec.rb +11 -11
  103. data/spec/babushka/lambda_chooser_spec.rb +47 -9
  104. data/spec/babushka/parameter_spec.rb +21 -0
  105. data/spec/babushka/path_checker_spec.rb +35 -0
  106. data/spec/babushka/path_helpers_spec.rb +51 -50
  107. data/spec/babushka/prompt_spec.rb +4 -4
  108. data/spec/babushka/renderable_spec.rb +61 -28
  109. data/spec/babushka/shell_helpers_spec.rb +110 -85
  110. data/spec/babushka/shell_spec.rb +15 -0
  111. data/spec/babushka/source_pool_spec.rb +204 -210
  112. data/spec/babushka/source_spec.rb +125 -42
  113. data/spec/babushka/source_support.rb +1 -1
  114. data/spec/babushka/system_profile_spec.rb +86 -49
  115. data/spec/babushka/task_spec.rb +80 -13
  116. data/spec/babushka/vars_spec.rb +2 -1
  117. data/spec/babushka/version_of_spec.rb +29 -2
  118. data/spec/babushka/version_str_spec.rb +91 -65
  119. data/spec/babushka/xml_string_spec.rb +1 -1
  120. data/spec/deps/bad/broken.rb +2 -2
  121. data/spec/deps/bad/working.rb +0 -1
  122. data/spec/deps/good/{meta.rb → template.rb} +0 -0
  123. data/spec/deps/good/test.rb +0 -3
  124. data/spec/deps/outer/deps.rb +0 -2
  125. data/spec/fancypath/fancypath_spec.rb +30 -0
  126. data/spec/inkan/inkan_spec.rb +34 -32
  127. data/spec/spec_helper.rb +7 -50
  128. data/spec/system_detector_spec.rb +70 -0
  129. metadata +163 -177
  130. data/deps/os_x.rb +0 -33
  131. data/deps/templates/ppa.rb +0 -24
  132. data/lib/babushka/core_patches/io.rb +0 -8
  133. data/lib/babushka/dep_runner.rb +0 -85
  134. data/lib/babushka/helpers/suggest_helpers.rb +0 -16
  135. data/lib/babushka/pkg_helpers/base_helper.rb +0 -19
  136. data/lib/babushka/pkg_helpers/macports_helper.rb +0 -22
  137. data/spec/babushka/dep_definer_support.rb +0 -36
  138. data/spec/babushka/meta_dep_definer_spec.rb +0 -127
  139. data/spec/babushka/meta_dep_wrapper_spec.rb +0 -32
  140. data/spec/babushka/resource_spec.rb +0 -141
  141. data/spec/babushka/run_helpers_spec.rb +0 -26
  142. data/spec/babushka/source_pool_support.rb +0 -31
data/deps/os_x.rb DELETED
@@ -1,33 +0,0 @@
1
- dep 'xcode tools', :template => 'external' do
2
- expects 'gcc', 'g++', 'autoconf', 'make', 'ld'
3
- otherwise {
4
- log_and_open "Install Xcode, and then run Babushka again.", "http://developer.apple.com/technology/xcode.html"
5
- }
6
- end
7
-
8
- dep 'xcode commandline tools', :template => 'installer' do
9
- # These pkgs consist of the packages inside the Xcode installer that contain the
10
- # commandline tools and compiler toolchain. They're not a custom build - they're
11
- # unmodified from the original Xcode install; just a subset (i.e. excluding the
12
- # packages for things like Interface Builder and Xcode.app).
13
- #
14
- # See http://github.com/kennethreitz/osx-gcc-installer for more info.
15
- source {
16
- on :lion, 'https://github.com/downloads/kennethreitz/osx-gcc-installer/GCC-10.7-v2.pkg'
17
- on :snow_leopard, 'https://github.com/downloads/kennethreitz/osx-gcc-installer/GCC-10.6.pkg'
18
- }
19
- provides %w[cc gcc c++ g++ llvm-gcc llvm-g++ clang] # compilers
20
- provides %w[ld libtool] # linkety link
21
- provides %w[make automake autoconf] # configure and build tools
22
- provides %w[cpp m4 nasm yacc bison] # misc - the preprocessor, assembler, grammar stuff
23
- end
24
-
25
- dep 'llvm in path', :for => :snow_leopard do
26
- requires 'xcode tools'
27
- met? { which 'llvm-gcc-4.2' }
28
- meet {
29
- cd('/usr/local/bin') {|path|
30
- shell "ln -s /Developer/usr/llvm-gcc-4.2/bin/llvm* .", :sudo => !path.writable?
31
- }
32
- }
33
- end
@@ -1,24 +0,0 @@
1
- dep 'python-software-properties.managed' do
2
- provides 'add-apt-repository'
3
- end
4
-
5
- meta :ppa do
6
- accepts_value_for :adds
7
- template {
8
- requires 'python-software-properties.managed'
9
- met? {
10
- Dir.glob("/etc/apt/sources.list.d/*").any? {|f|
11
- f.p.read[Regexp.new('https?://' + adds.gsub(':', '.*') + '/ubuntu ')]
12
- }
13
- }
14
- before {
15
- adds[/^\w+\:\w+/] or log_error("'#{adds}' doesn't look like 'ppa:something'.")
16
- }
17
- meet {
18
- sudo "sudo add-apt-repository #{adds}"
19
- }
20
- after {
21
- Babushka::Base.host.pkg_helper.update_pkg_lists "Updating apt lists to load #{adds}."
22
- }
23
- }
24
- end
@@ -1,8 +0,0 @@
1
- class IO
2
- # Return true iff reading from this IO object would return data immediately,
3
- # and not block while waiting for data.
4
- def ready_for_read?
5
- result = IO.select([self], [], [], 0)
6
- result && (result.first.first == self)
7
- end
8
- end
@@ -1,85 +0,0 @@
1
- module Babushka
2
- module DepRunner
3
- include GitHelpers
4
- include UriHelpers
5
-
6
- private
7
-
8
- # TODO: solve cmd/app and string/version handling better.
9
- def in_path? provided_list
10
- apps, command_names = [*provided_list].partition {|i| i.to_s[/\.app\/?$/] }
11
- commands = command_names.versions
12
- apps_in_path?(apps) and cmds_in_path?(commands) and matching_versions?(commands)
13
- end
14
-
15
- def apps_in_path? apps
16
- present, missing = [*apps].partition {|app_name| app_dir(app_name) }
17
-
18
- missing.empty?.tap {|result|
19
- if result
20
- log "#{present.map {|i| "'#{i}'" }.to_list} #{present.length == 1 ? 'is' : 'are'} present." unless present.empty?
21
- else
22
- log "#{missing.map {|i| "'#{i}'" }.to_list} #{missing.length == 1 ? 'is' : 'are'}n't present anywhere in $PATH."
23
- end
24
- }
25
- end
26
-
27
- def cmds_in_path? commands
28
- dir_hash = [*commands].group_by {|cmd| cmd_dir(cmd.name) }
29
-
30
- if dir_hash.keys.compact.length > 1
31
- unmeetable "The commands for '#{name}' run from more than one place.\n" +
32
- dir_hash.values.map {|cmds|
33
- cmd_location_str_for cmds
34
- }.to_list(:oxford => true, :conj => 'but').end_with('.')
35
- else
36
- cmds = dir_hash.values.first
37
- dir_hash[nil].blank?.tap {|result|
38
- if result
39
- log cmd_location_str_for(cmds).end_with('.') unless cmds.blank?
40
- else
41
- log "#{dir_hash[nil].map {|i| "'#{i}'" }.to_list} #{dir_hash[nil].length == 1 ? 'is' : 'are'} missing."
42
- end
43
- }
44
- end
45
- end
46
-
47
- def matching_versions? commands
48
- versions = commands.select {|cmd|
49
- !cmd.version.nil?
50
- }.inject({}) {|hsh,cmd|
51
- hsh[cmd] = (shell("#{cmd.name} --version") || '').split(/[\s\-]/).detect {|piece|
52
- begin
53
- cmd.matches? piece.to_version
54
- rescue VersionStrError
55
- false
56
- end
57
- }
58
- log "#{cmd.name} is #{hsh[cmd]}, which is#{"n't" unless hsh[cmd]} #{cmd.version}.", :as => (:ok if hsh[cmd])
59
- hsh
60
- }
61
- versions.values.all?
62
- end
63
-
64
- def app_dir app_name
65
- prefix.find {|app_path|
66
- (app_path.to_s / app_name).glob.select {|entry|
67
- (entry / 'Contents/MacOS').exists?
68
- }.first
69
- }
70
- end
71
-
72
- def cmd_location_str_for cmds
73
- "#{cmds.map {|i| "'#{i.name}'" }.to_list(:conj => '&')} run#{'s' if cmds.length == 1} from #{cmd_dir(cmds.first.name)}"
74
- end
75
-
76
- def call_task task_name
77
- if (task_block = send(task_name)).nil?
78
- true
79
- else
80
- instance_eval(&task_block)
81
- end
82
- end
83
-
84
- end
85
- end
@@ -1,16 +0,0 @@
1
- module Babushka
2
- module SuggestHelpers
3
- def suggest_value_for typo, choices
4
- if (possible_matches = choices.similar_to typo.to_s).empty?
5
- nil # nothing to suggest
6
- elsif possible_matches.length == 1
7
- Prompt.confirm "#{"Did you mean".colorize('grey')} '#{possible_matches.first}'#{"?".colorize('grey')}" do
8
- possible_matches.first
9
- end or false
10
- else
11
- log "Similar: #{possible_matches.map {|d| "'#{d}'" }.join(', ')}"
12
- Prompt.get_value("Did you mean any of those".colorize('grey'), :default => possible_matches.first)
13
- end
14
- end
15
- end
16
- end
@@ -1,19 +0,0 @@
1
- module Babushka
2
- class BaseHelper < PkgHelper
3
- class << self
4
- def pkg_type; :unknown end
5
- def manager_key; :unknown end
6
- def manager_dep; nil end
7
-
8
- private
9
-
10
- def _install! pkgs, opts
11
- raise DepDefiner::UnmeetableDep, "I don't know how to use the package manager on this system."
12
- end
13
-
14
- def _has? pkg
15
- raise DepDefiner::UnmeetableDep, "I don't know how to use the package manager on this system."
16
- end
17
- end
18
- end
19
- end
@@ -1,22 +0,0 @@
1
- module Babushka
2
- class MacportsHelper < PkgHelper
3
- class << self
4
- def existing_packages
5
- Dir.glob(prefix / "var/macports/software/*").map {|i| File.basename i }
6
- end
7
- def pkg_type; :port end
8
- def pkg_cmd; 'port' end
9
- def manager_key; :macports end
10
-
11
- def _install! pkgs, opts
12
- log_shell "Fetching #{pkgs.join(', ')}", "#{pkg_cmd} fetch #{pkgs.join(' ')}", :sudo => should_sudo?
13
- super
14
- end
15
-
16
- private
17
- def _has? pkg
18
- existing_packages.include? pkg.name.split(/\s+/, 2).first
19
- end
20
- end
21
- end
22
- end
@@ -1,36 +0,0 @@
1
- class TestDepContext < DepContext
2
- def chooser
3
- :osx # hardcode this for testing
4
- end
5
- end
6
- class TestTemplate
7
- def self.contextual_name; name end
8
- def self.context_class; TestDepContext end
9
- end
10
- class FakeOSXSystemProfile < OSXSystemProfile
11
- def version; '10.6.7' end
12
- def get_version_info; '' end
13
- def total_memory; 16_000_000_000 end
14
- end
15
-
16
- def setup_test_lambdas
17
- @lambda_hello = L{ "hello world!" }
18
- end
19
-
20
- def test_accepts_block_for_response accepter_name, lambda, value, opts = {}
21
- TestDepContext.accepts_block_for accepter_name
22
- dep 'accepts_block_for' do
23
- send accepter_name, opts, &lambda
24
- end
25
- on = opts[:on].nil? ? :all : Base.host.system
26
- Dep('accepts_block_for').context.payload[accepter_name][on].should == value
27
- end
28
-
29
- def make_test_deps
30
- dep 'test build tools' do
31
- requires {
32
- on :osx, 'xcode tools'
33
- on :linux, 'build-essential', 'autoconf'
34
- }
35
- end
36
- end
@@ -1,127 +0,0 @@
1
- require 'spec_helper'
2
- require 'dep_definer_support'
3
-
4
- describe "declaration" do
5
- before {
6
- @meta = meta 'test'
7
- }
8
- it "should work" do
9
- L{ meta 'count_test' }.should change(Base.sources.anonymous.templates, :count).by(1)
10
- end
11
- it "should set the name" do
12
- @meta.name.should == 'test'
13
- end
14
- it "should downcase the name" do
15
- meta("Case_Test").name.should == 'case_test'
16
- end
17
- it "should set the source" do
18
- @meta.source.should == Base.sources.anonymous
19
- end
20
- it "should define a dep context" do
21
- @meta.context_class.should be_an_instance_of(Class)
22
- @meta.context_class.ancestors.should include(Babushka::DepContext)
23
- end
24
- it "should define template on the context" do
25
- @meta.context_class.source_template.should == @meta
26
- end
27
- it "should not define a dep helper" do
28
- Object.new.should_not respond_to('test')
29
- end
30
- it "should not be marked as suffixed" do
31
- @meta.opts[:suffix].should be_false
32
- end
33
- after { Base.sources.anonymous.templates.clear! }
34
- end
35
-
36
- describe "using" do
37
- describe "invalid templates" do
38
- it "should not define deps as options" do
39
- L{
40
- dep('something undefined', :template => 'undefined').should be_nil
41
- }.should raise_error(TemplateNotFound, "There is no template named 'undefined' to define 'something undefined' against.")
42
- end
43
- it "should define deps as options" do
44
- dep('something.undefined').should be_an_instance_of(Dep)
45
- end
46
- end
47
-
48
- describe "without template" do
49
- before {
50
- @meta = meta('templateless_test') {}
51
- }
52
- it "should define deps based on the template" do
53
- dep('templateless dep.templateless_test').template.should == @meta
54
- end
55
- after { Base.sources.anonymous.templates.clear! }
56
- end
57
-
58
- describe "with template" do
59
- before {
60
- @meta = meta 'template_test' do
61
- def a_helper_method
62
- 'hello from the helper!'
63
- end
64
- template {
65
- def a_helper
66
- 'hello from the helper in the template!'
67
- end
68
- met? {
69
- 'this dep is met.'
70
- }
71
- }
72
- end
73
- }
74
- it "should define the helper on the context class" do
75
- @meta.context_class.respond_to?(:a_helper).should be_false
76
- @meta.context_class.new(nil).respond_to?(:a_helper).should be_false
77
- dep('dep1.template_test').context.respond_to?(:a_helper).should be_true
78
- end
79
- it "should correctly define the helper method" do
80
- dep('dep2.template_test').context.a_helper_method.should == 'hello from the helper!'
81
- end
82
- it "should correctly define the helper" do
83
- dep('dep2.template_test').context.a_helper.should == 'hello from the helper in the template!'
84
- end
85
- it "should correctly define the met? block" do
86
- dep('dep3.template_test').send(:process_task, :met?).should == 'this dep is met.'
87
- end
88
- it "should override the template correctly" do
89
- dep('dep4.template_test') {
90
- met? { 'overridden met? block.' }
91
- }.send(:process_task, :met?).should == 'overridden met? block.'
92
- end
93
- after { Base.sources.anonymous.templates.clear! }
94
- end
95
-
96
- describe "acceptors" do
97
- before {
98
- @meta = meta 'acceptor_test' do
99
- accepts_list_for :list_test
100
- accepts_block_for :block_test
101
- template {
102
- met? {
103
- list_test == ['valid']
104
- }
105
- meet {
106
- block_test.call
107
- }
108
- }
109
- end
110
- }
111
- it "should handle accepts_list_for" do
112
- dep('unmet accepts_list_for.acceptor_test') { list_test 'invalid' }.met?.should be_false
113
- dep('met accepts_list_for.acceptor_test') { list_test 'valid' }.met?.should be_true
114
- end
115
- it "should handle accepts_block_for" do
116
- block_called = false
117
- dep('accepts_block_for.acceptor_test') {
118
- list_test 'invalid'
119
- block_test {
120
- block_called = true
121
- }
122
- }.meet
123
- block_called.should be_true
124
- end
125
- after { Base.sources.anonymous.templates.clear! }
126
- end
127
- end
@@ -1,32 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "name checks" do
4
- it "should not allow blank names" do
5
- L{ meta(nil) }.should raise_error(ArgumentError, "You can't define a template with a blank name.")
6
- L{ meta('') }.should raise_error(ArgumentError, "You can't define a template with a blank name.")
7
- end
8
- it "should not allow reserved names" do
9
- L{ meta(:base) }.should raise_error(ArgumentError, "You can't use 'base' for a template name, because it's reserved.")
10
- end
11
- it "should allow valid names" do
12
- L{ meta(:a) }.should_not raise_error
13
- L{ meta('b') }.should_not raise_error
14
- L{ meta('valid') }.should_not raise_error
15
- end
16
- it "should not allow spaces and numbers" do
17
- L{ meta('meta dep 2') }.should raise_error(ArgumentError, "You can't use 'meta dep 2' for a template name - it can only contain [a-z0-9_].")
18
- end
19
- it "should not allow invalid characters" do
20
- L{ meta("meta\ndep") }.should raise_error(ArgumentError, "You can't use 'meta\ndep' for a template name - it can only contain [a-z0-9_].")
21
- end
22
- it "should not allow names that don't start with a letter" do
23
- L{ meta('3d_dep') }.should raise_error(ArgumentError, "You can't use '3d_dep' for a template name - it must start with a letter.")
24
- end
25
- describe "duplicate declaration" do
26
- before { meta 'duplicate' }
27
- it "should be prevented" do
28
- L{ meta(:duplicate) }.should raise_error(ArgumentError, "A template called 'duplicate' has already been defined.")
29
- end
30
- after { Base.sources.anonymous.templates.clear! }
31
- end
32
- end
@@ -1,141 +0,0 @@
1
- require 'spec_helper'
2
-
3
- def archive_path
4
- __FILE__.p.parent.parent / 'archives'
5
- end
6
-
7
- describe Resource do
8
- it "should detect file types" do
9
- Resource.type(archive_path / 'archive.zip').should == :zip
10
- Resource.type(archive_path / 'archive.tgz').should == :gzip
11
- end
12
- it "should first attempt to detect type using file extension" do
13
- Resource.type(archive_path / 'really_a_gzip.zip').should == :zip
14
- end
15
- it "should attempt to detect type via when there is no extension" do
16
- Resource.type(archive_path / 'zip_without_extension').should == :zip
17
- end
18
- it "should detect supported archive types" do
19
- Resource.for(archive_path / 'archive.tgz').should be_supported
20
- Resource.for(archive_path / 'archive.tbz2').should be_supported
21
- end
22
- it "should raise an error on unsupported types" do
23
- L{
24
- Resource.for(archive_path / 'invalid_archive')
25
- }.should raise_error("Don't know how to extract invalid_archive.")
26
- end
27
- it "should set the name" do
28
- Resource.for(archive_path / 'archive.tar').name.should == 'archive'
29
- Resource.for(archive_path / 'archive.tar.gz').name.should == 'archive'
30
- end
31
- it "should generate the proper command to extract the archive" do
32
- {
33
- 'tar' => "tar -xf '#{archive_path / 'archive.tar'}'",
34
- 'tgz' => "tar -zxf '#{archive_path / 'archive.tgz'}'",
35
- 'tbz2' => "tar -jxf '#{archive_path / 'archive.tbz2'}'",
36
- 'zip' => "unzip -o '#{archive_path / 'archive.zip'}'"
37
- }.each_pair {|ext,command|
38
- Resource.for(archive_path / "archive.#{ext}").extract_command.should == command
39
- }
40
- end
41
- it "should yield in the extracted dir" do
42
- Resource.for(archive_path / "archive.tar").extract {
43
- Dir.pwd.should == (tmp_prefix / 'archives/archive')
44
- }
45
- end
46
- it "should yield in the nested dir if there is one" do
47
- Resource.for(archive_path / "nested_archive.tar").extract {
48
- Dir.pwd.should == (tmp_prefix / 'archives/nested_archive/nested archive')
49
- }
50
- end
51
- it "should find a standard content dir as a nested dir" do
52
- Resource.for(archive_path / "test-0.3.1.tgz").extract {
53
- Dir.pwd.should == (tmp_prefix / 'archives/test-0.3.1/test-0.3.1')
54
- Dir.glob('*').should == ['content.txt']
55
- }
56
- end
57
- it "shouldn't descend into some dirs" do
58
- Resource.for(archive_path / "Blah.app.zip").extract {
59
- Dir.pwd.should == (tmp_prefix / 'archives/Blah.app')
60
- Dir.glob('**/*').should == ['Blah.app', 'Blah.app/content.txt']
61
- }
62
- end
63
- end
64
-
65
- describe Resource, '#content_subdir' do
66
- before {
67
- @resource = Resource.new('test.zip')
68
- }
69
-
70
- context "when there is just a single file inside the archive" do
71
- before {
72
- Dir.stub!(:glob).and_return(['a dir'])
73
- File.should_receive(:directory?).with('a dir').and_return(false)
74
- }
75
- it "should choose it, whatever it's called" do
76
- @resource.content_subdir.should be_nil
77
- end
78
- end
79
- context "when there is just a single non-descendable dir inside the archive" do
80
- before {
81
- Dir.stub!(:glob).and_return(['a dir.app'])
82
- File.should_receive(:directory?).with('a dir.app').and_return(true)
83
- }
84
- it "should choose it, whatever it's called" do
85
- @resource.content_subdir.should be_nil
86
- end
87
- end
88
- context "when there is just a single dir inside the archive" do
89
- before {
90
- Dir.stub!(:glob).and_return(['a dir'])
91
- File.should_receive(:directory?).with('a dir').and_return(true)
92
- }
93
- it "should choose it, whatever it's called" do
94
- @resource.content_subdir.should == 'a dir'
95
- end
96
- end
97
- context "when there is more than one dir" do
98
- context "and none are named after the archive" do
99
- before {
100
- Dir.stub!(:glob).and_return(['contents', 'another'])
101
- }
102
- it "should return nil (so the original extraction dir is used)" do
103
- @resource.content_subdir.should be_nil
104
- end
105
- end
106
- context "and one is named after the archive" do
107
- before {
108
- Dir.stub!(:glob).and_return(['contents', 'test'])
109
- }
110
- it "should choose the directory named after the archive" do
111
- @resource.content_subdir.should == 'test'
112
- end
113
- end
114
- end
115
- context "when there are non-descendable dirs" do
116
- context "and none are named after the archive" do
117
- before {
118
- Dir.stub!(:glob).and_return(['contents', 'LaunchBar.app', 'RSpec.tmbundle'])
119
- }
120
- it "should not choose the non-descendable dir" do
121
- @resource.content_subdir.should be_nil
122
- end
123
- end
124
- context "and one is named after the archive" do
125
- before {
126
- Dir.stub!(:glob).and_return(['contents', 'test.app'])
127
- }
128
- it "should not choose the non-descendable dir" do
129
- @resource.content_subdir.should be_nil
130
- end
131
- end
132
- context "one is named after the archive, and a descendable dir is present too" do
133
- before {
134
- Dir.stub!(:glob).and_return(['contents', 'test.app', 'test'])
135
- }
136
- it "should choose the descendable dir" do
137
- @resource.content_subdir.should == 'test'
138
- end
139
- end
140
- end
141
- end