minimart 1.1.6 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MjlkNTAzOTQ2YjM4YzNjNGQwNTE0NmE1NTY3MzMzZjlmYTdiZWJmOQ==
4
+ ZDJiYjYwYTVkNjQ5NzA3MTA0MzQwN2EyMGMyMzNkZWQxMWIzZjE3ZQ==
5
5
  data.tar.gz: !binary |-
6
- NzE5OTFlZDI3MjdkZmU2OGRlNjczZDZhN2YxNWQ0ZTYzNzk2ZDI5MQ==
6
+ MzVkNmI0OTgyMGYxMmQzNmM0YjBhZjBmZjcwMjhlMWFiMTY1N2NhMw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZmIzZGQ0YzA4MWI2MTQxMGZhMDk2NjMzMjk1YzgxMTE5NDAyMDk2OGRiMDVm
10
- Y2IzNWExN2Q5ZTJlYzY3YjU2MTE5ZWNkM2VlMDVjOGJjMDAyYmEzZTI4N2Mw
11
- OTZhYWI0NDQzMmRjM2FlYWQ2ZjVkYWZmOTlhYjlmYzNkYTg2NzE=
9
+ N2IyZTY1NjcyMTI5OTk5OGRlZmM1YjE2YTBiOWU5ZWRhYjE4NmQwYTdmNjQ1
10
+ MjFiY2I0NDU0ZTgyNGI5YWNiM2ZiODk2ODA5ZmI0NDAzZTgzMzI2YjRjYzRl
11
+ YTY0NTBiZTJlMmMwMmI5NTk2N2NlODUyNWFhMDVhMDVmYjA4MGM=
12
12
  data.tar.gz: !binary |-
13
- NjQ3ODcxNjY0Y2EwOWIwYjNhNTgwMGNiOThlMjE1NWVjMDQ5OGU3ODhjZGEz
14
- ZjZhNDg5MTY3YTU1YzQzNWQxNDNlMzM5ZmI5OGVlMDcyOTQwZThlN2ZiZjRh
15
- YTY5YjY1NzZiNWFiZmQyODU3ZWQyODBmNDFkM2VjZTZjMTRmYmQ=
13
+ Y2FhYTlmZjI5NzExNTI5OTMyNDg0ZTBiYWRjYjdmNmMzZThhZjEzNTRkMDAw
14
+ YmVhNjE0Y2IyMWJhZjExODkxYTY5MGQ5NzhjMzliZjUyNWMwMDcxOWYxNjk1
15
+ ZDJmNmIwNjQ5NTRiYjkxYTI3YTlmNjQxZDcyNDdkNjYwYjZhYjc=
data/lib/minimart/cli.rb CHANGED
@@ -86,6 +86,10 @@ YML
86
86
  default: true,
87
87
  desc: 'Flag to determine whether or not to generate HTML output along with the universe endpoint.'
88
88
 
89
+ option :clean_cookbooks,
90
+ type: :boolean,
91
+ default: true,
92
+ desc: 'Flag to determine whether or not existing cookbook packages are deleted and recreated'
89
93
  # Generate a web interface to download any mirrored cookbooks.
90
94
  def web
91
95
  Minimart::Commands::Web.new(options).execute!
@@ -17,17 +17,21 @@ module Minimart
17
17
  # @return [Boolean] Determine whether or not to generate HTML output
18
18
  attr_reader :can_generate_html
19
19
 
20
+ # @return [Boolean] Determine whether or not to clean the cookbook_files folder and recreate
21
+ attr_reader :clean_cookbooks
20
22
 
21
23
  # @param [Hash] opts
22
24
  # @option opts [String] :inventory_directory The directory that the inventory is stored in.
23
25
  # @option opts [String] :web_directory The directory to store the web output.
24
26
  # @option opts [String] :host The web endpoint where Minimart will be hosted.
25
27
  # @option opts [Boolean] :can_generate_html Determine whether or not to generate HTML output
