require 'repertoire/media' require 'repertoire/repository' require 'uri' module Repertoire class Repository # Path to the directory attr_reader :path # Media type of the directory attr_reader :media # # Creates a new Repository object with the specified _path_ and _media_ # type. If a _block_ is given, it will be passed the newly created # Repository object. # # Repository.new('path/to/repo',Media::SVN) # # Repository.new('path/to/svn_repo',Media::SVN) do |repo| # puts repo['**/'] # end # def initialize(path,media=nil,&block) @path = File.expand_path(path) begin @media = (media || Media.guess_from_path(@path)) rescue Media::UnknownMedia @media = nil end block.call(self) if block end # # Returns the +basename+ of the specified _uri_, unless the +basename+ is # +'trunk'+ then the +basename+ of the parent directory within the _uri_ # is returned. # # Repertoire.name('http://www.today.com/is/now') # # => "now" # # Repertoire.name('svn://svn.repo.com/var/svn/awesome/trunk') # # => "awesome" # def Repository.name(uri) uri = URI(uri.to_s) if uri.path.empty? path = File::SEPARATOR else path = File.expand_path(uri.path) end name = File.basename(path) if name == 'trunk' name = File.basename(File.dirname(path)) elsif name =~ /\.git$/ name.gsub!(/\.git$/,'') end if (name.empty? || name == File::SEPARATOR) name = uri.host end return name end # # Returns the name of the media used for the repository. If the media # could not be guessed, +nil+ will be returned. # def media_name return @media.name if @media return nil end # # Update the repository. # def update(uri=nil) if @media @media.update(uri) return true end return false end # # Delete the repository. # def delete Repertoire.delete(@path) end # # Similar to Dir.glob, except the media's directory is omitted # from the returned results. If a _block_ is given, it will be passed # each resulting path. # # repo = Repository.new('path/to/my_svn') # repo.glob('sub_path/.svn/*') # => [] # repo.glob('sub_path/**/') # => [...] # def glob(pattern,flags=0,&block) pattern = File.expand_path(File.join(@path,pattern)) paths = filter(Dir.glob(pattern,flags)) paths.each(&block) if block return paths end # # Returns +true+ if the directory contains the specified _sub_path_, # returns +false+ otherwise. # def has_path?(sub_path) !(glob(sub_path).empty?) end # # Returns an +Array+ of the files matching the _sub_path_ within the # directory. # def files(sub_path='*') glob(sub_path).select { |path| File.file?(path) } end # # Returns +true+ if there is a file with the _sub_path_ within the # directory, returns +false+ otherwise. # def has_file?(sub_path) !(files(sub_path).empty?) end # # Returns an +Array+ of the directories matching the _sub_path_ within # the directory. # def directories(sub_path='*') glob(sub_path).select { |path| File.directory?(path) } end # # Returns +true+ if there is a directory with the _sub_path_ within the # directory, returns +false+ otherwise. # def has_directory?(sub_path) !(directories(sub_path).empty?) end alias [] glob # # Returns the path of the directory in +String+ form. # def to_s @path.to_s end protected # # Filter the specified _paths_, removing any path that contains # the media's directory. # def filter(paths) return paths unless @media return paths.reject do |path| path.split(File::SEPARATOR).include?(@media.directory) end end end end