Project

General

Profile

« Previous | Next » 

Revision 2006

Maps repository users to Redmine users (#1383).
Users with same username or email are automatically mapped. Mapping can be manually adjusted in repository settings. Multiple usernames can be mapped to the same Redmine user.

View differences:

trunk/app/controllers/repositories_controller.rb
44 44
    render(:update) {|page| page.replace_html "tab-content-repository", :partial => 'projects/settings/repository'}
45 45
  end
46 46
  
47
  def committers
48
    @committers = @repository.committers
49
    @users = @project.users
50
    additional_user_ids = @committers.collect(&:last).collect(&:to_i) - @users.collect(&:id)
51
    @users += User.find_all_by_id(additional_user_ids) unless additional_user_ids.empty?
52
    @users.compact!
53
    @users.sort!
54
    if request.post?
55
      @repository.committer_ids = params[:committers]
56
      flash[:notice] = l(:notice_successful_update)
57
      redirect_to :action => 'committers', :id => @project
58
    end
59
  end
60
  
47 61
  def destroy
48 62
    @repository.destroy
49 63
    redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'repository'
trunk/app/models/changeset.rb
1
# redMine - project management software
2
# Copyright (C) 2006-2007  Jean-Philippe Lang
1
# Redmine - project management software
2
# Copyright (C) 2006-2008  Jean-Philippe Lang
3 3
#
4 4
# This program is free software; you can redistribute it and/or
5 5
# modify it under the terms of the GNU General Public License
......
19 19

  
20 20
class Changeset < ActiveRecord::Base
21 21
  belongs_to :repository
22
  belongs_to :user
22 23
  has_many :changes, :dependent => :delete_all
23 24
  has_and_belongs_to_many :issues
24 25

  
25 26
  acts_as_event :title => Proc.new {|o| "#{l(:label_revision)} #{o.revision}" + (o.comments.blank? ? '' : (': ' + o.comments))},
26 27
                :description => :comments,
27 28
                :datetime => :committed_on,
28
                :author => :committer,
29 29
                :url => Proc.new {|o| {:controller => 'repositories', :action => 'revision', :id => o.repository.project_id, :rev => o.revision}}
30 30
                
31 31
  acts_as_searchable :columns => 'comments',
......
57 57
    repository.project
58 58
  end
59 59
  
60
  def author
61
    user || committer.to_s.split('<').first
62
  end
63
  
64
  def before_create
65
    self.user = repository.find_committer_user(committer)
66
  end
67
  
60 68
  def after_create
61 69
    scan_comment_for_issue_ids
62 70
  end
......
96 104
          issue.reload
97 105
          # don't change the status is the issue is closed
98 106
          next if issue.status.is_closed?
99
          user = committer_user || User.anonymous
100 107
          csettext = "r#{self.revision}"
101 108
          if self.scmid && (! (csettext =~ /^r[0-9]+$/))
102 109
            csettext = "commit:\"#{self.scmid}\""
103 110
          end
104
          journal = issue.init_journal(user, l(:text_status_changed_by_changeset, csettext))
111
          journal = issue.init_journal(user || User.anonymous, l(:text_status_changed_by_changeset, csettext))
105 112
          issue.status = fix_status
106 113
          issue.done_ratio = done_ratio if done_ratio
107 114
          issue.save
......
113 120
    
114 121
    self.issues = referenced_issues.uniq
115 122
  end
116

  
117
  # Returns the Redmine User corresponding to the committer
118
  def committer_user
119
    if committer && committer.strip =~ /^([^<]+)(<(.*)>)?$/
120
      username, email = $1.strip, $3
121
      u = User.find_by_login(username)
122
      u ||= User.find_by_mail(email) unless email.blank?
123
      u
124
    end
125
  end
126 123
  
127 124
  # Returns the previous changeset
128 125
  def previous
......
140 137
  end
141 138
  
142 139
  private
143
  
140

  
141

  
144 142
  def self.to_utf8(str)
145 143
    return str if /\A[\r\n\t\x20-\x7e]*\Z/n.match(str) # for us-ascii
146 144
    encoding = Setting.commit_logs_encoding.to_s.strip
trunk/app/models/repository.rb
96 96
    self.changesets.each(&:scan_comment_for_issue_ids)
97 97
  end
98 98
  
99
  # Returns an array of committers usernames and associated user_id
100
  def committers
101
    @committers ||= Changeset.connection.select_rows("SELECT DISTINCT committer, user_id FROM #{Changeset.table_name} WHERE repository_id = #{id}")
102
  end
103
  
104
  # Maps committers username to a user ids
105
  def committer_ids=(h)
106
    if h.is_a?(Hash)
107
      committers.each do |committer, user_id|
108
        new_user_id = h[committer]
109
        if new_user_id && (new_user_id.to_i != user_id.to_i)
110
          new_user_id = (new_user_id.to_i > 0 ? new_user_id.to_i : nil)
111
          Changeset.update_all("user_id = #{ new_user_id.nil? ? 'NULL' : new_user_id }", ["repository_id = ? AND committer = ?", id, committer])
112
        end
113
      end
114
      @committers = nil
115
      true
116
    else
117
      false
118
    end
119
  end
120
  
121
  # Returns the Redmine User corresponding to the given +committer+
122
  # It will return nil if the committer is not yet mapped and if no User
123
  # with the same username or email was found
124
  def find_committer_user(committer)
125
    if committer
126
      c = changesets.find(:first, :conditions => {:committer => committer}, :include => :user)
127
      if c && c.user
128
        c.user
129
      elsif committer.strip =~ /^([^<]+)(<(.*)>)?$/
130
        username, email = $1.strip, $3
131
        u = User.find_by_login(username)
132
        u ||= User.find_by_mail(email) unless email.blank?
133
        u
134
      end
135
    end
136
  end
137
  
99 138
  # fetch new changesets for all repositories
100 139
  # can be called periodically by an external script
101 140
  # eg. ruby script/runner "Repository.fetch_changesets"
trunk/app/models/user.rb
37 37
  has_many :members, :dependent => :delete_all
38 38
  has_many :projects, :through => :memberships
39 39
  has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify
40
  has_many :changesets, :dependent => :nullify
40 41
  has_one :preference, :dependent => :destroy, :class_name => 'UserPreference'
41 42
  has_one :rss_token, :dependent => :destroy, :class_name => 'Token', :conditions => "action='feeds'"
42 43
  belongs_to :auth_source
trunk/app/views/issues/_changesets.rhtml
2 2
    <div class="changeset <%= cycle('odd', 'even') %>">
3 3
    <p><%= link_to("#{l(:label_revision)} #{changeset.revision}",
4 4
                :controller => 'repositories', :action => 'revision', :id => @project, :rev => changeset.revision) %><br />
5
        <span class="author"><%= authoring(changeset.committed_on, changeset.committer) %></span></p>
5
        <span class="author"><%= authoring(changeset.committed_on, changeset.author) %></span></p>
6 6
    <%= textilizable(changeset, :comments) %>
7 7
    </div>
8 8
<% end %>
trunk/app/views/issues/show.rfpdf
79 79
	    pdf.Ln	
80 80
		for changeset in @issue.changesets
81 81
			pdf.SetFontStyle('B',8)
82
		    pdf.Cell(190,5, format_time(changeset.committed_on) + " - " + changeset.committer)
82
		    pdf.Cell(190,5, format_time(changeset.committed_on) + " - " + changeset.author)
83 83
		    pdf.Ln
84 84
			unless changeset.comments.blank?
85 85
				pdf.SetFontStyle('',8)
trunk/app/views/projects/settings/_repository.rhtml
11 11
</div>
12 12

  
13 13
<div class="contextual">
14
<% if @repository && [email protected]_record? %>
15
<%= link_to(l(:label_user_plural), {:controller => 'repositories', :action => 'committers', :id => @project}, :class => 'icon icon-user') %>
14 16
<%= link_to(l(:button_delete), {:controller => 'repositories', :action => 'destroy', :id => @project},
15 17
            :confirm => l(:text_are_you_sure),
16 18
            :method => :post,
17
            :class => 'icon icon-del') if @repository && [email protected]_record? %>
19
            :class => 'icon icon-del') %>