28
+ # @option opts [Boolean] :clean_cookbooks Determine whether or not to clean the cookbook_files folder and recreate
26
29
  def initialize(opts = {})
27
30
  @inventory_directory = File.expand_path(opts[:inventory_directory])
28
31
  @web_directory = File.expand_path(opts[:web_directory])
29
32
  @web_endpoint = opts[:host]
30
33
  @can_generate_html = opts.fetch(:html, true)
34
+ @clean_cookbooks = opts.fetch(:clean_cookbooks, true)
31
35
  end
32
36
 
33
37
  # Generate the web output.
@@ -52,7 +56,9 @@ module Minimart
52
56
  generator = Minimart::Web::UniverseGenerator.new(
53
57
  web_directory: web_directory,
54
58
  endpoint: web_endpoint,
55
- cookbooks: cookbooks)
59
+ cookbooks: cookbooks,
60
+ clean_cookbooks: clean_cookbooks
61
+ )
56
62
 
57
63
  generator.generate
58
64
  end
@@ -64,7 +70,9 @@ module Minimart
64
70
 
65
71
  generator = Minimart::Web::HtmlGenerator.new(
66
72
  web_directory: web_directory,
67
- cookbooks: cookbooks)
73
+ cookbooks: cookbooks,
74
+ clean_cookbooks: clean_cookbooks
75
+ )
68
76
 
69
77
  generator.generate
70
78
  end
@@ -60,7 +60,10 @@ module Minimart
60
60
  # Convert the requirement to a Hash.
61
61
  # @return [Hash]
62
62
  def to_hash
63
- {}
63
+ {
64
+ :metadata_version => '2.0', #metadata document version.
65
+ :name => @name
66
+ }
64
67
  end
65
68
 
66
69
  # Determine if a cookbook in the inventory has metadata matching this requirement
@@ -68,7 +71,12 @@ module Minimart
68
71
  # in the inventory.
69
72
  # @return [Boolean] Defaults to true
70
73
  def matching_source?(metadata)
71
- return true
74
+ if metadata.has_key?('metadata_version') && metadata['metadata_version'] == '2.0'
75
+ metadata['name'] == @name &&
76
+ metadata['version'] == @version_requirement
77
+ else
78
+ true
79
+ end
72
80
  end
73
81
 
74
82
  private
@@ -56,9 +56,16 @@ module Minimart
56
56
  # in the inventory.
57
57
  # @return [Boolean] Defaults to true
58
58
  def matching_source?(metadata)
59
- metadata['source_type'] == 'git' &&
60
- metadata['commitish_type'] == commitish_type.to_s &&
61
- (metadata['commitish_type'] == 'ref' ? true : metadata['commitish'] == commitish.to_s)
59
+ if metadata.has_key?('metadata_version') && metadata['metadata_version'] == '2.0'
60
+ metadata['source_type'] == 'git' &&
61
+ metadata['location'] == @location &&
62
+ metadata['commitish_type'] == commitish_type.to_s &&
63
+ (metadata['commitish_type'] == 'ref' ? true : metadata['commitish'] == commitish.to_s)
64
+ else
65
+ metadata['source_type'] == 'git' &&
66
+ metadata['commitish_type'] == commitish_type.to_s &&
67
+ (metadata['commitish_type'] == 'ref' ? true : metadata['commitish'] == commitish.to_s)
68
+ end
62
69
  end
63
70
 
64
71
  private
@@ -25,12 +25,18 @@ module Minimart
25
25
  # @return [Hash]
26
26
  def to_hash
27
27
  result = super
28
+ result[:path] = @path
28
29
  result[:source_type] = :local_path
29
30
  result
30
31
  end
31
32
 
32
33
  def matching_source?(metadata)
33
- metadata['source_type'] == 'local_path'
34
+ if metadata.has_key?('metadata_version') && metadata['metadata_version'] == '2.0'
35
+ metadata['source_type'] == 'local_path' &&
36
+ metadata['path'] == @path
37
+ else
38
+ metadata['source_type'] == 'local_path'
39
+ end
34
40
  end
35
41
 
