# Copyright (C) 2011 RightScale, Inc, All Rights Reserved Worldwide. # # THIS PROGRAM IS CONFIDENTIAL AND PROPRIETARY TO RIGHTSCALE # AND CONSTITUTES A VALUABLE TRADE SECRET. Any unauthorized use, # reproduction, modification, or disclosure of this program is # strictly prohibited. Any use of this program by an authorized # licensee is strictly subject to the terms and conditions, # including confidentiality obligations, set forth in the applicable # License Agreement between RightScale.com, Inc. and # the licensee require 'rbconfig' module RightConf class Platform include Singleton # Generic platform family # # === Return # family(Symbol):: One of :linux, :windows or :darwin def family @family ||= case RbConfig::CONFIG['host_os'] when /mswin|win32|dos|mingw|cygwin/i then :windows when /darwin/i then :darwin when /linux/i then :linux end end # Is current platform linux? # # === Return # true:: If current platform is linux # false:: Otherwise def linux? return family == :linux end # Is current platform darwin? # # === Return # true:: If current platform is darwin # false:: Otherwise def darwin? return family == :darwin end # Is current platform windows? # # === Return # true:: If current platform is Windows # false:: Otherwise def windows? return family == :windows end # Call platform specific implementation of method whose symbol is returned # by the passed in block. Arguments are passed through. # e.g. # # Platform.dispatch(2) { :echo } # # will result in 'echo_linux(2)' being executed in self if running on linux, # 'echo_windows(2)' if running on Windows and 'echo_darwin(2)' if on # Mac OS X. Note that the method is run in the instance of the caller. # # === Parameters # args:: Pass-through arguments # # === Block # Given block should not take any argument and return a symbol for the # method that should be called # # === Return # res(ObjecT):: Result returned by platform specific implementation def dispatch(*args, &blk) raise "Platform.dispatch requires a block" unless blk binding = blk.binding.eval('self') meth = blk.call target = dispatch_candidates(meth).detect do |candidate| binding.respond_to?(candidate) end raise "No platform dispatch target found in #{binding.class} for " + "'#{meth.inspect}', tried " + dispatch_candidates(meth).join(', ') unless target binding.__send__(target, *args) end protected # Load platform specific implementation def initialize require File.expand_path(File.join(File.dirname(__FILE__), 'platforms', family.to_s)) init end # Candidate platform specific methods for given prefix # Ordered by most platform specific to most generic # # === Parameters # prefix(String):: Method prefix # # === Return # candidates(Array):: List of potential candidates def dispatch_candidates(prefix) candidates = ["#{prefix}_#{family}_#{flavor}_#{release}", "#{prefix}_#{family}_#{flavor}", "#{prefix}_#{family}"] candidates.map(&:to_sym) end end end