From 1948729ec88cee2cb6797cb5d10979ed38bf6f12 Mon Sep 17 00:00:00 2001
From: Markus Reiter <me@reitermark.us>
Date: Fri, 24 Nov 2017 17:44:01 +0100
Subject: [PATCH] Refactor caveats and add `kext` caveat.

---
 Library/Homebrew/cask/lib/hbc.rb              |   1 -
 .../lib/hbc/artifact/abstract_uninstall.rb    |   7 ++
 Library/Homebrew/cask/lib/hbc/cask.rb         |   2 +-
 Library/Homebrew/cask/lib/hbc/caveats.rb      |  14 ---
 Library/Homebrew/cask/lib/hbc/dsl.rb          |  14 ++-
 Library/Homebrew/cask/lib/hbc/dsl/caveats.rb  | 105 ++++++++++++------
 Library/Homebrew/cask/lib/hbc/installer.rb    |  26 +----
 7 files changed, 90 insertions(+), 79 deletions(-)
 delete mode 100644 Library/Homebrew/cask/lib/hbc/caveats.rb

diff --git a/Library/Homebrew/cask/lib/hbc.rb b/Library/Homebrew/cask/lib/hbc.rb
index 01a0850192..db036d2797 100644
--- a/Library/Homebrew/cask/lib/hbc.rb
+++ b/Library/Homebrew/cask/lib/hbc.rb
@@ -11,7 +11,6 @@ require "hbc/caskroom"
 require "hbc/checkable"
 require "hbc/cli"
 require "hbc/cask_dependencies"
-require "hbc/caveats"
 require "hbc/container"
 require "hbc/download"
 require "hbc/download_strategy"
diff --git a/Library/Homebrew/cask/lib/hbc/artifact/abstract_uninstall.rb b/Library/Homebrew/cask/lib/hbc/artifact/abstract_uninstall.rb
index 7505ac49a9..15e4f9c313 100644
--- a/Library/Homebrew/cask/lib/hbc/artifact/abstract_uninstall.rb
+++ b/Library/Homebrew/cask/lib/hbc/artifact/abstract_uninstall.rb
@@ -30,6 +30,13 @@ module Hbc
         super(cask)
         directives[:signal] = [*directives[:signal]].flatten.each_slice(2).to_a
         @directives = directives
+
+        return if MacOS.version < :high_sierra
+        return unless directives.key?(:kext)
+
+        cask.caveats do
+          kext
+        end
       end
 
       def to_h
diff --git a/Library/Homebrew/cask/lib/hbc/cask.rb b/Library/Homebrew/cask/lib/hbc/cask.rb
index 72a23066f8..df885371a9 100644
--- a/Library/Homebrew/cask/lib/hbc/cask.rb
+++ b/Library/Homebrew/cask/lib/hbc/cask.rb
@@ -24,7 +24,7 @@ module Hbc
     end
 
     DSL::DSL_METHODS.each do |method_name|
-      define_method(method_name) { @dsl.send(method_name) }
+      define_method(method_name) { |&block| @dsl.send(method_name, &block) }
     end
 
     def timestamped_versions
diff --git a/Library/Homebrew/cask/lib/hbc/caveats.rb b/Library/Homebrew/cask/lib/hbc/caveats.rb
deleted file mode 100644
index 983d288748..0000000000
--- a/Library/Homebrew/cask/lib/hbc/caveats.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-module Hbc
-  class Caveats
-    def initialize(block)
-      @block = block
-    end
-
-    def eval_and_print(cask)
-      dsl = DSL::Caveats.new(cask)
-      retval = dsl.instance_eval(&@block)
-      return if retval.nil?
-      puts retval.to_s.sub(/[\r\n \t]*\Z/, "\n\n")
-    end
-  end
-end
diff --git a/Library/Homebrew/cask/lib/hbc/dsl.rb b/Library/Homebrew/cask/lib/hbc/dsl.rb
index 2db2c66a98..22f0d2f665 100644
--- a/Library/Homebrew/cask/lib/hbc/dsl.rb
+++ b/Library/Homebrew/cask/lib/hbc/dsl.rb
@@ -232,12 +232,16 @@ module Hbc
       @staged_path = caskroom_path.join(cask_version.to_s)
     end
 
-    def caveats(*string, &block)
-      @caveats ||= []
+    def caveats(*strings, &block)
+      @caveats ||= DSL::Caveats.new(cask)
       if block_given?
-        @caveats << Hbc::Caveats.new(block)
-      elsif string.any?
-        @caveats << string.map { |s| s.to_s.sub(/[\r\n \t]*\Z/, "\n\n") }
+        @caveats.eval_caveats(&block)
+      elsif strings.any?
+        strings.each do |string|
+          @caveats.eval_caveats { string }
+        end
+      else
+        return @caveats.to_s
       end
       @caveats
     end
diff --git a/Library/Homebrew/cask/lib/hbc/dsl/caveats.rb b/Library/Homebrew/cask/lib/hbc/dsl/caveats.rb
index 45ee5d1601..77e03bd1cf 100644
--- a/Library/Homebrew/cask/lib/hbc/dsl/caveats.rb
+++ b/Library/Homebrew/cask/lib/hbc/dsl/caveats.rb
@@ -8,96 +8,130 @@
 module Hbc
   class DSL
     class Caveats < Base