36
42
  private
@@ -40,6 +40,10 @@ module Minimart
40
40
  metadata[key] if metadata
41
41
  end
42
42
 
43
+ def has_key?(key)
44
+ (metadata ? metadata.has_key?(key) : false)
45
+ end
46
+
43
47
  private
44
48
 
45
49
  def parse_file
@@ -35,6 +35,12 @@ module Minimart
35
35
  def install_cookbooks_with_explicit_location
36
36
  inventory_requirements.each_with_explicit_location do |requirement|
37
37
  begin
38
+ requirement_cookbook = local_store.cookbook_for_requirement(requirement)
39
+ if requirement_cookbook
40
+ Configuration.output.puts_yellow("cookbook already installed: #{requirement_cookbook}.")
41
+ next
42
+ end
43
+
38
44
  requirement.fetch_cookbook do |cookbook|
39
45
  validate_cookbook_against_local_store(cookbook, requirement)
40
46
  add_artifact_to_graph(cookbook)
@@ -16,14 +16,19 @@ module Minimart
16
16
  def initialize(directory_path)
17
17
  @directory_path = directory_path
18
18
  @cookbooks = {}
19
+ @metadata = {}
19
20
 
20
21
  load_local_inventory
22
+
21
23
  end
22
24
 
23
25
  # :nodoc:
24
26
  def add_cookbook_to_store(name, version)
25
27
  cookbooks[name] ||= []
26
28
  cookbooks[name] << version
29
+
30
+ metadata[name] ||= {}
31
+ metadata[name][version] = local_path_for("#{name}-#{version}")
27
32
  end
28
33
 
29
34
  # Copy a given cookbook to the local store, and record any metadata
@@ -45,6 +50,28 @@ module Minimart
45
50
  cookbooks[cookbook_name].include?(cookbook_version))
46
51
  end
47
52
 
53
+ def cookbook_for_requirement(requirement)
54
+ #we dont handle caching for anything other than git requirements in this function.
55
+ return nil unless requirement.is_a?(InventoryRequirement::GitRequirement)
56
+ # if this is a branch, we can't assume that the commit is the same (remote could have changed)
57
+ return nil if requirement.branch
58
+
59
+ @metadata.each{ |cookbook, versions|
60
+
61
+ versions.each{ |version, lazy_metadata|
62
+ #lazy populate the metadata
63
+ if(lazy_metadata.is_a?(String))
64
+ lazy_metadata = Minimart::Mirror::DownloadMetadata.new(lazy_metadata)
65
+ end
66
+
67
+ if requirement.matching_source?(lazy_metadata)
68
+ return "#{cookbook}-#{version}"
69
+ end
70
+ }
71
+ }
72
+ return nil
73
+ end
74
+
48
75
  # Validate that a new resolved requirement is not in the local store
49
76
  # with different requirements. If we download two different branches
50
77
  # of the same cookbook and they both resolve to the same version, then we
@@ -64,6 +91,7 @@ module Minimart
64
91
  private
65
92
 
66
93
  attr_reader :cookbooks
94
+ attr_reader :metadata
67
95
 
68
96
  def copy_cookbook(source, destination)
69
97
  FileUtils.rm_rf(destination) if Dir.exists?(destination)
@@ -51,6 +51,9 @@ module Minimart
51
51
  # @return [Hash]
52
52
  def to_hash
53
53
  {
54
+ metadata_version: '2.0',
55
+ name: @name,
56
+ version: @version,
54
57
  source_type: location_type,
55
58
  location: location_path
56
59
  }
@@ -1,3 +1,3 @@
1
1
  module Minimart
2
- VERSION = "1.1.6"
2
+ VERSION = "1.2.0"
3
3
  end
@@ -10,12 +10,15 @@ module Minimart
10
10
  # @return [Minimart::Web::Cookbooks] the cookbooks to generate show pages for
11
11
  attr_reader :cookbooks
12
12
 
13
+ attr_reader :clean_cookbooks
14
+
13
15
  # @param [Hash] opts
