minimart 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|