Class Repository::SubversionRepository
In: lib/repo/subversion_repository.rb
Parent: Repository::AbstractRepository

Implements AbstractRepository for Subversion repositories It implements the following paradigm:

  1. Repositories are created by using SubversionRepository.create()
  2. Existing repositories are opened by using either SubversionRepository.open()
     or SubversionRepository.new()

Methods

Constants

CLOSEABLE_VERSION = "1.6.5"

Public Class methods

Semi-private class method: Parses a subversion authz file passed in as a string

[Source]

     # File lib/repo/subversion_repository.rb, line 552
552:   def self.__parse_authz_file(authz_string)
553:     permissions_mapping = {}
554: 
555:     permissions_array = authz_string.scan(/\[(.+):\/\]\n([\w\s=]+)/)
556:     permissions_array.each do |permissions_group|
557:       # The first match is the group repository name
558:       user_permissions = {}
559:       raw_users_permissions = permissions_group[1].scan(/\s*(\w+)\s*=\s*(\w+)\s*/)
560:       raw_users_permissions.each do |raw_user_permissions|
561:         user_permissions[raw_user_permissions[0]] = self.__translate_perms_from_file(raw_user_permissions[1])
562:       end
563:       permissions_mapping[permissions_group[0]] = user_permissions
564:     end
565:     return permissions_mapping
566:   end

Semi-private class method: Transforms passed in permissions into subversion authz file syntax

[Source]

     # File lib/repo/subversion_repository.rb, line 570
570:   def self.__prepare_authz_string(permissions)
571:     result = ""
572:     permissions.each do |repository_name, users_permissions|
573:       result += "[#{repository_name}:/]\n"
574:       users_permissions.each do |user_id, user_permissions|
575:         user_permissions_string = self.__translate_to_svn_perms(user_permissions)
576:         result += "#{user_id} = #{user_permissions_string}\n"
577:       end
578:       result += "\n"
579:     end
580:     return result
581:   end

Semi-private class method: Reads in Repository.conf[:REPOSITORY_PERMISSION_FILE]

[Source]

     # File lib/repo/subversion_repository.rb, line 506
506:   def self.__read_in_authz_file()
507:     # Check if configuration is in order
508:     if Repository.conf[:REPOSITORY_PERMISSION_FILE].nil?
509:       raise ConfigurationError.new("Required config 'REPOSITORY_PERMISSION_FILE' not set")
510:     end
511:     if !File.exist?(Repository.conf[:REPOSITORY_PERMISSION_FILE])
512:         File.open(Repository.conf[:REPOSITORY_PERMISSION_FILE], "w").close() # create file if not existent
513:     end
514:     # Load up the Permissions:
515:     file_content = ""
516:     File.open(Repository.conf[:REPOSITORY_PERMISSION_FILE], "r+") do |auth_file|
517:       auth_file.flock(File::LOCK_EX)
518:       file_content = auth_file.read()
519:       auth_file.flock(File::LOCK_UN) # release lock
520:     end
521:     return file_content
522:   end

Helper method to translate Subversion permissions to internal permissions

[Source]

     # File lib/repo/subversion_repository.rb, line 682
682:   def self.__translate_perms_from_file(perm_string)
683:     case (perm_string)
684:       when "r"
685:         return Repository::Permission::READ
686:       when "rw"
687:         return Repository::Permission::READ_WRITE
688:       else raise "Unknown permissions"
689:     end # end case
690:   end

Helper method to translate internal permissions to Subversion permissions

[Source]

     # File lib/repo/subversion_repository.rb, line 670
670:   def self.__translate_to_svn_perms(permissions)
671:     case (permissions)
672:       when Repository::Permission::READ
673:         return "r"
674:       when Repository::Permission::READ_WRITE
675:         return "rw"
676:       else raise "Unknown permissions"
677:     end # end case
678:   end

Semi-private class method: Writes out Repository.conf[:REPOSITORY_PERMISSION_FILE]

[Source]

     # File lib/repo/subversion_repository.rb, line 525
