Simplify SubversionDownloadStrategy.
This commit is contained in:
parent
93051b27d6
commit
b6b8e8863f
@ -4,6 +4,7 @@ require "hbc/container/bzip2"
|
|||||||
require "hbc/container/cab"
|
require "hbc/container/cab"
|
||||||
require "hbc/container/criteria"
|
require "hbc/container/criteria"
|
||||||
require "hbc/container/dmg"
|
require "hbc/container/dmg"
|
||||||
|
require "hbc/container/directory"
|
||||||
require "hbc/container/executable"
|
require "hbc/container/executable"
|
||||||
require "hbc/container/generic_unar"
|
require "hbc/container/generic_unar"
|
||||||
require "hbc/container/gpg"
|
require "hbc/container/gpg"
|
||||||
@ -14,6 +15,7 @@ require "hbc/container/otf"
|
|||||||
require "hbc/container/pkg"
|
require "hbc/container/pkg"
|
||||||
require "hbc/container/seven_zip"
|
require "hbc/container/seven_zip"
|
||||||
require "hbc/container/sit"
|
require "hbc/container/sit"
|
||||||
|
require "hbc/container/svn_repository"
|
||||||
require "hbc/container/tar"
|
require "hbc/container/tar"
|
||||||
require "hbc/container/ttf"
|
require "hbc/container/ttf"
|
||||||
require "hbc/container/rar"
|
require "hbc/container/rar"
|
||||||
@ -43,6 +45,7 @@ module Hbc
|
|||||||
Xz, # pure xz
|
Xz, # pure xz
|
||||||
Gpg, # GnuPG signed data
|
Gpg, # GnuPG signed data
|
||||||
Executable,
|
Executable,
|
||||||
|
SvnRepository,
|
||||||
]
|
]
|
||||||
# for explicit use only (never autodetected):
|
# for explicit use only (never autodetected):
|
||||||
# Hbc::Container::Naked
|
# Hbc::Container::Naked
|
||||||
|
@ -13,9 +13,11 @@ module Hbc
|
|||||||
end
|
end
|
||||||
|
|
||||||
def magic_number(regex)
|
def magic_number(regex)
|
||||||
|
return false if path.directory?
|
||||||
|
|
||||||
# 262: length of the longest regex (currently: Hbc::Container::Tar)
|
# 262: length of the longest regex (currently: Hbc::Container::Tar)
|
||||||
@magic_number ||= File.open(@path, "rb") { |f| f.read(262) }
|
@magic_number ||= File.open(path, "rb") { |f| f.read(262) }
|
||||||
@magic_number =~ regex
|
@magic_number.match?(regex)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
24
Library/Homebrew/cask/lib/hbc/container/directory.rb
Normal file
24
Library/Homebrew/cask/lib/hbc/container/directory.rb
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
require "hbc/container/base"
|
||||||
|
|
||||||
|
module Hbc
|
||||||
|
class Container
|
||||||
|
class Directory < Base
|
||||||
|
def self.me?(*)
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def extract
|
||||||
|
@path.children.each do |child|
|
||||||
|
next if skip_path?(child)
|
||||||
|
FileUtils.cp child, @cask.staged_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def skip_path?(*)
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -8,7 +8,7 @@ module Hbc
|
|||||||
return true if criteria.magic_number(/^#!\s*\S+/)
|
return true if criteria.magic_number(/^#!\s*\S+/)
|
||||||
|
|
||||||
begin
|
begin
|
||||||
MachO.open(criteria.path).header.executable?
|
criteria.path.file? && MachO.open(criteria.path).header.executable?
|
||||||
rescue MachO::MagicError
|
rescue MachO::MagicError
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
15
Library/Homebrew/cask/lib/hbc/container/svn_repository.rb
Normal file
15
Library/Homebrew/cask/lib/hbc/container/svn_repository.rb
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
require "hbc/container/directory"
|
||||||
|
|
||||||
|
module Hbc
|
||||||
|
class Container
|
||||||
|
class SvnRepository < Directory
|
||||||
|
def self.me?(criteria)
|
||||||
|
criteria.path.join(".svn").directory?
|
||||||
|
end
|
||||||
|
|
||||||
|
def skip_path?(path)
|
||||||
|
path.basename.to_s == ".svn"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -10,7 +10,7 @@ module Hbc
|
|||||||
class AbstractDownloadStrategy
|
class AbstractDownloadStrategy
|
||||||
attr_reader :cask, :name, :url, :uri_object, :version
|
attr_reader :cask, :name, :url, :uri_object, :version
|
||||||
|
|
||||||
def initialize(cask, command = SystemCommand)
|
def initialize(cask, command: SystemCommand)
|
||||||
@cask = cask
|
@cask = cask
|
||||||
@command = command
|
@command = command
|
||||||
# TODO: this excess of attributes is a function of integrating
|
# TODO: this excess of attributes is a function of integrating
|
||||||
@ -33,8 +33,8 @@ module Hbc
|
|||||||
class HbVCSDownloadStrategy < AbstractDownloadStrategy
|
class HbVCSDownloadStrategy < AbstractDownloadStrategy
|
||||||
REF_TYPES = [:branch, :revision, :revisions, :tag].freeze
|
REF_TYPES = [:branch, :revision, :revisions, :tag].freeze
|
||||||
|
|
||||||
def initialize(cask, command = SystemCommand)
|
def initialize(*args, **options)
|
||||||
super
|
super(*args, **options)
|
||||||
@ref_type, @ref = extract_ref
|
@ref_type, @ref = extract_ref
|
||||||
@clone = Hbc.cache.join(cache_filename)
|
@clone = Hbc.cache.join(cache_filename)
|
||||||
end
|
end
|
||||||
@ -64,11 +64,6 @@ module Hbc
|
|||||||
end
|
end
|
||||||
|
|
||||||
class CurlDownloadStrategy < AbstractDownloadStrategy
|
class CurlDownloadStrategy < AbstractDownloadStrategy
|
||||||
# TODO: should be part of url object
|
|
||||||
def mirrors
|
|
||||||
@mirrors ||= []
|
|
||||||
end
|
|
||||||
|
|
||||||
def tarball_path
|
def tarball_path
|
||||||
@tarball_path ||= Hbc.cache.join("#{name}--#{version}#{ext}")
|
@tarball_path ||= Hbc.cache.join("#{name}--#{version}#{ext}")
|
||||||
end
|
end
|
||||||
@ -131,11 +126,6 @@ module Hbc
|
|||||||
ignore_interrupts { temporary_path.rename(tarball_path) }
|
ignore_interrupts { temporary_path.rename(tarball_path) }
|
||||||
end
|
end
|
||||||
tarball_path
|
tarball_path
|
||||||
rescue CurlDownloadStrategyError
|
|
||||||
raise if mirrors.empty?
|
|
||||||
puts "Trying a mirror..."
|
|
||||||
@url = mirrors.shift
|
|
||||||
retry
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@ -225,8 +215,8 @@ module Hbc
|
|||||||
|
|
||||||
# super does not provide checks for already-existing downloads
|
# super does not provide checks for already-existing downloads
|
||||||
def fetch
|
def fetch
|
||||||
if tarball_path.exist?
|
if cached_location.directory?
|
||||||
puts "Already downloaded: #{tarball_path}"
|
puts "Already downloaded: #{cached_location}"
|
||||||
else
|
else
|
||||||
@url = @url.sub(/^svn\+/, "") if @url =~ %r{^svn\+http://}
|
@url = @url.sub(/^svn\+/, "") if @url =~ %r{^svn\+http://}
|
||||||
ohai "Checking out #{@url}"
|
ohai "Checking out #{@url}"
|
||||||
@ -252,9 +242,8 @@ module Hbc
|
|||||||
else
|
else
|
||||||
fetch_repo @clone, @url
|
fetch_repo @clone, @url
|
||||||
end
|
end
|
||||||
compress
|
|
||||||
end
|
end
|
||||||
tarball_path
|
cached_location
|
||||||
end
|
end
|
||||||
|
|
||||||
# This primary reason for redefining this method is the trust_cert
|
# This primary reason for redefining this method is the trust_cert
|
||||||
@ -288,10 +277,6 @@ module Hbc
|
|||||||
print_stderr: false)
|
print_stderr: false)
|
||||||
end
|
end
|
||||||
|
|
||||||
def tarball_path
|
|
||||||
@tarball_path ||= cached_location.dirname.join(cached_location.basename.to_s + "-#{@cask.version}.tar")
|
|
||||||
end
|
|
||||||
|
|
||||||
def shell_quote(str)
|
def shell_quote(str)
|
||||||
# Oh god escaping shell args.
|
# Oh god escaping shell args.
|
||||||
# See http://notetoself.vrensk.com/2008/08/escaping-single-quotes-in-ruby-harder-than-expected/
|
# See http://notetoself.vrensk.com/2008/08/escaping-single-quotes-in-ruby-harder-than-expected/
|
||||||
@ -304,35 +289,5 @@ module Hbc
|
|||||||
yield name, url
|
yield name, url
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
# TODO/UPDATE: the tar approach explained below is fragile
|
|
||||||
# against challenges such as case-sensitive filesystems,
|
|
||||||
# and must be re-implemented.
|
|
||||||
#
|
|
||||||
# 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), "--", "."],
|
|
||||||
print_stderr: false)
|
|
||||||
end
|
|
||||||
clear_cache
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -112,11 +112,7 @@ module Hbc
|
|||||||
processed_output[:stderr],
|
processed_output[:stderr],
|
||||||
processed_status.exitstatus)
|
processed_status.exitstatus)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
module Hbc
|
|
||||||
class SystemCommand
|
|
||||||
class Result
|
class Result
|
||||||
attr_accessor :command, :stdout, :stderr, :exit_status
|
attr_accessor :command, :stdout, :stderr, :exit_status
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ describe "download strategies", :cask do
|
|||||||
describe Hbc::SubversionDownloadStrategy do
|
describe Hbc::SubversionDownloadStrategy do
|
||||||
let(:url_options) { { using: :svn } }
|
let(:url_options) { { using: :svn } }
|
||||||
let(:fake_system_command) { class_double(Hbc::SystemCommand) }
|
let(:fake_system_command) { class_double(Hbc::SystemCommand) }
|
||||||
let(:downloader) { Hbc::SubversionDownloadStrategy.new(cask, fake_system_command) }
|
let(:downloader) { Hbc::SubversionDownloadStrategy.new(cask, command: fake_system_command) }
|
||||||
before do
|
before do
|
||||||
allow(fake_system_command).to receive(:run!)
|
allow(fake_system_command).to receive(:run!)
|
||||||
end
|
end
|
||||||
@ -147,7 +147,7 @@ describe "download strategies", :cask do
|
|||||||
allow(downloader).to receive(:compress)
|
allow(downloader).to receive(:compress)
|
||||||
allow(downloader).to receive(:fetch_repo)
|
allow(downloader).to receive(:fetch_repo)
|
||||||
|
|
||||||
expect(downloader.fetch).to equal(downloader.tarball_path)
|
expect(downloader.fetch).to equal(downloader.cached_location)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "calls fetch_repo with default arguments for a simple Cask" do
|
it "calls fetch_repo with default arguments for a simple Cask" do
|
||||||
@ -237,44 +237,5 @@ describe "download strategies", :cask do
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "runs tar to serialize svn downloads" do
|
|
||||||
# sneaky stub to remake the directory, since homebrew code removes it
|
|
||||||
# before tar is called
|
|
||||||
allow(downloader).to receive(:fetch_repo) {
|
|
||||||
downloader.cached_location.mkdir
|
|
||||||
}
|
|
||||||
|
|
||||||
downloader.fetch
|
|
||||||
|
|
||||||
expect(fake_system_command).to have_received(:run!).with(
|
|
||||||
"/usr/bin/tar",
|
|
||||||
hash_including(args: [
|
|
||||||
'-s/^\\.//',
|
|
||||||
"--exclude",
|
|
||||||
".svn",
|
|
||||||
"-cf",
|
|
||||||
downloader.tarball_path,
|
|
||||||
"--",
|
|
||||||
".",
|
|
||||||
]),
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# does not work yet, because (for unknown reasons), the tar command
|
|
||||||
# returns an error code when running under the test suite
|
|
||||||
# it 'creates a tarball matching the expected checksum' do
|
|
||||||
# cask = Hbc::CaskLoader.load('svn-download-check-cask')
|
|
||||||
# downloader = Hbc::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.txt'))
|
|
||||||
# File.utime(1000,1000,target.join('empty_file.txt'))
|
|
||||||
# end
|
|
||||||
# expect(downloader.fetch).to equal(downloader.tarball_path)
|
|
||||||
# d = Hbc::Download.new(cask)
|
|
||||||
# d.send(:_check_sums, downloader.tarball_path, cask.sums)
|
|
||||||
# end
|
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user