lib/tty/platform.rb
# frozen_string_literal: true
require 'rbconfig'
require_relative 'platform/version'
module TTY
# Detects system platform properties
#
# @api public
class Platform
WINDOWS_PATTERN = /(cygwin|mswin|mingw|bccwin|wince|emx)/i
UNIX_PATTERN = /(aix|arch|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
LINUX_PATTERN = /linux|arch/i
MAC_PATTERN = /darwin/i
# Returns processor name, e.g. 'amdk6'
#
# @api public
attr_reader :cpu
# Returns the system/OS name, e.g. 'darwin'
#
# @api public
attr_reader :os
# Returns system's release version, e.g. '10.8.1'
#
# @api public
attr_reader :version
# Create platform properties
#
# @api public
def initialize(arch = nil)
@cpu, @os, @version = *detect_system_properties(arch)
end
# Add operating system query methods
constants.grep(/PATTERN/).each do |pattern|
name = pattern.to_s.split('_').first.downcase
system_query = :"#{name}?"
define_method(system_query) do
match_os?(self.class.const_get(pattern))
end
self.class.class_eval do
define_method(system_query) do
new.public_send(system_query)
end
end
end
# Detect if using windows path delimiter
#
# @return [Boolean]
#
# @api public
def windows_file_path?
::File::ALT_SEPARATOR == '\\'
end
# Check if platform matches given systems
#
# @return [Boolean]
#
# @api public
def match_os?(matcher)
!!(@os =~ matcher)
end
# Queries for system architecture information
#
# @return [String]
#
# @api public
def architecture
RbConfig::CONFIG['arch']
end
# @return [Array[String]]
#
# @api public
def to_a
[@cpu, @os, @version]
end
# String representation
#
# @api public
def to_s
to_a.compact.join('-')
end
private
# Infer system properties from architecture information
#
# @return [Array[String, String String]]
#
# @api private
def detect_system_properties(arch)
parts = (arch || architecture).split('-', 2)
if parts.length == 1
@cpu, system = nil, parts.shift
else
@cpu, system = *parts
end
@os, @version = *find_os_and_version(system)
[@cpu, @os, @version]
end
# @param [String] system
#
# @api private
def find_os_and_version(system)
case system
when /aix(\d+(\.\d+)*)?/ then ['aix', $1]
when /bccwin(\d+(\.\d+)*)?/ then ['bccwin', $1]
when /bitrig(\d+(\.\d+)*)?/ then ['bitrig', $1]
when /cygwin/ then ['cygwin', nil]
when /darwin(\d+(\.\d+)*)?/ then ['darwin', $1]
when /emx/ then ['emx', nil]
when /freebsd(\d+(\.\d+)*)?/ then ['freebsd', $1]
when /linux(\d+(\.\d+)*)?/ then ['linux', $1]
when /mingw32/ then ['mingw32', nil]
when /(mswin\d+)((\_|-)(\d+))?/ then [$1, $4]
when /netbsdelf/ then ['netbsdelf', nil]
when /openbsd(\d+(\.\d+)*)?/ then ['openbsd', $1]
when /solaris(\d+(\.\d+)*)?/ then ['solaris', $1]
when /wince(\d+(\.\d+)*)?/ then ['wince', $1]
else ['unknown', nil]
end
end
end # Platform
end # TTY