20
<% end %>
18 21
</div>
19 22

  
20 23
<%= submit_tag((@repository.nil? || @repository.new_record?) ? l(:button_create) : l(:button_save), :disabled => @repository.nil?) %>
trunk/app/views/repositories/_dir_list_content.rhtml
15 15
          :class => (entry.is_dir? ? 'icon icon-folder' : 'icon icon-file')%>
16 16
</td>
17 17
<td class="size"><%= (entry.size ? number_to_human_size(entry.size) : "?") unless entry.is_dir? %></td>
18
<% changeset = @project.repository.changesets.find_by_revision(entry.lastrev.identifier) if entry.lastrev && entry.lastrev.identifier %>
18 19
<td class="revision"><%= link_to(format_revision(entry.lastrev.name), :action => 'revision', :id => @project, :rev => entry.lastrev.identifier) if entry.lastrev && entry.lastrev.identifier %></td>
19 20
<td class="age"><%= distance_of_time_in_words(entry.lastrev.time, Time.now) if entry.lastrev && entry.lastrev.time %></td>
20
<td class="author"><%=h(entry.lastrev.author.to_s.split('<').first) if entry.lastrev %></td>
21
<% changeset = @project.repository.changesets.find_by_revision(entry.lastrev.identifier) if entry.lastrev && entry.lastrev.identifier %>
21
<td class="author"><%= changeset.nil? ? h(entry.lastrev.author.to_s.split('<').first) : changeset.author if entry.lastrev %></td>
22 22
<td class="comments"><%=h truncate(changeset.comments, 50) unless changeset.nil? %></td>
23 23
</tr>
24 24
<% end %>
trunk/app/views/repositories/_revisions.rhtml
17 17
<td class="checkbox"><%= radio_button_tag('rev', changeset.revision, (line_num==1), :id => "cb-#{line_num}", :onclick => "$('cbto-#{line_num+1}').checked=true;") if show_diff && (line_num < revisions.size) %></td>
18 18
<td class="checkbox"><%= radio_button_tag('rev_to', changeset.revision, (line_num==2), :id => "cbto-#{line_num}", :onclick => "if ($('cb-#{line_num}').checked==true) {$('cb-#{line_num-1}').checked=true;}") if show_diff && (line_num > 1) %></td>
19 19
<td class="committed_on"><%= format_time(changeset.committed_on) %></td>
20
<td class="author"><%=h changeset.committer.to_s.split('<').first %></td>
20
<td class="author"><%=h changeset.author %></td>
21 21
<td class="comments"><%= textilizable(truncate_at_line_break(changeset.comments)) %></td>
22 22
</tr>
23 23
<% line_num += 1 %>
trunk/app/views/repositories/committers.rhtml
1
<h2><%= l(:label_repository) %></h2>
2

  
3
<%= simple_format(l(:text_repository_usernames_mapping)) %>
4

  
5
<% if @committers.empty? %>
6
<p class="nodata"><%= l(:label_no_data) %></p>
7
<% else %>
8

  
9
<% form_tag({}) do %>
10
<table class="list">
11
<thead>
12
	<tr>
