class RunLoop::Xcode

A model of the active Xcode version.

@note All command line tools are run in the context of ‘xcrun`.

Throughout this class’s documentation, there are references to the _active version of Xcode_. The active Xcode version is the one returned by ‘xcrun xcodebuild`. The current Xcode version can be set using `xcode-select` or overridden using the `DEVELOPER_DIR`.

Attributes

xcode_versions[R]

Public Instance Methods

beta?() click to toggle source

Is this a beta version of Xcode?

@note Relies on Xcode beta versions having and app bundle named Xcode-Beta.app @return [Boolean] True if the Xcode version is beta.

# File lib/run_loop/xcode.rb, line 275
def beta?
  developer_dir[/Xcode-[Bb]eta.app/, 0]
end
core_simulator_dir() click to toggle source
# File lib/run_loop/xcode.rb, line 332
def core_simulator_dir
  if version_gte_110?
    core_simulator_dir = File.join(developer_dir,
                                  'Platforms', 'iPhoneOS.platform', 'Library',
                                  'Developer', 'CoreSimulator')
  else
    core_simulator_dir = File.join(developer_dir,
                                  'Platforms', 'iPhoneOS.platform', 'Developer',
                                  'Library', 'CoreSimulator')
  end
  File.expand_path(core_simulator_dir)
end
default_device() click to toggle source
# File lib/run_loop/xcode.rb, line 359
def default_device
  xcode_version = version

  # Xcode 13.
  if xcode_version.major == 13
    return "iPhone 13"
  end

  # Xcode 12.
  if xcode_version.major == 12 && xcode_version.minor >= 2
    return "iPhone 12"
  elsif xcode_version.major == 12 && xcode_version.minor < 2
    return "iPhone 11"
  end

  # Xcode 11.
  if xcode_version.major == 11
    return "iPhone 11"
  end

  # Xcode 10.
  if xcode_version.major == 10
    if xcode_version.minor >= 2
      return "iPhone Xs"
    else
      return "iPhone XS"
    end
  end

  # Xcode < 10.
  return "iPhone #{xcode_version.major - 1}"
end
developer_dir() click to toggle source
Returns the path to the current developer directory.

From the man pages:

```
$ man xcode-select
DEVELOPER_DIR
Overrides the active developer directory. When DEVELOPER_DIR is set,
its value will be used instead of the system-wide active developer
directory.

“‘

@return [String] path to current developer directory

@raise [RuntimeError] If path to Xcode.app/Contents/Developer
  cannot be determined.
# File lib/run_loop/xcode.rb, line 295
    def developer_dir
      @xcode_developer_dir ||= begin
        if RunLoop::Environment.developer_dir
          path = RunLoop::Environment.developer_dir
        else
          path = xcode_select_path
        end

        require 'pathname'
        path = Pathname.new(path).realpath.to_s

        if !File.directory?(path)
          raise RuntimeError,
%Q{Cannot determine the active Xcode.  Expected an Xcode here:

#{path}

Check the value of xcode-select:

# Does this resolve to a valid Xcode.app/Contents/Developer path?
$ xcode-select --print-path

Is the DEVELOPER_DIR variable set in your environment?  You would
only use this if you have multiple Xcode's installed.

$ echo $DEVELOPER_DIR

See the man pages for xcrun and xcode-select for details.

$ man xcrun
$ man xcode-select
}
        end
        path
      end
    end
inspect() click to toggle source

Returns debug String representation

# File lib/run_loop/xcode.rb, line 25
def inspect
  to_s
end
ios_version() click to toggle source
# File lib/run_loop/xcode.rb, line 345
def ios_version
  xcode_version = version
  sim_major = xcode_version.major + 2
  sim_minor = xcode_version.minor
  if xcode_version.major == 13
    sim_minor = 0
  end
  if xcode_version == v103
    sim_minor = 4
  end

  return RunLoop::Version.new("#{sim_major}.#{sim_minor}")
end
to_s() click to toggle source

Returns a String representation.

# File lib/run_loop/xcode.rb, line 20
def to_s
  "#<Xcode #{version.to_s}>"
end
v100() click to toggle source

Returns a version instance for Xcode 10.0; used to check for the availability of features and paths to various items on the filesystem

@return [RunLoop::Version] 10.0

# File lib/run_loop/xcode.rb, line 65
def v100
  fetch_version(:v100)
end
v102() click to toggle source

Returns a version instance for Xcode 10.2; used to check for the availability of features and paths to various items on the filesystem

@return [RunLoop::Version] 10.2

# File lib/run_loop/xcode.rb, line 57
def v102
  fetch_version(:v102)
end
v103() click to toggle source

Returns a version instance for Xcode 10.3; used to check for the availability of features and paths to various items on the filesystem

@return [RunLoop::Version] 10.3

# File lib/run_loop/xcode.rb, line 49
def v103
  fetch_version(:v103)
end
v110() click to toggle source

Returns a version instance for Xcode 11.0; used to check for the availability of features and paths to various items on the filesystem

@return [RunLoop::Version] 11.0

# File lib/run_loop/xcode.rb, line 41
def v110
  fetch_version(:v110)
end
v120() click to toggle source

Returns a version instance for Xcode 12.0; used to check for the availability of features and paths to various items on the filesystem

@return [RunLoop::Version] 12.0

# File lib/run_loop/xcode.rb, line 33
def v120
  fetch_version(:v120)
end
v80() click to toggle source

Returns a version instance for ‘Xcode 8.0`; used to check for the availability of features and paths to various items on the filesystem.