14
16
  # @option opts [String] :web_directory The directory to put any generated HTML in
15
17
  # @option opts [String] :cookbooks The cookbooks to generate show pages for
16
18
  def initialize(opts = {})
17
19
  @web_directory = opts[:web_directory]
18
20
  @cookbooks = opts[:cookbooks]
21
+ @clean_cookbooks = opts.fetch(:clean_cookbooks, true)
19
22
  end
20
23
 
21
24
  # Generate the HTML!
@@ -28,8 +31,9 @@ module Minimart
28
31
  private
29
32
 
30
33
  def clean_web_cookbooks_directory
31
- return unless Dir.exists?(cookbooks_directory)
32
- FileUtils.remove_entry(cookbooks_directory)
34
+ if Dir.exists?(cookbooks_directory) && @clean_cookbooks
35
+ FileUtils.remove_entry(cookbooks_directory)
36
+ end
33
37
  end
34
38
 
35
39
  def make_web_cookbooks_directory
@@ -39,7 +43,7 @@ module Minimart
39
43
  def create_html_files
40
44
  cookbooks.each do |cookbook_name, versions|
41
45
  versions.each do |cookbook|
42
- write_to_file(file(cookbook), template_content(cookbook, versions))
46
+ write_to_file(file(cookbook), template_content(cookbook, versions)) unless File.exists?(file(cookbook))
43
47
  end
44
48
  end
45
49
  end
@@ -12,7 +12,7 @@ module Minimart
12
12
  class HtmlGenerator
13
13
  include Minimart::Web::TemplateHelper
14
14
 
15
- attr_reader :web_directory, :cookbooks
15
+ attr_reader :web_directory, :cookbooks, :clean_cookbooks
16
16
 
17
17
  # @param [Hash] opts
18
18
  # @option opts [String] :web_directory The directory to put any generated HTML in
@@ -20,6 +20,7 @@ module Minimart
20
20
  def initialize(opts = {})
21
21
  @web_directory = opts[:web_directory]
22
22
  @cookbooks = opts[:cookbooks]
23
+ @clean_cookbooks = opts.fetch(:clean_cookbooks, true)
23
24
  end
24
25
 
25
26
  # Generate any HTML!
@@ -68,7 +69,8 @@ module Minimart
68
69
  def generate_cookbook_show_pages
69
70
  CookbookShowPageGenerator.new(
70
71
  web_directory: web_directory,
71
- cookbooks: cookbooks).generate
72
+ cookbooks: cookbooks,
73
+ clean_cookbooks: clean_cookbooks).generate
72
74
  end
73
75
 
74
76
  end
@@ -23,10 +23,12 @@ module Minimart
23
23
  # @option opts [String] web_directory The directory to put the universe.json file in
24
24
  # @option opts [String] endpoint The base URL to use to build paths for cookbook files.
25
25
  # @option opts [Minimart::Web::Cookbooks] cookbooks The cookbooks to build a universe for
26
+ # @option opts [Boolean] clean_cookbooks Determines if we should clean the cookbook_files folder and recreate cookbook packages
26
27
  def initialize(opts = {})
27
28
  @web_directory = opts[:web_directory]
28
29
  @endpoint = opts[:endpoint]
29
30
  @cookbooks = opts[:cookbooks]
31
+ @clean_cookbooks = opts.fetch(:clean_cookbooks, true)
30
32
  @universe = {}
31
33
  end
32
34
 
@@ -41,8 +43,9 @@ module Minimart
41
43
  private
42
44
 
43
45
  def clean_existing_cookbook_files
44
- return unless Dir.exists?(cookbook_files_directory)
45
- FileUtils.remove_entry(cookbook_files_directory)
46
+ if Dir.exists?(cookbook_files_directory) && @clean_cookbooks
47
+ FileUtils.remove_entry(cookbook_files_directory)
48
+ end
46
49
  end
47
50
 
48
51
  def make_cookbook_files_directory
@@ -51,8 +54,10 @@ module Minimart
51
54
 
