luffa 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/CONTRIBUTING.md +39 -0
 - data/LICENSE +204 -0
 - data/README.md +7 -0
 - data/VERSIONING.md +16 -0
 - data/bin/luffa +17 -0
 - data/lib/luffa.rb +12 -0
 - data/lib/luffa/cli/cli.rb +65 -0
 - data/lib/luffa/environment.rb +31 -0
 - data/lib/luffa/gem.rb +35 -0
 - data/lib/luffa/ios/ideviceinstaller.rb +116 -0
 - data/lib/luffa/ios/simulator.rb +36 -0
 - data/lib/luffa/ios/xcode.rb +93 -0
 - data/lib/luffa/logging.rb +21 -0
 - data/lib/luffa/patches/awesome_print.rb +16 -0
 - data/lib/luffa/patches/kernel.rb +19 -0
 - data/lib/luffa/retry.rb +13 -0
 - data/lib/luffa/unix_command.rb +43 -0
 - data/lib/luffa/version.rb +166 -0
 - data/lib/luffa/with_debugging.rb +13 -0
 - data/script/ci/com.apple.dt.instruments.process.analysis.plist +34 -0
 - data/script/ci/com.apple.dt.instruments.process.kill.plist +34 -0
 - metadata +323 -0
 
| 
         @@ -0,0 +1,36 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'singleton'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Luffa
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Simulator
         
     | 
| 
      
 5 
     | 
    
         
            +
                def core_simulator_home_dir
         
     | 
| 
      
 6 
     | 
    
         
            +
                  @core_simulator_home_dir ||= File.expand_path('~/Library/Developer/CoreSimulator')
         
     | 
| 
      
 7 
     | 
    
         
            +
                end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                def core_simulator_device_dir(sim_udid=nil)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  if sim_udid.nil?
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @core_simulator_device_dir ||= File.expand_path(File.join(core_simulator_home_dir, 'Devices'))
         
     | 
| 
      
 12 
     | 
    
         
            +
                  else
         
     | 
| 
      
 13 
     | 
    
         
            +
                    File.expand_path(File.join(core_simulator_device_dir, sim_udid))
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                def core_simulator_device_containers_dir(sim_udid)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  File.expand_path(File.join(core_simulator_device_dir(sim_udid), 'Containers'))
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                def core_simulator_for_xcode_version(idiom, form_factor, xcode_version)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  if xcode_version < Luffa::Version.new('6.1')
         
     | 
| 
      
 23 
     | 
    
         
            +
                    ios_version = '8.0'
         
     | 
| 
      
 24 
     | 
    
         
            +
                  elsif xcode_version < Luffa::Version.new('6.2')
         
     | 
| 
      
 25 
     | 
    
         
            +
                    ios_version = '8.1'
         
     | 
| 
      
 26 
     | 
    
         
            +
                  elsif xcode_version < Luffa::Version.new('6.3')
         
     | 
| 
      
 27 
     | 
    
         
            +
                    ios_version = '8.2'
         
     | 
| 
      
 28 
     | 
    
         
            +
                  elsif xcode_version >= Luffa::Version.new('6.3')
         
     | 
| 
      
 29 
     | 
    
         
            +
                    ios_version = '8.3'
         
     | 
| 
      
 30 
     | 
    
         
            +
                  else
         
     | 
| 
      
 31 
     | 
    
         
            +
                    raise "Unsupported Xcode version: #{xcode_version}"
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
                  "#{idiom} #{form_factor} (#{ios_version} Simulator)"
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,93 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Luffa
         
     | 
| 
      
 2 
     | 
    
         
            +
              class XcodeInstall
         
     | 
| 
      
 3 
     | 
    
         
            +
                attr :version
         
     | 
| 
      
 4 
     | 
    
         
            +
                attr :path
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                def initialize(path)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  Luffa::Xcode.with_developer_dir(path) do
         
     | 