525:   def self.__write_out_authz_file(authz_file_contents)
526:     # Check if configuration is in order
527:     if Repository.conf[:IS_REPOSITORY_ADMIN].nil?
528:       raise ConfigurationError.new("Required config 'IS_REPOSITORY_ADMIN' not set")
529:     end
530:     if Repository.conf[:REPOSITORY_PERMISSION_FILE].nil?
531:       raise ConfigurationError.new("Required config 'REPOSITORY_PERMISSION_FILE' not set")
532:     end
533:     # If we're not in authoritative mode, bail out
534:     if !Repository.conf[:IS_REPOSITORY_ADMIN] # Are we admin?
535:       raise NotAuthorityError.new("Unable to write out repo permissions:  Not in authoritative mode!");
536:     end
537: 
538:     if !File.exist?(Repository.conf[:REPOSITORY_PERMISSION_FILE])
539:         File.open(Repository.conf[:REPOSITORY_PERMISSION_FILE], "w").close() # create file if not existent
540:     end
541:     result = false
542:     File.open(Repository.conf[:REPOSITORY_PERMISSION_FILE], "w+") do |auth_file|
543:       auth_file.flock(File::LOCK_EX)
544:       # Blast out the string to the file
545:       result = (auth_file.write(authz_file_contents) == authz_file_contents.length)
546:       auth_file.flock(File::LOCK_UN) # release lock
547:     end
548:     return result
549:   end

Static method: Yields an existing Subversion repository and closes it afterwards

[Source]

    # File lib/repo/subversion_repository.rb, line 88
88:   def self.access(connect_string)
89:     repository = self.open(connect_string)
90:     yield repository
91:     repository.close
92:   end

Static method: Returns whether or not the available Svn library supports closing

[Source]

     # File lib/repo/subversion_repository.rb, line 134
134:   def self.closeable?
135:     return Svn::Client.version.to_s >= CLOSEABLE_VERSION
136:   end

Static method: Creates a new Subversion repository at location ‘connect_string‘

[Source]

    # File lib/repo/subversion_repository.rb, line 62
62:   def self.create(connect_string)
63:     if SubversionRepository.repository_exists?(connect_string)
64:       raise RepositoryCollision.new("There is already a repository at #{connect_string}")
65:     end
66:     if File.exists?(connect_string)
67:       raise IOError.new("Could not create a repository at #{connect_string}: some directory with same name exists already")
68:     end
69: 
70:     # create the repository using the ruby bindings
71:     fs_config = {Svn::Fs::CONFIG_FS_TYPE => Repository::SVN_FS_TYPES[:fsfs]}
72:     repository = Svn::Repos.create(connect_string, {}, fs_config) #raises exception if not successful
73: 
74:     if SubversionRepository.closeable?
75:       repository.close
76:     end
77: 
78:     return true
79:   end

Static method: Deletes an existing Subversion repository

[Source]

    # File lib/repo/subversion_repository.rb, line 95
95:   def self.delete(repo_path)
96:     Svn::Repos::delete(repo_path)
97:   end

Deletes permissions over several repositories. Use remove_user to remove permissions of a single repository.

[Source]

     # File lib/repo/subversion_repository.rb, line 460
460:   def self.delete_bulk_permissions(repo_names, user_ids) 
461:     # Check if configuration is in order
462:     if Repository.conf[:IS_REPOSITORY_ADMIN].nil?
463:       raise ConfigurationError.new("Required config 'IS_REPOSITORY_ADMIN' not set")
464:     end
465:     # If we're not in authoritative mode, bail out
466:     if !Repository.conf[:IS_REPOSITORY_ADMIN] # Are we admin?
467:       raise NotAuthorityError.new("Unable to delete bulk permissions:  Not in authoritative mode!");
468:     end
469: 
470:     # Read in the authz file
471:     authz_file_contents = self.__read_in_authz_file()
472:        
473:     # Parse the file contents into to something we can work with
474:     repo_permissions = self.__parse_authz_file(authz_file_contents)
475:     
476:     # Delete the user_id for each repository
477:     repo_names.each do |repo_name|
478:       repo_name = File.basename(repo_name)
479:       user_ids.each do |user_id|
480:         repo_permissions[repo_name].delete(user_id)
481:       end
482:     end
483:     
484:     # Translate the hash into the svn authz file format
485:     authz_file_contents = self.__prepare_authz_string(repo_permissions)
486:     
487:     # Write out the authz file
488:     return self.__write_out_authz_file(authz_file_contents)
489:   end