13
		<th><%= l(:field_login) %></th>
14
		<th><%= l(:label_user) %></th>
15
	</tr>
16
</thead>
17
<tbody>
18
<% @committers.each do |committer, user_id| -%>
19
	<tr class="<%= cycle 'odd', 'even' %>">
20
		<td><%=h committer %></td>
21
		<td><%= select_tag "committers[#{committer}]", content_tag('option', "-- #{l :actionview_instancetag_blank_option} --", :value => '') + options_from_collection_for_select(@users, 'id', 'name', user_id.to_i) %></td>
22
	</tr>
23
<% end -%>
24
</tbody>
25
</table>
26
<p><%= submit_tag(l(:button_update)) %></p>
27
<% end %>
28

  
29
<% end %>
0 30

  
trunk/app/views/repositories/revision.rhtml
22 22
<h2><%= l(:label_revision) %> <%= format_revision(@changeset.revision) %></h2>
23 23

  
24 24
<p><% if @changeset.scmid %>ID: <%= @changeset.scmid %><br /><% end %>
25
<em><%= @changeset.committer.to_s.split('<').first %>, <%= format_time(@changeset.committed_on) %></em></p>
25
<span class="author"><%= authoring(@changeset.committed_on, @changeset.author) %></span></p>
26 26

  
27 27
<%= textilizable @changeset.comments %>
28 28

  
trunk/db/migrate/100_add_changesets_user_id.rb
1
class AddChangesetsUserId < ActiveRecord::Migration
2
  def self.up
3
    add_column :changesets, :user_id, :integer, :default => nil
4
  end
5

  
6
  def self.down
7
    remove_column :changesets, :user_id
8
  end
9
end
0 10

  
trunk/db/migrate/101_populate_changesets_user_id.rb
1
class PopulateChangesetsUserId < ActiveRecord::Migration
2
  def self.up