| 
      
 8 
     | 
    
         
            +
                    @version = lambda {
         
     | 
| 
      
 9 
     | 
    
         
            +
                      xcode_build_output = `xcrun xcodebuild -version`.split(/\s/)[1]
         
     | 
| 
      
 10 
     | 
    
         
            +
                      Luffa::Version.new(xcode_build_output)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    }.call
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                    @path = path
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                def version_string
         
     | 
| 
      
 18 
     | 
    
         
            +
                  version.to_s
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                def == (other)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  other.path == path && other.version == version
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              class Xcode
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                def self.with_developer_dir(developer_dir, &block)
         
     | 
| 
      
 29 
     | 
    
         
            +
                  original_developer_dir = Luffa::Environment.developer_dir
         
     | 
| 
      
 30 
     | 
    
         
            +
                  stripped = developer_dir.strip
         
     | 
| 
      
 31 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 32 
     | 
    
         
            +
                    ENV['DEVELOPER_DIR'] = stripped
         
     | 
| 
      
 33 
     | 
    
         
            +
                    block.call
         
     | 
| 
      
 34 
     | 
    
         
            +
                  ensure
         
     | 
| 
      
 35 
     | 
    
         
            +
                    ENV['DEVELOPER_DIR'] = original_developer_dir
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                def self.with_xcode_install(xcode_install, &block)
         
     | 
| 
      
 40 
     | 
    
         
            +
                  self.with_developer_dir(xcode_install.path, &block)
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                def self.ios_version_incompatible_with_xcode_version?(ios_version, xcode_version)
         
     | 
| 
      
 44 
     | 
    
         
            +
                  [(ios_version >= Luffa::Version.new('8.0') && xcode_version < Luffa::Version.new('6.0')),
         
     | 
| 
      
 45 
     | 
    
         
            +
                   (ios_version >= Luffa::Version.new('8.1') && xcode_version < Luffa::Version.new('6.1')),
         
     | 
| 
      
 46 
     | 
    
         
            +
                   (ios_version >= Luffa::Version.new('8.2') && xcode_version < Luffa::Version.new('6.2')),
         
     | 
| 
      
 47 
     | 
    
         
            +
                   (ios_version >= Luffa::Version.new('8.3') && xcode_version < Luffa::Version.new('6.3'))].any?
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                def xcode_installs
         
     | 
| 
      
 51 
     | 
    
         
            +
                  @xcode_installs ||= lambda do
         
     | 
| 
      
 52 
     | 
    
         
            +
                    min_xcode_version = Luffa::Version.new('5.1.1')
         
     | 
| 
      
 53 
     | 
    
         
            +
                    active_xcode = Luffa::Xcode.new.active_xcode
         
     | 
| 
      
 54 
     | 
    
         
            +
                    xcodes = [active_xcode]
         
     | 
| 
      
 55 
     | 
    
         
            +
                    Dir.glob('/Xcode/*/*.app/Contents/Developer').each do |path|
         
     | 
| 
      
 56 
     | 
    
         
            +
                      xcode_version = path[/(\d\.\d(\.\d)?)/, 0]
         
     | 
| 
      
 57 
     | 
    
         
            +
                      if Luffa::Version.new(xcode_version) >= min_xcode_version
         
     | 
| 
      
 58 
     | 
    
         
            +
                        install = Luffa::XcodeInstall.new(path)
         
     | 
| 
      
 59 
     | 
    
         
            +
                        unless install == active_xcode
         
     | 
| 
      
 60 
     | 
    
         
            +
                          xcodes << install
         
     | 
| 
      
 61 
     | 
    
         
            +
                        end
         
     | 
| 
      
 62 
     | 
    
         
            +
                      end
         
     | 
| 
      
 63 
     | 
    
         
            +
                    end
         
     | 
| 
      
 64 
     | 
    
         
            +
                    xcodes
         
     | 
| 
      
 65 
     | 
    
         
            +
                  end.call
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                # The developer dir at the time the tests start.
         
     | 
| 
      
 69 
     | 
    
         
            +
                #
         
     | 