52
55
  def create_universe
53
56
  cookbooks.individual_cookbooks.each do |cookbook|
54
- make_cookbook_directory(cookbook)
55
- generate_archive_file(cookbook)
57
+ unless Dir.exists?(archive_directory(cookbook))
58
+ make_cookbook_directory(cookbook)
59
+ generate_archive_file(cookbook)
60
+ end
56
61
  add_cookbook_to_universe(cookbook)
57
62
  end
58
63
  end
data/minimart.gemspec CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.add_dependency 'redcarpet', '= 3.3.2'
26
26
  spec.add_dependency 'rest-client', '~> 1.7'
27
27
  spec.add_dependency 'ridley', '~> 4.1'
28
- spec.add_dependency 'solve', '~> 1.2', '>= 1.2.1'
28
+ spec.add_dependency 'solve', '~> 2.0', '>= 2.0'
29
29
  spec.add_dependency 'thor', '~> 0.19'
30
30
  spec.add_dependency 'tilt', '~> 2.0'
31
31
  spec.add_dependency 'sprockets', '~> 3.5'
@@ -0,0 +1,9 @@
1
+ sources:
2
+ - "https://supermarket.getchef.com"
3
+ cookbooks:
4
+ sample_cookbook:
5
+ git:
6
+ location: spec/fixtures/sample_cookbook
7
+ tags:
8
+ - v1.2.3
9
+ - v2.3.4
@@ -69,7 +69,8 @@ describe Minimart::Cli do
69
69
  'web_directory' => './web',
70
70
  'inventory_directory' => './inventory',
71
71
  'host' => 'http://example.com',
72
- 'html' => true).and_return command_double
72
+ 'html' => true,
73
+ 'clean_cookbooks' => true).and_return command_double
73
74
 
74
75
  Minimart::Cli.start %w[web --host=http://example.com]
75
76
  end
@@ -79,7 +80,8 @@ describe Minimart::Cli do
79
80
  'web_directory' => './my-web',
80
81
  'inventory_directory' => './my-inventory',
81
82
  'host' => 'http://example.com',
82
- 'html' => false).and_return command_double
83
+ 'html' => false,
84
+ 'clean_cookbooks' => true).and_return command_double
83
85
 
84
86
  Minimart::Cli.start %w[
85
87
  web
@@ -44,6 +44,7 @@ describe Minimart::Commands::Web do
44
44
  expect(Minimart::Web::UniverseGenerator).to receive(:new).with(
45
45
  web_directory: subject.web_directory,
46
46
  endpoint: subject.web_endpoint,
47
+ clean_cookbooks: true,
47
48
  cookbooks: an_instance_of(Minimart::Web::Cookbooks)).and_return generator_double
48
49
 
49
50
  subject.execute!
@@ -52,7 +53,8 @@ describe Minimart::Commands::Web do
52
53
  it 'should generate the static HTML files' do
53
54
  expect(Minimart::Web::HtmlGenerator).to receive(:new).with(
54
55
  web_directory: subject.web_directory,
55
- cookbooks: an_instance_of(Minimart::Web::Cookbooks)).and_return generator_double
56
+ cookbooks: an_instance_of(Minimart::Web::Cookbooks),
57
+ clean_cookbooks: true).and_return generator_double
56
58
 
57
59
  subject.execute!
58
60
  end
@@ -57,16 +57,12 @@ describe Minimart::Mirror::InventoryBuilder do
57
57
  end
58
58
 
59
59
  context 'when the same cookbook is present in the local store with a different source' do
60
- before(:each) do
61
- subject.build!
62
- allow_any_instance_of(Minimart::Cookbook).to receive(:download_metadata).and_return(
63
- 'source_type' => 'git',
64
- 'location' => 'spec/fixtures/sample_cookbook',
65
- 'commitish_type' => 'ref',
66
- 'commitish' => 'SHA')
60
+ let(:inventory_config) do
61
+ Minimart::Mirror::InventoryConfiguration.new('spec/fixtures/bad_git_inventory.yml')
67
62
  end