3
    committers = Changeset.connection.select_values("SELECT DISTINCT committer FROM #{Changeset.table_name}")
4
    committers.each do |committer|
5
      next if committer.blank?
6
      if committer.strip =~ /^([^<]+)(<(.*)>)?$/
7
        username, email = $1.strip, $3
8
        u = User.find_by_login(username)
9
        u ||= User.find_by_mail(email) unless email.blank?
10
        Changeset.update_all("user_id = #{u.id}", ["committer = ?", committer]) unless u.nil?
11
      end
12
    end
13
  end
14

  
15
  def self.down
16
    Changeset.update_all('user_id = NULL')
17
  end
18
end
0 19

  
trunk/lang/bg.yml
689 689
permission_edit_own_issue_notes: Edit own notes
690 690
setting_gravatar_enabled: Use Gravatar user icons
691 691
label_example: Example
692
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/ca.yml
690 690
permission_edit_own_issue_notes: Edit own notes
691 691
setting_gravatar_enabled: Use Gravatar user icons
692 692
label_example: Example
693
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/cs.yml
694 694
permission_edit_own_issue_notes: Edit own notes
695 695
setting_gravatar_enabled: Use Gravatar user icons
696 696
label_example: Example
697
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/da.yml
690 690
permission_edit_own_issue_notes: Edit own notes
691 691
setting_gravatar_enabled: Use Gravatar user icons
692 692
label_example: Example
693
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/de.yml
690 690
permission_edit_own_issue_notes: Edit own notes
691 691
setting_gravatar_enabled: Use Gravatar user icons
692 692
label_example: Example
693
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/en.yml
665 665
text_enumeration_destroy_question: '%d objects are assigned to this value.'
666 666
text_enumeration_category_reassign_to: 'Reassign them to this value:'
667 667
text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
668
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
668 669

  
669 670
default_role_manager: Manager
670 671
default_role_developper: Developer
trunk/lang/es.yml
692 692
permission_edit_own_issue_notes: Edit own notes
693 693
setting_gravatar_enabled: Use Gravatar user icons
694 694
label_example: Example
695
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/fi.yml
689 689
permission_edit_own_issue_notes: Edit own notes
690 690
setting_gravatar_enabled: Use Gravatar user icons
691 691
label_example: Example
692
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/fr.yml
665 665
text_enumeration_destroy_question: 'Cette valeur est affectée à %d objets.'
666 666
text_enumeration_category_reassign_to: 'Réaffecter les objets à cette valeur:'
667 667
text_email_delivery_not_configured: "L'envoi de mail n'est pas configuré, les notifications sont désactivées.\nConfigurez votre serveur SMTP dans config/email.yml et redémarrez l'application pour les activer."
668
text_repository_usernames_mapping: "Vous pouvez sélectionner ou modifier l'utilisateur Redmine associé à chaque nom d'utilisateur figurant dans l'historique du dépôt.\nLes utilisateurs avec le même identifiant ou la même adresse mail seront automatiquement associés."
668 669

  
669 670
default_role_manager: Manager
670 671
default_role_developper: Développeur
trunk/lang/he.yml
689 689
permission_edit_own_issue_notes: Edit own notes
690 690
setting_gravatar_enabled: Use Gravatar user icons
691 691
label_example: Example
692
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/hu.yml
690 690
permission_edit_own_issue_notes: Saját jegyzetek szerkesztése
691 691
setting_gravatar_enabled: Felhasználói fényképek engedélyezése
692 692
label_example: Example
693
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/it.yml
689 689
permission_edit_own_issue_notes: Modifica proprie note
690 690
setting_gravatar_enabled: Usa icone utente Gravatar
691 691
label_example: Example
692
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/ja.yml
690 690
permission_edit_own_issue_notes: Edit own notes
691 691
setting_gravatar_enabled: Use Gravatar user icons
692 692
label_example: Example
693
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/ko.yml
689 689
permission_edit_own_issue_notes: Edit own notes
690 690
setting_gravatar_enabled: Use Gravatar user icons
691 691
label_example: Example
692
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/lt.yml
691 691
permission_edit_own_issue_notes: Edit own notes
692 692
setting_gravatar_enabled: Use Gravatar user icons
693 693
label_example: Example
694
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/nl.yml
691 691
permission_edit_own_issue_notes: Edit own notes
692 692
setting_gravatar_enabled: Use Gravatar user icons
693 693
label_example: Example
694
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/no.yml
690 690
permission_edit_own_issue_notes: Edit own notes
691 691
setting_gravatar_enabled: Use Gravatar user icons
692 692
label_example: Example
693
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/pl.yml
724 724
setting_gravatar_enabled: Używaj ikon użytkowników Gravatar
725 725

  
726 726
label_example: Example
727
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/pt-br.yml
690 690
permission_edit_own_issue_notes: Editar próprias notas
691 691
setting_gravatar_enabled: Usar ícones do Gravatar
692 692
label_example: Example
693
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/pt.yml
691 691
permission_edit_own_issue_notes: Edit own notes
692 692
setting_gravatar_enabled: Use Gravatar user icons
693 693
label_example: Example
694
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/ro.yml
689 689
permission_edit_own_issue_notes: Edit own notes
690 690
setting_gravatar_enabled: Use Gravatar user icons
691 691
label_example: Example
692
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/ru.yml
722 722
text_user_wrote: '%s написал(а):'
723 723
text_wiki_destroy_confirmation: Вы уверены, что хотите удалить данную Wiki и все ее содержимое?
724 724
text_workflow_edit: Выберите роль и трекер для редактирования последовательности состояний
725
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/sk.yml
694 694
permission_edit_own_issue_notes: Editácia vlastných poznámok úlohy
695 695
setting_gravatar_enabled: Použitie uživateľských Gravatar ikon
696 696
label_example: Example
697
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/sr.yml
690 690
permission_edit_own_issue_notes: Edit own notes
691 691
setting_gravatar_enabled: Use Gravatar user icons
692 692
label_example: Example
693
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/sv.yml
690 690
permission_edit_own_issue_notes: Edit own notes
691 691
setting_gravatar_enabled: Use Gravatar user icons
692 692
label_example: Example
693
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/th.yml
692 692
permission_edit_own_issue_notes: Edit own notes
693 693
setting_gravatar_enabled: Use Gravatar user icons
694 694
label_example: Example
695
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/tr.yml
690 690
permission_edit_own_issue_notes: Edit own notes
691 691
setting_gravatar_enabled: Use Gravatar user icons
692 692
label_example: Example
693
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/uk.yml
691 691
permission_edit_own_issue_notes: Edit own notes
692 692
setting_gravatar_enabled: Use Gravatar user icons
693 693
label_example: Example
694
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/vn.yml
690 690
permission_edit_time_entries: Edit time logs
691 691
permission_edit_own_time_entries: Edit own time logs
692 692
label_example: Example
693
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/zh-tw.yml
691 691
enumeration_doc_categories: 文件分類
692 692
enumeration_activities: 活動 (時間追蹤)
693 693
label_example: Example
694
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lang/zh.yml
691 691
enumeration_doc_categories: 文档类别
692 692
enumeration_activities: 活动(时间跟踪)
693 693
label_example: Example
694
text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
trunk/lib/redmine.rb
88 88
  end