@return [RunLoop::Version] 8.0

# File lib/run_loop/xcode.rb, line 137
def v80
  fetch_version(:v80)
end
v81() click to toggle source

Returns a version instance for ‘Xcode 8.1`; used to check for the availability of features and paths to various items on the filesystem.

@return [RunLoop::Version] 8.1

# File lib/run_loop/xcode.rb, line 129
def v81
  fetch_version(:v81)
end
v82() click to toggle source

Returns a version instance for Xcode 8.2; used to check for the availability of features and paths to various items on the filesystem

@return [RunLoop::Version] 8.2

# File lib/run_loop/xcode.rb, line 121
def v82
  fetch_version(:v82)
end
v83() click to toggle source

Returns a version instance for Xcode 8.3; used to check for the availability of features and paths to various items on the filesystem

@return [RunLoop::Version] 8.3

# File lib/run_loop/xcode.rb, line 113
def v83
  fetch_version(:v83)
end
v90() click to toggle source

Returns a version instance for Xcode 9.0; used to check for the availability of features and paths to various items on the filesystem

@return [RunLoop::Version] 9.0

# File lib/run_loop/xcode.rb, line 105
def v90
  fetch_version(:v90)
end
v91() click to toggle source

Returns a version instance for Xcode 9.1; used to check for the availability of features and paths to various items on the filesystem

@return [RunLoop::Version] 9.1

# File lib/run_loop/xcode.rb, line 97
def v91
  fetch_version(:v91)
end
v92() click to toggle source

Returns a version instance for Xcode 9.2; used to check for the availability of features and paths to various items on the filesystem

@return [RunLoop::Version] 9.2

# File lib/run_loop/xcode.rb, line 89
def v92
  fetch_version(:v92)
end
v93() click to toggle source

Returns a version instance for Xcode 9.3; used to check for the availability of features and paths to various items on the filesystem

@return [RunLoop::Version] 9.3

# File lib/run_loop/xcode.rb, line 81
def v93
  fetch_version(:v93)
end
v94() click to toggle source

Returns a version instance for Xcode 9.4; used to check for the availability of features and paths to various items on the filesystem

@return [RunLoop::Version] 9.4

# File lib/run_loop/xcode.rb, line 73
def v94
  fetch_version(:v94)
end
version() click to toggle source

Returns the current version of Xcode.

@return [RunLoop::Version] The current version of Xcode as reported by

`xcrun xcodebuild -version`.
# File lib/run_loop/xcode.rb, line 243
    def version
      @xcode_version ||= begin
        if RunLoop::Environment.xtc?
          RunLoop::Version.new("0.0.0")
        else
          version = RunLoop::Version.new("0.0.0")
          begin
            args = ["xcrun", "xcodebuild", "-version"]
            hash = run_shell_command(args)
            if hash[:exit_status] != 0
              RunLoop.log_error("xcrun xcodebuild -version exited non-zero")
            else
              out = hash[:out]
              version_string = out.chomp[VERSION_REGEX, 0]
              version = RunLoop::Version.new(version_string)
            end
          rescue RuntimeError => e
            RunLoop.log_error(%Q[
Could not find Xcode version:

  #{e.class}: #{e.message}
])
          end
          version
        end
      end
    end
version_gte_100?() click to toggle source

Is the active Xcode version 10.0 or above?

@return [Boolean] ‘true` if the current Xcode version is >= 10.0

# File lib/run_loop/xcode.rb, line 172
def version_gte_100?
  version >= v100
end
version_gte_102?() click to toggle source

Is the active Xcode version 10.2 or above?

