minimart 0.0.1

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