Simplify SubversionDownloadStrategy.
This commit is contained in:
		
							parent
							
								
									69799d97b1
								
							
						
					
					
						commit
						fb59e79689
					
				@ -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