89 89
    
90 90
  map.project_module :repository do |map|
91
    map.permission :manage_repository, {:repositories => [:edit, :destroy]}, :require => :member
91
    map.permission :manage_repository, {:repositories => [:edit, :committers, :destroy]}, :require => :member
92 92
    map.permission :browse_repository, :repositories => [:show, :browse, :entry, :annotate, :changes, :diff, :stats, :graph]
93 93
    map.permission :view_changesets, :repositories => [:show, :revisions, :revision]
94 94
    map.permission :commit_access, {}
trunk/test/fixtures/changesets.yml
7 7
  comments: My very first commit
8 8
  repository_id: 10
9 9
  committer: dlopper
10
  user_id: 3
10 11
changesets_002: 
11 12
  commit_date: 2007-04-12
12 13
  committed_on: 2007-04-12 15:14:44 +02:00
......
15 16
  comments: 'This commit fixes #1, #2 and references #1 & #3'
16 17
  repository_id: 10
17 18
  committer: dlopper
19
  user_id: 3
18 20
changesets_003: 
19 21
  commit_date: 2007-04-12
20 22
  committed_on: 2007-04-12 15:14:44 +02:00
......
25 27
    IssueID 666 3
26 28
  repository_id: 10
27 29
  committer: dlopper
30
  user_id: 3
28 31
changesets_004: 
29 32
  commit_date: 2007-04-12
30 33
  committed_on: 2007-04-12 15:14:44 +02:00
......
35 38
    IssueID 4 2
36 39
  repository_id: 10