68
63
 
69
- # broken
64
+ # Will fail due to multiple cookbooks with same version coming
65
+ # from different Git locations
70
66
  it 'should raise an error' do
71
67
  expect {
72
68
  subject.build!
@@ -61,4 +61,39 @@ describe Minimart::Mirror::LocalStore do
61
61
  end
62
62
  end
63
63
 
64
+ describe '#cookbook_for_requirement' do
65
+ let(:sample_cookbook_path) { 'spec/fixtures/sample_cookbook' }
66
+ it 'should return cookbook name when requirement matches existing cookbook' do
67
+ subject.add_cookbook_from_path(sample_cookbook_path, {
68
+ 'source_type' => 'git',
69
+ 'location' => 'spec/fixtures/sample_cookbook',
70
+ 'commitish_type' => 'tag',
71
+ 'commitish' => 'v1.2.3'})
72
+
73
+ requirement = Minimart::InventoryRequirement::GitRequirement.new('sample_cookbook', {
74
+ :tag => 'v1.2.3',
75
+ :location => 'spec/fixtures/sample_cookbook',
76
+ :version_requirement => '1.2.3'
77
+ })
78
+
79
+ expect(subject.cookbook_for_requirement(requirement)).to eq 'sample_cookbook-1.2.3'
80
+ end
81
+
82
+ it 'should return nil when requirement does not match any existing cookbook' do
83
+ subject.add_cookbook_from_path(sample_cookbook_path, {
84
+ 'source_type' => 'git',
85
+ 'location' => 'spec/fixtures/sample_cookbook',
86
+ 'commitish_type' => 'tag',
87
+ 'commitish' => 'v1.2.3'})
88
+
89
+ requirement = Minimart::InventoryRequirement::GitRequirement.new('sample_cookbook', {
90
+ :branch => 'feature_branch',
91
+ :location => 'spec/fixtures/sample_cookbook',
92
+ :version_requirement => '1.2.3'
93
+ })
94
+
95
+ expect(subject.cookbook_for_requirement(requirement)).to eq nil
96
+ end
97
+ end
98
+
64
99
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minimart
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.6
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - MadGlory
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-03-07 00:00:00.000000000 Z
13
+ date: 2016-03-24 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: git
@@ -108,20 +108,20 @@ dependencies:
108
108
  requirements:
109
109
  - - ~>
110
110
  - !ruby/object:Gem::Version
111
- version: '1.2'
111
+ version: '2.0'
112
112
  - - ! '>='
113
113
  - !ruby/object:Gem::Version
114
- version: 1.2.1
114
+ version: '2.0'
115
115
  type: :runtime
116
116
  prerelease: false
117
117
  version_requirements: !ruby/object:Gem::Requirement
118
118
  requirements:
119
119
  - - ~>
120
120
  - !ruby/object:Gem::Version
121
- version: '1.2'
121
+ version: '2.0'
122
122
  - - ! '>='
123
123
  - !ruby/object:Gem::Version
124
- version: 1.2.1
124
+ version: '2.0'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: thor
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -333,6 +333,7 @@ files:
333
333
  - lib/minimart/web/template_helper.rb
334
334
  - lib/minimart/web/universe_generator.rb
335
335
  - minimart.gemspec
336
+ - spec/fixtures/bad_git_inventory.yml
336
337
  - spec/fixtures/bad_metadata_inventory.yml
337
338
  - spec/fixtures/sample_cookbook.tar.gz
338
339
  - spec/fixtures/sample_cookbook/Berksfile
@@ -459,6 +460,7 @@ specification_version: 4
459
460
  summary: MiniMart is a RubyGem that makes it simple to build a repository of Chef
460
461
  cookbooks using only static files.
461
462
  test_files:
463
+ - spec/fixtures/bad_git_inventory.yml
462
464
  - spec/fixtures/bad_metadata_inventory.yml
463
465
  - spec/fixtures/sample_cookbook.tar.gz
464
466
  - spec/fixtures/sample_cookbook/Berksfile