| 
      
 70 
     | 
    
         
            +
                # To change the active Xcode:
         
     | 
| 
      
 71 
     | 
    
         
            +
                #
         
     | 
| 
      
 72 
     | 
    
         
            +
                #   $ DEVELOPER_DIR=/path/to/Xcode.app/Contents/Developer be rake spec
         
     | 
| 
      
 73 
     | 
    
         
            +
                def active_xcode_dir
         
     | 
| 
      
 74 
     | 
    
         
            +
                  @active_xcode_dir ||= lambda {
         
     | 
| 
      
 75 
     | 
    
         
            +
                    env = Luffa::Environment.developer_dir
         
     | 
| 
      
 76 
     | 
    
         
            +
                    if env
         
     | 
| 
      
 77 
     | 
    
         
            +
                      env
         
     | 
| 
      
 78 
     | 
    
         
            +
                    else
         
     | 
| 
      
 79 
     | 
    
         
            +
                      # fall back to xcode-select
         
     | 
| 
      
 80 
     | 
    
         
            +
                      xcode_select_path
         
     | 
| 
      
 81 
     | 
    
         
            +
                    end
         
     | 
| 
      
 82 
     | 
    
         
            +
                  }.call
         
     | 
| 
      
 83 
     | 
    
         
            +
                end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                def xcode_select_path
         
     | 
| 
      
 86 
     | 
    
         
            +
                  @xcode_select_dir ||= `xcode-select --print-path`.strip
         
     | 
| 
      
 87 
     | 
    
         
            +
                end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                def active_xcode
         
     | 
| 
      
 90 
     | 
    
         
            +
                  @active_xcode ||= Luffa::XcodeInstall.new(active_xcode_dir)
         
     | 
| 
      
 91 
     | 
    
         
            +
                end
         
     | 
| 
      
 92 
     | 
    
         
            +
              end
         
     | 
| 
      
 93 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Luffa
         
     | 
| 
      
 2 
     | 
    
         
            +
              def self.log_unix_cmd(msg)
         
     | 
| 
      
 3 
     | 
    
         
            +
                puts "\033[36mEXEC: #{msg}\033[0m" if msg
         
     | 
| 
      
 4 
     | 
    
         
            +
              end
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              def self.log_pass(msg)
         
     | 
| 
      
 7 
     | 
    
         
            +
                puts "\033[32mPASS: #{msg}\033[0m" if msg
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              def self.log_warn(msg)
         
     | 
| 
      
 11 
     | 
    
         
            +
                puts "\033[34mWARN: #{msg}\033[0m"
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              def self.log_fail(msg)
         
     | 
| 
      
 15 
     | 
    
         
            +
                puts "\033[31mFAIL: #{msg}\033[0m" if msg
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              def self.log_info(msg)
         
     | 
| 
      
 19 
     | 
    
         
            +
                puts "\033[46mINFO: #{msg}\033[0m" if msg
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,16 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'awesome_print'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # monkey patch for AwesomePrint + objects that implement '=='
         
     | 
| 
      
 4 
     | 
    
         
            +
            module AwesomePrint
         
     | 
| 
      
 5 
     | 
    
         
            +
              class Formatter
         
     | 
| 
      
 6 
     | 
    
         
            +
                def awesome_self(object, type)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  if @options[:raw] && object.instance_variables.any?
         
     | 
| 
      
 8 
     | 
    
         
            +
                    awesome_object(object)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  elsif object.respond_to?(:to_hash)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    awesome_hash(object.to_hash)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  else
         
     | 
| 
      
 12 
     | 
    
         
            +
                    colorize(object.inspect.to_s, type)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Kernel
         
     | 
| 
      
 2 
     | 
    
         
            +
              def capture_stdout
         
     | 
| 
      
 3 
     | 
    
         
            +
                out = StringIO.new
         
     | 
| 
      
 4 
     | 
    
         
            +
                $stdout = out
         
     | 
| 
      
 5 
     | 
    
         
            +
                yield
         
     | 
