From 0574662679314eb586e6bb268d76b92cd4d4ff8c Mon Sep 17 00:00:00 2001 From: Roland Walker Date: Tue, 9 Sep 2014 13:14:19 -0400 Subject: [PATCH] metadata directory support - incidentally adds defensive driving against null version in method `destination_path` --- lib/cask.rb | 59 ++++++++++++++++++++++++++++++++++++- lib/cask/installer.rb | 21 ++++++++++++- lib/cask/locations.rb | 4 +++ test/cask/installer_test.rb | 25 ++++++++++++++++ test/cask_test.rb | 9 ++++++ 5 files changed, 116 insertions(+), 2 deletions(-) diff --git a/lib/cask.rb b/lib/cask.rb index f294b3286bdc..fe926891c901 100644 --- a/lib/cask.rb +++ b/lib/cask.rb @@ -126,6 +126,17 @@ def self.title self.name.gsub(/([a-zA-Z\d])([A-Z])/,'\1-\2').gsub(/([a-zA-Z\d])([A-Z])/,'\1-\2').downcase end + def self.nowstamp_metadata_path(container_path) + @timenow ||= Time.now.gmtime + if container_path.respond_to?(:join) + precision = 3 + timestamp = @timenow.strftime('%Y%m%d%H%M%S') + fraction = ("%.#{precision}f" % (@timenow.to_f - @timenow.to_i))[1..-1] + timestamp.concat(fraction) + container_path.join(timestamp) + end + end + attr_reader :title def initialize(title=self.class.title) @title = title @@ -136,7 +147,53 @@ def caskroom_path end def destination_path - caskroom_path.join(version.to_s) + cask_version = version ? version : :unknown + caskroom_path.join(cask_version.to_s) + end + + def metadata_master_container_path + caskroom_path.join(self.class.metadata_subdir) + end + + def metadata_versioned_container_path + cask_version = version ? version : :unknown + metadata_master_container_path.join(cask_version.to_s) + end + + def metadata_path(timestamp=:latest, create=false) + return nil unless metadata_versioned_container_path.respond_to?(:join) + if create and timestamp == :latest + raise CaskError.new('Cannot create metadata path when timestamp is :latest') + end + if timestamp == :latest + path = Pathname.glob(metadata_versioned_container_path.join('*')).sort.last + elsif timestamp == :now + path = self.class.nowstamp_metadata_path(metadata_versioned_container_path) + else + path = metadata_versioned_container_path.join(timestamp) + end + if create + odebug "Creating metadata directory #{path}" + FileUtils.mkdir_p path + end + path + end + + def metadata_subdir(leaf, timestamp=:latest, create=false) + if create and timestamp == :latest + raise CaskError.new('Cannot create metadata subdir when timestamp is :latest') + end + unless leaf.respond_to?(:length) and leaf.length > 0 + raise CaskError.new('Cannot create metadata subdir for empty leaf') + end + parent = metadata_path(timestamp, create) + return nil unless parent.respond_to?(:join) + subdir = parent.join(leaf) + if create + odebug "Creating metadata subdirectory #{subdir}" + FileUtils.mkdir_p subdir + end + subdir end def installed? diff --git a/lib/cask/installer.rb b/lib/cask/installer.rb index 07d6c0c402c4..b1deac35d361 100644 --- a/lib/cask/installer.rb +++ b/lib/cask/installer.rb @@ -1,4 +1,7 @@ class Cask::Installer + + PERSISTENT_METADATA_SUBDIRS = [ 'gpg' ] + def initialize(cask, command=Cask::SystemCommand) @cask = cask @command = command @@ -137,7 +140,9 @@ def uninstall_artifacts def purge_files odebug "Purging files" - if @cask.destination_path.exist? + + # versioned staged distribution + if @cask.destination_path.respond_to?(:rmtree) and @cask.destination_path.exist? begin @cask.destination_path.rmtree rescue @@ -149,6 +154,20 @@ def purge_files end end end + + if @cask.metadata_versioned_container_path.respond_to?(:children) and @cask.metadata_versioned_container_path.exist? + @cask.metadata_versioned_container_path.children.each do |subdir| + subdir.rmtree unless PERSISTENT_METADATA_SUBDIRS.include?(subdir.basename) + end + end + if @cask.metadata_versioned_container_path.respond_to?(:rmdir_if_possible) + @cask.metadata_versioned_container_path.rmdir_if_possible + end + if @cask.metadata_master_container_path.respond_to?(:rmdir_if_possible) + @cask.metadata_master_container_path.rmdir_if_possible + end + + # toplevel staged distribution @cask.caskroom_path.rmdir_if_possible end end diff --git a/lib/cask/locations.rb b/lib/cask/locations.rb index 132d8f89f3eb..a9a9690c406c 100644 --- a/lib/cask/locations.rb +++ b/lib/cask/locations.rb @@ -8,6 +8,10 @@ def tapspath HOMEBREW_REPOSITORY.join "Library", "Taps" end + def metadata_subdir + '.metadata' + end + def caskroom @@caskroom ||= Pathname('/opt/homebrew-cask/Caskroom') end diff --git a/test/cask/installer_test.rb b/test/cask/installer_test.rb index e54b545ce5c6..8787a56c4a00 100644 --- a/test/cask/installer_test.rb +++ b/test/cask/installer_test.rb @@ -274,6 +274,31 @@ dest_path = Cask.appdir/'MyNestedApp.app' TestHelper.valid_alias?(dest_path).must_equal true end + + it "generates and finds a timestamped metadata directory for an installed Cask" do + caffeine = Cask.load('local-caffeine') + + shutup do + Cask::Installer.new(caffeine).install + end + + m_path = caffeine.metadata_path(:now, true) + caffeine.metadata_path(:now, false).must_equal(m_path) + caffeine.metadata_path(:latest).must_equal(m_path) + end + + it "generates and finds a metadata subdirectory for an installed Cask" do + caffeine = Cask.load('local-caffeine') + + shutup do + Cask::Installer.new(caffeine).install + end + + subdir_name = 'Casks' + m_subdir = caffeine.metadata_subdir(subdir_name, :now, true) + caffeine.metadata_subdir(subdir_name, :now, false).must_equal(m_subdir) + caffeine.metadata_subdir(subdir_name, :latest).must_equal(m_subdir) + end end describe "uninstall" do diff --git a/test/cask_test.rb b/test/cask_test.rb index 8291b777b2ea..3fd9aaa6c1a3 100644 --- a/test/cask_test.rb +++ b/test/cask_test.rb @@ -87,4 +87,13 @@ GamesXChange.title.must_equal 'games-x-change' end end + + describe "metadata" do + it "proposes a versioned metadata directory name for each instance" do + cask_name = "adium" + c = Cask.load(cask_name) + metadata_path = Cask.caskroom.join(cask_name, '.metadata', c.version) + c.metadata_versioned_container_path.to_s.must_equal(metadata_path.to_s) + end + end end