Constructor: Connects to an existing Subversion repository, using Ruby bindings; Note: A repository has to be created using SubversionRepository.create(), it it is not yet existent

[Source]

    # File lib/repo/subversion_repository.rb, line 38
38:   def initialize(connect_string)
39:     # Check if configuration is in order
40:     if Repository.conf[:IS_REPOSITORY_ADMIN].nil?
41:       raise ConfigurationError.new("Required config 'IS_REPOSITORY_ADMIN' not set")
42:     end
43:     if Repository.conf[:REPOSITORY_PERMISSION_FILE].nil?
44:       raise ConfigurationError.new("Required config 'REPOSITORY_PERMISSION_FILE' not set")
45:     end
46:     begin
47:       super(connect_string) # dummy call to super
48:     rescue NotImplementedError; end
49:     @repos_path = connect_string
50:     @closed = false
51:     @repos_auth_file = Repository.conf[:REPOSITORY_PERMISSION_FILE] || File.dirname(connect_string) + "/svn_authz"
52:     @repos_admin = Repository.conf[:IS_REPOSITORY_ADMIN]
53:     if (SubversionRepository.repository_exists?(@repos_path))
54:       @repos = Svn::Repos.open(@repos_path)
55:     else
56:       raise "Repository does not exist at path \"" + @repos_path + "\""
57:     end
58:   end

Static method: Opens an existing Subversion repository at location ‘connect_string‘

[Source]

    # File lib/repo/subversion_repository.rb, line 83
83:   def self.open(connect_string)
84:     return SubversionRepository.new(connect_string)
85:   end

Static method: Reports if a Subversion repository exists It‘s in fact a pretty hacky method checking for files typical for Subversion repositories

[Source]

     # File lib/repo/subversion_repository.rb, line 158
158:   def self.repository_exists?(repos_path)
159:     repos_meta_files_exist = false
160:     if File.exist?(File.join(repos_path, "conf"))
161:       if File.exist?(File.join(repos_path, "conf/svnserve.conf"))
162:         if File.exist?(File.join(repos_path, "format"))
163:            repos_meta_files_exist = true
164:         end
165:       end
166:     end
167:     return repos_meta_files_exist
168:   end

Sets permissions over several repositories. Use set_permissions to set permissions on a single repository.

[Source]

     # File lib/repo/subversion_repository.rb, line 425
425:   def self.set_bulk_permissions(repo_names, user_id_permissions_map) 
426:     # Check if configuration is in order
427:     if Repository.conf[:IS_REPOSITORY_ADMIN].nil?
428:       raise ConfigurationError.new("Required config 'IS_REPOSITORY_ADMIN' not set")
429:     end
430:     # If we're not in authoritative mode, bail out
431:     if !Repository.conf[:IS_REPOSITORY_ADMIN] # Are we admin?
432:       raise NotAuthorityError.new("Unable to set bulk permissions:  Not in authoritative mode!");
433:     end
434: 
435:     # Read in the authz file
436:     authz_file_contents = self.__read_in_authz_file()
437:        
438:     # Parse the file contents into to something we can work with
439:     repo_permissions = self.__parse_authz_file(authz_file_contents)
440:     # Set / clobber permissions on each group for this user
441:     repo_names.each do |repo_name|
442:       repo_name = File.basename(repo_name)
443:       user_id_permissions_map.each do |user_id, permissions|
444:         if repo_permissions[repo_name].nil?
445:           repo_permissions[repo_name] = {}
446:         end
447:         repo_permissions[repo_name][user_id] = permissions
448:       end
449:     end
450: 
451:     # Translate the hash into the svn authz file format
452:     authz_file_contents = self.__prepare_authz_string(repo_permissions)
453:     
454:     # Write out the authz file
455:     return self.__write_out_authz_file(authz_file_contents)
456:   end