| 
      
 6 
     | 
    
         
            +
                return out
         
     | 
| 
      
 7 
     | 
    
         
            +
              ensure
         
     | 
| 
      
 8 
     | 
    
         
            +
                $stdout = STDOUT
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              def capture_stderr
         
     | 
| 
      
 12 
     | 
    
         
            +
                out = StringIO.new
         
     | 
| 
      
 13 
     | 
    
         
            +
                $stderr = out
         
     | 
| 
      
 14 
     | 
    
         
            +
                yield
         
     | 
| 
      
 15 
     | 
    
         
            +
                return out
         
     | 
| 
      
 16 
     | 
    
         
            +
              ensure
         
     | 
| 
      
 17 
     | 
    
         
            +
                $stderr = STDERR
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/luffa/retry.rb
    ADDED
    
    
| 
         @@ -0,0 +1,43 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Luffa
         
     | 
| 
      
 2 
     | 
    
         
            +
              def self.unix_command(cmd, opts={})
         
     | 
| 
      
 3 
     | 
    
         
            +
                default_opts = {:pass_msg => nil,
         
     | 
| 
      
 4 
     | 
    
         
            +
                                :fail_msg => nil,
         
     | 
| 
      
 5 
     | 
    
         
            +
                                :exit_on_nonzero_status => true,
         
     | 
| 
      
 6 
     | 
    
         
            +
                                :env_vars => {},
         
     | 
| 
      
 7 
     | 
    
         
            +
                                :log_cmd => true,
         
     | 
| 
      
 8 
     | 
    
         
            +
                                :obscure_fields => []}
         
     | 
| 
      
 9 
     | 
    
         
            +
                merged_opts = default_opts.merge(opts)
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                obscure_fields = merged_opts[:obscure_fields]
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                if not obscure_fields.empty? and merged_opts[:log_cmd]
         
     | 
| 
      
 14 
     | 
    
         
            +
                  obscured = cmd.split(' ').map do |token|
         
     | 
| 
      
 15 
     | 
    
         
            +
                    if obscure_fields.include? token
         
     | 
| 
      
 16 
     | 
    
         
            +
                      "#{token[0,1]}***#{token[token.length-1,1]}"
         
     | 
| 
      
 17 
     | 
    
         
            +
                    else
         
     | 
| 
      
 18 
     | 
    
         
            +
                      token
         
     | 
| 
      
 19 
     | 
    
         
            +
                    end
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
                  Luffa.log_unix_cmd obscured.join(' ')
         
     | 
| 
      
 22 
     | 
    
         
            +
                elsif merged_opts[:log_cmd]
         
     | 
| 
      
 23 
     | 
    
         
            +
                  Luffa.log_unix_cmd cmd
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                exit_on_err = merged_opts[:exit_on_nonzero_status]
         
     | 
| 
      
 27 
     | 
    
         
            +
                unless exit_on_err
         
     | 
| 
      
 28 
     | 
    
         
            +
                  system 'set +e'
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                env_vars = merged_opts[:env_vars]
         
     | 
| 
      
 32 
     | 
    
         
            +
                res = system(env_vars, cmd)
         
     | 
| 
      
 33 
     | 
    
         
            +
                exit_code = $?.exitstatus
         
     | 
| 
      
 34 
     | 
    
         
            +
                if res
         
     | 
| 
      
 35 
     | 
    
         
            +
                  Luffa.log_pass merged_opts[:pass_msg]
         
     | 
| 
      
 36 
     | 
    
         
            +
                else
         
     | 
| 
      
 37 
     | 
    
         
            +
                  Luffa.log_fail merged_opts[:fail_msg]
         
     | 
| 
      
 38 
     | 
    
         
            +
                  exit exit_code if exit_on_err
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
                system 'set -e'
         
     | 
| 
      
 41 
     | 
    
         
            +
                exit_code
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,166 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Luffa
         
     | 
