minimart 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.
Files changed (135) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +21 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +13 -0
  5. data/Gemfile +3 -0
  6. data/README.md +198 -0
  7. data/Rakefile +45 -0
  8. data/bin/minimart +4 -0
  9. data/lib/minimart.rb +15 -0
  10. data/lib/minimart/cli.rb +93 -0
  11. data/lib/minimart/commands/mirror.rb +30 -0
  12. data/lib/minimart/commands/web.rb +91 -0
  13. data/lib/minimart/configuration.rb +46 -0
  14. data/lib/minimart/cookbook.rb +173 -0
  15. data/lib/minimart/download/cookbook.rb +70 -0
  16. data/lib/minimart/download/git_cache.rb +60 -0
  17. data/lib/minimart/download/git_repository.rb +41 -0
  18. data/lib/minimart/error.rb +32 -0
  19. data/lib/minimart/inventory_requirement/base_requirement.rb +81 -0
  20. data/lib/minimart/inventory_requirement/git_requirement.rb +87 -0
  21. data/lib/minimart/inventory_requirement/git_requirements_builder.rb +101 -0
  22. data/lib/minimart/inventory_requirement/local_path_requirement.rb +45 -0
  23. data/lib/minimart/inventory_requirement/local_requirements_builder.rb +31 -0
  24. data/lib/minimart/inventory_requirement/supermarket_requirements_builder.rb +35 -0
  25. data/lib/minimart/mirror.rb +12 -0
  26. data/lib/minimart/mirror/dependency_graph.rb +73 -0
  27. data/lib/minimart/mirror/download_metadata.rb +57 -0
  28. data/lib/minimart/mirror/inventory_builder.rb +143 -0
  29. data/lib/minimart/mirror/inventory_configuration.rb +74 -0
  30. data/lib/minimart/mirror/inventory_requirements.rb +104 -0
  31. data/lib/minimart/mirror/local_store.rb +107 -0
  32. data/lib/minimart/mirror/source.rb +57 -0
  33. data/lib/minimart/mirror/source_cookbook.rb +77 -0
  34. data/lib/minimart/mirror/sources.rb +37 -0
  35. data/lib/minimart/output.rb +34 -0
  36. data/lib/minimart/utils/archive.rb +39 -0
  37. data/lib/minimart/utils/file_helper.rb +34 -0
  38. data/lib/minimart/utils/http.rb +60 -0
  39. data/lib/minimart/version.rb +3 -0
  40. data/lib/minimart/web.rb +10 -0
  41. data/lib/minimart/web/cookbook_show_page_generator.rb +78 -0
  42. data/lib/minimart/web/cookbooks.rb +83 -0
  43. data/lib/minimart/web/dashboard_generator.rb +46 -0
  44. data/lib/minimart/web/html_generator.rb +52 -0
  45. data/lib/minimart/web/markdown_parser.rb +47 -0
  46. data/lib/minimart/web/template_helper.rb +132 -0
  47. data/lib/minimart/web/universe_generator.rb +109 -0
  48. data/minimart.gemspec +36 -0
  49. data/spec/fixtures/sample_cookbook.tar.gz +0 -0
  50. data/spec/fixtures/sample_cookbook/Berksfile +3 -0
  51. data/spec/fixtures/sample_cookbook/CHANGELOG.md +3 -0
  52. data/spec/fixtures/sample_cookbook/Gemfile +16 -0
  53. data/spec/fixtures/sample_cookbook/LICENSE +3 -0
  54. data/spec/fixtures/sample_cookbook/README.md +42 -0
  55. data/spec/fixtures/sample_cookbook/Thorfile +5 -0
  56. data/spec/fixtures/sample_cookbook/Vagrantfile +90 -0
  57. data/spec/fixtures/sample_cookbook/chefignore +94 -0
  58. data/spec/fixtures/sample_cookbook/metadata.rb +9 -0
  59. data/spec/fixtures/sample_cookbook/recipes/default.rb +8 -0
  60. data/spec/fixtures/sample_inventory.yml +16 -0
  61. data/spec/fixtures/simple_git_inventory.yml +8 -0
  62. data/spec/fixtures/simple_inventory.yml +6 -0
  63. data/spec/fixtures/simple_local_path_inventory.yml +5 -0
  64. data/spec/fixtures/universe.json +42 -0
  65. data/spec/fixtures/vcr_cassettes/local_path_cookbooks.yml +3316 -0
  66. data/spec/fixtures/vcr_cassettes/location_specific_cookbooks.yml +3316 -0
  67. data/spec/fixtures/vcr_cassettes/supermarket_cookbooks_graph.yml +905 -0
  68. data/spec/fixtures/vcr_cassettes/supermarket_cookbooks_installing_cookbooks.yml +4218 -0
  69. data/spec/lib/minimart/cli_spec.rb +104 -0
  70. data/spec/lib/minimart/commands/mirror_spec.rb +37 -0
  71. data/spec/lib/minimart/commands/web_spec.rb +75 -0
  72. data/spec/lib/minimart/configuration_spec.rb +54 -0
  73. data/spec/lib/minimart/cookbook_spec.rb +137 -0
  74. data/spec/lib/minimart/download/cookbook_spec.rb +135 -0
  75. data/spec/lib/minimart/download/git_cache_spec.rb +69 -0
  76. data/spec/lib/minimart/download/git_repository_spec.rb +39 -0
  77. data/spec/lib/minimart/error_spec.rb +18 -0
  78. data/spec/lib/minimart/inventory_requirement/base_requirement_spec.rb +38 -0
  79. data/spec/lib/minimart/inventory_requirement/git_requirement_spec.rb +92 -0
  80. data/spec/lib/minimart/inventory_requirement/git_requirements_builder_spec.rb +130 -0
  81. data/spec/lib/minimart/inventory_requirement/local_path_requirement_spec.rb +35 -0
  82. data/spec/lib/minimart/inventory_requirement/local_requirements_builder_spec.rb +33 -0
  83. data/spec/lib/minimart/inventory_requirement/supermarket_requirements_builder_spec.rb +69 -0
  84. data/spec/lib/minimart/mirror/dependency_graph_spec.rb +123 -0
  85. data/spec/lib/minimart/mirror/download_metadata_spec.rb +73 -0
  86. data/spec/lib/minimart/mirror/inventory_builder_spec.rb +195 -0
  87. data/spec/lib/minimart/mirror/inventory_configuration_spec.rb +86 -0
  88. data/spec/lib/minimart/mirror/inventory_requirements_spec.rb +78 -0
  89. data/spec/lib/minimart/mirror/local_store_spec.rb +64 -0
  90. data/spec/lib/minimart/mirror/source_spec.rb +54 -0
  91. data/spec/lib/minimart/mirror/sources_spec.rb +50 -0
  92. data/spec/lib/minimart/output_spec.rb +29 -0
  93. data/spec/lib/minimart/utils/archive_spec.rb +38 -0
  94. data/spec/lib/minimart/utils/file_helper_spec.rb +43 -0
  95. data/spec/lib/minimart/utils/http_spec.rb +37 -0
  96. data/spec/lib/minimart/web/cookbook_show_page_generator_spec.rb +101 -0
  97. data/spec/lib/minimart/web/cookbooks_spec.rb +70 -0
  98. data/spec/lib/minimart/web/dashboard_generator_spec.rb +33 -0
  99. data/spec/lib/minimart/web/html_generator_spec.rb +34 -0
  100. data/spec/lib/minimart/web/markdown_parser_spec.rb +54 -0
  101. data/spec/lib/minimart/web/template_helper_spec.rb +86 -0
  102. data/spec/lib/minimart/web/universe_generator_spec.rb +125 -0
  103. data/spec/spec_helper.rb +35 -0
  104. data/spec/support/file_system.rb +22 -0
  105. data/web/_assets/javascripts/app.js +164 -0
  106. data/web/_assets/javascripts/backbone.min.js +6 -0
  107. data/web/_assets/javascripts/jquery.min.js +4 -0
  108. data/web/_assets/javascripts/jquery.tabslet.min.js +9 -0
  109. data/web/_assets/javascripts/manifest.js +5 -0
  110. data/web/_assets/javascripts/underscore.min.js +5 -0
  111. data/web/_assets/stylesheets/font-awesome.min.css +4 -0
  112. data/web/_assets/stylesheets/font-mfizz.css +318 -0
  113. data/web/_assets/stylesheets/main.css +720 -0
  114. data/web/_assets/stylesheets/manifest.css +4 -0
  115. data/web/_assets/stylesheets/normalize.css +427 -0
  116. data/web/assets/fonts/FontAwesome.otf +0 -0
  117. data/web/assets/fonts/font-mfizz.eot +0 -0
  118. data/web/assets/fonts/font-mfizz.svg +1344 -0
  119. data/web/assets/fonts/font-mfizz.ttf +0 -0
  120. data/web/assets/fonts/font-mfizz.woff +0 -0
  121. data/web/assets/fonts/fontawesome-webfont.eot +0 -0
  122. data/web/assets/fonts/fontawesome-webfont.svg +520 -0
  123. data/web/assets/fonts/fontawesome-webfont.ttf +0 -0
  124. data/web/assets/fonts/fontawesome-webfont.woff +0 -0
  125. data/web/assets/images/header-slim.jpg +0 -0
  126. data/web/assets/images/icon-search.png +0 -0
  127. data/web/assets/images/mad-glory-logo.png +0 -0
  128. data/web/assets/images/main-gradient.png +0 -0
  129. data/web/assets/images/top-bar-logo.png +0 -0
  130. data/web/assets/javascripts/application.min.js +5 -0
  131. data/web/assets/stylesheets/application.min.css +4 -0
  132. data/web/templates/cookbook_show.erb +96 -0
  133. data/web/templates/dashboard.erb +81 -0
  134. data/web/templates/layout.erb +38 -0
  135. metadata +433 -0
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe Minimart::InventoryRequirement::SupermarketRequirementsBuilder do
4
+
5
+ let(:versions) { ['> 1.0.0', '~> 0.1'] }
6
+
7
+ subject do
8
+ described_class.new('mysql', 'versions' => versions)
9
+ end
10
+
11
+ describe '#build' do
12
+ it 'should return an array' do
13
+ expect(subject.build).to be_a Array
14
+ end
15
+
16
+ it 'should build requirements using the base requirement class' do
17
+ expect(subject.build.first).to be_a Minimart::InventoryRequirement::BaseRequirement
18
+ end
19
+
20
+ it "should build a requirement for version '> 1.0.0'" do
21
+ requirements = subject.build
22
+ expect(requirements.any? { |r| r.version_requirement == '> 1.0.0'}).to eq true
23
+ end
24
+
25
+ it "should build a requirement for version '~> 0.1'" do
26
+ requirements = subject.build
27
+ expect(requirements.any? { |r| r.version_requirement == '~> 0.1'}).to eq true
28
+ end
29
+
30
+ context 'when no versions are supplied' do
31
+ subject do
32
+ described_class.new('mysql', {})
33
+ end
34
+
35
+ it 'should return an empty array' do
36
+ expect(subject.build).to be_empty
37
+ end
38
+ end
39
+
40
+ context 'when a string version is supplied' do
41
+ subject do
42
+ described_class.new('mysql', 'versions' => '~> 0.1')
43
+ end
44
+
45
+ it 'should build a single requirement' do
46
+ expect(subject.build.size).to eq 1
47
+ end
48
+
49
+ it 'should give the requirement the proper version' do
50
+ expect(subject.build.first.version_requirement).to eq '~> 0.1'
51
+ end
52
+
53
+ it 'should give the requirement the proper name' do
54
+ expect(subject.build.first.name).to eq 'mysql'
55
+ end
56
+ end
57
+
58
+ context 'when the string "version" is used as the key' do
59
+ subject do
60
+ described_class.new('mysql', 'version' => '~> 0.1')
61
+ end
62
+
63
+ it 'should give the requirement the proper version' do
64
+ expect(subject.build.first.version_requirement).to eq '~> 0.1'
65
+ end
66
+ end
67
+ end
68
+
69
+ end
@@ -0,0 +1,123 @@
1
+ require 'spec_helper'
2
+
3
+ describe Minimart::Mirror::DependencyGraph do
4
+
5
+ subject do
6
+ Minimart::Mirror::DependencyGraph.new
7
+ end
8
+
9
+ let(:cookbook) do
10
+ Minimart::Mirror::SourceCookbook.new(
11
+ name: 'mysql',
12
+ version: '1.0.0',
13
+ dependencies: { 'yum' => '> 1.0.0' })
14
+ end
15
+
16
+ describe '#add_artifact' do
17
+ let(:cookbook_dependencies) do
18
+ subject.find_graph_artifact(cookbook).dependencies.map(&:name)
19
+ end
20
+
21
+ before(:each) do
22
+ subject.add_artifact(cookbook)
23
+ end
24
+
25
+ it 'should add the cookbook to the graph' do
26
+ expect(subject.source_cookbook_added?(cookbook.name, cookbook.version)).to eq true
27
+ end
28
+
29
+ it 'should add any possible dependencies to the graph' do
30
+ expect(cookbook_dependencies).to include 'yum'
31
+ end
32
+
33
+ context 'when the cookbook has already been added' do
34
+ let(:modified_cookbook) do
35
+ Minimart::Mirror::SourceCookbook.new(
36
+ name: 'mysql',
37
+ version: '1.0.0',
38
+ dependencies: { 'apt' => '> 1.0.0' })
39
+ end
40
+
41
+ before(:each) do
42
+ subject.add_artifact(modified_cookbook)
43
+ end
44
+
45
+ it 'should not add any new dependencies' do
46
+ expect(cookbook_dependencies).to_not include 'apt'
47
+ end
48
+
49
+ it 'should leave existing dependencies in place' do
50
+ expect(cookbook_dependencies).to include 'yum'
51
+ end
52
+ end
53
+ end
54
+
55
+ describe '#source_cookbook_added?' do
56
+ context 'when the cookbook has been added' do
57
+ before(:each) { subject.add_artifact(cookbook) }
58
+
59
+ it 'should return true' do
60
+ expect(subject.source_cookbook_added?(cookbook.name, cookbook.version)).to eq true
61
+ end
62
+ end
63
+
64
+ context 'when the cookbook has not been added' do
65
+ it 'should return false' do
66
+ expect(subject.source_cookbook_added?(cookbook.name, cookbook.version)).to eq false
67
+ end
68
+ end
69
+ end
70
+
71
+ describe '#add_requirement' do
72
+ it 'should add the requirement' do
73
+ subject.add_requirement('yum' => '~> 1.0.0')
74
+ expect(subject.inventory_requirements).to include ['yum', '~> 1.0.0']
75
+ end
76
+ end
77
+
78
+ describe '#resolved_requirements' do
79
+ let(:apt_cookbook) do
80
+ Minimart::Mirror::SourceCookbook.new(name: 'apt', version: '2.0.0')
81
+ end
82
+
83
+ let(:yum_cookbook) do
84
+ Minimart::Mirror::SourceCookbook.new(name: 'yum', version: '5.0.0')
85
+ end
86
+
87
+ context 'when all dependencies are met' do
88
+ before(:each) do
89
+ subject.add_artifact(cookbook)
90
+ subject.add_artifact(yum_cookbook)
91
+ subject.add_artifact(apt_cookbook)
92
+ subject.add_requirement('apt' => '> 1.0.0')
93
+ subject.add_requirement('mysql' => '= 1.0.0')
94
+ end
95
+
96
+ it 'should return a resolved mysql version' do
97
+ expect(subject.resolved_requirements).to include ['mysql', '1.0.0']
98
+ end
99
+
100
+ it 'should return a resolved apt version' do
101
+ expect(subject.resolved_requirements).to include ['apt', '2.0.0']
102
+ end
103
+
104
+ it 'should return a resolved yum version for the mysql dependency' do
105
+ expect(subject.resolved_requirements).to include ['yum', '5.0.0']
106
+ end
107
+ end
108
+
109
+ context 'when a dependency cannot be resolved' do
110
+ before(:each) do
111
+ # leaving out the yum dependency needed for mysql
112
+ subject.add_artifact(cookbook)
113
+ subject.add_requirement('mysql' => '= 1.0.0')
114
+ end
115
+
116
+ it 'should raise an error' do
117
+ expect {
118
+ subject.resolved_requirements
119
+ }.to raise_error Minimart::Error::UnresolvedDependency
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe Minimart::Mirror::DownloadMetadata do
4
+
5
+ let(:path) { File.join(test_directory, 'sample_cookbook') }
6
+
7
+ subject do
8
+ Minimart::Mirror::DownloadMetadata.new(path)
9
+ end
10
+
11
+ before(:each) { FileUtils.cp_r('spec/fixtures/sample_cookbook', path) }
12
+
13
+ describe '::new' do
14
+ it 'should assign #path_to_cookbook' do
15
+ expect(subject.path_to_cookbook).to eq path
16
+ end
17
+
18
+ context 'when metadata for that file has already been written' do
19
+ let(:metadata) { { 'fake_data' => 'info' } }
20
+
21
+ before(:each) do
22
+ File.open(File.join(path, '.minimart.json'), 'w+') do |f|
23
+ f.write(metadata.to_json)
24
+ end
25
+ end
26
+
27
+ it 'should parse the metadata' do
28
+ expect(subject.metadata).to eq metadata
29
+ end
30
+ end
31
+ end
32
+
33
+ describe '#write' do
34
+ let(:file_contents) do
35
+ JSON.parse(File.open(File.join(path, '.minimart.json')).read)
36
+ end
37
+
38
+ before(:each) { subject.write({'source' => 'example.com'}) }
39
+
40
+ it 'should write any of the provided content to the file' do
41
+ expect(file_contents['source']).to eq 'example.com'
42
+ end
43
+
44
+ it 'should write the downloaded at timestamp' do
45
+ expect(file_contents.keys).to include 'downloaded_at'
46
+ end
47
+
48
+ it 'should store any of the metadata as an instance variable' do
49
+ expect(subject.metadata).to include(
50
+ 'source' => 'example.com',
51
+ 'downloaded_at' => an_instance_of(String))
52
+ end
53
+ end
54
+
55
+ describe '#downloaded_at' do
56
+ context 'when no downloaded_at is in the metadata' do
57
+ subject { Minimart::Mirror::DownloadMetadata.new('new-cookbook') }
58
+
59
+ it 'should return nil' do
60
+ expect(subject.downloaded_at).to be_nil
61
+ end
62
+ end
63
+
64
+ context 'when the downloaded_at has been set' do
65
+ before(:each) { subject.write }
66
+
67
+ it 'should parse the time' do
68
+ expect(subject.downloaded_at).to be_a Time
69
+ end
70
+ end
71
+ end
72
+
73
+ end
@@ -0,0 +1,195 @@
1
+ require 'spec_helper'
2
+
3
+ describe Minimart::Mirror::InventoryBuilder do
4
+
5
+ subject do
6
+ Minimart::Mirror::InventoryBuilder.new(test_directory, inventory_config)
7
+ end
8
+
9
+ describe '#build' do
10
+ describe 'when a git cookbook is present' do
11
+ let(:inventory_config) do
12
+ Minimart::Mirror::InventoryConfiguration.new('spec/fixtures/simple_git_inventory.yml')
13
+ end
14
+
15
+ before(:each) do
16
+ # stub out actually cloning the repo
17
+ allow_any_instance_of(Minimart::Download::GitRepository).to receive(:fetch).and_yield 'spec/fixtures/sample_cookbook'
18
+ end
19
+
20
+ around(:each) do |e|
21
+ VCR.use_cassette('location_specific_cookbooks') { e.call }
22
+ end
23
+
24
+ it 'should add the cookbook to the graph' do
25
+ subject.build!
26
+ expect(subject.graph.source_cookbook_added?('sample_cookbook', '1.2.3')).to eq true
27
+ end
28
+
29
+ it 'should add the cookbook to the local store' do
30
+ subject.build!
31
+ expect(subject.local_store.installed?('sample_cookbook', '1.2.3')).to eq true
32
+ end
33
+
34
+ it 'should add any dependencies of the cookbook to the local store' do
35
+ subject.build!
36
+ expect(subject.local_store.installed?('yum', '3.5.1')).to eq true
37
+ end
38
+
39
+ it 'should clear the git cache' do
40
+ expect_any_instance_of(Minimart::Download::GitCache).to receive :clear
41
+ subject.build!
42
+ end
43
+
44
+ it 'should store metadata about downloading the cookbook' do
45
+ subject.build!
46
+ metadata = JSON.parse(File.open(File.join(test_directory, 'sample_cookbook-1.2.3', '.minimart.json')).read)
47
+ expect(metadata).to include(
48
+ 'source_type' => 'git',
49
+ 'location' => 'spec/fixtures/sample_cookbook',
50
+ 'commitish_type' => 'tag',
51
+ 'commitish' => 'v1.2.3')
52
+ end
53
+
54
+ context 'when the same cookbook is present in the local store with a different source' do
55
+ before(:each) do
56
+ subject.build!
57
+ allow_any_instance_of(Minimart::Cookbook).to receive(:download_metadata).and_return(
58
+ 'source_type' => 'git',
59
+ 'location' => 'spec/fixtures/sample_cookbook',
60
+ 'commitish_type' => 'ref',
61
+ 'commitish' => 'SHA')
62
+ end
63
+
64
+ it 'should raise an error' do
65
+ expect {
66
+ subject.build!
67
+ }.to raise_error Minimart::Error::BrokenDependency
68
+ end
69
+ end
70
+ end
71
+
72
+ describe 'when a cookbook with a local path is present' do
73
+ let(:inventory_config) do
74
+ Minimart::Mirror::InventoryConfiguration.new('spec/fixtures/simple_local_path_inventory.yml')
75
+ end
76
+
77
+ around(:each) do |e|
78
+ VCR.use_cassette('local_path_cookbooks') { e.call }
79
+ end
80
+
81
+ it 'should add the cookbook to the graph' do
82
+ subject.build!
83
+ expect(subject.graph.source_cookbook_added?('sample_cookbook', '1.2.3')).to eq true
84
+ end
85
+
86
+ it 'should add the cookbook to the local store' do
87
+ subject.build!
88
+ expect(subject.local_store.installed?('sample_cookbook', '1.2.3')).to eq true
89
+ end
90
+
91
+ it 'should add any dependencies of the cookbook to the local store' do
92
+ subject.build!
93
+ expect(subject.local_store.installed?('yum', '3.5.1')).to eq true
94
+ end
95
+
96
+ it 'should store metadata about downloading the cookbook' do
97
+ subject.build!
98
+ metadata = JSON.parse(File.open(File.join(test_directory, 'sample_cookbook-1.2.3', '.minimart.json')).read)
99
+ expect(metadata).to include('source_type' => 'local_path')
100
+ end
101
+ end
102
+
103
+ describe 'fetching cookbooks from a supermarket' do
104
+ let(:inventory_config) do
105
+ Minimart::Mirror::InventoryConfiguration.new('spec/fixtures/simple_inventory.yml')
106
+ end
107
+
108
+ describe 'building the dependency graph' do
109
+ before(:each) do
110
+ stub_request(:get, "https://supermarket.getchef.com/universe").
111
+ to_return(status: 200, body: File.open('spec/fixtures/universe.json').read)
112
+ end
113
+
114
+ around(:each) do |e|
115
+ VCR.use_cassette('supermarket_cookbooks_graph') { e.call }
116
+ end
117
+
118
+ let(:expected_universe) do
119
+ [['mysql', '5.6.1'], ['mysql', '5.5.4'], ['yum', '3.4.1', '3.3.1']]
120
+ end
121
+
122
+ it 'should populate the dependency graph with anything returned by the universe' do
123
+ subject.build!
124
+ expected_universe.each do |name, version|
125
+ expect(subject.graph.source_cookbook_added?(name, version)).to eq true
126
+ end
127
+ end
128
+ end
129
+
130
+ describe 'installing cookbooks' do
131
+ around(:each) do |e|
132
+ VCR.use_cassette('supermarket_cookbooks_installing_cookbooks') { e.call }
133
+ end
134
+
135
+ it 'should add the resolved version of the cookbook to the local store' do
136
+ subject.build!
137
+ expect(subject.local_store.installed?('mysql', '5.5.4')).to eq true
138
+ end
139
+
140
+ it 'should add the cookbook to the local inventory' do
141
+ subject.build!
142
+ expect(Dir.exists?(File.join(test_directory, 'mysql-5.5.4'))).to eq true
143
+ end
144
+
145
+ it 'should add any resolved dependencies to the local store' do
146
+ subject.build!
147
+ expect(subject.local_store.installed?('yum', '3.5.1')).to eq true
148
+ expect(subject.local_store.installed?('yum-mysql-community', '0.1.10')).to eq true
149
+ end
150
+
151
+ it 'should actually add the dependent cookbooks to the local inventory' do
152
+ subject.build!
153
+ expect(Dir.exists?(File.join(test_directory, 'yum-3.5.1'))).to eq true
154
+ expect(Dir.exists?(File.join(test_directory, 'yum-mysql-community-0.1.10'))).to eq true
155
+ end
156
+
157
+ it 'should store metadata about downloading the cookbook' do
158
+ subject.build!
159
+ metadata = JSON.parse(File.open(File.join(test_directory, 'mysql-5.5.4', '.minimart.json')).read)
160
+ expect(metadata).to include(
161
+ 'source_type' => 'opscode',
162
+ 'location' => 'https://supermarket.chef.io/api/v1')
163
+ end
164
+
165
+ context 'when a cookbook has already been installed' do
166
+ before(:each) do
167
+ allow(subject.local_store).to receive(:installed?).and_return true
168
+ end
169
+
170
+ it 'should not download the cookbooks a second time' do
171
+ expect(Minimart::Download::Cookbook).to_not receive(:download)
172
+ subject.build!
173
+ end
174
+ end
175
+
176
+ context 'when a coookbook depends on a non explicit version of a required cookbook' do
177
+ let(:bad_requirements) do
178
+ [%w[mysql 5.4], %w[mysql 0.0.1]]
179
+ end
180
+
181
+ before(:each) do
182
+ allow_any_instance_of(Minimart::Mirror::DependencyGraph).to receive(:resolved_requirements).and_return(bad_requirements)
183
+ end
184
+
185
+ it 'should raise an error' do
186
+ expect {
187
+ subject.build!
188
+ }.to raise_error Minimart::Error::BrokenDependency
189
+ end
190
+ end
191
+ end
192
+
193
+ end
194
+ end
195
+ end