add Cask::SubversionDownloadStrategy
abstract out module `Cask::DownloadStrategy`, add some commentary
This commit is contained in:
parent
a89a4ad218
commit
b55f1804f0
|
@ -8,7 +8,11 @@ class Cask::Download
|
|||
def perform
|
||||
require 'software_spec'
|
||||
cask = @cask
|
||||
downloader = Cask::CurlDownloadStrategy.new(cask)
|
||||
if cask.url.using == :svn
|
||||
downloader = Cask::SubversionDownloadStrategy.new(cask)
|
||||
else
|
||||
downloader = Cask::CurlDownloadStrategy.new(cask)
|
||||
end
|
||||
downloaded_path = downloader.fetch
|
||||
|
||||
_check_sums(downloaded_path, cask.sums) unless cask.sums === 0
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
require 'cgi'
|
||||
|
||||
class Cask::CurlDownloadStrategy < CurlDownloadStrategy
|
||||
# We abuse Homebrew's download strategies considerably here.
|
||||
# * Our downloader instances only invoke the fetch method,
|
||||
# ignoring stage and clear_cache.
|
||||
# * Our overridden fetch methods are expected to return
|
||||
# a value: the successfully downloaded file.
|
||||
|
||||
module Cask::DownloadStrategy
|
||||
attr_reader :cask, :cask_url
|
||||
|
||||
def initialize(cask)
|
||||
def initialize(cask, command=Cask::SystemCommand)
|
||||
@cask = cask
|
||||
@command = command
|
||||
@cask_url = cask.url
|
||||
super(
|
||||
cask.title,
|
||||
|
@ -14,6 +21,11 @@ class Cask::CurlDownloadStrategy < CurlDownloadStrategy
|
|||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
class Cask::CurlDownloadStrategy < CurlDownloadStrategy
|
||||
|
||||
include Cask::DownloadStrategy
|
||||
|
||||
def _fetch
|
||||
odebug "Calling curl with args #{curl_args}"
|
||||
|
@ -63,3 +75,74 @@ class Cask::CurlDownloadStrategy < CurlDownloadStrategy
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Cask::SubversionDownloadStrategy < SubversionDownloadStrategy
|
||||
include Cask::DownloadStrategy
|
||||
|
||||
# super does not provide checks for already-existing downloads
|
||||
def fetch
|
||||
if tarball_path.exist?
|
||||
puts "Already downloaded: #{tarball_path}"
|
||||
else
|
||||
super
|
||||
compress
|
||||
end
|
||||
tarball_path
|
||||
end
|
||||
|
||||
# This primary reason for redefining this method is the trust_cert
|
||||
# option, controllable from the Cask definition. The rest of this
|
||||
# method is similar to Homebrew's, but translated to local idiom.
|
||||
def fetch_repo target, url, revision=cask_url.revision, ignore_externals=false
|
||||
# Use "svn up" when the repository already exists locally.
|
||||
# This saves on bandwidth and will have a similar effect to verifying the
|
||||
# cache as it will make any changes to get the right revision.
|
||||
svncommand = target.directory? ? 'up' : 'checkout'
|
||||
args = [svncommand]
|
||||
|
||||
# SVN shipped with XCode 3.1.4 can't force a checkout.
|
||||
args << '--force' unless MacOS.version == :leopard
|
||||
|
||||
if cask_url.trust_cert
|
||||
args << '--trust-server-cert'
|
||||
args << '--non-interactive'
|
||||
end
|
||||
|
||||
args << url unless target.directory?
|
||||
args << target
|
||||
args << '-r' << revision if revision
|
||||
args << '--ignore-externals' if ignore_externals
|
||||
@command.run!('/usr/bin/svn',
|
||||
:args => args,
|
||||
:stderr => :silence)
|
||||
end
|
||||
|
||||
def tarball_path
|
||||
@tarball_path ||= cached_location.dirname.join(cached_location.basename.to_s + "-#{@cask.version}.tar")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Seems nutty: we "download" the contents into a tape archive.
|
||||
# Why?
|
||||
# * A single file is tractable to the rest of the Cask toolchain,
|
||||
# * An alternative would be to create a Directory container type.
|
||||
# However, some type of file-serialization trick would still be
|
||||
# needed in order to enable calculating a single checksum over
|
||||
# a directory. So, in that alternative implementation, the
|
||||
# special cases would propagate outside this class, including
|
||||
# the use of tar or equivalent.
|
||||
# * SubversionDownloadStrategy.cached_location is not versioned
|
||||
# * tarball_path provides a needed return value for our overridden
|
||||
# fetch method.
|
||||
# * We can also take this private opportunity to strip files from
|
||||
# the download which are protocol-specific.
|
||||
|
||||
def compress
|
||||
Dir.chdir(cached_location) do
|
||||
@command.run!('/usr/bin/tar', :args => ['-s/^\.//', '--exclude', '.svn', '-cf', Pathname.new(tarball_path), '--', '.'],
|
||||
:stderr => :silent)
|
||||
end
|
||||
clear_cache
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ require 'forwardable'
|
|||
class Cask::URL
|
||||
FAKE_USER_AGENT = 'Chrome/32.0.1000.00'
|
||||
|
||||
attr_reader :uri, :cookies, :referer
|
||||
attr_reader :using, :revision, :trust_cert, :uri, :cookies, :referer
|
||||
|
||||
extend Forwardable
|
||||
def_delegators :uri, :path, :scheme, :to_s
|
||||
|
@ -13,6 +13,9 @@ class Cask::URL
|
|||
@user_agent = options[:user_agent]
|
||||
@cookies = options[:cookies]
|
||||
@referer = options[:referer]
|
||||
@using = options[:using]
|
||||
@revision = options[:revision]
|
||||
@trust_cert = options[:trust_cert]
|
||||
end
|
||||
|
||||
def user_agent
|
||||
|
|
|
@ -94,4 +94,121 @@ describe Cask::CurlDownloadStrategy do
|
|||
|
||||
shutup { downloader.fetch }
|
||||
end
|
||||
|
||||
describe Cask::SubversionDownloadStrategy do
|
||||
it 'recognizes the SVN download strategy' do
|
||||
cask = Cask.load('svn-download-cask')
|
||||
cask.url.using.must_equal :svn
|
||||
downloader = Cask::SubversionDownloadStrategy.new(cask, Cask::FakeSystemCommand)
|
||||
downloader.must_respond_to(:fetch)
|
||||
end
|
||||
|
||||
it 'properly assigns a name and Resource based on the cask' do
|
||||
cask = Cask.load('svn-download-cask')
|
||||
|
||||
downloader = Cask::SubversionDownloadStrategy.new(cask, Cask::FakeSystemCommand)
|
||||
downloader.name.must_equal 'svn-download-cask'
|
||||
downloader.resource.name.must_equal 'svn-download-cask'
|
||||
downloader.resource.url.must_equal cask.url.to_s
|
||||
downloader.resource.version.to_s.must_equal cask.version
|
||||
end
|
||||
|
||||
it 'returns a tarball path on fetch' do
|
||||
cask = Cask.load('svn-download-cask')
|
||||
downloader = Cask::SubversionDownloadStrategy.new(cask, Cask::FakeSystemCommand)
|
||||
downloader.stubs(:fetch_repo)
|
||||
downloader.stubs(:compress)
|
||||
shutup { downloader.fetch }.must_equal downloader.tarball_path
|
||||
end
|
||||
|
||||
it 'calls fetch_repo with default arguments for a simple Cask' do
|
||||
cask = Cask.load('svn-download-cask')
|
||||
downloader = Cask::SubversionDownloadStrategy.new(cask, Cask::FakeSystemCommand)
|
||||
downloader.stubs(:compress)
|
||||
downloader.expects(:fetch_repo).with(
|
||||
downloader.cached_location,
|
||||
cask.url.to_s
|
||||
)
|
||||
shutup { downloader.fetch }.must_equal downloader.tarball_path
|
||||
end
|
||||
|
||||
it 'calls svn with default arguments for a simple Cask' do
|
||||
cask = Cask.load('svn-download-cask')
|
||||
downloader = Cask::SubversionDownloadStrategy.new(cask, Cask::FakeSystemCommand)
|
||||
Cask::FakeSystemCommand.expects_command([
|
||||
'/usr/bin/svn',
|
||||
'checkout',
|
||||
'--force',
|
||||
cask.url.to_s,
|
||||
downloader.cached_location,
|
||||
])
|
||||
downloader.stubs(:compress)
|
||||
shutup { downloader.fetch }.must_equal downloader.tarball_path
|
||||
end
|
||||
|
||||
it 'adds svn arguments for :trust_cert' do
|
||||
cask = Cask.load('svn-download-trust-cask')
|
||||
downloader = Cask::SubversionDownloadStrategy.new(cask, Cask::FakeSystemCommand)
|
||||
Cask::FakeSystemCommand.expects_command([
|
||||
'/usr/bin/svn',
|
||||
'checkout',
|
||||
'--force',
|
||||
'--trust-server-cert',
|
||||
'--non-interactive',
|
||||
cask.url.to_s,
|
||||
downloader.cached_location,
|
||||
])
|
||||
downloader.stubs(:compress)
|
||||
shutup { downloader.fetch }.must_equal downloader.tarball_path
|
||||
end
|
||||
|
||||
it 'adds svn arguments for :revision' do
|
||||
cask = Cask.load('svn-download-revision-cask')
|
||||
downloader = Cask::SubversionDownloadStrategy.new(cask, Cask::FakeSystemCommand)
|
||||
Cask::FakeSystemCommand.expects_command([
|
||||
'/usr/bin/svn',
|
||||
'checkout',
|
||||
'--force',
|
||||
cask.url.to_s,
|
||||
downloader.cached_location,
|
||||
'-r',
|
||||
'10',
|
||||
])
|
||||
downloader.stubs(:compress)
|
||||
shutup { downloader.fetch }.must_equal downloader.tarball_path
|
||||
end
|
||||
|
||||
it 'runs tar to serialize svn downloads' do
|
||||
cask = Cask.load('svn-download-cask')
|
||||
downloader = Cask::SubversionDownloadStrategy.new(cask, Cask::FakeSystemCommand)
|
||||
# special mocking required for tar to have something to work with
|
||||
def downloader.fetch_repo(target, url, revision=nil, ignore_externals=false)
|
||||
target.mkpath
|
||||
end
|
||||
Cask::FakeSystemCommand.expects_command([
|
||||
'/usr/bin/tar',
|
||||
'-s/^\\.//',
|
||||
'--exclude',
|
||||
'.svn',
|
||||
'-cf',
|
||||
downloader.tarball_path,
|
||||
'--',
|
||||
'.',
|
||||
])
|
||||
shutup { downloader.fetch }.must_equal downloader.tarball_path
|
||||
end
|
||||
end
|
||||
# does not work yet, for numerous reasons
|
||||
# it 'creates a tarball matching the expected checksum' do
|
||||
# cask = Cask.load('svn-download-check-cask')
|
||||
# downloader = Cask::SubversionDownloadStrategy.new(cask)
|
||||
# # special mocking required for tar to have something to work with
|
||||
# def downloader.fetch_repo(target, url, revision=nil, ignore_externals=false)
|
||||
# target.mkpath
|
||||
# FileUtils.touch(target.join('empty_file'))
|
||||
# end
|
||||
# shutup { downloader.fetch }.must_equal downloader.tarball_path
|
||||
# d = Cask::Download.new(cask)
|
||||
# d._check_sums(downloader.tarball_path, cask.sums)
|
||||
# end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
class SvnDownloadCask < TestCask
|
||||
url 'http://example.com/trunk/projectdir/subdir', :using => :svn
|
||||
homepage 'http://example.com/'
|
||||
version '1.2.3'
|
||||
sha1 '39f3444fcb5d49618c2d62dd7b34304ea5f97a3a'
|
||||
link 'TestCask.app'
|
||||
end
|
|
@ -0,0 +1,7 @@
|
|||
class SvnDownloadCheckCask < TestCask
|
||||
url 'http://example.com/trunk/projectdir/subdir', :using => :svn
|
||||
homepage 'http://example.com/'
|
||||
version '1.2.3'
|
||||
sha1 '39f3444fcb5d49618c2d62dd7b34304ea5f97a3a'
|
||||
link 'TestCask.app'
|
||||
end
|
|
@ -0,0 +1,7 @@
|
|||
class SvnDownloadRevisionCask < TestCask
|
||||
url 'http://example.com/trunk/projectdir/subdir', :using => :svn, :revision => '10'
|
||||
homepage 'http://example.com/'
|
||||
version '1.2.3'
|
||||
sha1 '39f3444fcb5d49618c2d62dd7b34304ea5f97a3a'
|
||||
link 'TestCask.app'
|
||||
end
|
|
@ -0,0 +1,7 @@
|
|||
class SvnDownloadTrustCask < TestCask
|
||||
url 'http://example.com/trunk/projectdir/subdir', :using => :svn, :trust_cert => true
|
||||
homepage 'http://example.com/'
|
||||
version '1.2.3'
|
||||
sha1 '39f3444fcb5d49618c2d62dd7b34304ea5f97a3a'
|
||||
link 'TestCask.app'
|
||||
end
|
Loading…
Reference in New Issue