Le 12/4/2005, "Bob Aman" <vacindak / gmail.com> a ñÄrit: >> On Apr 8, 2005 10:37 PM, Kouhei Sutou <kou / cozmixng.org> wrote: >> > I don't have Windows box, so I can't help you about the >> > thing. But INSTALL file in Subversion repository may help >> > you: >> >> I'll give it a whirl, see what happens. > >From the INSTALL file: > > E.1 Prerequisites > > [snip requirements] > >Please tell me that I don't need to do all of that just to generate >the SWIG bindings for Windows... (mumble, grumble, why can't this be >automated more easily?) Hey, it is not that bad. See the snippet at the end that I wrote for a 'native' extension. The code is not all that great (I was mainly trying to get it to just work) but that Apache Portable Runtime is some truly horrible stuff. >I was looking through the pickaxe book and I saw that rubygems seems >to make allowance for precompiled gems... Can I make use of this? > >Ultimately, what I'd like to create is a simple ruby-svn gem that can >be installed anywhere with zero hassle. If it's possible, I'd like to >just include the external libraries for svn for each of the possible >platforms inside the gem or something like that. I don't want to rely >on the library's user actually having all of the required build tools >(especially for the windows platform). Is this possible? If so, how >hard is it, and what do I have to watch out for as far as pitfalls? >I'd prefer not to have to make seperate gems for each platform, is >that possible, given what I want to do? > >For that matter, how hard would it be to make a pure-ruby svn client >that conversed with svn only via http/apache? How bad of an idea is >this? > >Be aware, I've never tried to make a gem before. (Heck, I'm only just >getting started with ruby, so...) Someone is already working on a SVN extension to go with the RSCM project... I would suggest taking a look if you can help there instead? >-- >Bob Aman E ////////////////////// // rsvn.c //-- rsvn_client_ls / Method --// /* -- Lists the contents of a repo directory. */ VALUE rsvn_client_ls(VALUE self, VALUE path_or_url, VALUE revision, VALUE recurse) { rsvn_client_rep* clt; // The raw client info const char* encoded_uri; // URI-encoded path/URL svn_opt_revision_t revision_data; // SVN revision information apr_pool_t* pool; // Memory pool for this operation apr_pool_t* subpool; // Temporary pool for looping apr_hash_t* directory; // Hash for the file/dir names apr_hash_index_t* element; // A single element in the directory has const void* filename; // Hashed file/directory name void* file_entry; // File information svn_error_t* error; // Any received errors VALUE directory; // The directory structure // Initializations // Get the raw data for the client Data_Get_Struct(self, rsvn_client_rep, clt); // Extract the revision information from the Ruby object _rsvn_revision_get_svn_revision(revision, &revision_data); // Subpool for safe looping pool = svn_pool_create(clt->memory_pool); subpool = svn_pool_create(pool); // Generate an encoded URI (spaces replaced etc.) // TODO: Can't seem to be able to access local reps on a Windows // machine. encoded_uri = svn_path_uri_encode(STR2CSTR(path_or_url), pool); // Implementation // Propagate to SVN error = svn_client_ls(&directory, // Directory entries encoded_uri, // Path to list &revision_data, // Revision to retrieve 0, // Recursion clt->context, // Context pool); if (error != 0) { // Throw an error <fix>Only prints the topmost error</fix> rb_raise(rsvn_eSVNError, "Ruby-SVN::rsvn_new_client (%s:%d): %s\n", error->file, error->line, error->message); } // Sort the retrieved file names // TODO: Remove completely? //files = svn_sort__hash(directory_hash, svn_sort_compare_items_as_paths, pool); // Create a directory to fill directory = rb_class_new_instance(0, 0, rsvn_cDirectory); // Fill it for (element = apr_hash_first(pool, directory); element != 0; element = apr_hash_next(element)) { // Extract the key (filename) and value (file info) // from the hash, ignore key length apr_hash_this(element, &filename, 0, &file_entry); // Add the file to the directory _rsvn_directory_add(directory, filename, file_entry); } // Release both pools svn_pool_destroy(pool); // The user will receive the directory return directory; } // ... //-- _rsvn_client_on_username_prompt / Callback --// /* -- Invoked if the authenticator needs to get the username interactively. */ svn_error_t* _rsvn_client_on_username_prompt(svn_auth_cred_username_t** credentials, void* client, const char* realm_string, svn_boolean_t may_save, apr_pool_t * pool) { VALUE self; // Calling Client object VALUE listener; // Event listener for this Client VALUE retval; // The retrieved values in a hash svn_auth_cred_username_t* cred = 0; // Collected credential data // Extract the variables, propagate error out if there's a problem SVN_TRY(_rsvn_client_get_listener(client, &self, &listener), "Ruby-SVN::rsvn_client_on_username_prompt: "); // Query the Listener for a username (may_save should be 0 or 1) retval = rb_funcall(listener, ID_PROMPT_USERNAME, 2, rb_str_new2(realm_string), INT2FIX(may_save)); // Verify the query succeeded if (retval == Qnil) { // Error and cancel return svn_error_createf(SVN_ERR_CANCELLED, 0, "Ruby-SVN::rsvn_client_on_username_prompt: No username from Listener."); } cred = apr_palloc(pool, sizeof(svn_auth_cred_username_t)); // Collect the data <todo>UTF conversion unnecessary?</todo> SVN_TRY(svn_utf_cstring_to_utf8(&cred->username, STR2CSTR(rb_funcall(retval, ID_GET_INDEX, 1, rb_str_new2("username"))), pool), "Ruby-SVN::rsvn_client_on_username_prompt: "); cred->may_save = FIX2INT(rb_funcall(retval, ID_GET_INDEX, 1, rb_str_new2("cache"))); // No errors, we're done *credentials = cred; return SVN_NO_ERROR; } // End -- No-one expects the Solaris POSIX implementation!