| 
      
 2 
     | 
    
         
            +
              VERSION = '1.0.0'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              # A model of a software release version that can be used to compare two versions.
         
     | 
| 
      
 5 
     | 
    
         
            +
              #
         
     | 
| 
      
 6 
     | 
    
         
            +
              # Calabash and RunLoop try very hard to comply with Semantic Versioning rules.
         
     | 
| 
      
 7 
     | 
    
         
            +
              # However, the semantic versioning spec is incompatible with RubyGem's patterns
         
     | 
| 
      
 8 
     | 
    
         
            +
              # for pre-release gems.
         
     | 
| 
      
 9 
     | 
    
         
            +
              #
         
     | 
| 
      
 10 
     | 
    
         
            +
              # > "But returning to the practical: No release version of SemVer is compatible with Rubygems." - _David Kellum_
         
     | 
| 
      
 11 
     | 
    
         
            +
              #
         
     | 
| 
      
 12 
     | 
    
         
            +
              # Calabash and RunLoop version numbers will be in the form `<major>.<minor>.<patch>[.pre<N>]`.
         
     | 
| 
      
 13 
     | 
    
         
            +
              #
         
     | 
| 
      
 14 
     | 
    
         
            +
              # @see http://semver.org/
         
     | 
| 
      
 15 
     | 
    
         
            +
              # @see http://gravitext.com/2012/07/22/versioning.html
         
     | 
| 
      
 16 
     | 
    
         
            +
              class Version
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                # @!attribute [rw] major
         
     | 
| 
      
 19 
     | 
    
         
            +
                #   @return [Integer] the major version
         
     | 
| 
      
 20 
     | 
    
         
            +
                attr_accessor :major
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                # @!attribute [rw] minor
         
     | 
| 
      
 23 
     | 
    
         
            +
                #   @return [Integer] the minor version
         
     | 
| 
      
 24 
     | 
    
         
            +
                attr_accessor :minor
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                # @!attribute [rw] patch
         
     | 
| 
      
 27 
     | 
    
         
            +
                #   @return [Integer] the patch version
         
     | 
| 
      
 28 
     | 
    
         
            +
                attr_accessor :patch
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                # @!attribute [rw] pre
         
     | 
| 
      
 31 
     | 
    
         
            +
                #   @return [Boolean] true if this is a pre-release version
         
     | 
| 
      
 32 
     | 
    
         
            +
                attr_accessor :pre
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                # @!attribute [rw] pre_version
         
     | 
| 
      
 35 
     | 
    
         
            +
                #   @return [Integer] if this is a pre-release version, returns the
         
     | 
| 
      
 36 
     | 
    
         
            +
                #     pre-release version; otherwise this is nil
         
     | 
| 
      
 37 
     | 
    
         
            +
                attr_accessor :pre_version
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                # Creates a new Version instance with all the attributes set.
         
     | 
| 
      
 40 
     | 
    
         
            +
                #
         
     | 
| 
      
 41 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 42 
     | 
    
         
            +
                #  version = Version.new(0.10.1)
         
     | 
| 
      
 43 
     | 
    
         
            +
                #  version.major       => 0
         
     | 
| 
      
 44 
     | 
    
         
            +
                #  version.minor       => 10
         
     | 
| 
      
 45 
     | 
    
         
            +
                #  version.patch       => 1
         
     | 
| 
      
 46 
     | 
    
         
            +
                #  version.pre         => false
         
     | 
| 
      
 47 
     | 
    
         
            +
                #  version.pre_release => nil
         
     | 
| 
      
 48 
     | 
    
         
            +
                #
         
     | 
| 
      
 49 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 50 
     | 
    
         
            +
                #  version = Version.new(1.6.3.pre5)
         
     | 
| 
      
 51 
     | 
    
         
            +
                #  version.major       => 1
         
     | 
| 
      
 52 
     | 
    
         
            +
                #  version.minor       => 6
         
     | 
| 
      
 53 
     | 
    
         
            +
                #  version.patch       => 3
         
     | 