Public Instance methods

Not (!) part of the AbstractRepository API: Returns

   prop

of Subversion repository file

[Source]

     # File lib/repo/subversion_repository.rb, line 625
625:   def __get_file_property(prop, path, revision_number)
626:     return @repos.fs.root(revision_number).node_prop(path, Repository::SVN_CONSTANTS[prop])
627:   end

Not (!) part of the AbstractRepository API: Returns a hash of files/directories part of the requested revision; Don‘t use it directly, use SubversionRevision‘s ‘files_at_path’ instead

[Source]

     # File lib/repo/subversion_repository.rb, line 600
600:   def __get_files(path="/", revision_number=nil)
601:     begin
602:       entries = @repos.fs.root(revision_number).dir_entries(path)
603:     rescue Exception
604:       raise FileDoesNotExist.new("#{path} does not exist in the repository for revision #{revision_number}")
605:     end
606:     entries.each do |key, value|
607:       entries[key] = (value.kind == 1) ? :file : :directory
608:     end
609:     return entries
610:   end

Not (!) part of the AbstractRepository API: This function is very similar to @repos.fs.history(); however, it‘s been altered a little to return only an array of revision numbers. This function, in contrast to the original, takes multiple paths and returns one large history for all paths given.

[Source]

     # File lib/repo/subversion_repository.rb, line 642
642:   def __get_history(paths, starting_revision=nil, ending_revision=nil)
643:     # We do the to_i's because we want to leave the value nil if it is.
644:     if (starting_revision.to_i < 0)
645:       raise "Invalid starting revision " + starting_revision.to_i.to_s + "."
646:     end
647:     revision_numbers = []
648:     paths = [paths].flatten
649:     paths.each do |path|
650:       hist = []
651:       history_function = Proc.new do |path, revision|
652:         yield(path, revision) if block_given?
653:         hist << revision
654:       end
655:       begin
656:         Svn::Repos.history2(@repos.fs, path, history_function, nil, starting_revision || 0, 
657:                        ending_revision || @repos.fs.youngest_rev, true)
658:       rescue Svn::Error::FS_NOT_FOUND => e
659:         raise Repository::FileDoesNotExistConflict.new(path)
660:       rescue Svn::Error::FS_NO_SUCH_REVISION => e
661:         raise "Ending revision " + ending_revision.to_s + " does not exist."
662:       end               
663:       revision_numbers.concat hist
664:     end
665:     return revision_numbers.sort.uniq
666:   end

Not (!) part of the AbstractRepository API: Returns

   The last modified date

of a Subversion repository file or directory

[Source]

     # File lib/repo/subversion_repository.rb, line 634
634:   def __get_node_last_modified_date(path, revision_number)
635:     return @repos.fs.root(revision_number).stat(path).time2
636:   end

Not (!) part of the AbstractRepository API: Returns

   prop

of Subversion repository

[Source]

     # File lib/repo/subversion_repository.rb, line 616
616:   def __get_property(prop, rev=nil)
617:     return @repos.prop(Repository::SVN_CONSTANTS[prop] || prop.to_s, rev)  
618:   end

Not (!) part of the AbstractRepository API: Check if given file or path exists in repository beeing member of the provided revision

[Source]

     # File lib/repo/subversion_repository.rb, line 592
592:   def __path_exists?(path, revision=nil)
593:     return @repos.fs.root(revision).check_path(path) != 0
594:   end

Adds a user with given permissions to the repository

[Source]

     # File lib/repo/subversion_repository.rb, line 274
