File: app/models/repository/subversion.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  class: Repository
  class: Subversion#20
inherits from
  Repository   
has properties
class method: scm_adapter_class #25
class method: scm_name #29
method: supports_directory_revisions? #33
method: repo_log_encoding #37
method: latest_changesets / 3 #41
method: relative_path / 1 #47
method: fetch_changesets #51
method: relative_url #90

Class Hierarchy

Code

   1  # Redmine - project management software
   2  # Copyright (C) 2006-2011  Jean-Philippe Lang
   3  #
   4  # This program is free software; you can redistribute it and/or
   5  # modify it under the terms of the GNU General Public License
   6  # as published by the Free Software Foundation; either version 2
   7  # of the License, or (at your option) any later version.
   8  #
   9  # This program is distributed in the hope that it will be useful,
  10  # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  # GNU General Public License for more details.
  13  #
  14  # You should have received a copy of the GNU General Public License
  15  # along with this program; if not, write to the Free Software
  16  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  17 
  18  require 'redmine/scm/adapters/subversion_adapter'
  19 
  20  class Repository::Subversion < Repository
  21    attr_protected :root_url
  22    validates_presence_of :url
  23    validates_format_of :url, :with => /^(http|https|svn(\+[^\s:\/\\]+)?|file):\/\/.+/i
  24 
  25    def self.scm_adapter_class
  26      Redmine::Scm::Adapters::SubversionAdapter
  27    end
  28 
  29    def self.scm_name
  30      'Subversion'
  31    end
  32 
  33    def supports_directory_revisions?
  34      true
  35    end
  36 
  37    def repo_log_encoding
  38      'UTF-8'
  39    end
  40 
  41    def latest_changesets(path, rev, limit=10)
  42      revisions = scm.revisions(path, rev, nil, :limit => limit)
  43      revisions ? changesets.find_all_by_revision(revisions.collect(&:identifier), :order => "committed_on DESC", :include => :user) : []
  44    end
  45 
  46    # Returns a path relative to the url of the repository
  47    def relative_path(path)
  48      path.gsub(Regexp.new("^\/?#{Regexp.escape(relative_url)}"), '')
  49    end
  50 
  51    def fetch_changesets
  52      scm_info = scm.info
  53      if scm_info
  54        # latest revision found in database
  55        db_revision = latest_changeset ? latest_changeset.revision.to_i : 0
  56        # latest revision in the repository
  57        scm_revision = scm_info.lastrev.identifier.to_i
  58        if db_revision < scm_revision
  59          logger.debug "Fetching changesets for repository #{url}" if logger && logger.debug?
  60          identifier_from = db_revision + 1
  61          while (identifier_from <= scm_revision)
  62            # loads changesets by batches of 200
  63            identifier_to = [identifier_from + 199, scm_revision].min
  64            revisions = scm.revisions('', identifier_to, identifier_from, :with_paths => true)
  65            revisions.reverse_each do |revision|
  66              transaction do
  67                changeset = Changeset.create(:repository   => self,
  68                                             :revision     => revision.identifier,
  69                                             :committer    => revision.author,
  70                                             :committed_on => revision.time,
  71                                             :comments     => revision.message)
  72 
  73                revision.paths.each do |change|
  74                  changeset.create_change(change)
  75                end unless changeset.new_record?
  76              end
  77            end unless revisions.nil?
  78            identifier_from = identifier_to + 1
  79          end
  80        end
  81      end
  82    end
  83 
  84    private
  85 
  86    # Returns the relative url of the repository
  87    # Eg: root_url = file:///var/svn/foo
  88    #     url      = file:///var/svn/foo/bar
  89    #     => returns /bar
  90    def relative_url
  91      @relative_url ||= url.gsub(Regexp.new("^#{Regexp.escape(root_url || scm.root_url)}", Regexp::IGNORECASE), '')
  92    end
  93  end