Class: TT::CExtensionManager
- Inherits:
-
Object
- Object
- TT::CExtensionManager
- Defined in:
- TT_Lib2/c_extension_manager.rb
Overview
Loads the appropriate C Extension loader after ensuring the appropriate version has been copied from the staging area.
Constant Summary
- VERSION_PATTERN =
/\d+\.\d+\.\d+$/
Instance Method Summary collapse
-
#initialize(path, version) ⇒ CExtensionManager
constructor
The `path` argument should point to the path where a 'stage' folder is located with the following folder structure:.
-
#prepare_path ⇒ String
Copies the necessary C Extension libraries to a version dependent folder from where they can be loaded.
- #print_log ⇒ Object
- #to_s ⇒ String (also: #inspect)
Constructor Details
#initialize(path, version) ⇒ CExtensionManager
The `path` argument should point to the path where a 'stage' folder is located with the following folder structure:
+ `path`
+-+ stage
+-+ 1.8
| +-+ HelloWorld.so
| + HelloWorld.bundle
+-+ 2.0
+-+ HelloWorld.so
+ HelloWorld.bundle
The appropriate file will be copied on demand to a folder structure like: `path`/<EXTENSION_VERSION>/<RUBY_VERSION>/HelloWorld.so
When a new version is deployed the files will be copied again from the staging area to a new folder named with the new extension version.
The old versions are cleaned up if possible. This attempt is done upon each time #prepare_path is called.
This way the C extensions can be updated because they are never loaded from the staging folder directly.
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'TT_Lib2/c_extension_manager.rb', line 44 def initialize( path, version ) # ENV, __FILE__, $LOAD_PATH, $LOADED_FEATURE and more might return an # encoding different from UTF-8. It's often ASCII-US or ASCII-8BIT. # If the developer has derived from these strings the encoding sticks with # it and will often lead to errors further down the road when trying to # load the files. To work around this the path is attempted to be # relabeled as UTF-8 if we can produce a valid UTF-8 string. # I'm forcing an encoding instead of converting because the encoding label # of the strings seem to be consistently mislabeled - the data is in # fact UTF-8. if path.respond_to?(:encoding) test_path = path.dup.force_encoding("UTF-8") path = test_path if test_path.valid_encoding? end unless version =~ VERSION_PATTERN raise ArgumentError, 'Version must be in "X.Y.Z" format' end unless File.directory?( path ) raise IOError, "Stage path not found: #{path}" end @version = version @path = path @stage = File.join( path, 'stage' ) @target = File.join( path, version ) @log = [] # See method comments for more info. #require_file_utils() end |
Instance Method Details
#prepare_path ⇒ String
Copies the necessary C Extension libraries to a version dependent folder from where they can be loaded. This will allow the SketchUp RBZ installer to update the extension without running into errors when trying to overwrite files from previous installation.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'TT_Lib2/c_extension_manager.rb', line 84 def prepare_path log("prepare_path") pointer_size = ['a'].pack('P').size * 8 # 32 or 64 ruby = RUBY_VERSION.split('.')[0..1].join('.') # Get Major.Minor string. platform = ( TT::System::PLATFORM_IS_OSX ) ? 'osx' : 'win' platform = "#{platform}#{pointer_size}" stage_path = File.join( @stage, ruby, platform ) target_path = File.join( @target, ruby, platform ) fallback = false log("> stage_path: #{stage_path}") log("> target_path: #{target_path}") begin # Copy files if target doesn't exist. unless File.directory?( stage_path ) raise IOError, 'Staging directory not found' end unless File.directory?( target_path ) log("MKDIR: #{target_path}") require_file_utils() # See method comments for more info. log(FileUtils.mkdir_p( target_path )) end stage_content = Dir.entries( stage_path ) target_content = Dir.entries( target_path ) log("> stage_content: #{stage_content}") log("> target_content: #{target_content}") unless (stage_content - target_content).empty? log("COPY: #{stage_path} => #{target_path}") require_file_utils() # See method comments for more info. log(FileUtils.copy_entry( stage_path, target_path )) end # Clean up old versions. version_pattern = /\d+\.\d+\.\d+$/ filter = File.join( @path, '*' ) log("> cleanup: #{filter}") Dir.glob( filter ).each { |entry| log(">>> entry: #{entry}") next unless File.directory?( entry ) log(">>> @target: #{@target} (#{entry.downcase == @target.downcase})") log(">>> @stage: #{@stage} (#{entry.downcase == @stage.downcase})") log(">>>>> @target vs entry") log(">>>>> #{entry.class.name}: #{entry.bytes}") if entry.respond_to?(:bytes) log(">>>>> #{@target.class.name}: #{@target.bytes}") if @target.respond_to?(:bytes) next if entry.downcase == @stage.downcase || entry.downcase == @target.downcase log(">>> match: #{entry =~ version_pattern}") next unless entry =~ version_pattern begin log("REMOVE: #{entry}") require_file_utils() # See method comments for more info. log(FileUtils.rm_r( entry )) rescue log_warn("#{TT::Lib::PLUGIN_NAME} - Unable to clean up: #{entry}") end } rescue Errno::EACCES if fallback UI.( "Failed to load #{TT::Lib::PLUGIN_NAME}. Missing permissions to " << "Plugins and temp folder." ) raise else # Even though the temp folder contains the username, it appear to be # returned in DOS 8.3 format which Ruby 1.8 can open. Fall back to # using the temp folder for these kind of systems. log_warn("#{TT::Lib::PLUGIN_NAME} - Unable to access: #{target_path}") temp_tt_lib_path = File.join( temp_path(), TT::Lib::PLUGIN_ID ) target_path = File.join( temp_tt_lib_path, @version, ruby, platform ) log_warn("#{TT::Lib::PLUGIN_NAME} - Falling back to: #{target_path}") fallback = true retry end end target_path end |
#print_log ⇒ Object
173 174 175 |
# File 'TT_Lib2/c_extension_manager.rb', line 173 def print_log puts @log.join("\n") end |
#to_s ⇒ String Also known as: inspect
166 167 168 169 |
# File 'TT_Lib2/c_extension_manager.rb', line 166 def to_s object_hex_id = "0x%x" % (self.object_id << 1) "<##{self.class}::#{object_hex_id}>" end |