| 
      
 54 
     | 
    
         
            +
                #  version.pre         => true
         
     | 
| 
      
 55 
     | 
    
         
            +
                #  version.pre_release => 5
         
     | 
| 
      
 56 
     | 
    
         
            +
                #
         
     | 
| 
      
 57 
     | 
    
         
            +
                # @param [String] version the version string to parse.
         
     | 
| 
      
 58 
     | 
    
         
            +
                # @raise [ArgumentError] if version is not in the form 5, 6.1, 7.1.2, 8.2.3.pre1
         
     | 
| 
      
 59 
     | 
    
         
            +
                def initialize(version)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  tokens = version.strip.split('.')
         
     | 
| 
      
 61 
     | 
    
         
            +
                  count = tokens.count
         
     | 
| 
      
 62 
     | 
    
         
            +
                  if tokens.empty?
         
     | 
| 
      
 63 
     | 
    
         
            +
                    raise ArgumentError, "expected '#{version}' to be like 5, 6.1, 7.1.2, 8.2.3.pre1"
         
     | 
| 
      
 64 
     | 
    
         
            +
                  end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                  if count < 4 and tokens.any? { |elm| elm =~ /\D/ }
         
     | 
| 
      
 67 
     | 
    
         
            +
                    raise ArgumentError, "expected '#{version}' to be like 5, 6.1, 7.1.2, 8.2.3.pre1"
         
     | 
| 
      
 68 
     | 
    
         
            +
                  end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                  if count == 4
         
     | 
| 
      
 71 
     | 
    
         
            +
                    @pre = tokens[3]
         
     | 
| 
      
 72 
     | 
    
         
            +
                    pre_tokens = @pre.scan(/\D+|\d+/)
         
     | 
| 
      
 73 
     | 
    
         
            +
                    @pre_version = pre_tokens[1].to_i if pre_tokens.count == 2
         
     | 
| 
      
 74 
     | 
    
         
            +
                  end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                  @major, @minor, @patch = version.split('.').map(&:to_i)
         
     | 
| 
      
 77 
     | 
    
         
            +
                end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                # Returns an string representation of this version.
         
     | 
| 
      
 80 
     | 
    
         
            +
                # @return [String] a string in the form `<major>.<minor>.<patch>[.pre<N>]`
         
     | 
| 
      
 81 
     | 
    
         
            +
                def to_s
         
     | 
| 
      
 82 
     | 
    
         
            +
                  str = [major, minor, patch].compact.join('.')
         
     | 
| 
      
 83 
     | 
    
         
            +
                  str = "#{str}.#{pre}" if pre
         
     | 
| 
      
 84 
     | 
    
         
            +
                  str
         
     | 
| 
      
 85 
     | 
    
         
            +
                end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                # Compare this version to another for equality.
         
     | 
| 
      
 88 
     | 
    
         
            +
                # @param [Version] other the version to compare against
         
     | 
| 
      
 89 
     | 
    
         
            +
                # @return [Boolean] true if this Version is the same as `other`
         
     | 
| 
      
 90 
     | 
    
         
            +
                def == (other)
         
     | 
| 
      
 91 
     | 
    
         
            +
                  Version.compare(self, other) == 0
         
     | 
| 
      
 92 
     | 
    
         
            +
                end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                # Compare this version to another for inequality.
         
     | 
| 
      
 95 
     | 
    
         
            +
                # @param [Version] other the version to compare against
         
     | 
| 
      
 96 
     | 
    
         
            +
                # @return [Boolean] true if this Version is not the same as `other`
         
     | 
| 
      
 97 
     | 
    
         
            +
                def != (other)
         
     | 
| 
      
 98 
     | 
    
         
            +
                  Version.compare(self, other) != 0
         
     | 
| 
      
 99 
     | 
    
         
            +
                end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                # Is this version less-than another version?
         
     | 
| 
      
 102 
     | 
    
         
            +
                # @param [Version] other the version to compare against
         
     | 