@return [Boolean] ‘true` if the current Xcode version is >= 10.2

# File lib/run_loop/xcode.rb, line 165
def version_gte_102?
  version >= v102
end
version_gte_103?() click to toggle source

Is the active Xcode version 10.3 or above?

@return [Boolean] ‘true` if the current Xcode version is >= 10.3

# File lib/run_loop/xcode.rb, line 158
def version_gte_103?
  version >= v103
end
version_gte_110?() click to toggle source

Is the active Xcode version 11.0 or above?

@return [Boolean] ‘true` if the current Xcode version is >= 11.0

# File lib/run_loop/xcode.rb, line 151
def version_gte_110?
  version >= v110
end
version_gte_120?() click to toggle source

Is the active Xcode version 12.0 or above?

@return [Boolean] ‘true` if the current Xcode version is >= 12.0

# File lib/run_loop/xcode.rb, line 144
def version_gte_120?
  version >= v120
end
version_gte_81?() click to toggle source

Is the active Xcode version 8.1 or above?

@return [Boolean] ‘true` if the current Xcode version is >= 8.1

# File lib/run_loop/xcode.rb, line 228
def version_gte_81?
  version >= v81
end
version_gte_82?() click to toggle source

Is the active Xcode version 8.2 or above?

@return [Boolean] ‘true` if the current Xcode version is >= 8.2

# File lib/run_loop/xcode.rb, line 221
def version_gte_82?
  version >= v82
end
version_gte_83?() click to toggle source

Is the active Xcode version 8.3 or above?

@return [Boolean] ‘true` if the current Xcode version is >= 8.3

# File lib/run_loop/xcode.rb, line 214
def version_gte_83?
  version >= v83
end
version_gte_8?() click to toggle source

Is the active Xcode version 8.0 or above?

@return [Boolean] ‘true` if the current Xcode version is >= 8.0

# File lib/run_loop/xcode.rb, line 235
def version_gte_8?
  version >= v80
end
version_gte_90?() click to toggle source

Is the active Xcode version 9.0 or above?

@return [Boolean] ‘true` if the current Xcode version is >= 9.0

# File lib/run_loop/xcode.rb, line 207
def version_gte_90?
  version >= v90
end
version_gte_91?() click to toggle source

Is the active Xcode version 9.1 or above?

@return [Boolean] ‘true` if the current Xcode version is >= 9.1

# File lib/run_loop/xcode.rb, line 200
def version_gte_91?
  version >= v91
end
version_gte_92?() click to toggle source

Is the active Xcode version 9.2 or above?

@return [Boolean] ‘true` if the current Xcode version is >= 9.2

# File lib/run_loop/xcode.rb, line 193
def version_gte_92?
  version >= v92
end
version_gte_93?() click to toggle source

Is the active Xcode version 9.3 or above?

@return [Boolean] ‘true` if the current Xcode version is >= 9.3

# File lib/run_loop/xcode.rb, line 186
def version_gte_93?
  version >= v93
end
version_gte_94?() click to toggle source

Is the active Xcode version 9.4 or above?

@return [Boolean] ‘true` if the current Xcode version is >= 9.4

# File lib/run_loop/xcode.rb, line 179
def version_gte_94?
  version >= v94
end

Private Instance Methods

ensure_valid_version_key(key) click to toggle source
# File lib/run_loop/xcode.rb, line 414
def ensure_valid_version_key(key)
  string = key.to_s

  if !string.start_with?("v")
    raise "Expected version key to start with 'v'"
  end

  if string.start_with?("v10") || string.start_with?("v11") || string.start_with?("v12")
    expected_length = 4
    regex = /v\d{3}/
  else
    expected_length = 3
    regex = /v\d{2}/
  end

  if string.length != expected_length
    raise "Expected version key '#{key}' to be exactly #{expected_length} chars long"
  end

  if !string[regex]
    raise "Expected version key '#{key}' to match this pattern: #{regex}"
  end
end
fetch_version(key) click to toggle source
# File lib/run_loop/xcode.rb, line 400
def fetch_version(key)
  ensure_valid_version_key key
  value = xcode_versions[key]

  return value if value

  string = key.to_s
  string[0] = ''
  version_string = string.split(/^(10|11)*|(?!^)/).reject(&:empty?).join('.')
  version = RunLoop::Version.new(version_string)
  xcode_versions[key] = version
  version
end
xcode_select_path() click to toggle source
# File lib/run_loop/xcode.rb, line 438
def xcode_select_path
  hash = run_shell_command(["xcode-select", "--print-path"], {log_cmd: true})
  hash[:out].chomp
end