274:   def add_user(user_id, permissions)
275:     if @repos_admin # Are we admin?
276:       if !File.exist?(@repos_auth_file)
277:         File.open(@repos_auth_file, "w").close() # create file if not existent
278:       end
279:       
280:       retval = false
281:       repo_permissions = {}
282:       File.open(@repos_auth_file, "r+") do |auth_file|
283:         auth_file.flock(File::LOCK_EX)
284:         # get current permissions from file
285:         file_content = auth_file.read()
286:         if (file_content.length != 0)
287:           repo_permissions = get_repo_permissions_from_file_string(file_content)
288:         end
289:         if repo_permissions.key?(user_id)
290:           raise UserAlreadyExistent.new(user_id + " already existent")
291:         end
292:         svn_permissions = self.class.__translate_to_svn_perms(permissions)
293:         repo_permissions[user_id] = svn_permissions
294:         # inject new permissions into file string
295:         write_string = inject_permissions(repo_permissions, defined?(file_content)? file_content: "")
296:         # rewind, so that mime-type is preserved
297:         auth_file.rewind
298:         auth_file.truncate(0) # truncate file
299:         retval = (auth_file.write(write_string) == write_string.length)
300:         auth_file.flock(File::LOCK_UN) # release lock
301:       end
302:       return retval
303:     else
304:       raise NotAuthorityError.new("Unable to modify permissions: Not in authoritative mode!")
305:     end
306:   end

Closes the repository

[Source]

     # File lib/repo/subversion_repository.rb, line 139
139:   def close
140:     if self.class.closeable?
141:       @repos.close
142:     end
143:     @closed = true
144:   end

Returns whether or not repository is closed

[Source]

     # File lib/repo/subversion_repository.rb, line 147
147:   def closed?
148:     if self.class.closeable?
149:       return @repos.closed?
150:     end
151:     return @closed
152:   end

Carries out actions on a Subversion repository stored in ‘transaction’. In case of certain conflicts corresponding Repositor::Conflict(s) are added to the transaction object

[Source]

     # File lib/repo/subversion_repository.rb, line 233
233:   def commit(transaction)
234:     jobs = transaction.jobs
235:     txn = @repos.fs.transaction # transaction date is set implicitly
236:     txn.set_prop(Repository::SVN_CONSTANTS[:author], transaction.user_id)
237:     jobs.each do |job|
238:       case job[:action]
239:         when :add_path
240:           begin
241:             txn = make_directory(txn, job[:path])
242:           rescue Repository::Conflict => e
243:             transaction.add_conflict(e)
244:           end
245:         when :add
246:           begin
247:             txn = add_file(txn, job[:path], job[:file_data], job[:mime_type])
248:           rescue Repository::Conflict => e
249:             transaction.add_conflict(e)
250:           end
251:         when :remove
252:           begin
253:             txn = remove_file(txn, job[:path], job[:expected_revision_number])
254:           rescue Repository::Conflict => e
255:             transaction.add_conflict(e)
256:           end
257:         when :replace
258:           begin
259:             txn = replace_file(txn, job[:path], job[:file_data], job[:mime_type], job[:expected_revision_number])
260:           rescue Repository::Conflict => e
261:             transaction.add_conflict(e)
262:           end
263:       end
264:     end
265:     
266:     if transaction.conflicts?
267:       return false
268:     end
269:     txn.commit
270:     return true
271:   end
download_as_string(files)

Alias for stringify_files

Converts a pathname to an absolute pathname

[Source]

     # File lib/repo/subversion_repository.rb, line 492
492:   def expand_path(file_name, dir_string = "/")
493:     expanded = File.expand_path(file_name, dir_string) 
494:     if RUBY_PLATFORM =~ /(:?mswin|mingw)/ #only if the platform is Windows
495:       expanded = expanded[2..-1]#remove the drive letter
496:     end
497:     return expanded
498:   end

method : Export an existing Subversion repository to a new folder

[Source]

     # File lib/repo/subversion_repository.rb, line 100
