Laurent Sansonetti
lsans****@apple*****
Mon Apr 28 04:10:33 JST 2008
Hi Scott, Sorry for the late response. Your patch looks great. I have a few points, nevertheless. 1/ Automatically loading bridge support files in sub-frameworks is a good idea, but a better idea would be to extend the parser to automatically load bridge support files marked as dependencies (the depend_on element). I have a new parser that I'm currently using in MacRuby, which is basically the same parser RubyCocoa uses but extracted and improved. It does automatically load dependencies. I would like to integrate it in RC trunk as soon as I have time. However this might not happen soon, so in the interim (next release) your patch can be applied. 2/ Could you mark the functions as static, so that the symbols will not be exported? Thanks! Laurent On Apr 25, 2008, at 2:05 PM, Scott Thompson wrote: > Did I submit something the wrong way, or do we just need to peer > review the changes and refine them? > > Scott > > On Apr 25, 2008, at 2:38 PM, Eloy Duran <e.dur****@super*****> wrote: > >> Hi Scott, >> >> Laurent asked me if I could send your patch to the list because he >> has >> some thoughts >> and maybe others as well. So here it is (http://pasternak.superalloy.nl/pastes/335 >> ). >> >> Cheers, >> Eloy >> diff --git a/framework/src/objc/BridgeSupport.m b/framework/src/objc/ >> BridgeSupport.m >> index 13863b1..5b60665 100644 >> --- a/framework/src/objc/BridgeSupport.m >> +++ b/framework/src/objc/BridgeSupport.m >> @@ -26,6 +26,8 @@ >> #import "ocexception.h" >> #import "objc_compat.h" >> >> +#define BRIDGE_SUPPORT_NAME @"BridgeSupport" >> + >> static VALUE cOSXBoxed; >> static ID ivarEncodingID; >> >> @@ -2016,6 +2018,321 @@ osx_lookup_informal_protocol_method_type >> (VALUE rcv, VALUE sel, >> return method == NULL ? Qnil : rb_str_new2(method->encoding); >> } >> >> +NSString *_find_framework_in_directory(NSString *base_path, NSString >> *framework_name) >> +{ >> + // Given a base directory, search for a Frameworks folder and a >> PrivateFrameworks >> + // folder, If a framework with a given name can be found in that >> folder, return >> + // the path to the framework. If no such framework exists, then >> return nil. >> + >> + // Make sure that the framework_name has an extension, >> add .framework if not >> + if([[framework_name pathExtension] length] == 0) { >> + framework_name = [framework_name stringByAppendingPathExtension: >> @"framework"]; >> + } >> + >> + NSString *frameworks_test_path = [[base_path >> stringByAppendingPathComponent: @"Frameworks"] >> stringByAppendingPathComponent: framework_name]; >> + NSString *shared_frameworks_test_path = [[base_path >> stringByAppendingPathComponent: @"SharedFrameworks"] >> stringByAppendingPathComponent: framework_name]; >> + NSString *private_frameworks_test_path = [[base_path >> stringByAppendingPathComponent: @"PrivateFrameworks"] >> stringByAppendingPathComponent: framework_name]; >> + >> + NSString *retVal = nil; >> + BOOL isDirectory = false; >> + NSFileManager *fileManager = [NSFileManager defaultManager]; >> + >> + if(!([fileManager fileExistsAtPath: private_frameworks_test_path >> isDirectory: &isDirectory] && isDirectory)) { >> + >> + // The framework is not in private frameworks... try the public >> ones. >> + if(!([fileManager fileExistsAtPath: frameworks_test_path >> isDirectory: &isDirectory] && isDirectory)) { >> + // In documentation and on the lists, it looks like >> SharedFrameworks >> + // may be unused functionality in modern Mac OS X but we'll >> check it anyway >> + // for completeness >> + if(([fileManager fileExistsAtPath: shared_frameworks_test_path >> isDirectory: &isDirectory] && isDirectory)) { >> + retVal = shared_frameworks_test_path; >> + } >> + } else { >> + retVal = frameworks_test_path; >> + } >> + } else { >> + retVal = private_frameworks_test_path; >> + } >> + >> + return retVal; >> +} >> + >> +NSString * >> +_find_shortcut_load_path(NSString *path_hint) >> +{ >> + // The system recognizes some shortcuts to frameworks that are >> buried in >> + // other umbrella frameworks. This dictionary gives those >> shortcuts. >> + // >> + // Ideally external code would just load the umbrella frameworks, >> but this >> + // is retained for backward compatibility with existing code >> + NSDictionary *shortcuts = [NSDictionary >> dictionaryWithObjectsAndKeys: >> + @"/System/Library/Frameworks/ApplicationServices.framework/ >> Frameworks/CoreGraphics.framework", @"CoreGraphics", >> + @"/System/Library/Frameworks/Quartz.framework/Frameworks/ >> PDFKit.framework", @"PDFKit", >> + @"/System/Library/Frameworks/Quartz.framework/Frameworks/ >> QuartzComposer.framework", @"QuartzComposer", >> + @"/System/Library/Frameworks/Quartz.framework/Frameworks/ >> ImageKit.framework", @"ImageKit", >> + nil, nil]; >> + >> + return [shortcuts objectForKey: path_hint]; >> +} >> + >> +static NSString *nsstring_for_ruby_path(VALUE ruby_path) >> +{ >> + // Convert a ruby string into a NSString with a file system path. >> + Check_Type(ruby_path, T_STRING); >> + const char *path_cstr = RSTRING_PTR(ruby_path); >> + return [[NSFileManager defaultManager] >> stringWithFileSystemRepresentation: path_cstr >> + length: >> strlen(path_cstr)]; >> +} >> + >> +NSString * >> +_find_application_load_path(VALUE mOSX, NSString *path_hint) >> +{ >> + // When the init routines in RBRuntime.m are loading an >> appilcation, plugin >> + // or other bundle, they stuff the location of the frameworks and/ >> or >> + // shared frameworks directory of that bundle in the array-valued >> constant >> + // RUBYCOCOA_FRAMEWORK_PATHS in the Ruby environment. This >> routine >> searches >> + // those paths for a framework matching the given path hint. >> + NSString *framework_load_path = nil; >> + >> + // Make sure that the path_hint has an extension, add .framework >> if >> not >> + if([[path_hint pathExtension] length] == 0) { >> + path_hint = [path_hint stringByAppendingPathExtension: >> @"framework"]; >> + } >> + >> + RB_ID constant_name = rb_intern("RUBYCOCOA_FRAMEWORK_PATHS"); >> + if(rb_const_defined(mOSX, constant_name)) { >> + long index; >> + VALUE ruby_array = rb_const_get(mOSX, constant_name); >> + NSFileManager *fileManager = [NSFileManager defaultManager]; >> + >> + Check_Type(ruby_array, T_ARRAY); >> + for(index = 0; (nil == framework_load_path) && index < >> RARRAY_LEN(ruby_array); index++) >> + { >> + VALUE ruby_search_path = rb_ary_entry(ruby_array, index); >> + Check_Type(ruby_search_path, T_STRING); >> + >> + BOOL isDirectory = false; >> + NSString *search_path = nsstring_for_ruby_path >> (ruby_search_path); >> + NSString *framework_test_path = [search_path >> stringByAppendingPathComponent: path_hint]; >> + if([fileManager fileExistsAtPath: framework_test_path >> isDirectory: &isDirectory] && isDirectory) { >> + framework_load_path = framework_test_path; >> + } >> + } >> + } >> + >> + return framework_load_path; >> +} >> + >> +NSString * >> +_bundle_path_for_framework(VALUE mOSX, NSString *path_hint) >> +{ >> + NSString *framework_load_path = nil; // The result we are looking >> for. >> + >> + BOOL isDirectory = false; >> + if([path_hint isAbsolutePath] >> + && [[NSFileManager defaultManager] fileExistsAtPath: >> path_hint isDirectory: &isDirectory] >> + && isDirectory) >> + { >> + // If the path is an absolute path to a directory, then we >> assume >> its a >> + // framework and return it. >> + framework_load_path = path_hint; >> + } else { >> + // If the path hint is one of the shortcut paths, this will >> resolve the >> + // shortcut and return the proper path. >> + framework_load_path = _find_shortcut_load_path(path_hint); >> + >> + // If it's not found yet, consult the application load paths >> that >> + // are part of the Ruby environment. >> + if(nil == framework_load_path) { >> + framework_load_path = _find_application_load_path(mOSX, >> path_hint); >> + } >> + >> + // Still not found? Try the standard library locations >> + if(nil == framework_load_path) { >> + NSString *search_path = nil; >> + NSArray *paths_to_search = >> NSSearchPathForDirectoriesInDomains( NSLibraryDirectory, >> NSUserDomainMask | NSLocalDomainMask | NSSystemDomainMask, true); >> + NSEnumerator *enumerator = [paths_to_search objectEnumerator]; >> + while( (nil == framework_load_path) && nil != (search_path = >> [enumerator nextObject])) >> + { >> + framework_load_path = >> _find_framework_in_directory(search_path, path_hint); >> + } >> + } >> + >> + // If the framework still hasn't been found then we look inside >> the >> + // Developer tree for it. >> + if(nil == framework_load_path) >> + { >> + NSString *search_path = nil; >> + NSArray *paths_to_search = >> NSSearchPathForDirectoriesInDomains(NSDeveloperDirectory, >> NSUserDomainMask | NSLocalDomainMask | NSSystemDomainMask, YES); >> + NSEnumerator *enumerator = [paths_to_search objectEnumerator]; >> + while( (nil == framework_load_path) && nil != (search_path = >> [enumerator nextObject])) >> + { >> + framework_load_path = >> _find_framework_in_directory(search_path, path_hint); >> + } >> + } >> + } >> + >> + return framework_load_path; >> +} >> + >> +static VALUE >> +osx__bundle_path_for_framework(VALUE mOSX, VALUE ruby_path_hint) >> +{ >> + // This is a Ruby interface routine for >> _bundle_path_for_framework. >> + // It does little more than handle translation of the arguments >> and >> + // return values. >> + >> + VALUE retVal = Qnil; >> + >> + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; >> + NSString *path_hint = nsstring_for_ruby_path(ruby_path_hint); >> + NSString *bundle_path = _bundle_path_for_framework(mOSX, >> path_hint); >> + if(bundle_path) >> + { >> + const char *export_path = [bundle_path >> fileSystemRepresentation]; >> + retVal = rb_str_new2(export_path); >> + } >> + >> + [pool release]; >> + return retVal; >> +} >> + >> +// Forward declaration of _load_subframeworks for recursive calling >> +static void _load_subframeworks(VALUE mOSX, NSBundle >> *umbrella_framework); >> + >> +static VALUE _load_framework(VALUE mOSX, NSString >> *framework_load_path) >> +{ >> + VALUE retVal = Qfalse; >> + >> + // Load a given framework and import its bridge support symbols >> + const char *path_as_cstr = [framework_load_path >> fileSystemRepresentation]; >> + >> + NSBundle *framework_as_bundle = [NSBundle bundleWithPath: >> framework_load_path]; >> + if(nil != framework_as_bundle) >> + { >> + >> + // If the framework has already been loaded then >> require_framework returns false. >> + // But we go ahead and try to read the bridge support >> information. >> + if([framework_as_bundle isLoaded]) { >> + retVal = Qfalse; >> + } else { >> + // The framework was not loaded so try to load it. >> + NSError *error = nil; >> + if(![framework_as_bundle loadAndReturnError: &error]) >> + { >> + rb_raise(rb_eRuntimeError, "Framework at path `%s' could >> not be loaded: %s", >> + path_as_cstr, [[error description] UTF8String]); >> + } else { >> + retVal = Qtrue; >> + } >> + } >> + >> + rb_funcall(mOSX, rb_intern("load_bridge_support_signatures"), >> 1, rb_str_new2(path_as_cstr)); >> + >> + // Load the contents of subframeworks as well. >> + _load_subframeworks(mOSX, framework_as_bundle); >> + } else { >> + rb_raise(rb_eRuntimeError, "The directory at path `%s' is >> not a >> framework or could not be loaded", path_as_cstr); >> + } >> + >> + return retVal; >> +} >> + >> +static void _load_subframeworks_in_path(VALUE mOSX, NSString >> *base_path) >> +{ >> + // Given a base path that is assumed to be a folder, find all the >> framework >> + // items in that path and try to load them. This can end up >> recursively >> + // calling this routine. >> + NSError *file_error = nil; >> + >> + NSArray *items_in_base = [[NSFileManager defaultManager] >> contentsOfDirectoryAtPath: base_path error: &file_error]; >> + if( nil == file_error && nil != items_in_base) >> + { >> + NSString *path_to_load = nil; >> + NSEnumerator *file_enumerator = [items_in_base >> objectEnumerator]; >> + while(nil != (path_to_load = [file_enumerator nextObject])) >> + { >> + if([[path_to_load pathExtension] isEqualToString: >> @"framework"]) >> + { >> + _load_framework(mOSX, [base_path >> stringByAppendingPathComponent: path_to_load]); >> + } >> + } >> + } >> +} >> + >> +static void _load_subframeworks(VALUE mOSX, NSBundle >> *umbrella_framework) >> +{ >> + // Load both the shared and private frameworks of the umbrella >> framework >> + // (if any) >> + _load_subframeworks_in_path(mOSX, [umbrella_framework >> privateFrameworksPath]); >> + _load_subframeworks_in_path(mOSX, [umbrella_framework >> sharedFrameworksPath]); >> +} >> + >> +static VALUE >> +osx_require_framework(VALUE mOSX, VALUE ruby_path_hint) >> +{ >> + VALUE retVal = Qfalse; >> + >> + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; >> + >> + // Try to find the path to a framework given the hint. If one is >> found >> + // try to load it. >> + NSString *path_hint = nsstring_for_ruby_path(ruby_path_hint); >> + NSString *framework_load_path = _bundle_path_for_framework(mOSX, >> path_hint); >> + if(framework_load_path) >> + { >> + retVal = _load_framework(mOSX, framework_load_path); >> + } else { >> + [pool release]; >> + pool = nil; >> + >> + // Note, this raises an ArgumntError to be consistent with the >> previous RubyCocoa code, however >> + // in MacRuby the code that performs this same function raises a >> RuntimeError. >> + rb_raise(rb_eArgError, "framework `%s' could not be found", >> RSTRING_PTR(ruby_path_hint)); >> + } >> + >> + [pool release]; >> + return retVal; >> +} >> + >> +static VALUE >> +osx_get_bridgesupport_search_paths(VALUE mOSX) >> +{ >> + VALUE pathsArray = rb_ary_new(); >> + >> + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; >> + >> + // Get the list of the usual domain search paths and append >> BridgeSupport to >> + // them construct a ruby array along the way. These paths will be >> used by the >> + // Ruby side of things to locate bridge support files. >> + NSArray *searchPaths = >> NSSearchPathForDirectoriesInDomains( NSLibraryDirectory, >> NSUserDomainMask | NSLocalDomainMask | NSSystemDomainMask, true); >> + NSEnumerator *enumerator = [searchPaths objectEnumerator]; >> + NSString *pathToAdd; >> + >> + while(nil != (pathToAdd = [enumerator nextObject])) >> + { >> + NSString *completePath = [pathToAdd >> stringByAppendingPathComponent: BRIDGE_SUPPORT_NAME]; >> + rb_ary_push(pathsArray, rb_str_new2([completePath >> fileSystemRepresentation])); >> + } >> + >> + // When the initialization routines in RBRuntime.m initialize >> RubyCocoa for >> + // an applicaiton, or other type of bundle, they put the >> application's private >> + // bridge support directories in a Ruby constant named >> RUBYCOCOA_SIGN_PATHS. >> + // We prefix the system search paths in the pathsArray with the >> values from >> + // RUBYCOCOA_SIGN_PATHS if it is defined. >> + RB_ID constant_name = rb_intern("RUBYCOCOA_SIGN_PATHS"); >> + if(rb_const_defined(mOSX, constant_name)) { >> + VALUE app_paths_array = rb_const_get(mOSX, constant_name); >> + Check_Type(app_paths_array, T_ARRAY); >> + >> + pathsArray = rb_ary_plus(pathsArray, app_paths_array); >> + } >> + >> + [pool release]; >> + >> + return pathsArray; >> +} >> + >> void >> initialize_bridge_support (VALUE mOSX) >> { >> @@ -2047,4 +2364,13 @@ initialize_bridge_support (VALUE mOSX) >> >> rb_define_module_function(mOSX, >> "lookup_informal_protocol_method_type", >> osx_lookup_informal_protocol_method_type, 2); >> + >> + rb_define_module_function(mOSX, "require_framework", >> + osx_require_framework, 1); >> + >> + rb_define_module_function(mOSX, "get_bridgesupport_search_paths", >> + osx_get_bridgesupport_search_paths, 0); >> + >> + rb_define_module_function(mOSX, "_bundle_path_for_framework", >> + osx__bundle_path_for_framework, 1); >> } >> diff --git a/framework/src/ruby/osx/objc/oc_import.rb b/framework/ >> src/ >> ruby/osx/objc/oc_import.rb >> index 78229d1..cff1b71 100644 >> --- a/framework/src/ruby/osx/objc/oc_import.rb >> +++ b/framework/src/ruby/osx/objc/oc_import.rb >> @@ -8,94 +8,9 @@ >> require 'osx/objc/oc_wrapper' >> >> module OSX >> - >> - FRAMEWORK_PATHS = [ >> - '/System/Library/Frameworks', >> - '/Library/Frameworks' >> - ] >> - >> - SIGN_PATHS = [ >> - '/System/Library/BridgeSupport', >> - '/Library/BridgeSupport' >> - ] >> - >> - PRE_SIGN_PATHS = >> - if path = ENV['BRIDGE_SUPPORT_PATH'] >> - path.split(':') >> - else >> - [] >> - end >> - >> - FRAMEWORK_PATHS.concat(RUBYCOCOA_FRAMEWORK_PATHS) >> - >> - if path = ENV['HOME'] >> - FRAMEWORK_PATHS << File.join(ENV['HOME'], 'Library', >> 'Frameworks') >> - SIGN_PATHS << File.join(ENV['HOME'], 'Library', 'BridgeSupport') >> - end >> - >> - # A name-to-path cache for the frameworks we support that are >> buried into umbrella frameworks. >> - QUICK_FRAMEWORKS = { >> - 'CoreGraphics' => '/System/Library/Frameworks/ >> ApplicationServices.framework/Frameworks/CoreGraphics.framework', >> - 'PDFKit' => '/System/Library/Frameworks/Quartz.framework/ >> Frameworks/PDFKit.framework', >> - 'QuartzComposer' => '/System/Library/Frameworks/ >> Quartz.framework/ >> Frameworks/QuartzComposer.framework', >> - 'ImageKit' => '/System/Library/Frameworks/Quartz.framework/ >> Frameworks/ImageKit.framework' >> - } >> - >> - def _bundle_path_for_framework(framework) >> - if framework[0] == ?/ >> - [OSX::NSBundle.bundleWithPath(framework), framework] >> - elsif path = QUICK_FRAMEWORKS[framework] >> - [OSX::NSBundle.bundleWithPath(path), path] >> - else >> - path = FRAMEWORK_PATHS.map { |dir| >> - File.join(dir, "#{framework}.framework") >> - }.find { |path| >> - File.exist?(path) >> - } >> - if path >> - [OSX::NSBundle.bundleWithPath(path), path] >> - end >> - end >> - end >> - module_function :_bundle_path_for_framework >> - >> - # The OSX::require_framework method imports Mac OS X frameworks >> and >> uses the >> - # BridgeSupport metadata to add Ruby entry points for the >> framework's Classes, >> - # methods, and Constants into the OSX module. >> - # >> - # The framework parameter is a reference to the framework that >> should be >> - # imported. This may be a full path name to a particular >> framework, a shortcut, >> - # or a framework name. The shortcuts are the keys listed in the >> - # <tt>QUICK_FRAMEWORKS</tt> hash. >> - # >> - # If a framework name (with no path) is given, then the method >> searches a number >> - # of directories. Those directories (in search order) are: >> - # 1. /System/Library/Frameworks >> - # 2. /Library/Frameworks >> - # 3. Any directories in the RUBYCOCOA_FRAMEWORK_PATHS array, if >> defined >> - # 4. ENV['HOME']/Library/Frameworks, if the HOME environment >> variable is defined >> - # >> - # When using the search paths, the <tt>.framework</tt> file type >> extension should >> - # be omitted from the framework name passed to the method. >> - # >> - # If the method loads the framework successfully, it returns >> <tt>true</tt>. >> - # If the framework was already loaded the method returns >> <tt>false</ >> tt>. >> - # If the method is unable to locate, or unable to load the >> framework then it >> - # raises an <tt>ArgumentError</tt>. >> - def require_framework(framework) >> - return false if framework_loaded?(framework) >> - bundle, path = _bundle_path_for_framework(framework) >> - bundle.oc_load >> - if not bundle.isLoaded? then >> - raise ArgumentError, "Can't load framework '#{framework}'" >> - end >> - load_bridge_support_signatures(path) >> - return true >> - end >> - module_function :require_framework >> - >> def framework_loaded?(framework) >> - bundle, path = _bundle_path_for_framework(framework) >> + path = _bundle_path_for_framework(framework) >> + bundle = NSBundle.bundleWithPath(path); >> unless bundle.nil? >> loaded = bundle.isLoaded >> if loaded then >> @@ -135,35 +50,28 @@ module OSX >> module_function :__load_bridge_support_file__ >> >> def load_bridge_support_signatures(framework) >> - # First, look into the pre paths. >> - fname = framework[0] == ?/ ? File.basename(framework, >> '.framework') : framework >> - PRE_SIGN_PATHS.each { |dir| return true if >> __load_bridge_support_file__(dir, fname) } >> - >> - # A path to a framework, let's search for a BridgeSupport file >> inside the Resources folder. >> - if framework[0] == ?/ >> - path = File.join(framework, 'Resources', 'BridgeSupport') >> + # strip the framework path down to it's base file name. >> + fname = (framework[0] == ?/) ? File.basename(framework, >> '.framework') : framework >> + >> + # The environment variable BRIDGE_SUPPORT_PATH can contain a >> list >> of >> + # directories that should be searched for bridge support files >> before the >> + # standard loctions are examined. >> + bridge_support_env = ENV['BRIDGE_SUPPORT_PATH']; >> + bridge_support_paths = bridge_support_env ? >> bridge_support_env.split(':') : [] >> + bridge_support_paths.each { |dir| return true if >> __load_bridge_support_file__(dir, fname) } >> + >> + # search the framework itself to see if it has BridgeSupport in >> its >> + # resources area >> + path = _bundle_path_for_framework(framework); >> + if path && File.exist?(path) >> + path = File.join(path, 'Resources', 'BridgeSupport') >> return true if __load_bridge_support_file__(path, fname) >> - framework = fname >> - end >> - >> - # Let's try to localize the framework and see if it contains the >> metadata. >> - FRAMEWORK_PATHS.each do |dir| >> - path = File.join(dir, "#{framework}.framework") >> - if File.exist?(path) >> - path = File.join(path, 'Resources', 'BridgeSupport') >> - return true if __load_bridge_support_file__(path, fname) >> - end >> - end >> - >> - # Try the app/bundle specific and RubyCocoa.framework metadata >> directories. >> - RUBYCOCOA_SIGN_PATHS.each do |path| >> - if File.exist?(path) then >> - return true if __load_bridge_support_file__(path, fname) >> - end >> end >> >> - # We can still look into the general metadata directories. >> - SIGN_PATHS.each { |dir| return true if >> __load_bridge_support_file__(dir, fname) } >> + # Get the bridge support folders in the currently loading >> bundle, >> as well >> + # as those in the file domain areas (~/Library/BridgeSupport, / >> Library/BridgeSupport >> + # /System/Library/BridgeSupport, etc). >> + get_bridgesupport_search_paths.each { |dir| return true if >> __load_bridge_support_file__(dir, fname) } >> >> # Damnit! >> warn "Can't find signatures file for #{framework}" if OSX._debug? >> >> >> On 19 apr 2008, at 05:11, Scott Thompson wrote: >>> My apologies for needing remedial hand-holding on this. I'm new to >>> git and it's got me a bit confused. >>> >>> I've made my changes in support of require_framework and I'd like to >>> submit them now. I'm afraid, however, that after reading a lot of >>> documentation on git, I'm not sure how to do that. >>> >>> I used "git" to clone down a copy of the source. Then I branched >>> the >>> code, made my changes in the branch, but I'm unsure how to proceed. >>> My git status says something like: >>> >>> # On branch rst_require_framework >>> # Changes to be committed: >>> # (use "git reset HEAD <file>..." to unstage) >>> # >>> # modified: framework/src/objc/BridgeSupport.m >>> # modified: framework/src/ruby/osx/objc/oc_import.rb >>> # >>> # Changed but not updated: >>> # (use "git add <file>..." to update what will be committed) >>> # >>> # modified: framework/RubyCocoa.xcodeproj/project.pbxproj >>> # >>> [snip -- untracked files left off for brevity] >>> >>> So the two files I've changed are there in my branch and I'm ready >>> to >>> commit them. What's not clear to me is how I make those changes >>> available to you guys so you can review them and put them in the >>> "real" repository. >>> >>> My understanding is that when I did the git clone, I got both a >>> repository and a working copy. If I commit it should change the >>> repository, but how do I forward those changes to the community at >>> large? >>> >>> Scott >>> >>> _______________________________________________ >>> Rubycocoa-devel mailing list >>> Rubyc****@lists***** >>> http://lists.sourceforge.jp/mailman/listinfo/rubycocoa-devel >> >> _______________________________________________ >> Rubycocoa-devel mailing list >> Rubyc****@lists***** >> http://lists.sourceforge.jp/mailman/listinfo/rubycocoa-devel > > _______________________________________________ > Rubycocoa-devel mailing list > Rubyc****@lists***** > http://lists.sourceforge.jp/mailman/listinfo/rubycocoa-devel