Merge pull request #4474 from reitermarkus/refactor-containers
Refactor containers and automatically determine dependencies.
This commit is contained in:
		
						commit
						f92e3086ac
					
				@ -6,7 +6,6 @@ require "hbc/container/bzip2"
 | 
			
		||||
require "hbc/container/cab"
 | 
			
		||||
require "hbc/container/criteria"
 | 
			
		||||
require "hbc/container/dmg"
 | 
			
		||||
require "hbc/container/directory"
 | 
			
		||||
require "hbc/container/executable"
 | 
			
		||||
require "hbc/container/generic_unar"
 | 
			
		||||
require "hbc/container/gpg"
 | 
			
		||||
 | 
			
		||||
@ -3,34 +3,21 @@ require "hbc/container/base"
 | 
			
		||||
module Hbc
 | 
			
		||||
  class Container
 | 
			
		||||
    class Air < Base
 | 
			
		||||
      INSTALLER_PATHNAME =
 | 
			
		||||
        Pathname("/Applications/Utilities/Adobe AIR Application Installer.app" \
 | 
			
		||||
                 "/Contents/MacOS/Adobe AIR Application Installer")
 | 
			
		||||
 | 
			
		||||
      def self.me?(criteria)
 | 
			
		||||
        %w[.air].include?(criteria.path.extname)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def self.installer_cmd
 | 
			
		||||
        return @installer_cmd ||= INSTALLER_PATHNAME if installer_exist?
 | 
			
		||||
        raise CaskError, <<~EOS
 | 
			
		||||
          Adobe AIR runtime not present, try installing it via
 | 
			
		||||
 | 
			
		||||
              brew cask install adobe-air
 | 
			
		||||
 | 
			
		||||
        EOS
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def self.installer_exist?
 | 
			
		||||
        INSTALLER_PATHNAME.exist?
 | 
			
		||||
        criteria.path.extname == ".air"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def extract
 | 
			
		||||
        install = @command.run(self.class.installer_cmd,
 | 
			
		||||
                               args: ["-silent", "-location", @cask.staged_path, Pathname.new(@path).realpath])
 | 
			
		||||
        unpack_dir = @cask.staged_path
 | 
			
		||||
 | 
			
		||||
        return unless install.exit_status == 9
 | 
			
		||||
        raise CaskError, "Adobe AIR application #{@cask} already exists on the system, and cannot be reinstalled."
 | 
			
		||||
        @command.run!(
 | 
			
		||||
          "/Applications/Utilities/Adobe AIR Application Installer.app/Contents/MacOS/Adobe AIR Application Installer",
 | 
			
		||||
          args: ["-silent", "-location", unpack_dir, path],
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def dependencies
 | 
			
		||||
        @dependencies ||= [CaskLoader.load("adobe-air")]
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,8 @@
 | 
			
		||||
module Hbc
 | 
			
		||||
  class Container
 | 
			
		||||
    class Base
 | 
			
		||||
      attr_reader :path
 | 
			
		||||
 | 
			
		||||
      def initialize(cask, path, command, nested: false, verbose: false)
 | 
			
		||||
        @cask = cask
 | 
			
		||||
        @path = path
 | 
			
		||||
@ -41,6 +43,10 @@ module Hbc
 | 
			
		||||
 | 
			
		||||
        true
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def dependencies
 | 
			
		||||
        []
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@ -4,13 +4,13 @@ module Hbc
 | 
			
		||||
  class Container
 | 
			
		||||
    class Bzip2 < Base
 | 
			
		||||
      def self.me?(criteria)
 | 
			
		||||
        criteria.magic_number(/^BZh/n)
 | 
			
		||||
        criteria.magic_number(/\ABZh/n)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def extract
 | 
			
		||||
        Dir.mktmpdir do |unpack_dir|
 | 
			
		||||
          @command.run!("/usr/bin/ditto",   args: ["--", @path, unpack_dir])
 | 
			
		||||
          @command.run!("/usr/bin/bunzip2", args: ["--quiet", "--", Pathname.new(unpack_dir).join(@path.basename)])
 | 
			
		||||
          @command.run!("/usr/bin/ditto", args: ["--", @path, unpack_dir])
 | 
			
		||||
          @command.run!("bunzip2", args: ["--quiet", "--", Pathname.new(unpack_dir).join(@path.basename)])
 | 
			
		||||
 | 
			
		||||
          extract_nested_inside(unpack_dir)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
@ -4,19 +4,21 @@ module Hbc
 | 
			
		||||
  class Container
 | 
			
		||||
    class Cab < Base
 | 
			
		||||
      def self.me?(criteria)
 | 
			
		||||
        criteria.magic_number(/^(MSCF|MZ)/n)
 | 
			
		||||
        criteria.magic_number(/\A(MSCF|MZ)/n)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def extract
 | 
			
		||||
        unless cabextract = which("cabextract", PATH.new(ENV["PATH"], HOMEBREW_PREFIX/"bin"))
 | 
			
		||||
          raise CaskError, "Expected to find cabextract executable. Cask '#{@cask}' must add: depends_on formula: 'cabextract'"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        Dir.mktmpdir do |unpack_dir|
 | 
			
		||||
          @command.run!(cabextract, args: ["-d", unpack_dir, "--", @path])
 | 
			
		||||
          @command.run!("cabextract",
 | 
			
		||||
                        args: ["-d", unpack_dir, "--", @path],
 | 
			
		||||
                        env: { "PATH" => PATH.new(Formula["cabextract"].opt_bin, ENV["PATH"]) })
 | 
			
		||||
          @command.run!("/usr/bin/ditto", args: ["--", unpack_dir, @cask.staged_path])
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def dependencies
 | 
			
		||||
        @dependencies ||= [Formula["cabextract"]]
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,7 @@ module Hbc
 | 
			
		||||
        return false if path.directory?
 | 
			
		||||
 | 
			
		||||
        # 262: length of the longest regex (currently: Hbc::Container::Tar)
 | 
			
		||||
        @magic_number ||= File.open(path, "rb") { |f| f.read(262) }
 | 
			
		||||
        @magic_number ||= File.binread(path, 262)
 | 
			
		||||
        @magic_number.match?(regex)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@ -1,24 +0,0 @@
 | 
			
		||||
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
 | 
			
		||||
@ -15,7 +15,7 @@ module Hbc
 | 
			
		||||
      def extract
 | 
			
		||||
        mount do |mounts|
 | 
			
		||||
          begin
 | 
			
		||||
            raise CaskError, "No mounts found in '#{@path}'; perhaps it is a bad DMG?" if mounts.empty?
 | 
			
		||||
            raise CaskError, "No mounts found in '#{@path}'; perhaps it is a bad disk image?" if mounts.empty?
 | 
			
		||||
            mounts.each(&method(:extract_mount))
 | 
			
		||||
          ensure
 | 
			
		||||
            mounts.each(&method(:eject))
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@ module Hbc
 | 
			
		||||
  class Container
 | 
			
		||||
    class Executable < Naked
 | 
			
		||||
      def self.me?(criteria)
 | 
			
		||||
        return true if criteria.magic_number(/^#!\s*\S+/)
 | 
			
		||||
        return true if criteria.magic_number(/\A#!\s*\S+/n)
 | 
			
		||||
 | 
			
		||||
        begin
 | 
			
		||||
          criteria.path.file? && MachO.open(criteria.path).header.executable?
 | 
			
		||||
 | 
			
		||||
@ -3,22 +3,20 @@ require "hbc/container/base"
 | 
			
		||||
module Hbc
 | 
			
		||||
  class Container
 | 
			
		||||
    class GenericUnar < Base
 | 
			
		||||
      def self.me?(criteria)
 | 
			
		||||
        return false unless lsar = which("lsar", PATH.new(ENV["PATH"], HOMEBREW_PREFIX/"bin"))
 | 
			
		||||
        criteria.command.run(lsar,
 | 
			
		||||
                             args:         ["-l", "-t", "--", criteria.path],
 | 
			
		||||
                             print_stderr: false).stdout.chomp.end_with?("passed, 0 failed.")
 | 
			
		||||
      def self.me?(_criteria)
 | 
			
		||||
        false
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def extract
 | 
			
		||||
        unless unar = which("unar", PATH.new(ENV["PATH"], HOMEBREW_PREFIX/"bin"))
 | 
			
		||||
          raise CaskError, "Expected to find unar executable. Cask #{@cask} must add: depends_on formula: 'unar'"
 | 
			
		||||
        end
 | 
			
		||||
        unpack_dir = @cask.staged_path
 | 
			
		||||
 | 
			
		||||
        Dir.mktmpdir do |unpack_dir|
 | 
			
		||||
          @command.run!(unar, args: ["-force-overwrite", "-quiet", "-no-directory", "-output-directory", unpack_dir, "--", @path])
 | 
			
		||||
          @command.run!("/usr/bin/ditto", args: ["--", unpack_dir, @cask.staged_path])
 | 
			
		||||
        end
 | 
			
		||||
        @command.run!("unar",
 | 
			
		||||
                      args: ["-force-overwrite", "-quiet", "-no-directory", "-output-directory", unpack_dir, "--", path],
 | 
			
		||||
                      env: { "PATH" => PATH.new(Formula["unar"].opt_bin, ENV["PATH"]) })
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def dependencies
 | 
			
		||||
        @dependencies ||= [Formula["unar"]]
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -18,22 +18,26 @@ module Hbc
 | 
			
		||||
          ["--fetch-key", @cask.gpg.key_url.to_s]
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        @command.run!("gpg", args: args)
 | 
			
		||||
        @command.run!("gpg",
 | 
			
		||||
                      args: args,
 | 
			
		||||
                      env: { "PATH" => PATH.new(Formula["gnupg"].opt_bin, ENV["PATH"]) })
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def extract
 | 
			
		||||
        unless gpg = which("gpg", PATH.new(ENV["PATH"], HOMEBREW_PREFIX/"bin"))
 | 
			
		||||
          raise CaskError, "Expected to find gpg executable. Cask '#{@cask}' must add: depends_on formula: 'gpg'"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        import_key
 | 
			
		||||
 | 
			
		||||
        Dir.mktmpdir do |unpack_dir|
 | 
			
		||||
          @command.run!(gpg, args: ["--batch", "--yes", "--output", Pathname(unpack_dir).join(@path.basename(".gpg")), "--decrypt", @path])
 | 
			
		||||
          @command.run!("gpg",
 | 
			
		||||
                        args: ["--batch", "--yes", "--output", Pathname(unpack_dir).join(@path.basename(".gpg")), "--decrypt", @path],
 | 
			
		||||
                        env: { "PATH" => PATH.new(Formula["gnupg"].opt_bin, ENV["PATH"]) })
 | 
			
		||||
 | 
			
		||||
          extract_nested_inside(unpack_dir)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def dependencies
 | 
			
		||||
        @dependencies ||= [Formula["gnupg"]]
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@ -4,13 +4,13 @@ module Hbc
 | 
			
		||||
  class Container
 | 
			
		||||
    class Gzip < Base
 | 
			
		||||
      def self.me?(criteria)
 | 
			
		||||
        criteria.magic_number(/^\037\213/n)
 | 
			
		||||
        criteria.magic_number(/\A\037\213/n)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def extract
 | 
			
		||||
        Dir.mktmpdir do |unpack_dir|
 | 
			
		||||
          @command.run!("/usr/bin/ditto",  args: ["--", @path, unpack_dir])
 | 
			
		||||
          @command.run!("/usr/bin/gunzip", args: ["--quiet", "--name", "--", Pathname.new(unpack_dir).join(@path.basename)])
 | 
			
		||||
          @command.run!("/usr/bin/ditto", args: ["--", @path, unpack_dir])
 | 
			
		||||
          @command.run!("gunzip", args: ["--quiet", "--name", "--", Pathname.new(unpack_dir).join(@path.basename)])
 | 
			
		||||
 | 
			
		||||
          extract_nested_inside(unpack_dir)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
@ -4,20 +4,22 @@ module Hbc
 | 
			
		||||
  class Container
 | 
			
		||||
    class Lzma < Base
 | 
			
		||||
      def self.me?(criteria)
 | 
			
		||||
        criteria.magic_number(/^\]\000\000\200\000/n)
 | 
			
		||||
        criteria.magic_number(/\A\]\000\000\200\000/n)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def extract
 | 
			
		||||
        unless unlzma = which("unlzma", PATH.new(ENV["PATH"], HOMEBREW_PREFIX/"bin"))
 | 
			
		||||
          raise CaskError, "Expected to find unlzma executable. Cask '#{@cask}' must add: depends_on formula: 'lzma'"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        Dir.mktmpdir do |unpack_dir|
 | 
			
		||||
          @command.run!("/usr/bin/ditto", args: ["--", @path, unpack_dir])
 | 
			
		||||
          @command.run!(unlzma, args: ["-q", "--", Pathname(unpack_dir).join(@path.basename)])
 | 
			
		||||
          @command.run!("unlzma",
 | 
			
		||||
                        args: ["-q", "--", Pathname(unpack_dir).join(@path.basename)],
 | 
			
		||||
                        env: { "PATH" => PATH.new(Formula["unlzma"].opt_bin, ENV["PATH"]) })
 | 
			
		||||
          @command.run!("/usr/bin/ditto", args: ["--", unpack_dir, @cask.staged_path])
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def dependencies
 | 
			
		||||
        @dependencies ||= [Formula["unlzma"]]
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@ module Hbc
 | 
			
		||||
  class Container
 | 
			
		||||
    class Otf < Naked
 | 
			
		||||
      def self.me?(criteria)
 | 
			
		||||
        criteria.magic_number(/^OTTO/n)
 | 
			
		||||
        criteria.magic_number(/\AOTTO/n)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -5,8 +5,7 @@ module Hbc
 | 
			
		||||
    class Pkg < Naked
 | 
			
		||||
      def self.me?(criteria)
 | 
			
		||||
        criteria.extension(/m?pkg$/) &&
 | 
			
		||||
          (criteria.path.directory? ||
 | 
			
		||||
           criteria.magic_number(/^xar!/n))
 | 
			
		||||
          (criteria.path.directory? || criteria.magic_number(/\Axar!/n))
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -2,11 +2,21 @@ require "hbc/container/generic_unar"
 | 
			
		||||
 | 
			
		||||
module Hbc
 | 
			
		||||
  class Container
 | 
			
		||||
    class Rar < GenericUnar
 | 
			
		||||
    class Rar
 | 
			
		||||
      def self.me?(criteria)
 | 
			
		||||
        criteria.magic_number(/^Rar!/n) &&
 | 
			
		||||
        criteria.magic_number(/\ARar!/n) &&
 | 
			
		||||
          super
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def extract
 | 
			
		||||
        path = @path
 | 
			
		||||
        unpack_dir = @cask.staged_path
 | 
			
		||||
        @command.run!(Formula["unrar"].opt_bin/"unrar", args: ["x", "-inul", path, unpack_dir])
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def dependencies
 | 
			
		||||
        @dependencies ||= [Formula["unrar"]]
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@ -4,9 +4,19 @@ module Hbc
 | 
			
		||||
  class Container
 | 
			
		||||
    class SevenZip < GenericUnar
 | 
			
		||||
      def self.me?(criteria)
 | 
			
		||||
        # TODO: cover self-extracting archives
 | 
			
		||||
        criteria.magic_number(/^7z/n) &&
 | 
			
		||||
          super
 | 
			
		||||
        criteria.magic_number(/\A7z\xBC\xAF\x27\x1C/n)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def extract
 | 
			
		||||
        unpack_dir = @cask.staged_path
 | 
			
		||||
 | 
			
		||||
        @command.run!("7zr",
 | 
			
		||||
                      args: ["x", "-y", "-bd", "-bso0", path, "-o#{unpack_dir}"],
 | 
			
		||||
                      env: { "PATH" => PATH.new(Formula["p7zip"].opt_bin, ENV["PATH"]) })
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def dependencies
 | 
			
		||||
        @dependencies ||= [Formula["p7zip"]]
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -4,8 +4,7 @@ module Hbc
 | 
			
		||||
  class Container
 | 
			
		||||
    class Sit < GenericUnar
 | 
			
		||||
      def self.me?(criteria)
 | 
			
		||||
        criteria.magic_number(/^StuffIt/n) &&
 | 
			
		||||
          super
 | 
			
		||||
        criteria.magic_number(/\AStuffIt/n)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,15 @@
 | 
			
		||||
require "hbc/container/directory"
 | 
			
		||||
 | 
			
		||||
module Hbc
 | 
			
		||||
  class Container
 | 
			
		||||
    class SvnRepository < Directory
 | 
			
		||||
    class SvnRepository < Base
 | 
			
		||||
      def self.me?(criteria)
 | 
			
		||||
        criteria.path.join(".svn").directory?
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def skip_path?(path)
 | 
			
		||||
        path.basename.to_s == ".svn"
 | 
			
		||||
      def extract
 | 
			
		||||
        path = @path
 | 
			
		||||
        unpack_dir = @cask.staged_path
 | 
			
		||||
 | 
			
		||||
        @command.run!("svn", args: ["export", "--force", path, unpack_dir])
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -4,16 +4,15 @@ module Hbc
 | 
			
		||||
  class Container
 | 
			
		||||
    class Tar < Base
 | 
			
		||||
      def self.me?(criteria)
 | 
			
		||||
        criteria.magic_number(/^.{257}ustar/n) ||
 | 
			
		||||
        criteria.magic_number(/\A.{257}ustar/n) ||
 | 
			
		||||
          # or compressed tar (bzip2/gzip/lzma/xz)
 | 
			
		||||
          IO.popen(["/usr/bin/tar", "-t", "-f", criteria.path.to_s], err: "/dev/null") { |io| !io.read(1).nil? }
 | 
			
		||||
          IO.popen(["/usr/bin/tar", "-t", "-f", criteria.path.to_s], err: File::NULL) { |io| !io.read(1).nil? }
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def extract
 | 
			
		||||
        Dir.mktmpdir do |unpack_dir|
 | 
			
		||||
          @command.run!("/usr/bin/tar", args: ["-x", "-f", @path, "-C", unpack_dir])
 | 
			
		||||
          @command.run!("/usr/bin/ditto", args: ["--", unpack_dir, @cask.staged_path])
 | 
			
		||||
        end
 | 
			
		||||
        unpack_dir = @cask.staged_path
 | 
			
		||||
 | 
			
		||||
        @command.run!("tar", args: ["xf", path, "-C", unpack_dir])
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -5,9 +5,9 @@ module Hbc
 | 
			
		||||
    class Ttf < Naked
 | 
			
		||||
      def self.me?(criteria)
 | 
			
		||||
        # TrueType Font
 | 
			
		||||
        criteria.magic_number(/^\000\001\000\000\000/n) ||
 | 
			
		||||
        criteria.magic_number(/\A\000\001\000\000\000/n) ||
 | 
			
		||||
          # Truetype Font Collection
 | 
			
		||||
          criteria.magic_number(/^ttcf/n)
 | 
			
		||||
          criteria.magic_number(/\Attcf/n)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -4,14 +4,13 @@ module Hbc
 | 
			
		||||
  class Container
 | 
			
		||||
    class Xar < Base
 | 
			
		||||
      def self.me?(criteria)
 | 
			
		||||
        criteria.magic_number(/^xar!/n)
 | 
			
		||||
        criteria.magic_number(/\Axar!/n)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def extract
 | 
			
		||||
        Dir.mktmpdir do |unpack_dir|
 | 
			
		||||
          @command.run!("/usr/bin/xar", args: ["-x", "-f", @path, "-C", unpack_dir])
 | 
			
		||||
          @command.run!("/usr/bin/ditto", args: ["--", unpack_dir, @cask.staged_path])
 | 
			
		||||
        end
 | 
			
		||||
        unpack_dir = @cask.staged_path
 | 
			
		||||
 | 
			
		||||
        @command.run!("xar", args: ["-x", "-f", @path, "-C", unpack_dir])
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -4,19 +4,21 @@ module Hbc
 | 
			
		||||
  class Container
 | 
			
		||||
    class Xz < Base
 | 
			
		||||
      def self.me?(criteria)
 | 
			
		||||
        criteria.magic_number(/^\xFD7zXZ\x00/n)
 | 
			
		||||
        criteria.magic_number(/\A\xFD7zXZ\x00/n)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def extract
 | 
			
		||||
        unless unxz = which("unxz", PATH.new(ENV["PATH"], HOMEBREW_PREFIX/"bin"))
 | 
			
		||||
          raise CaskError, "Expected to find unxz executable. Cask '#{@cask}' must add: depends_on formula: 'xz'"
 | 
			
		||||
        end
 | 
			
		||||
        unpack_dir = @cask.staged_path
 | 
			
		||||
        basename = path.basename
 | 
			
		||||
 | 
			
		||||
        Dir.mktmpdir do |unpack_dir|
 | 
			
		||||
          @command.run!("/usr/bin/ditto", args: ["--", @path, unpack_dir])
 | 
			
		||||
          @command.run!(unxz, args: ["-q", "--", Pathname(unpack_dir).join(@path.basename)])
 | 
			
		||||
          @command.run!("/usr/bin/ditto", args: ["--", unpack_dir, @cask.staged_path])
 | 
			
		||||
        end
 | 
			
		||||
        @command.run!("/usr/bin/ditto", args: ["--", path, unpack_dir])
 | 
			
		||||
        @command.run!("xz",
 | 
			
		||||
                      args: ["-q", "--", unpack_dir/basename],
 | 
			
		||||
                      env: { "PATH" => PATH.new(Formula["xz"].opt_bin, ENV["PATH"]) })
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def dependencies
 | 
			
		||||
        @dependencies ||= [Formula["xz"]]
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@ module Hbc
 | 
			
		||||
  class Container
 | 
			
		||||
    class Zip < Base
 | 
			
		||||
      def self.me?(criteria)
 | 
			
		||||
        criteria.magic_number(/^PK(\003\004|\005\006)/n)
 | 
			
		||||
        criteria.magic_number(/\APK(\003\004|\005\006)/n)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def extract
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,7 @@ module Hbc
 | 
			
		||||
 | 
			
		||||
    PERSISTENT_METADATA_SUBDIRS = ["gpg"].freeze
 | 
			
		||||
 | 
			
		||||
    def initialize(cask, command: SystemCommand, force: false, skip_cask_deps: false, binaries: true, verbose: false, require_sha: false, upgrade: false)
 | 
			
		||||
    def initialize(cask, command: SystemCommand, force: false, skip_cask_deps: false, binaries: true, verbose: false, require_sha: false, upgrade: false, installed_as_dependency: false)
 | 
			
		||||
      @cask = cask
 | 
			
		||||
      @command = command
 | 
			
		||||
      @force = force
 | 
			
		||||
@ -29,9 +29,10 @@ module Hbc
 | 
			
		||||
      @require_sha = require_sha
 | 
			
		||||
      @reinstall = false
 | 
			
		||||
      @upgrade = upgrade
 | 
			
		||||
      @installed_as_dependency = installed_as_dependency
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    attr_predicate :binaries?, :force?, :skip_cask_deps?, :require_sha?, :upgrade?, :verbose?
 | 
			
		||||
    attr_predicate :binaries?, :force?, :skip_cask_deps?, :require_sha?, :upgrade?, :verbose?, :installed_as_dependency?
 | 
			
		||||
 | 
			
		||||
    def self.print_caveats(cask)
 | 
			
		||||
      odebug "Printing caveats"
 | 
			
		||||
@ -47,6 +48,7 @@ module Hbc
 | 
			
		||||
      odebug "Hbc::Installer#fetch"
 | 
			
		||||
 | 
			
		||||
      satisfy_dependencies
 | 
			
		||||
 | 
			
		||||
      verify_has_sha if require_sha? && !force?
 | 
			
		||||
      download
 | 
			
		||||
      verify
 | 
			
		||||
@ -57,6 +59,8 @@ module Hbc
 | 
			
		||||
 | 
			
		||||
      Caskroom.ensure_caskroom_exists
 | 
			
		||||
 | 
			
		||||
      unpack_dependencies
 | 
			
		||||
 | 
			
		||||
      extract_primary_container
 | 
			
		||||
      save_caskfile
 | 
			
		||||
    rescue StandardError => e
 | 
			
		||||
@ -140,22 +144,28 @@ module Hbc
 | 
			
		||||
      Verify.all(@cask, @downloaded_path)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def primary_container
 | 
			
		||||
      @primary_container ||= begin
 | 
			
		||||
        container = if @cask.container&.type
 | 
			
		||||
          Container.from_type(@cask.container.type)
 | 
			
		||||
        else
 | 
			
		||||
          Container.for_path(@downloaded_path, @command)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        container&.new(@cask, @downloaded_path, @command, verbose: verbose?)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def extract_primary_container
 | 
			
		||||
      odebug "Extracting primary container"
 | 
			
		||||
 | 
			
		||||
      FileUtils.mkdir_p @cask.staged_path
 | 
			
		||||
      container = if @cask.container&.type
 | 
			
		||||
        Container.from_type(@cask.container.type)
 | 
			
		||||
      else
 | 
			
		||||
        Container.for_path(@downloaded_path, @command)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless container
 | 
			
		||||
      unless primary_container
 | 
			
		||||
        raise CaskError, "Uh oh, could not figure out how to unpack '#{@downloaded_path}'"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      odebug "Using container class #{container} for #{@downloaded_path}"
 | 
			
		||||
      container.new(@cask, @downloaded_path, @command, verbose: verbose?).extract
 | 
			
		||||
      odebug "Using container class #{primary_container.class} for #{@downloaded_path}"
 | 
			
		||||
      FileUtils.mkdir_p @cask.staged_path
 | 
			
		||||
      primary_container.extract
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def install_artifacts
 | 
			
		||||
@ -200,7 +210,7 @@ module Hbc
 | 
			
		||||
      arch_dependencies
 | 
			
		||||
      x11_dependencies
 | 
			
		||||
      formula_dependencies
 | 
			
		||||
      cask_dependencies unless skip_cask_deps?
 | 
			
		||||
      cask_dependencies unless skip_cask_deps? || installed_as_dependency?
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def macos_dependencies
 | 
			
		||||
@ -249,27 +259,21 @@ module Hbc
 | 
			
		||||
 | 
			
		||||
      ohai "Installing Formula dependencies: #{not_installed.map(&:to_s).join(", ")}"
 | 
			
		||||
      not_installed.each do |formula|
 | 
			
		||||
        begin
 | 
			
		||||
          old_argv = ARGV.dup
 | 
			
		||||
          ARGV.replace([])
 | 
			
		||||
          FormulaInstaller.new(formula).tap do |fi|
 | 
			
		||||
            fi.installed_as_dependency = true
 | 
			
		||||
            fi.installed_on_request = false
 | 
			
		||||
            fi.show_header = true
 | 
			
		||||
            fi.verbose = verbose?
 | 
			
		||||
            fi.prelude
 | 
			
		||||
            fi.install
 | 
			
		||||
            fi.finish
 | 
			
		||||
          end
 | 
			
		||||
        ensure
 | 
			
		||||
          ARGV.replace(old_argv)
 | 
			
		||||
        FormulaInstaller.new(formula).tap do |fi|
 | 
			
		||||
          fi.installed_as_dependency = true
 | 
			
		||||
          fi.installed_on_request = false
 | 
			
		||||
          fi.show_header = true
 | 
			
		||||
          fi.verbose = verbose?
 | 
			
		||||
          fi.prelude
 | 
			
		||||
          fi.install
 | 
			
		||||
          fi.finish
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def cask_dependencies
 | 
			
		||||
      return if @cask.depends_on.cask.empty?
 | 
			
		||||
      casks = CaskDependencies.new(@cask)
 | 
			
		||||
      return if casks.empty?
 | 
			
		||||
 | 
			
		||||
      if casks.all?(&:installed?)
 | 
			
		||||
        puts "All Cask dependencies satisfied."
 | 
			
		||||
@ -280,7 +284,36 @@ module Hbc
 | 
			
		||||
 | 
			
		||||
      ohai "Installing Cask dependencies: #{not_installed.map(&:to_s).join(", ")}"
 | 
			
		||||
      not_installed.each do |cask|
 | 
			
		||||
        Installer.new(cask, binaries: binaries?, verbose: verbose?, skip_cask_deps: true, force: false).install
 | 
			
		||||
        Installer.new(cask, binaries: binaries?, verbose: verbose?, installed_as_dependency: true, force: false).install
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def unpack_dependencies
 | 
			
		||||
      formulae = primary_container.dependencies.select { |dep| dep.is_a?(Formula) }
 | 
			
		||||
      casks = primary_container.dependencies.select { |dep| dep.is_a?(Cask) }
 | 
			
		||||
                               .flat_map { |cask| [*CaskDependencies.new(cask), cask] }
 | 
			
		||||
 | 
			
		||||
      not_installed_formulae = formulae.reject(&:any_version_installed?)
 | 
			
		||||
      not_installed_casks = casks.reject(&:installed?)
 | 
			
		||||
 | 
			
		||||
      return if (not_installed_formulae + not_installed_casks).empty?
 | 
			
		||||
 | 
			
		||||
      ohai "Satisfying unpack dependencies"
 | 
			
		||||
 | 
			
		||||
      not_installed_formulae.each do |formula|
 | 
			
		||||
        FormulaInstaller.new(formula).tap do |fi|
 | 
			
		||||
          fi.installed_as_dependency = true
 | 
			
		||||
          fi.installed_on_request = false
 | 
			
		||||
          fi.show_header = true
 | 
			
		||||
          fi.verbose = verbose?
 | 
			
		||||
          fi.prelude
 | 
			
		||||
          fi.install
 | 
			
		||||
          fi.finish
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      not_installed_casks.each do |cask|
 | 
			
		||||
        Installer.new(cask, verbose: verbose?, installed_as_dependency: true).install
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -238,7 +238,7 @@ class RarUnpackStrategy < UnpackStrategy
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
  def extract_to_dir(unpack_dir, basename:)
 | 
			
		||||
    safe_system "unrar", "x", "-inul", path, unpack_dir
 | 
			
		||||
    safe_system Formula["unrar"].opt_bin/"unrar", "x", "-inul", path, unpack_dir
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user