| 
      
 103 
     | 
    
         
            +
                # @return [Boolean] true if this Version is less-than `other`
         
     | 
| 
      
 104 
     | 
    
         
            +
                def < (other)
         
     | 
| 
      
 105 
     | 
    
         
            +
                  Version.compare(self, other) < 0
         
     | 
| 
      
 106 
     | 
    
         
            +
                end
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
                # Is this version greater-than another version?
         
     | 
| 
      
 109 
     | 
    
         
            +
                # @param [Version] other the version to compare against
         
     | 
| 
      
 110 
     | 
    
         
            +
                # @return [Boolean] true if this Version is greater-than `other`
         
     | 
| 
      
 111 
     | 
    
         
            +
                def > (other)
         
     | 
| 
      
 112 
     | 
    
         
            +
                  Version.compare(self, other) > 0
         
     | 
| 
      
 113 
     | 
    
         
            +
                end
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
                # Is this version less-than or equal to another version?
         
     | 
| 
      
 116 
     | 
    
         
            +
                # @param [Version] other the version to compare against
         
     | 
| 
      
 117 
     | 
    
         
            +
                # @return [Boolean] true if this Version is less-than or equal `other`
         
     | 
| 
      
 118 
     | 
    
         
            +
                def <= (other)
         
     | 
| 
      
 119 
     | 
    
         
            +
                  Version.compare(self, other) <= 0
         
     | 
| 
      
 120 
     | 
    
         
            +
                end
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                # Is this version greater-than or equal to another version?
         
     | 
| 
      
 123 
     | 
    
         
            +
                # @param [Version] other the version to compare against
         
     | 
| 
      
 124 
     | 
    
         
            +
                # @return [Boolean] true if this Version is greater-than or equal `other`
         
     | 
| 
      
 125 
     | 
    
         
            +
                def >= (other)
         
     | 
| 
      
 126 
     | 
    
         
            +
                  Version.compare(self, other) >= 0
         
     | 
| 
      
 127 
     | 
    
         
            +
                end
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
                # Compare version `a` to version `b`.
         
     | 
| 
      
 130 
     | 
    
         
            +
                #
         
     | 
| 
      
 131 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 132 
     | 
    
         
            +
                #   compare Version.new(0.10.0), Version.new(0.9.0)  =>  1
         
     | 
| 
      
 133 
     | 
    
         
            +
                #   compare Version.new(0.9.0),  Version.new(0.10.0) => -1
         
     | 
| 
      
 134 
     | 
    
         
            +
                #   compare Version.new(0.9.0),  Version.new(0.9.0)  =>  0
         
     | 
| 
      
 135 
     | 
    
         
            +
                #
         
     | 
| 
      
 136 
     | 
    
         
            +
                # @return [Integer] an integer `(-1, 1)`
         
     | 
| 
      
 137 
     | 
    
         
            +
                def self.compare(a, b)
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
                  if a.major != b.major
         
     | 
| 
      
 140 
     | 
    
         
            +
                    return a.major > b.major ? 1 : -1
         
     | 
| 
      
 141 
     | 
    
         
            +
                  end
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
                  if a.minor != b.minor
         
     | 
| 
      
 144 
     | 
    
         
            +
                    return a.minor.to_i  > b.minor.to_i ? 1 : -1
         
     | 
| 
      
 145 
     | 
    
         
            +
                  end
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                  if a.patch != b.patch
         
     | 
| 
      
 148 
     | 
    
         
            +
                    return a.patch.to_i > b.patch.to_i ? 1 : -1
         
     | 
| 
      
 149 
     | 
    
         
            +
                  end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                  return -1 if a.pre and (not a.pre_version) and b.pre_version
         
     | 
| 
      
 152 
     | 
    
         
            +
                  return 1 if a.pre_version and b.pre and (not b.pre_version)
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                  return -1 if a.pre and (not b.pre)
         
     | 
| 
      
 155 
     | 
    
         
            +
                  return 1 if (not a.pre) and b.pre
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
                  return -1 if a.pre_version and (not b.pre_version)
         
     | 
