annotate .svn/pristine/ca/caaf4adc236fed5cfdedcad59181499afa1fb97d.svn-base @ 1524:82fac3dcf466 redmine-2.5-integration

Fix failure to interpret Javascript when autocompleting members for project
author Chris Cannam <chris.cannam@soundsoftware.ac.uk>
date Thu, 11 Sep 2014 10:24:38 +0100
parents cbb26bc654de
children
rev   line source
Chris@909 1 # Redmine - project management software
Chris@909 2 # Copyright (C) 2006-2011 Jean-Philippe Lang
Chris@909 3 #
Chris@909 4 # This program is free software; you can redistribute it and/or
Chris@909 5 # modify it under the terms of the GNU General Public License
Chris@909 6 # as published by the Free Software Foundation; either version 2
Chris@909 7 # of the License, or (at your option) any later version.
Chris@909 8 #
Chris@909 9 # This program is distributed in the hope that it will be useful,
Chris@909 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@909 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@909 12 # GNU General Public License for more details.
Chris@909 13 #
Chris@909 14 # You should have received a copy of the GNU General Public License
Chris@909 15 # along with this program; if not, write to the Free Software
Chris@909 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Chris@909 17
Chris@909 18 require 'redmine/scm/adapters/cvs_adapter'
Chris@909 19 require 'digest/sha1'
Chris@909 20
Chris@909 21 class Repository::Cvs < Repository
Chris@909 22 validates_presence_of :url, :root_url, :log_encoding
Chris@909 23
Chris@909 24 def self.human_attribute_name(attribute_key_name)
Chris@909 25 attr_name = attribute_key_name
Chris@909 26 if attr_name == "root_url"
Chris@909 27 attr_name = "cvsroot"
Chris@909 28 elsif attr_name == "url"
Chris@909 29 attr_name = "cvs_module"
Chris@909 30 end
Chris@909 31 super(attr_name)
Chris@909 32 end
Chris@909 33
Chris@909 34 def self.scm_adapter_class
Chris@909 35 Redmine::Scm::Adapters::CvsAdapter
Chris@909 36 end
Chris@909 37
Chris@909 38 def self.scm_name
Chris@909 39 'CVS'
Chris@909 40 end
Chris@909 41
Chris@909 42 def entry(path=nil, identifier=nil)
Chris@909 43 rev = identifier.nil? ? nil : changesets.find_by_revision(identifier)
Chris@909 44 scm.entry(path, rev.nil? ? nil : rev.committed_on)
Chris@909 45 end
Chris@909 46
Chris@909 47 def entries(path=nil, identifier=nil)
Chris@909 48 rev = nil
Chris@909 49 if ! identifier.nil?
Chris@909 50 rev = changesets.find_by_revision(identifier)
Chris@909 51 return nil if rev.nil?
Chris@909 52 end
Chris@909 53 entries = scm.entries(path, rev.nil? ? nil : rev.committed_on)
Chris@909 54 if entries
Chris@909 55 entries.each() do |entry|
Chris@909 56 if ( ! entry.lastrev.nil? ) && ( ! entry.lastrev.revision.nil? )
Chris@909 57 change=changes.find_by_revision_and_path(
Chris@909 58 entry.lastrev.revision,
Chris@909 59 scm.with_leading_slash(entry.path) )
Chris@909 60 if change
Chris@909 61 entry.lastrev.identifier = change.changeset.revision
Chris@909 62 entry.lastrev.revision = change.changeset.revision
Chris@909 63 entry.lastrev.author = change.changeset.committer
Chris@909 64 # entry.lastrev.branch = change.branch
Chris@909 65 end
Chris@909 66 end
Chris@909 67 end
Chris@909 68 end
Chris@909 69 entries
Chris@909 70 end
Chris@909 71
Chris@909 72 def cat(path, identifier=nil)
Chris@909 73 rev = nil
Chris@909 74 if ! identifier.nil?
Chris@909 75 rev = changesets.find_by_revision(identifier)
Chris@909 76 return nil if rev.nil?
Chris@909 77 end
Chris@909 78 scm.cat(path, rev.nil? ? nil : rev.committed_on)
Chris@909 79 end
Chris@909 80
Chris@909 81 def annotate(path, identifier=nil)
Chris@909 82 rev = nil
Chris@909 83 if ! identifier.nil?
Chris@909 84 rev = changesets.find_by_revision(identifier)
Chris@909 85 return nil if rev.nil?
Chris@909 86 end
Chris@909 87 scm.annotate(path, rev.nil? ? nil : rev.committed_on)
Chris@909 88 end
Chris@909 89
Chris@909 90 def diff(path, rev, rev_to)
Chris@909 91 # convert rev to revision. CVS can't handle changesets here
Chris@909 92 diff=[]
Chris@909 93 changeset_from = changesets.find_by_revision(rev)
Chris@909 94 if rev_to.to_i > 0
Chris@909 95 changeset_to = changesets.find_by_revision(rev_to)
Chris@909 96 end
Chris@909 97 changeset_from.changes.each() do |change_from|
Chris@909 98 revision_from = nil
Chris@909 99 revision_to = nil
Chris@909 100 if path.nil? || (change_from.path.starts_with? scm.with_leading_slash(path))
Chris@909 101 revision_from = change_from.revision
Chris@909 102 end
Chris@909 103 if revision_from
Chris@909 104 if changeset_to
Chris@909 105 changeset_to.changes.each() do |change_to|
Chris@909 106 revision_to = change_to.revision if change_to.path == change_from.path
Chris@909 107 end
Chris@909 108 end
Chris@909 109 unless revision_to
Chris@909 110 revision_to = scm.get_previous_revision(revision_from)
Chris@909 111 end
Chris@909 112 file_diff = scm.diff(change_from.path, revision_from, revision_to)
Chris@909 113 diff = diff + file_diff unless file_diff.nil?
Chris@909 114 end
Chris@909 115 end
Chris@909 116 return diff
Chris@909 117 end
Chris@909 118
Chris@909 119 def fetch_changesets
Chris@909 120 # some nifty bits to introduce a commit-id with cvs
Chris@909 121 # natively cvs doesn't provide any kind of changesets,
Chris@909 122 # there is only a revision per file.
Chris@909 123 # we now take a guess using the author, the commitlog and the commit-date.
Chris@909 124
Chris@909 125 # last one is the next step to take. the commit-date is not equal for all
Chris@909 126 # commits in one changeset. cvs update the commit-date when the *,v file was touched. so
Chris@909 127 # we use a small delta here, to merge all changes belonging to _one_ changeset
Chris@909 128 time_delta = 10.seconds
Chris@909 129 fetch_since = latest_changeset ? latest_changeset.committed_on : nil
Chris@909 130 transaction do
Chris@909 131 tmp_rev_num = 1
Chris@909 132 scm.revisions('', fetch_since, nil, :log_encoding => repo_log_encoding) do |revision|
Chris@909 133 # only add the change to the database, if it doen't exists. the cvs log
Chris@909 134 # is not exclusive at all.
Chris@909 135 tmp_time = revision.time.clone
Chris@909 136 unless changes.find_by_path_and_revision(
Chris@909 137 scm.with_leading_slash(revision.paths[0][:path]),
Chris@909 138 revision.paths[0][:revision]
Chris@909 139 )
Chris@909 140 cmt = Changeset.normalize_comments(revision.message, repo_log_encoding)
Chris@909 141 author_utf8 = Changeset.to_utf8(revision.author, repo_log_encoding)
Chris@909 142 cs = changesets.find(
Chris@909 143 :first,
Chris@909 144 :conditions => {
Chris@909 145 :committed_on => tmp_time - time_delta .. tmp_time + time_delta,
Chris@909 146 :committer => author_utf8,
Chris@909 147 :comments => cmt
Chris@909 148 }
Chris@909 149 )
Chris@909 150 # create a new changeset....
Chris@909 151 unless cs
Chris@909 152 # we use a temporaray revision number here (just for inserting)
Chris@909 153 # later on, we calculate a continous positive number
Chris@909 154 tmp_time2 = tmp_time.clone.gmtime
Chris@909 155 branch = revision.paths[0][:branch]
Chris@909 156 scmid = branch + "-" + tmp_time2.strftime("%Y%m%d-%H%M%S")
Chris@909 157 cs = Changeset.create(:repository => self,
Chris@909 158 :revision => "tmp#{tmp_rev_num}",
Chris@909 159 :scmid => scmid,
Chris@909 160 :committer => revision.author,
Chris@909 161 :committed_on => tmp_time,
Chris@909 162 :comments => revision.message)
Chris@909 163 tmp_rev_num += 1
Chris@909 164 end
Chris@909 165 # convert CVS-File-States to internal Action-abbrevations
Chris@909 166 # default action is (M)odified
Chris@909 167 action = "M"
Chris@909 168 if revision.paths[0][:action] == "Exp" && revision.paths[0][:revision] == "1.1"
Chris@909 169 action = "A" # add-action always at first revision (= 1.1)
Chris@909 170 elsif revision.paths[0][:action] == "dead"
Chris@909 171 action = "D" # dead-state is similar to Delete
Chris@909 172 end
Chris@909 173 Change.create(
Chris@909 174 :changeset => cs,
Chris@909 175 :action => action,
Chris@909 176 :path => scm.with_leading_slash(revision.paths[0][:path]),
Chris@909 177 :revision => revision.paths[0][:revision],
Chris@909 178 :branch => revision.paths[0][:branch]
Chris@909 179 )
Chris@909 180 end
Chris@909 181 end
Chris@909 182
Chris@909 183 # Renumber new changesets in chronological order
Chris@909 184 changesets.find(
Chris@909 185 :all,
Chris@909 186 :order => 'committed_on ASC, id ASC',
Chris@909 187 :conditions => "revision LIKE 'tmp%'"
Chris@909 188 ).each do |changeset|
Chris@909 189 changeset.update_attribute :revision, next_revision_number
Chris@909 190 end
Chris@909 191 end # transaction
Chris@909 192 @current_revision_number = nil
Chris@909 193 end
Chris@909 194
Chris@909 195 private
Chris@909 196
Chris@909 197 # Returns the next revision number to assign to a CVS changeset
Chris@909 198 def next_revision_number
Chris@909 199 # Need to retrieve existing revision numbers to sort them as integers
Chris@909 200 sql = "SELECT revision FROM #{Changeset.table_name} "
Chris@909 201 sql << "WHERE repository_id = #{id} AND revision NOT LIKE 'tmp%'"
Chris@909 202 @current_revision_number ||= (connection.select_values(sql).collect(&:to_i).max || 0)
Chris@909 203 @current_revision_number += 1
Chris@909 204 end
Chris@909 205 end