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,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