| 
      
 158 
     | 
    
         
            +
                  return 1 if (not a.pre_version) and b.pre_version
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
                  if a.pre_version != b.pre_version
         
     | 
| 
      
 161 
     | 
    
         
            +
                    return a.pre_version.to_i > b.pre_version.to_i ? 1 : -1
         
     | 
| 
      
 162 
     | 
    
         
            +
                  end
         
     | 
| 
      
 163 
     | 
    
         
            +
                  0
         
     | 
| 
      
 164 
     | 
    
         
            +
                end
         
     | 
| 
      
 165 
     | 
    
         
            +
              end
         
     | 
| 
      
 166 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,34 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            <?xml version="1.0" encoding="UTF-8"?>
         
     | 
| 
      
 2 
     | 
    
         
            +
            <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
         
     | 
| 
      
 3 
     | 
    
         
            +
            <plist version="1.0">
         
     | 
| 
      
 4 
     | 
    
         
            +
            <dict>
         
     | 
| 
      
 5 
     | 
    
         
            +
            	<key>allow-root</key>
         
     | 
| 
      
 6 
     | 
    
         
            +
            	<true/>
         
     | 
| 
      
 7 
     | 
    
         
            +
            	<key>authenticate-user</key>
         
     | 
| 
      
 8 
     | 
    
         
            +
            	<true/>
         
     | 
| 
      
 9 
     | 
    
         
            +
            	<key>class</key>
         
     | 
| 
      
 10 
     | 
    
         
            +
            	<string>user</string>
         
     | 
| 
      
 11 
     | 
    
         
            +
            	<key>comment</key>
         
     | 
| 
      
 12 
     | 
    
         
            +
            	<string>Rights for Instruments</string>
         
     | 
| 
      
 13 
     | 
    
         
            +
            	<key>created</key>
         
     | 
| 
      
 14 
     | 
    
         
            +
            	<real>409022991.255041</real>
         
     | 
| 
      
 15 
     | 
    
         
            +
            	<key>group</key>
         
     | 
| 
      
 16 
     | 
    
         
            +
            	<string>admin</string>
         
     | 
| 
      
 17 
     | 
    
         
            +
            	<key>identifier</key>
         
     | 
| 
      
 18 
     | 
    
         
            +
            	<string>com.apple.dt.instruments.dtsecurity.xpc</string>
         
     | 
| 
      
 19 
     | 
    
         
            +
            	<key>modified</key>
         
     | 
| 
      
 20 
     | 
    
         
            +
            	<real>409022991.255041</real>
         
     | 
| 
      
 21 
     | 
    
         
            +
            	<key>requirement</key>
         
     | 
| 
      
 22 
     | 
    
         
            +
            	<string>identifier "com.apple.dt.instruments.dtsecurity.xpc" and anchor apple</string>
         
     | 
| 
      
 23 
     | 
    
         
            +
            	<key>session-owner</key>
         
     | 
| 
      
 24 
     | 
    
         
            +
            	<false/>
         
     | 
| 
      
 25 
     | 
    
         
            +
            	<key>shared</key>
         
     | 
| 
      
 26 
     | 
    
         
            +
            	<true/>
         
     | 
| 
      
 27 
     | 
    
         
            +
            	<key>timeout</key>
         
     | 
| 
      
 28 
     | 
    
         
            +
            	<integer>36000</integer>
         
     | 
| 
      
 29 
     | 
    
         
            +
            	<key>tries</key>
         
     | 
| 
      
 30 
     | 
    
         
            +
            	<integer>10000</integer>
         
     | 
| 
      
 31 
     | 
    
         
            +
            	<key>version</key>
         
     | 
| 
      
 32 
     | 
    
         
            +
            	<integer>0</integer>
         
     | 
| 
      
 33 
     | 
    
         
            +
            </dict>
         
     | 
| 
      
 34 
     | 
    
         
            +
            </plist>
         
     |