Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow download strategies to preprocess download options #57

Merged
merged 8 commits into from
Jun 10, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@
[Sylvain Guillopé](https://github.com/sguillope)
[#55](https://github.com/CocoaPods/cocoapods-downloader/issues/55)
[CocoaPods#5318](https://github.com/CocoaPods/CocoaPods/issues/5318)


* Allow download strategies to preprocess download options. This is used by
`git` strategy to resolve branches into commits directly.
[Juan Civile](https://github.com/champo)
[CocoaPods#5386](https://github.com/CocoaPods/CocoaPods/pull/5386)


##### Bug Fixes

Expand Down
1 change: 1 addition & 0 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ require 'cocoapods-downloader'

target_path = './Downloads/MyDownload'
options = { :git => 'example.com' }
options = Pod::Downloader.preprocess_options(options)
downloader = Pod::Downloader.for_target(target_path, options)
downloader.cache_root = '~/Library/Caches/APPNAME'
downloader.max_cache_size = 500
Expand Down
39 changes: 33 additions & 6 deletions lib/cocoapods-downloader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,42 @@ def self.strategy_from_options(options)
# options.
#
def self.for_target(target_path, options)
options = Hash[options.map { |k, v| [k.to_sym, v] }]
options = options_to_sym(options)

if target_path.nil?
raise DownloaderError, 'No target path provided.'
end

strategy, klass = class_for_options(options)

url = options[strategy]
sub_options = options.dup
sub_options.delete(strategy)

klass.new(target_path, url, sub_options)
end

# Have the concrete strategy preprocess options
#
# @param [Hash<Symbol,String>] options
# The request options to preprocess
#
# @return [Hash<Symbol,String>] the new options
#
def self.preprocess_options(options)
options = options_to_sym(options)

_, klass = class_for_options(options)
klass.preprocess_options(options)
end

private_class_method

def self.options_to_sym(options)
Hash[options.map { |k, v| [k.to_sym, v] }]
end

def self.class_for_options(options)
if options.nil? || options.empty?
raise DownloaderError, 'No source URL provided.'
end
Expand All @@ -63,11 +93,8 @@ def self.for_target(target_path, options)
"`#{options.inspect}`."
end

url = options[strategy]
sub_options = options.dup
sub_options.delete(strategy)
klass = downloader_class_by_key[strategy]
klass.new(target_path, url, sub_options)
# Explicit return for multiple params, rubocop thinks it's useless but it's not
return strategy, downloader_class_by_key[strategy] # rubocop:disable Style/RedundantReturn
end
end
end
3 changes: 3 additions & 0 deletions lib/cocoapods-downloader/api_exposable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ def expose_api(mod = nil, &block)
raise 'Only a module *or* is required, not both.'
end
include mod
# TODO: Try to find a nicer way to do this
# See https://github.com/CocoaPods/cocoapods-downloader/pull/57
extend mod
end

alias override_api expose_api
Expand Down
14 changes: 14 additions & 0 deletions lib/cocoapods-downloader/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,20 @@ def self.executable(name)
execute_command(name.to_s, command.flatten, true)
end
end

# preprocess download options
#
# Usage of this method is optional. concrete strategies should not
# assume options are preprocessed for correct execution.
#
# @param [Hash<Symbol,String>] options
# The request options to preprocess
#
# @return [Hash<Symbol,String>] the new options
#
def self.preprocess_options(options)
options
end
end
end
end
17 changes: 17 additions & 0 deletions lib/cocoapods-downloader/git.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,23 @@ def checkout_options
end
end

def self.preprocess_options(options)
return options unless options[:branch]

command = ['ls-remote',
options[:git],
options[:branch]]
output = Git.execute_command('git', command)
match = /^([a-z0-9]*)\t.*/.match(output)

return options if match.nil?

options[:commit] = match[1]
options.delete(:branch)

options
end

private

# @!group Base class hooks
Expand Down
6 changes: 6 additions & 0 deletions spec/base_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ module Downloader
e = lambda { Base.new('path', 'url', options) }.should.raise DownloaderError
e.message.should.match /Unrecognized options/
end

it 'has no preprocessing' do
options = { :symbol => 'aaaaaa' }
new_options = Base.preprocess_options(options)
new_options.should == options
end
end
end
end
6 changes: 6 additions & 0 deletions spec/bazaar_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ module Downloader
downloader = Downloader.for_target(tmp_folder, options)
lambda { downloader.download }.should.raise DownloaderError
end

it 'has no preprocessing' do
options = { :bzr => fixture('bazaar-repo'), :revision => '1' }
new_options = Downloader.preprocess_options(options)
new_options.should == options
end
end
end
end
20 changes: 20 additions & 0 deletions spec/git_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,26 @@ def ensure_only_one_ref(folder)
should.not.raise { downloader.download }
end
end

describe '::preprocess_options' do
it 'skips non-branch requests' do
options = { :git => fixture_url('git-repo'), :commit => 'aaaa' }
new_options = Downloader.preprocess_options(options)
options.should == new_options
end

it 'resolves master to a commit' do
options = { :git => fixture_url('git-repo'), :branch => 'master' }
new_options = Downloader.preprocess_options(options)
new_options[:commit].should == '98cbf14201a78b56c6b7290f6cac840a7597a1c2'
end

it 'ignores invalid branches' do
options = { :git => fixture_url('git-repo'), :branch => 'aaaa' }
new_options = Downloader.preprocess_options(options)
new_options[:branch].should == 'aaaa'
end
end
end
end
end
6 changes: 6 additions & 0 deletions spec/http_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,12 @@ module Downloader
downloader.send(:type).should == :zip
end
end

it 'has no preprocessing' do
options = { :http => 'https://host/file', :type => 'zip' }
new_options = Downloader.preprocess_options(options)
new_options.should == options
end
end
end
end
6 changes: 6 additions & 0 deletions spec/mercurial_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ module Downloader
:revision => '61118fa8988c2b2eae826f48abd1e3340dae0c6b',
}
end

it 'has no preprocessing' do
options = { :hg => fixture('mercurial-repo'), :tag => '1.0.0' }
new_options = Downloader.preprocess_options(options)
new_options.should == options
end
end
end
end
10 changes: 10 additions & 0 deletions spec/subversion_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,16 @@ module Downloader
tmp_folder('README').read.strip.should == 'first commit'
tmp_folder('.svn').should.exist
end

it 'has no preprocessing' do
options = {
:svn => "file://#{fixture('subversion-repo')}",
:revision => '1',
:checkout => true,
}
new_options = Downloader.preprocess_options(options)
new_options.should == options
end
end
end
end