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!