-      def path_environment_variable(path)
-        puts <<~EOS
+      def initialize(*args)
+        super(*args)
+        @built_in_caveats = {}
+        @custom_caveats = []
+      end
+
+      def self.caveat(name, &block)
+        define_method(name) do |*args|
+          key = [name, *args]
+          @built_in_caveats[key] = instance_exec(*args, &block)
+          :built_in_caveat
+        end
+      end
+
+      private_class_method :caveat
+
+      def to_s
+        (@custom_caveats + @built_in_caveats.values).join("\n")
+      end
+
+      # Override `puts` to collect caveats.
+      def puts(*args)
+        @custom_caveats += args
+        :built_in_caveat
+      end
+
+      def eval_caveats(&block)
+        result = instance_eval(&block)
+        return unless result
+        return if result == :built_in_caveat
+        @custom_caveats << result.to_s.sub(/\s*\Z/, "\n")
+      end
+
+      caveat :kext do
+        <<~EOS
+          To install and/or use #{@cask} you may need to enable their kernel extension in
+
+            System Preferences 鈫� Security & Privacy 鈫� General
+
+          For more information refer to vendor documentation or the Apple Technical Note:
+
+            #{Formatter.url("https://developer.apple.com/library/content/technotes/tn2459/_index.html")}
+        EOS
+      end
+
+      caveat :path_environment_variable do |path|
+        <<~EOS
           To use #{@cask}, you may need to add the #{path} directory
           to your PATH environment variable, eg (for bash shell):
 
             export PATH=#{path}:"$PATH"
-
         EOS
       end
 
-      def zsh_path_helper(path)
-        puts <<~EOS
+      caveat :zsh_path_helper do |path|
+        <<~EOS
           To use #{@cask}, zsh users may need to add the following line to their
           ~/.zprofile.  (Among other effects, #{path} will be added to the
           PATH environment variable):
 
             eval `/usr/libexec/path_helper -s`
-
         EOS
       end
 
-      def files_in_usr_local
-        localpath = "/usr/local"
-        return unless HOMEBREW_PREFIX.to_s.downcase.start_with?(localpath)
-        puts <<~EOS
-          Cask #{@cask} installs files under "#{localpath}". The presence of such
+      caveat :files_in_usr_local do
+        next unless HOMEBREW_PREFIX.to_s.downcase.start_with?("/usr/local")
+        <<~EOS
+          Cask #{@cask} installs files under /usr/local. The presence of such
           files can cause warnings when running "brew doctor", which is considered
           to be a bug in Homebrew-Cask.
-
         EOS
       end
 
-      def depends_on_java(java_version = "any")
-        if java_version == "any"
-          puts <<~EOS
+      caveat :depends_on_java do |java_version = :any|
+        if java_version == :any
+          <<~EOS
             #{@cask} requires Java. You can install the latest version with
 
               brew cask install java
-
           EOS
         elsif java_version.include?("9") || java_version.include?("+")
-          puts <<~EOS
+          <<~EOS
             #{@cask} requires Java #{java_version}. You can install the latest version with
 
               brew cask install java
-
           EOS
         else
-          puts <<~EOS
+          <<~EOS
             #{@cask} requires Java #{java_version}. You can install it with
 
               brew cask install caskroom/versions/java#{java_version}
-
           EOS
         end
       end
 
-      def logout
-        puts <<~EOS
-          You must log out and log back in for the installation of #{@cask}
-          to take effect.
-
+      caveat :logout do
+        <<~EOS
+          You must log out and log back in for the installation of #{@cask} to take effect.
         EOS
       end
 
-      def reboot
-        puts <<~EOS
+      caveat :reboot do
+        <<~EOS
           You must reboot for the installation of #{@cask} to take effect.
-
         EOS
       end
 
-      def discontinued
-        puts <<~EOS
+      caveat :discontinued do
+        <<~EOS
           #{@cask} has been officially discontinued upstream.
           It may stop working correctly (or at all) in recent versions of macOS.
 
         EOS
       end
 
-      def free_license(web_page)
-        puts <<~EOS
+      caveat :free_license do |web_page|
+        <<~EOS
           The vendor offers a free license for #{@cask} at
             #{web_page}
-
         EOS
       end
 
-      def malware(radar_number)
-        puts <<~EOS
+      caveat :malware do |radar_number|
+        <<~EOS
           #{@cask} has been reported to bundle malware. Like with any app, use at your own risk.
 
           A report has been made to Apple about this app. Their certificate will hopefully be revoked.
@@ -108,7 +142,6 @@ module Hbc
             #{Formatter.url("https://bugreport.apple.com/")}
           If this report is a mistake, please let us know by opening an issue at
             #{Formatter.url("https://github.com/caskroom/homebrew-cask/issues/new")}
-
         EOS
       end
     end
diff --git a/Library/Homebrew/cask/lib/hbc/installer.rb b/Library/Homebrew/cask/lib/hbc/installer.rb
index 6056250fc0..b2087e643d 100644
--- a/Library/Homebrew/cask/lib/hbc/installer.rb
+++ b/Library/Homebrew/cask/lib/hbc/installer.rb
@@ -35,30 +35,12 @@ module Hbc
 
     def self.print_caveats(cask)
       odebug "Printing caveats"
-      return if cask.caveats.empty?
-
-      output = capture_output do
-        cask.caveats.each do |caveat|
-          if caveat.respond_to?(:eval_and_print)
-            caveat.eval_and_print(cask)
-          else
-            puts caveat
-          end
-        end
-      end
 
-      return if output.empty?
-      ohai "Caveats"
-      puts output
-    end
+      caveats = cask.caveats
+      return if caveats.empty?
 
-    def self.capture_output(&block)
-      old_stdout = $stdout
-      $stdout = Buffer.new($stdout.tty?)
-      block.call
-      output = $stdout.string
-      $stdout = old_stdout
-      output
+      ohai "Caveats"
+      puts caveats + "\n"
     end
 
     def fetch
-- 
GitLab