100:   def export(repo_dest_dir, revision_number=nil)
101:     # Modify the path of the repository
102:     # If libsvn-ruby raise a segfault, check the first argument of
103:     # Svn::Client::export which must be an URI (ex : file:///home/...)
104: 
105:     repo_path_dir = "file://" + expand_path(@repos_path)
106:     ctx = Svn::Client::Context.new
107: 
108:     # don't fail on non CA signed ssl server
109:     ctx.add_ssl_server_trust_file_provider
110:     setup_auth_baton(ctx.auth_baton)
111:     ctx.add_username_provider
112: 
113:     # username and password
114:     ctx.add_simple_prompt_provider(0) do |cred, realm, username, may_save|
115:       cred.username = "markus"
116:       cred.password = "markus"
117:       cred.may_save = false
118:     end
119: 
120:     # Raise an error if the destination repository already exists
121:     if (File.exists?(repo_dest_dir))
122:       raise(ExportRepositoryAlreadyExists, "Exported repository already exists")
123:     end
124: 
125:     begin
126:       result = ctx.export( repo_path_dir, repo_dest_dir, revision_number, nil)
127:     end
128: 
129:     return result
130:   end

Returns a Repository::SubversionRevision instance holding the latest Subversion repository revision number

[Source]

     # File lib/repo/subversion_repository.rb, line 199
199:   def get_latest_revision
200:     return get_revision(latest_revision_number())
201:   end

Gets permissions of a particular user

[Source]

     # File lib/repo/subversion_repository.rb, line 336
336:   def get_permissions(user_id)
337:     if svn_auth_file_checks() # do basic file checks
338:       repo_permissions = {}
339:       File.open(@repos_auth_file) do |auth_file|
340: 
341:         auth_file.flock(File::LOCK_EX)
342:         file_content = auth_file.read()
343:         if (file_content.length != 0)
344:           repo_permissions = get_repo_permissions_from_file_string(file_content)
345:         end
346:         auth_file.flock(File::LOCK_UN) # release lock
347:       end
348:     if !repo_permissions.key?(user_id)
349:       raise UserNotFound.new(user_id + " not found")
350:     end
351:         return self.class.__translate_perms_from_file(repo_permissions[user_id])
352:     end
353:   end

Returns revision_number wrapped as a SubversionRevision instance

[Source]

     # File lib/repo/subversion_repository.rb, line 205
205:   def get_revision(revision_number)
206:     return Repository::SubversionRevision.new(revision_number, self)   
207:   end

Returns a SubversionRevision instance representing a revision at a current timestamp

   target_timestamp

should be a Ruby Time instance

[Source]

     # File lib/repo/subversion_repository.rb, line 213
213:   def get_revision_by_timestamp(target_timestamp)
214:     if !target_timestamp.kind_of?(Time)
215:       raise "Was expecting a timestamp of type Time"
216:     end
217:     target_timestamp = target_timestamp.utc
218:     return get_revision(get_revision_number_by_timestamp(target_timestamp))
219:   end

Returns a Repository::TransAction object, to work with. Do operations, like ‘add’, ‘remove’, etc. on the transaction instead of the repository

[Source]

     # File lib/repo/subversion_repository.rb, line 223
223:   def get_transaction(user_id, comment="")
224:     if user_id.nil?
225:       raise "Expected a user_id (Repository.get_transaction(user_id))"
226:     end
227:     return Repository::Transaction.new(user_id, comment)
228:   end

Gets a list of users with AT LEAST the provided permissions. Returns nil if there aren‘t any.

[Source]

     # File lib/repo/subversion_repository.rb, line 310
310:   def get_users(permissions)
311:     if svn_auth_file_checks() # do basic file checks
312:       repo_permissions = {}
313:       File.open(@repos_auth_file) do |auth_file|
314:         auth_file.flock(File::LOCK_EX)
315:         file_content = auth_file.read()
316:         if (file_content.length != 0)
317:           repo_permissions = get_repo_permissions_from_file_string(file_content)
318:         end
319:         auth_file.flock(File::LOCK_UN) # release lock
320:       end
321:       result_list = []
322:       repo_permissions.each do |user, perm|
323:         if self.class.__translate_perms_from_file(perm) >= permissions
324:           result_list.push(user)
325:         end
326:       end
327:       if !result_list.empty?
328:         return result_list
329:       else
330:         return nil
331:       end
332:     end
333:   end

