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.
- checksums.yaml +15 -0
- data/.gitignore +21 -0
- data/.rspec +3 -0
- data/.travis.yml +13 -0
- data/Gemfile +3 -0
- data/README.md +198 -0
- data/Rakefile +45 -0
- data/bin/minimart +4 -0
- data/lib/minimart.rb +15 -0
- data/lib/minimart/cli.rb +93 -0
- data/lib/minimart/commands/mirror.rb +30 -0
- data/lib/minimart/commands/web.rb +91 -0
- data/lib/minimart/configuration.rb +46 -0
- data/lib/minimart/cookbook.rb +173 -0
- data/lib/minimart/download/cookbook.rb +70 -0
- data/lib/minimart/download/git_cache.rb +60 -0
- data/lib/minimart/download/git_repository.rb +41 -0
- data/lib/minimart/error.rb +32 -0
- data/lib/minimart/inventory_requirement/base_requirement.rb +81 -0
- data/lib/minimart/inventory_requirement/git_requirement.rb +87 -0
- data/lib/minimart/inventory_requirement/git_requirements_builder.rb +101 -0
- data/lib/minimart/inventory_requirement/local_path_requirement.rb +45 -0
- data/lib/minimart/inventory_requirement/local_requirements_builder.rb +31 -0
- data/lib/minimart/inventory_requirement/supermarket_requirements_builder.rb +35 -0
- data/lib/minimart/mirror.rb +12 -0
- data/lib/minimart/mirror/dependency_graph.rb +73 -0
- data/lib/minimart/mirror/download_metadata.rb +57 -0
- data/lib/minimart/mirror/inventory_builder.rb +143 -0
- data/lib/minimart/mirror/inventory_configuration.rb +74 -0
- data/lib/minimart/mirror/inventory_requirements.rb +104 -0
- data/lib/minimart/mirror/local_store.rb +107 -0
- data/lib/minimart/mirror/source.rb +57 -0
- data/lib/minimart/mirror/source_cookbook.rb +77 -0
- data/lib/minimart/mirror/sources.rb +37 -0
- data/lib/minimart/output.rb +34 -0
- data/lib/minimart/utils/archive.rb +39 -0
- data/lib/minimart/utils/file_helper.rb +34 -0
- data/lib/minimart/utils/http.rb +60 -0
- data/lib/minimart/version.rb +3 -0
- data/lib/minimart/web.rb +10 -0
- data/lib/minimart/web/cookbook_show_page_generator.rb +78 -0
- data/lib/minimart/web/cookbooks.rb +83 -0
- data/lib/minimart/web/dashboard_generator.rb +46 -0
- data/lib/minimart/web/html_generator.rb +52 -0
- data/lib/minimart/web/markdown_parser.rb +47 -0
- data/lib/minimart/web/template_helper.rb +132 -0
- data/lib/minimart/web/universe_generator.rb +109 -0
- data/minimart.gemspec +36 -0
- data/spec/fixtures/sample_cookbook.tar.gz +0 -0
- data/spec/fixtures/sample_cookbook/Berksfile +3 -0
- data/spec/fixtures/sample_cookbook/CHANGELOG.md +3 -0
- data/spec/fixtures/sample_cookbook/Gemfile +16 -0
- data/spec/fixtures/sample_cookbook/LICENSE +3 -0
- data/spec/fixtures/sample_cookbook/README.md +42 -0
- data/spec/fixtures/sample_cookbook/Thorfile +5 -0
- data/spec/fixtures/sample_cookbook/Vagrantfile +90 -0
- data/spec/fixtures/sample_cookbook/chefignore +94 -0
- data/spec/fixtures/sample_cookbook/metadata.rb +9 -0
- data/spec/fixtures/sample_cookbook/recipes/default.rb +8 -0
- data/spec/fixtures/sample_inventory.yml +16 -0
- data/spec/fixtures/simple_git_inventory.yml +8 -0
- data/spec/fixtures/simple_inventory.yml +6 -0
- data/spec/fixtures/simple_local_path_inventory.yml +5 -0
- data/spec/fixtures/universe.json +42 -0
- data/spec/fixtures/vcr_cassettes/local_path_cookbooks.yml +3316 -0
- data/spec/fixtures/vcr_cassettes/location_specific_cookbooks.yml +3316 -0
- data/spec/fixtures/vcr_cassettes/supermarket_cookbooks_graph.yml +905 -0
- data/spec/fixtures/vcr_cassettes/supermarket_cookbooks_installing_cookbooks.yml +4218 -0
- data/spec/lib/minimart/cli_spec.rb +104 -0
- data/spec/lib/minimart/commands/mirror_spec.rb +37 -0
- data/spec/lib/minimart/commands/web_spec.rb +75 -0
- data/spec/lib/minimart/configuration_spec.rb +54 -0
- data/spec/lib/minimart/cookbook_spec.rb +137 -0
- data/spec/lib/minimart/download/cookbook_spec.rb +135 -0
- data/spec/lib/minimart/download/git_cache_spec.rb +69 -0
- data/spec/lib/minimart/download/git_repository_spec.rb +39 -0
- data/spec/lib/minimart/error_spec.rb +18 -0
- data/spec/lib/minimart/inventory_requirement/base_requirement_spec.rb +38 -0
- data/spec/lib/minimart/inventory_requirement/git_requirement_spec.rb +92 -0
- data/spec/lib/minimart/inventory_requirement/git_requirements_builder_spec.rb +130 -0
- data/spec/lib/minimart/inventory_requirement/local_path_requirement_spec.rb +35 -0
- data/spec/lib/minimart/inventory_requirement/local_requirements_builder_spec.rb +33 -0
- data/spec/lib/minimart/inventory_requirement/supermarket_requirements_builder_spec.rb +69 -0
- data/spec/lib/minimart/mirror/dependency_graph_spec.rb +123 -0
- data/spec/lib/minimart/mirror/download_metadata_spec.rb +73 -0
- data/spec/lib/minimart/mirror/inventory_builder_spec.rb +195 -0
- data/spec/lib/minimart/mirror/inventory_configuration_spec.rb +86 -0
- data/spec/lib/minimart/mirror/inventory_requirements_spec.rb +78 -0
- data/spec/lib/minimart/mirror/local_store_spec.rb +64 -0
- data/spec/lib/minimart/mirror/source_spec.rb +54 -0
- data/spec/lib/minimart/mirror/sources_spec.rb +50 -0
- data/spec/lib/minimart/output_spec.rb +29 -0
- data/spec/lib/minimart/utils/archive_spec.rb +38 -0
- data/spec/lib/minimart/utils/file_helper_spec.rb +43 -0
- data/spec/lib/minimart/utils/http_spec.rb +37 -0
- data/spec/lib/minimart/web/cookbook_show_page_generator_spec.rb +101 -0
- data/spec/lib/minimart/web/cookbooks_spec.rb +70 -0
- data/spec/lib/minimart/web/dashboard_generator_spec.rb +33 -0
- data/spec/lib/minimart/web/html_generator_spec.rb +34 -0
- data/spec/lib/minimart/web/markdown_parser_spec.rb +54 -0
- data/spec/lib/minimart/web/template_helper_spec.rb +86 -0
- data/spec/lib/minimart/web/universe_generator_spec.rb +125 -0
- data/spec/spec_helper.rb +35 -0
- data/spec/support/file_system.rb +22 -0
- data/web/_assets/javascripts/app.js +164 -0
- data/web/_assets/javascripts/backbone.min.js +6 -0
- data/web/_assets/javascripts/jquery.min.js +4 -0
- data/web/_assets/javascripts/jquery.tabslet.min.js +9 -0
- data/web/_assets/javascripts/manifest.js +5 -0
- data/web/_assets/javascripts/underscore.min.js +5 -0
- data/web/_assets/stylesheets/font-awesome.min.css +4 -0
- data/web/_assets/stylesheets/font-mfizz.css +318 -0
- data/web/_assets/stylesheets/main.css +720 -0
- data/web/_assets/stylesheets/manifest.css +4 -0
- data/web/_assets/stylesheets/normalize.css +427 -0
- data/web/assets/fonts/FontAwesome.otf +0 -0
- data/web/assets/fonts/font-mfizz.eot +0 -0
- data/web/assets/fonts/font-mfizz.svg +1344 -0
- data/web/assets/fonts/font-mfizz.ttf +0 -0
- data/web/assets/fonts/font-mfizz.woff +0 -0
- data/web/assets/fonts/fontawesome-webfont.eot +0 -0
- data/web/assets/fonts/fontawesome-webfont.svg +520 -0
- data/web/assets/fonts/fontawesome-webfont.ttf +0 -0
- data/web/assets/fonts/fontawesome-webfont.woff +0 -0
- data/web/assets/images/header-slim.jpg +0 -0
- data/web/assets/images/icon-search.png +0 -0
- data/web/assets/images/mad-glory-logo.png +0 -0
- data/web/assets/images/main-gradient.png +0 -0
- data/web/assets/images/top-bar-logo.png +0 -0
- data/web/assets/javascripts/application.min.js +5 -0
- data/web/assets/stylesheets/application.min.css +4 -0
- data/web/templates/cookbook_show.erb +96 -0
- data/web/templates/dashboard.erb +81 -0
- data/web/templates/layout.erb +38 -0
- metadata +433 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
module Minimart
|
|
2
|
+
module Commands
|
|
3
|
+
# Web is the main entrance point for building the web interface for Minimart.
|
|
4
|
+
# This class will generate the index file to be used by Berkshelf, archived
|
|
5
|
+
# cookbooks, and HTML used to browse the available inventory.
|
|
6
|
+
class Web
|
|
7
|
+
|
|
8
|
+
# @return [String] The directory that the inventory is stored in.
|
|
9
|
+
attr_reader :inventory_directory
|
|
10
|
+
|
|
11
|
+
# @return [String] The directory to store the web output.
|
|
12
|
+
attr_reader :web_directory
|
|
13
|
+
|
|
14
|
+
# @return [String] The web endpoint where Minimart will be hosted.
|
|
15
|
+
attr_reader :web_endpoint
|
|
16
|
+
|
|
17
|
+
# @return [Boolean] Determine whether or not to generate HTML output
|
|
18
|
+
attr_reader :can_generate_html
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# @param [Hash] opts
|
|
22
|
+
# @option opts [String] :inventory_directory The directory that the inventory is stored in.
|
|
23
|
+
# @option opts [String] :web_directory The directory to store the web output.
|
|
24
|
+
# @option opts [String] :host The web endpoint where Minimart will be hosted.
|
|
25
|
+
# @option opts [Boolean] :can_generate_html Determine whether or not to generate HTML output
|
|
26
|
+
def initialize(opts = {})
|
|
27
|
+
@inventory_directory = File.expand_path(opts[:inventory_directory])
|
|
28
|
+
@web_directory = File.expand_path(opts[:web_directory])
|
|
29
|
+
@web_endpoint = opts[:host]
|
|
30
|
+
@can_generate_html = opts.fetch(:html, true)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Generate the web output.
|
|
34
|
+
def execute!
|
|
35
|
+
make_web_directory
|
|
36
|
+
generate_universe
|
|
37
|
+
generate_html
|
|
38
|
+
print_success_message
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
attr_reader :cookbooks
|
|
44
|
+
|
|
45
|
+
def make_web_directory
|
|
46
|
+
FileUtils.mkdir_p web_directory
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def generate_universe
|
|
50
|
+
Configuration.output.puts "Building the cookbook index."
|
|
51
|
+
|
|
52
|
+
generator = Minimart::Web::UniverseGenerator.new(
|
|
53
|
+
web_directory: web_directory,
|
|
54
|
+
endpoint: web_endpoint,
|
|
55
|
+
cookbooks: cookbooks)
|
|
56
|
+
|
|
57
|
+
generator.generate
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def generate_html
|
|
61
|
+
return unless generate_html?
|
|
62
|
+
|
|
63
|
+
Configuration.output.puts "Generating Minimart HTML."
|
|
64
|
+
|
|
65
|
+
generator = Minimart::Web::HtmlGenerator.new(
|
|
66
|
+
web_directory: web_directory,
|
|
67
|
+
cookbooks: cookbooks)
|
|
68
|
+
|
|
69
|
+
generator.generate
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def cookbooks
|
|
73
|
+
@cookbooks ||= Minimart::Web::Cookbooks.new(inventory_directory: inventory_directory)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def generate_html?
|
|
77
|
+
can_generate_html
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def print_success_message
|
|
81
|
+
Configuration.output.puts_green('Minimart successfully built the static web files!')
|
|
82
|
+
Configuration.output.puts_green("The static web files can be found in #{relative_web_path}")
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def relative_web_path
|
|
86
|
+
File.join('.', Pathname.new(web_directory).relative_path_from(Pathname.pwd))
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'minimart/output'
|
|
2
|
+
|
|
3
|
+
module Minimart
|
|
4
|
+
# General configuration settings for Minimart.
|
|
5
|
+
class Configuration
|
|
6
|
+
|
|
7
|
+
class << self
|
|
8
|
+
# IO interface for minimart
|
|
9
|
+
# @return [Minimart::Output]
|
|
10
|
+
def output
|
|
11
|
+
@output || Minimart::Output.new($stdout)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Set which IO output should use
|
|
15
|
+
# @param [IO] io
|
|
16
|
+
def output=(io)
|
|
17
|
+
@output = Minimart::Output.new(io)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def chef_server_config=(config)
|
|
21
|
+
@chef_server = config
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def chef_server_config
|
|
25
|
+
(@chef_server || {}).merge(ssl: {verify: verify_ssl})
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def github_config=(config)
|
|
29
|
+
@github_config = config
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def github_config
|
|
33
|
+
(@github_config || {}).merge(connection_options: {ssl: {verify: verify_ssl}})
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def verify_ssl
|
|
37
|
+
@verify_ssl.nil? ? true : @verify_ssl
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def verify_ssl=(val)
|
|
41
|
+
@verify_ssl = val
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
require 'ridley'
|
|
2
|
+
require 'semverse'
|
|
3
|
+
|
|
4
|
+
require 'minimart/web/markdown_parser'
|
|
5
|
+
require 'minimart/web/template_helper'
|
|
6
|
+
require 'minimart/utils/file_helper'
|
|
7
|
+
|
|
8
|
+
module Minimart
|
|
9
|
+
|
|
10
|
+
# An object wrapper to get information about a cookbook.
|
|
11
|
+
class Cookbook
|
|
12
|
+
include Web::TemplateHelper
|
|
13
|
+
|
|
14
|
+
# Generate a new Minimart::Cookbook from a path
|
|
15
|
+
# @param [String] path The path to the cookbook directory
|
|
16
|
+
# @return [Minimart::Cookbook]
|
|
17
|
+
def self.from_path(path)
|
|
18
|
+
path = Minimart::Utils::FileHelper.cookbook_path_in_directory(path)
|
|
19
|
+
new (Ridley::Chef::Cookbook.from_path(path))
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @param [Ridley::Chef::Cookbok] raw_cookbook
|
|
23
|
+
def initialize(raw_cookbook)
|
|
24
|
+
@raw_cookbook = raw_cookbook
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Get the name of the cookbook
|
|
28
|
+
# @return [String]
|
|
29
|
+
def name
|
|
30
|
+
raw_cookbook.cookbook_name
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Get the version of the cookbook
|
|
34
|
+
# @return [String]
|
|
35
|
+
def version
|
|
36
|
+
raw_cookbook.version
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Return a the cookbook name, and version number separated by a dash
|
|
40
|
+
# @return [String]
|
|
41
|
+
def to_s
|
|
42
|
+
raw_cookbook.name
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Get a short description of the cookbook.
|
|
46
|
+
# @return [String]
|
|
47
|
+
def description
|
|
48
|
+
metadata.description
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Get the maintainer of the cookbook
|
|
52
|
+
# @return [String]
|
|
53
|
+
def maintainer
|
|
54
|
+
metadata.maintainer
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Get the path to the cookbook on the file system
|
|
58
|
+
# @return [String]
|
|
59
|
+
def path
|
|
60
|
+
raw_cookbook.path
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Get a URL friendly version of the cookbook version
|
|
64
|
+
# @return [String]
|
|
65
|
+
def web_friendly_version
|
|
66
|
+
version.gsub('.', '_')
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Get any dependencies that this cookbook may have
|
|
70
|
+
# @return [Hash] cookbook_name => version_requirement
|
|
71
|
+
def dependencies
|
|
72
|
+
metadata.dependencies
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Get a list of platforms this cookbook can run on
|
|
76
|
+
# @return [Array<String>]
|
|
77
|
+
def platforms
|
|
78
|
+
metadata.platforms.keys
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Get the path to the README file if one is available
|
|
82
|
+
# @return [String]
|
|
83
|
+
def readme_file
|
|
84
|
+
@readme_file ||= find_file('readme')
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Get the path to the CHANGELOG file if one is available
|
|
88
|
+
# @return [String]
|
|
89
|
+
def changelog_file
|
|
90
|
+
@changelog_file ||= find_file('changelog')
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Get the parsed Markdown content of the README
|
|
94
|
+
# @return [String]
|
|
95
|
+
def readme_content
|
|
96
|
+
@readme_content ||= Web::MarkdownParser.parse(readme_file) if readme_file
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Get the parsed Markdown content of the CHANGELOG
|
|
100
|
+
# @return [String]
|
|
101
|
+
def changelog_content
|
|
102
|
+
@changelog_content ||= Web::MarkdownParser.parse(changelog_file) if changelog_file
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def to_hash
|
|
106
|
+
{
|
|
107
|
+
name: name,
|
|
108
|
+
version: version,
|
|
109
|
+
description: description,
|
|
110
|
+
maintainer: maintainer,
|
|
111
|
+
download_url: cookbook_download_path(self),
|
|
112
|
+
url: cookbook_path(self),
|
|
113
|
+
downloaded_at: downloaded_at,
|
|
114
|
+
download_date: download_date,
|
|
115
|
+
platforms: normalized_platforms
|
|
116
|
+
}
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def to_json(opts = {})
|
|
120
|
+
to_hash.to_json
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Get the time at which this cookbook was downloaded by Minimart.
|
|
124
|
+
# @return [Time]
|
|
125
|
+
def downloaded_at
|
|
126
|
+
download_metadata.downloaded_at
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Get a human friendly downlaod date of this cookbook (ex. January 1st, 2015)
|
|
130
|
+
# @return [String]
|
|
131
|
+
def download_date
|
|
132
|
+
return unless downloaded_at
|
|
133
|
+
downloaded_at.strftime('%B %d, %Y')
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def <=>(other)
|
|
137
|
+
Semverse::Version.new(version) <=> Semverse::Version.new(other.version)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def satisfies_requirement?(constraint)
|
|
141
|
+
Semverse::Constraint.new(constraint).satisfies?(version)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def normalized_platforms
|
|
145
|
+
return {'question' => 'Not Specified'} if platforms.nil? || platforms.empty?
|
|
146
|
+
|
|
147
|
+
platforms.inject({}) do |memo, platform|
|
|
148
|
+
memo[platform_icon(platform)] = platform.capitalize
|
|
149
|
+
memo
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Get any metadata about how this cookbook was downloaded.
|
|
154
|
+
# @return [Minimart::Mirror::DownloadMetadata]
|
|
155
|
+
def download_metadata
|
|
156
|
+
@download_metadata ||= Minimart::Mirror::DownloadMetadata.new(self.path)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
protected
|
|
160
|
+
|
|
161
|
+
attr_reader :raw_cookbook
|
|
162
|
+
|
|
163
|
+
def metadata
|
|
164
|
+
raw_cookbook.metadata
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def find_file(name)
|
|
168
|
+
Dir.glob(File.join(path, '*')).find do |file|
|
|
169
|
+
File.basename(file, File.extname(file)) =~ /\A#{name}\z/i
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
require 'octokit'
|
|
2
|
+
require 'ridley'
|
|
3
|
+
|
|
4
|
+
require 'minimart/utils/archive'
|
|
5
|
+
require 'minimart/utils/http'
|
|
6
|
+
|
|
7
|
+
module Minimart
|
|
8
|
+
module Download
|
|
9
|
+
# This class will download a cookbook from one of the inventory specified sources.
|
|
10
|
+
class Cookbook
|
|
11
|
+
|
|
12
|
+
# @return [Minimart::Mirror::SourceCookbook] The cookbook to download
|
|
13
|
+
attr_reader :cookbook
|
|
14
|
+
|
|
15
|
+
# @param [Minimart::Mirror::SourceCookbook] cookbook The cookbook to download
|
|
16
|
+
def initialize(cookbook)
|
|
17
|
+
@cookbook = cookbook
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Download the cookbook
|
|
21
|
+
# @yield Minimart::Cookbook]
|
|
22
|
+
def fetch(&block)
|
|
23
|
+
Configuration.output.puts "-- Downloading #{cookbook.name} #{cookbook.version}"
|
|
24
|
+
|
|
25
|
+
unless respond_to?("download_#{cookbook.location_type}", true)
|
|
26
|
+
raise Minimart::Error::UnknownLocationType,
|
|
27
|
+
"Minimart cannot download #{cookbook.name} because it has an unknown location type #{cookbook.location_type}"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
Dir.mktmpdir do |dir|
|
|
31
|
+
send("download_#{cookbook.location_type}", dir)
|
|
32
|
+
block.call(Minimart::Cookbook.from_path(dir)) if block
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def download_opscode(dir)
|
|
39
|
+
details = Utils::Http.get_json(cookbook.location_path, "cookbooks/#{cookbook.name}/versions/#{cookbook.web_friendly_version}")
|
|
40
|
+
get_archive(details['file'], dir)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def download_uri(dir)
|
|
44
|
+
get_archive(cookbook.location_path, dir)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def download_chef_server(dir)
|
|
48
|
+
opts = Minimart::Configuration.chef_server_config.merge(server_url: cookbook.location_path)
|
|
49
|
+
|
|
50
|
+
Ridley.open(opts) do |ridley_client|
|
|
51
|
+
ridley_client.cookbook.download(cookbook.name, cookbook.version, dir)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def download_github(dir)
|
|
56
|
+
location_path = cookbook.location_path_uri.path.gsub(/\A\//, '')
|
|
57
|
+
client = Octokit::Client.new(Minimart::Configuration.github_config)
|
|
58
|
+
url = client.archive_link(location_path, ref: "v#{cookbook.version}")
|
|
59
|
+
|
|
60
|
+
get_archive(url, dir)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def get_archive(url, dir)
|
|
64
|
+
archive_file = Utils::Http.get_binary("#{cookbook.name}-#{cookbook.version}", url)
|
|
65
|
+
Utils::Archive.extract_archive(archive_file, dir)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
module Minimart
|
|
2
|
+
module Download
|
|
3
|
+
# GitCache manages cloning repositories, and storing them for later access.
|
|
4
|
+
class GitCache
|
|
5
|
+
|
|
6
|
+
class << self
|
|
7
|
+
# Get the GitCache singleton instance
|
|
8
|
+
# @return [Minimart::Download::GitCache]
|
|
9
|
+
def instance
|
|
10
|
+
@instance ||= GitCache.new
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def initialize
|
|
15
|
+
self.cache = {}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Get a repository from the GitCache. This repository will be cloned, if
|
|
19
|
+
# it hasn't been already.
|
|
20
|
+
# @param [String] repo_location Any location that can be cloned by Git (Path, URL).
|
|
21
|
+
# @return [Git::Base]
|
|
22
|
+
def get_repository(repo_location)
|
|
23
|
+
cache[repo_location] ||= clone_bare_repo(repo_location)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Get the local path to the repository passed in. This repository will be cloned,
|
|
27
|
+
# if it hasn't been already.
|
|
28
|
+
# @param [String] repo_location Any location that can be cloned by Git (Path, URL).
|
|
29
|
+
# @return [String] The path to the repository
|
|
30
|
+
def local_path_for(repo_location)
|
|
31
|
+
get_repository(repo_location).repo.path
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# This method will empty the GitCache.
|
|
35
|
+
def clear
|
|
36
|
+
cache.values.each do |git|
|
|
37
|
+
FileUtils.remove_entry(git.repo.path)
|
|
38
|
+
end
|
|
39
|
+
self.cache = {}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# See if the GitCache has any reference to a repository location.
|
|
43
|
+
# @param [String] repo_location Any location that can be cloned by Git (Path, URL).
|
|
44
|
+
# @return [Boolean]
|
|
45
|
+
def has_location?(repo_location)
|
|
46
|
+
cache.has_key? repo_location
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
attr_accessor :cache
|
|
52
|
+
|
|
53
|
+
def clone_bare_repo(repo_location)
|
|
54
|
+
Configuration.output.puts "-- Cloning Git Repository From '#{repo_location}'"
|
|
55
|
+
Git.clone(repo_location, Dir.mktmpdir, bare: true)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'git'
|
|
2
|
+
require 'minimart/download/git_cache'
|
|
3
|
+
|
|
4
|
+
module Minimart
|
|
5
|
+
module Download
|
|
6
|
+
# GitRepository manages cloning, and checking out a given Git endpoint.
|
|
7
|
+
class GitRepository
|
|
8
|
+
|
|
9
|
+
# @return [String] any location that can be cloned by Git (Path, URL).
|
|
10
|
+
attr_reader :location
|
|
11
|
+
|
|
12
|
+
# @param [String] location Any location that can be cloned by Git (Path, URL).
|
|
13
|
+
def initialize(location)
|
|
14
|
+
@location = location
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Fetch the given commit, branch, or tag.
|
|
18
|
+
# @param commitish The commit, branch, or tag to clone for the given location.
|
|
19
|
+
# @yield [Dir] Tmp directory containing the repository. This directory will be removed when the block exits.
|
|
20
|
+
def fetch(commitish, &block)
|
|
21
|
+
Dir.mktmpdir do |tmpdir|
|
|
22
|
+
result_repo = Git.clone(bare_repo_path, tmpdir)
|
|
23
|
+
result_repo.fetch(bare_repo_path, tags: true)
|
|
24
|
+
result_repo.reset_hard(bare_repo.revparse(commitish))
|
|
25
|
+
block.call(tmpdir) if block
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def bare_repo_path
|
|
32
|
+
@bare_repo_path ||= Download::GitCache.instance.local_path_for(location)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def bare_repo
|
|
36
|
+
@bare_repo ||= Download::GitCache.instance.get_repository(location)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|