37 40
  committer: dlopper
41
  user_id: 3
38 42
  
trunk/test/fixtures/roles.yml
43 43
    - :view_files
44 44
    - :manage_files
45 45
    - :browse_repository
46
    - :manage_repository
46 47
    - :view_changesets
47 48

  
48 49
  position: 1
trunk/test/functional/repositories_controller_test.rb
61 61
    assert_response :success
62 62
    assert_equal 'image/svg+xml', @response.content_type
63 63
  end
64
  
65
  def test_committers
66
    @request.session[:user_id] = 2
67
    # add a commit with an unknown user
68
    Changeset.create!(:repository => Project.find(1).repository, :committer => 'foo', :committed_on => Time.now, :revision => 100, :comments => 'Committed by foo.')
69
    
70
    get :committers, :id => 1
71
    assert_response :success
72
    assert_template 'committers'
73
    
74
    assert_tag :td, :content => 'dlopper',
75
                    :sibling => { :tag => 'td',
76
                                  :child => { :tag => 'select', :attributes => { :name => 'committers[dlopper]' },
77
                                                                :child => { :tag => 'option', :content => 'Dave Lopper',
78
                                                                                              :attributes => { :value => '3', :selected => 'selected' }}}}
79
    assert_tag :td, :content => 'foo',
80
                    :sibling => { :tag => 'td',
81
                                  :child => { :tag => 'select', :attributes => { :name => 'committers[foo]' }}}
82
    assert_no_tag :td, :content => 'foo',
83
                       :sibling => { :tag => 'td',
84
                                     :descendant => { :tag => 'option', :attributes => { :selected => 'selected' }}}
85
  end
86

  
87
  def test_map_committers
88
    @request.session[:user_id] = 2
89
    # add a commit with an unknown user
90
    c = Changeset.create!(:repository => Project.find(1).repository, :committer => 'foo', :committed_on => Time.now, :revision => 100, :comments => 'Committed by foo.')
91
    
92
    assert_no_difference "Changeset.count(:conditions => 'user_id = 3')" do
93
      post :committers, :id => 1, :committers => { 'foo' => '2', 'dlopper' => '3'}
94
      assert_redirected_to '/repositories/committers/ecookbook'
95
      assert_equal User.find(2), c.reload.user
96
    end
97
  end
64 98
end
trunk/test/unit/repository_git_test.rb
40 40
      commit = @repository.changesets.find(:first, :order => 'committed_on ASC')
41 41
      assert_equal "Initial import.\nThe repository contains 3 files.", commit.comments
42 42
      assert_equal "jsmith <[email protected]>", commit.committer
43
      assert_equal User.find_by_login('jsmith'), commit.user
43 44
      # TODO: add a commit with commit time <> author time to the test repository
44 45
      assert_equal "2007-12-14 09:22:52".to_time, commit.committed_on
45 46
      assert_equal "2007-12-14".to_date, commit.commit_date
trunk/test/unit/repository_test.rb
127 127
    assert_equal ':pserver:login:password@host:/path/to/the/repository', repository.url
128 128
    assert_equal 'foo', repository.root_url
129 129
  end
130
  
131
  def test_manual_user_mapping
132
    assert_no_difference "Changeset.count(:conditions => 'user_id <> 2')" do
133
      c = Changeset.create!(:repository => @repository, :committer => 'foo', :committed_on => Time.now, :revision => 100, :comments => 'Committed by foo.')
134
      assert_nil c.user
135
      @repository.committer_ids = {'foo' => '2'}
136
      assert_equal User.find(2), c.reload.user
137
      # committer is now mapped
138
      c = Changeset.create!(:repository => @repository, :committer => 'foo', :committed_on => Time.now, :revision => 101, :comments => 'Another commit by foo.')
139
      assert_equal User.find(2), c.user
140
    end
141
  end
142
  
143
  def test_auto_user_mapping_by_username
144
    c = Changeset.create!(:repository => @repository, :committer => 'jsmith', :committed_on => Time.now, :revision => 100, :comments => 'Committed by john.')
145
    assert_equal User.find(2), c.user
146
  end
147
  
148
  def test_auto_user_mapping_by_email
149
    c = Changeset.create!(:repository => @repository, :committer => 'john <[email protected]>', :committed_on => Time.now, :revision => 100, :comments => 'Committed by john.')
150
    assert_equal User.find(2), c.user
151
  end
130 152
end

Also available in: Unified diff