Delete user from access list

[Source]

     # File lib/repo/subversion_repository.rb, line 391
391:   def remove_user(user_id)
392:     if @repos_admin # Are we admin?
393:       if !File.exist?(@repos_auth_file)
394:         File.open(@repos_auth_file, "w").close() # create file if not existent
395:       end
396:       
397:       retval = false
398:       File.open(@repos_auth_file, "r+") do |auth_file|
399:         auth_file.flock(File::LOCK_EX)
400:         # get current permissions from file
401:         file_content = auth_file.read()
402:         if (file_content.length != 0)
403:           repo_permissions = get_repo_permissions_from_file_string(file_content)
404:         end
405:         if !repo_permissions.key?(user_id)
406:           raise UserNotFound.new(user_id + " not found")
407:         end
408:         repo_permissions.delete(user_id) # delete user_id
409:         # inject new permissions into file string
410:         write_string = inject_permissions(repo_permissions, defined?(file_content)? file_content: "")
411:         # rewind, so that mime-type is preserved
412:         auth_file.rewind
413:         auth_file.truncate(0) # truncate file
414:         retval = (auth_file.write(write_string) == write_string.length)
415:         auth_file.flock(File::LOCK_UN) # release lock
416:       end
417:       return retval
418:     else
419:       raise NotAuthorityError.new("Unable to modify permissions: Not in authoritative mode!")
420:     end
421:   end

Set permissions for a given user

[Source]

     # File lib/repo/subversion_repository.rb, line 356
356:   def set_permissions(user_id, permissions)
357:     if @repos_admin # Are we admin?
358:       if !File.exist?(@repos_auth_file)
359:         File.open(@repos_auth_file, "w").close() # create file if not existent
360:       end
361:       
362:       retval = false
363:       repo_permissions = {}
364:       File.open(@repos_auth_file, "r+") do |auth_file|
365:         auth_file.flock(File::LOCK_EX)
366:         # get current permissions from file
367:         file_content = auth_file.read()
368:         if (file_content.length != 0)
369:           repo_permissions = get_repo_permissions_from_file_string(file_content)
370:         end
371:         if !repo_permissions.key?(user_id)
372:           raise UserNotFound.new(user_id + " not found")
373:         end
374:         svn_permissions = self.class.__translate_to_svn_perms(permissions)
375:         repo_permissions[user_id] = svn_permissions
376:         # inject new permissions into file string
377:         write_string = inject_permissions(repo_permissions, defined?(file_content)? file_content: "")
378:         # rewind, so that mime-type is preserved
379:         auth_file.rewind
380:         auth_file.truncate(0) # truncate file
381:         retval = (auth_file.write(write_string) == write_string.length)
382:         auth_file.flock(File::LOCK_UN) # release lock
383:       end
384:       return retval
385:     else
386:       raise NotAuthorityError.new("Unable to modify permissions: Not in authoritative mode!")
387:     end
388:   end

Given a single object, or an array of objects of type RevisionFile, try to find the file in question, and return it as a string

[Source]

     # File lib/repo/subversion_repository.rb, line 173
173:   def stringify_files(files)
174:     expects_array = files.kind_of? Array
175:     if (!expects_array)
176:       files = [files]  
177:     end
178:     files.collect! {|file|   
179:       if (!file.kind_of? Repository::RevisionFile)
180:         raise TypeError.new("Expected a Repository::RevisionFile")
181:       end 
182:       begin
183:         @repos.fs.root(file.from_revision).file_contents(File.join(file.path, file.name)){|f| f.read}
184:       rescue Svn::Error::FS_NOT_FOUND => e
185:         raise FileDoesNotExistConflict.new(File.join(file.path, file.name))
186:       end
187:     }
188:     if (!expects_array)
189:       return files.first
190:     else
191:       return files
192:     end  
193:   end

[Validate]