I'm looking for a part-time remote job.

Hire me


I'm the author of:

Mastering Redmine is a comprehensive guide with tips, tricks and best practices, and an easy-to-learn structure.

Check the book's project or

Buy the book

Social pages of the book:

By buying this book you also donate to Redmine (see this page).


Follow me:

redmine_git_hosting_v0.7.9_redmine_scm_compatibility_patch.diff

Isaiah Softleigh, 24 Feb 2015 16:18

Download (466 KB)

View differences:

app/controllers/repository_protected_branches_controller.rb
1
class RepositoryProtectedBranchesController < RedmineGitHostingController
2
  unloadable
3

  
4
  before_filter :set_current_tab
5
  before_filter :can_view_protected_branches,   :only => [:index]
6
  before_filter :can_create_protected_branches, :only => [:new, :create]
7
  before_filter :can_edit_protected_branches,   :only => [:edit, :update, :destroy]
8

  
9
  before_filter :find_repository_protected_branch, :except => [:index, :new, :create, :sort]
10

  
11

  
12
  def index
13
    @repository_protected_branches = RepositoryProtectedBranche.find_all_by_repository_id(@repository.id)
14

  
15
    respond_to do |format|
16
      format.html { render :layout => 'popup' }
17
      format.js
18
    end
19
  end
20

  
21

  
22
  def new
23
    @protected_branch = RepositoryProtectedBranche.new()
24
    @protected_branch.repository = @repository
25
    @protected_branch.user_list  = []
26
  end
27

  
28

  
29
  def create
30
    @protected_branch = RepositoryProtectedBranche.new(params[:repository_protected_branche])
31
    @protected_branch.repository = @repository
32

  
33
    respond_to do |format|
34
      if @protected_branch.save
35
        flash[:notice] = l(:notice_protected_branch_created)
36

  
37
        format.html { redirect_to success_url }
38
        format.js   { render :js => "window.location = #{success_url.to_json};" }
39
      else
40
        format.html {
41
          flash[:error] = l(:notice_protected_branch_create_failed)
42
          render :action => "create"
43
        }
44
        format.js { render "form_error", :layout => false }
45
      end
46
    end
47
  end
48

  
49

  
50
  def update
51
    respond_to do |format|
52
      if @protected_branch.update_attributes(params[:repository_protected_branche])
53
        flash[:notice] = l(:notice_protected_branch_updated)
54

  
55
        format.html { redirect_to success_url }
56
        format.js   { render :js => "window.location = #{success_url.to_json};" }
57
      else
58
        format.html {
59
          flash[:error] = l(:notice_protected_branch_update_failed)
60
          render :action => "edit"
61
        }
62
        format.js { render "form_error", :layout => false }
63
      end
64
    end
65
  end
66

  
67

  
68
  def destroy
69
    respond_to do |format|
70
      if @protected_branch.destroy
71
        flash[:notice] = l(:notice_protected_branch_deleted)
72
        format.js { render :js => "window.location = #{success_url.to_json};" }
73
      else
74
        format.js { render :layout => false }
75
      end
76
    end
77
  end
78

  
79

  
80
  def clone
81
    @protected_branch = RepositoryProtectedBranche.clone_from(params[:id])
82
    render "new"
83
  end
84

  
85

  
86
  def sort
87
    params[:repository_protected_branche].each_with_index do |id, index|
88
      RepositoryProtectedBranche.update_all({position: index + 1}, {id: id})
89
    end
90
    render :nothing => true
91
  end
92

  
93

  
94
  private
95

  
96

  
97
  def can_view_protected_branches
98
    render_403 unless view_context.user_allowed_to(:view_repository_protected_branches, @project)
99
  end
100

  
101

  
102
  def can_create_protected_branches
103
    render_403 unless view_context.user_allowed_to(:create_repository_protected_branches, @project)
104
  end
105

  
106

  
107
  def can_edit_protected_branches
108
    render_403 unless view_context.user_allowed_to(:edit_repository_protected_branches, @project)
109
  end
110

  
111

  
112
  def find_repository_protected_branch
113
    protected_branch = RepositoryProtectedBranche.find_by_id(params[:id])
114

  
115
    if protected_branch && protected_branch.repository_id == @repository.id
116
      @protected_branch = protected_branch
117
    elsif protected_branch
118
      render_403
119
    else
120
      render_404
121
    end
122
  end
123

  
124

  
125
  def set_current_tab
126
    @tab = 'repository_protected_branches'
127
  end
128

  
129
end
app/models/repository_protected_branche.rb
1
class RepositoryProtectedBranche < ActiveRecord::Base
2
  unloadable
3

  
4
  VALID_PERMS  = [ "RW+", "RW" ]
5
  DEFAULT_PERM = "RW+"
6

  
7
  acts_as_list
8

  
9
  ## Attributes
10
  attr_accessible :path, :permissions, :position, :user_list
11

  
12
  ## Relations
13
  belongs_to :repository
14

  
15
  ## Validations
16
  validates :repository_id, :presence => true
17
  validates :path,          :presence => true, :uniqueness => { :scope => :permissions }
18
  validates :permissions,   :presence => true, :inclusion => { :in => VALID_PERMS }
19
  validates :user_list,     :presence => true
20

  
21
  ## Serializations
22
  serialize :user_list, Array
23

  
24
  ## Callbacks
25
  before_validation :remove_blank_items
26

  
27
  after_commit ->(obj) { obj.update_permissions }, :on => :create
28
  after_commit ->(obj) { obj.update_permissions }, :on => :update
29
  after_commit ->(obj) { obj.update_permissions }, :on => :destroy
30

  
31
  ## Scopes
32
  default_scope order('position ASC')
33

  
34

  
35
  def self.clone_from(parent)
36
    parent = find_by_id(parent) unless parent.kind_of? RepositoryProtectedBranche
37
    copy = self.new
38
    copy.attributes = parent.attributes
39
    copy.repository = parent.repository
40

  
41
    copy
42
  end
43

  
44

  
45
  def available_users
46
    repository.project.member_principals.map(&:user).compact.uniq.map{ |user| user.login }.sort
47
  end
48

  
49

  
50
  def allowed_users
51
    self.user_list.map{ |user| User.find_by_login(user).gitolite_identifier }.sort
52
  end
53

  
54

  
55
  protected
56

  
57

  
58
  def update_permissions
59
    RedmineGitolite::GitHosting.logger.info { "Update branch permissions for repository : '#{repository.gitolite_repository_name}'" }
60
    RedmineGitolite::GitHosting.resync_gitolite(:update_repository, repository.id)
61
  end
62

  
63

  
64
  private
65

  
66

  
67
  def remove_blank_items
68
    self.user_list = user_list.select{ |user| !user.blank? } rescue []
69
  end
70

  
71
end
app/services/download_git_revision.rb
1
class DownloadGitRevision
2
  unloadable
3

  
4
  attr_reader :commit_valid
5
  attr_reader :content_type
6
  attr_reader :filename
7

  
8

  
9
  def initialize(repository, revision, format)
10
    @repository = repository
11
    @revision   = revision
12
    @format     = format
13
    @project    = repository.project
14

  
15
    @commit_valid  = false
16
    @commit_id     = ''
17
    @content_type  = ''
18
    @filename      = ''
19
    @cmd_args      = []
20

  
21
    validate_revision
22
    fill_data
23
  end
24

  
25

  
26
  def content
27
    RedmineGitolite::GitoliteWrapper.sudo_capture('git', "--git-dir=#{@repository.gitolite_repository_path}", 'archive', *@cmd_args, @commit_id)
28
  end
29

  
30

  
31
  private
32

  
33

  
34
  def validate_revision
35
    commit_id = nil
36

  
37
    # is the revision a branch?
38
    @repository.branches.each do |x|
39
      if x.to_s == @revision
40
        commit_id = x.revision
41
        break
42
      end
43
    end
44

  
45
    # is the revision a tag?
46
    if commit_id.nil?
47
      tags = RedmineGitolite::GitoliteWrapper.sudo_capture('git', "--git-dir=#{@repository.gitolite_repository_path}", 'tag').split
48
      tags.each do |x|
49
        if x == @revision
50
          commit_id = RedmineGitolite::GitoliteWrapper.sudo_capture('git', "--git-dir=#{@repository.gitolite_repository_path}", 'rev-list', @revision).split[0]
51
          break
52
        end
53
      end
54
    end
55

  
56
    # well, let check if this is a valid commit_id
57
    if commit_id.nil?
58
      commit_id = @revision
59
    end
60

  
61
    valid_commit = RedmineGitolite::GitoliteWrapper.sudo_capture('git', "--git-dir=#{@repository.gitolite_repository_path}", 'rev-parse', '--quiet', '--verify', commit_id).chomp.strip
62

  
63
    if valid_commit == ''
64
      @commit_valid = false
65
    else
66
      @commit_valid = true
67
      @commit_id = valid_commit
68
    end
69
  end
70

  
71

  
72
  def fill_data
73
    project_name = @project.to_s.parameterize.to_s
74

  
75
    if project_name.length == 0
76
      project_name = "tarball"
77
    end
78

  
79
    case @format
80
      when 'tar' then
81
        extension     = 'tar'
82
        @content_type = 'application/x-tar'
83
        @cmd_args << "--format=tar"
84

  
85
      when 'tar.gz' then
86
        extension     = 'tar.gz'
87
        @content_type = 'application/x-gzip'
88
        @cmd_args << "--format=tar.gz"
89
        @cmd_args << "-7"
90

  
91
      when 'zip' then
92
        extension     = 'zip'
93
        @content_type = 'application/x-zip'
94
        @cmd_args << "--format=zip"
95
        @cmd_args << "-7"
96
    end
97

  
98
    @filename = "#{project_name}-#{@revision}.#{extension}"
99
  end
100

  
101
end
app/services/git_notifier.rb
1
class GitNotifier
2
  unloadable
3

  
4

  
5
  attr_reader :email_prefix
6
  attr_reader :sender_address
7
  attr_reader :default_list
8
  attr_reader :mail_mapping
9

  
10

  
11
  def initialize(repository)
12
    @repository     = repository
13
    @project        = repository.project
14

  
15
    @email_prefix   = ''
16
    @sender_address = ''
17
    @default_list   = []
18
    @mail_mapping   = {}
19

  
20
    build_notifier
21
  end
22

  
23

  
24
  def mailing_list
25
    @mail_mapping.keys
26
  end
27

  
28

  
29
  private
30

  
31

  
32
  def build_notifier
33
    set_email_prefix
34
    set_sender_address
35
    set_default_list
36
    set_mail_mapping
37
  end
38

  
39

  
40
  def set_email_prefix
41
    if !@repository.git_notification.nil? && !@repository.git_notification.prefix.empty?
42
      @email_prefix = @repository.git_notification.prefix
43
    else
44
      @email_prefix = RedmineGitolite::Config.get_setting(:gitolite_notify_global_prefix)
45
    end
46
  end
47

  
48

  
49
  def set_sender_address
50
    if !@repository.git_notification.nil? && !@repository.git_notification.sender_address.empty?
51
      @sender_address = @repository.git_notification.sender_address
52
    else
53
      @sender_address = RedmineGitolite::Config.get_setting(:gitolite_notify_global_sender_address)
54
    end
55
  end
56

  
57

  
58
  def set_default_list
59
    @default_list = @project.member_principals.map(&:user).compact.uniq
60
                                                          .select{|user| user.allowed_to?(:receive_git_notifications, @project)}
61
                                                          .map(&:mail).uniq.sort
62
  end
63

  
64

  
65
  def set_mail_mapping
66
    mail_mapping = {}
67

  
68
    # First collect all project users
69
    default_users = @default_list.map{ |mail| mail_mapping[mail] = :project }
70

  
71
    # Then add global include list
72
    RedmineGitolite::Config.get_setting(:gitolite_notify_global_include).sort.map{ |mail| mail_mapping[mail] = :global }
73

  
74
    # Then filter
75
    mail_mapping = filter_list(mail_mapping)
76

  
77
    # Then add local include list
78
    if !@repository.git_notification.nil? && !@repository.git_notification.include_list.empty?
79
      @repository.git_notification.include_list.sort.map{ |mail| mail_mapping[mail] = :local }
80
    end
81

  
82
    @mail_mapping = mail_mapping
83
  end
84

  
85

  
86
  def filter_list(merged_map)
87
    mail_mapping = {}
88
    exclude_list = []
89

  
90
    # Build exclusion list
91
    if !RedmineGitolite::Config.get_setting(:gitolite_notify_global_exclude).empty?
92
      exclude_list = RedmineGitolite::Config.get_setting(:gitolite_notify_global_exclude)
93
    end
94

  
95
    if !@repository.git_notification.nil? && !@repository.git_notification.exclude_list.empty?
96
      exclude_list = exclude_list + @repository.git_notification.exclude_list
97
    end
98

  
99
    exclude_list = exclude_list.uniq.sort
100

  
101
    merged_map.each do |mail, from|
102
      mail_mapping[mail] = from unless exclude_list.include?(mail)
103
    end
104

  
105
    return mail_mapping
106
  end
107

  
108
end
app/services/github_payload.rb
1
class GithubPayload
2
  unloadable
3

  
4

  
5
  attr_reader :payload
6

  
7

  
8
  def initialize(repository, payload)
9
    @repository = repository
10
    @project    = repository.project
11
    @payload    = build_payload(payload)
12
  end
13

  
14

  
15
  private
16

  
17

  
18
  def logger
19
    RedmineGitolite::Log.get_logger(:git_hooks)
20
  end
21

  
22

  
23
  # Returns an array of GitHub post-receive hook style hashes
24
  # http://help.github.com/post-receive-hooks/
25
  def build_payload(refs)
26
    payload = []
27

  
28
    refs.each do |ref|
29

  
30
      oldhead, newhead, refname = ref.split(',')
31

  
32
      # Only pay attention to branch updates
33
      next if !refname.match(/refs\/heads\//)
34

  
35
      branch = refname.gsub('refs/heads/', '')
36

  
37
      if newhead.match(/^0{40}$/)
38
        # Deleting a branch
39
        logger.info { "Deleting branch '#{branch}'" }
40
        next
41
      elsif oldhead.match(/^0{40}$/)
42
        # Creating a branch
43
        logger.info { "Creating branch '#{branch}'" }
44
        range = newhead
45
      else
46
        range = "#{oldhead}..#{newhead}"
47
      end
48

  
49
      # Grab the repository path
50
      revisions_in_range = RedmineGitolite::GitoliteWrapper.sudo_capture('git', "--git-dir=#{@repository.gitolite_repository_path}", 'rev-list', '--reverse', range)
51
      logger.debug { "Revisions in range : #{revisions_in_range.split().join(' ')}" }
52

  
53
      commits = []
54

  
55
      revisions_in_range.split().each do |rev|
56
        logger.debug { "Revision : '#{rev.strip}'" }
57
        revision = @repository.find_changeset_by_name(rev.strip)
58
        next if revision.nil?
59

  
60
        revision_url = Rails.application.routes.url_helpers.url_for(
61
                         :controller => 'repositories', :action => 'revision',
62
                         :id => @project, :repository_id => @repository.identifier_param, :rev => rev,
63
                         :only_path => false, :host => Setting['host_name'], :protocol => Setting['protocol']
64
                       )
65

  
66
        commit = {
67
          :id        => revision.revision,
68
          :message   => revision.comments,
69
          :timestamp => revision.committed_on,
70
          :added     => [],
71
          :modified  => [],
72
          :removed   => [],
73
          :url       => revision_url,
74
          :author    => {
75
            :name  => revision.committer.gsub(/^([^<]+)\s+.*$/, '\1'),
76
            :email => revision.committer.gsub(/^.*<([^>]+)>.*$/, '\1')
77
          }
78
        }
79

  
80
        revision.filechanges.each do |change|
81
          if change.action == "M"
82
            commit[:modified] << change.path
83
          elsif change.action == "A"
84
            commit[:added] << change.path
85
          elsif change.action == "D"
86
            commit[:removed] << change.path
87
          end
88
        end
89

  
90
        commits << commit
91
      end
92

  
93
      repository_url = Rails.application.routes.url_helpers.url_for(
94
                         :controller => 'repositories', :action => 'show',
95
                         :id => @project, :repository_id => @repository.identifier_param,
96
                         :only_path => false, :host => Setting['host_name'], :protocol => Setting['protocol']
97
                       )
98

  
99
      payload << {
100
        :before     => oldhead,
101
        :after      => newhead,
102
        :ref        => refname,
103
        :commits    => commits,
104
        :pusher     => {
105
          :name  => Setting["app_title"],
106
          :email => Setting["mail_from"]
107
        },
108
        :repository => {
109
          :description => @project.description,
110
          :fork        => false,
111
          :forks       => 0,
112
          :homepage    => @project.homepage,
113
          :name        => @repository.redmine_name,
114
          :open_issues => @project.issues.open.length,
115
          :watchers    => 0,
116
          :private     => !@project.is_public,
117
          :url         => repository_url,
118
          :owner       => {
119
            :name  => Setting["app_title"],
120
            :email => Setting["mail_from"]
121
          }
122
        }
123
      }
124
    end
125

  
126
    return payload
127
  end
128

  
129
end
app/services/hooks/git_mirrors.rb
1
module Hooks
2
  class GitMirrors
3
    unloadable
4

  
5

  
6
    def initialize(repository, payload)
7
      @repository = repository
8
      @project    = repository.project
9
      @payload    = payload
10
    end
11

  
12

  
13
    def execute
14
      call_mirrors
15
    end
16

  
17

  
18
    private
19

  
20

  
21
    def logger
22
      RedmineGitolite::Log.get_logger(:git_hooks)
23
    end
24

  
25

  
26
    def call_mirrors
27
      y = ""
28

  
29
      ## Push to each mirror
30
      if @repository.mirrors.active.any?
31

  
32
        logger.info { "Notifying mirrors about changes to this repository :" }
33
        y << "\nNotifying mirrors about changes to this repository :\n"
34

  
35
        @repository.mirrors.active.each do |mirror|
36
          if mirror.needs_push(@payload)
37
            logger.info { "Pushing changes to #{mirror.url} ... " }
38
            y << "  - Pushing changes to #{mirror.url} ... "
39

  
40
            push_failed, push_message = mirror.push
41

  
42
            if push_failed
43
              logger.error { "Failed!" }
44
              logger.error { "#{push_message}" }
45
              y << " [failure]\n"
46
            else
47
              logger.info { "Succeeded!" }
48
              y << " [success]\n"
49
            end
50
          end
51
        end
52
      end
53

  
54
      return y
55
    end
56

  
57
  end
58
end
app/services/hooks/github_issues_sync.rb
1
require 'json'
2

  
3
module Hooks
4
  class GithubIssuesSync
5
    unloadable
6

  
7
    include HttpHelper
8

  
9

  
10
    def initialize(project, params)
11
      @project = project
12
      @params  = params
13
    end
14

  
15

  
16
    def execute
17
      sync_with_github
18
    end
19

  
20

  
21
    private
22

  
23

  
24
    def logger
25
      RedmineGitolite::Log.get_logger(:git_hooks)
26
    end
27

  
28

  
29
    def sync_with_github
30
      github_issue = GithubIssue.find_by_github_id(@params[:issue][:id])
31
      redmine_issue = Issue.find_by_subject(@params[:issue][:title])
32
      create_relation = false
33

  
34
      ## We don't have stored relation
35
      if github_issue.nil?
36

  
37
        ## And we don't have issue in Redmine
38
        if redmine_issue.nil?
39
          create_relation = true
40
          redmine_issue = create_redmine_issue
41
        else
42
          ## Create relation and update issue
43
          create_relation = true
44
          redmine_issue = update_redmine_issue(redmine_issue)
45
        end
46
      else
47
        ## We have one relation, update issue
48
        redmine_issue = update_redmine_issue(github_issue.issue)
49
      end
50

  
51
      if create_relation
52
        github_issue = GithubIssue.new
53
        github_issue.github_id = @params[:issue][:id]
54
        github_issue.issue_id = redmine_issue.id
55
        github_issue.save!
56
      end
57

  
58
      if @params.has_key?(:comment)
59
        issue_journal = GithubComment.find_by_github_id(@params[:comment][:id])
60

  
61
        if issue_journal.nil?
62
          issue_journal = create_issue_journal(github_issue.issue)
63

  
64
          github_comment = GithubComment.new
65
          github_comment.github_id = @params[:comment][:id]
66
          github_comment.journal_id = issue_journal.id
67
          github_comment.save!
68
        end
69
      end
70
    end
71

  
72

  
73
    def create_redmine_issue
74
      logger.info { "Github Issues Sync : create new issue" }
75

  
76
      issue = Issue.new
77
      issue.project_id = @project.id
78
      issue.tracker_id = @project.trackers.find(:first).try(:id)
79
      issue.subject = @params[:issue][:title].chomp[0, 255]
80
      issue.description = @params[:issue][:body]
81
      issue.updated_on = @params[:issue][:updated_at]
82
      issue.created_on = @params[:issue][:created_at]
83

  
84
      ## Get user mail
85
      user = find_user(@params[:issue][:user][:url])
86
      issue.author = user
87

  
88
      issue.save!
89
      return issue
90
    end
91

  
92

  
93
    def create_issue_journal(issue)
94
      logger.info { "Github Issues Sync : create new journal for issue '##{issue.id}'" }
95

  
96
      journal = Journal.new
97
      journal.journalized_id = issue.id
98
      journal.journalized_type = 'Issue'
99
      journal.notes = @params[:comment][:body]
100
      journal.created_on = @params[:comment][:created_at]
101

  
102
      ## Get user mail
103
      user = find_user(@params[:comment][:user][:url])
104
      journal.user_id = user.id
105

  
106
      journal.save!
107
      return journal
108
    end
109

  
110

  
111
    def update_redmine_issue(issue)
112
      logger.info { "Github Issues Sync : update issue '##{issue.id}'" }
113

  
114
      if @params[:issue][:state] == 'closed'
115
        issue.status_id = 5
116
      else
117
        issue.status_id = 1
118
      end
119

  
120
      issue.subject = @params[:issue][:title].chomp[0, 255]
121
      issue.description = @params[:issue][:body]
122
      issue.updated_on = @params[:issue][:updated_at]
123

  
124
      issue.save!
125
      return issue
126
    end
127

  
128

  
129
    def find_user(url)
130
      post_failed, user_data = post_data(url, "", :method => :get)
131
      user_data = JSON.parse(user_data)
132

  
133
      user = User.find_by_mail(user_data['email'])
134

  
135
      if user.nil?
136
        logger.info { "Github Issues Sync : cannot find user '#{user_data['email']}' in Redmine, use anonymous" }
137
        user = User.anonymous
138
        user.mail = user_data['email']
139
        user.firstname = user_data['name']
140
        user.lastname  = user_data['login']
141
      end
142

  
143
      return user
144
    end
145

  
146
  end
147
end
app/services/hooks/http_helper.rb
1
require 'net/http'
2
require 'net/https'
3
require 'uri'
4

  
5
module Hooks
6
  module HttpHelper
7
    unloadable
8

  
9
    def post_data(url, payload, opts={})
10
      uri  = URI(url)
11
      http = Net::HTTP.new(uri.host, uri.port)
12

  
13
      if uri.scheme == 'https'
14
        http.use_ssl = true
15
        http.verify_mode = OpenSSL::SSL::VERIFY_NONE
16
      end
17

  
18
      if opts[:method] == :post
19
        request = Net::HTTP::Post.new(uri.request_uri)
20
        request.set_form_data({"payload" => payload.to_json})
21
      else
22
        request = Net::HTTP::Get.new(uri.request_uri)
23
      end
24

  
25
      message = ""
26

  
27
      begin
28
        res = http.start {|openhttp| openhttp.request request}
29
        if !res.is_a?(Net::HTTPSuccess)
30
          message = "Return code : #{res.code} (#{res.message})."
31
          failed = true
32
        else
33
          message = res.body
34
          failed = false
35
        end
36
      rescue => e
37
        message = "Exception : #{e.message}"
38
        failed = true
39
      end
40

  
41
      return failed, message
42
    end
43

  
44
  end
45
end
app/services/hooks/redmine.rb
1
module Hooks
2
  class Redmine
3
    unloadable
4

  
5

  
6
    def initialize(repository)
7
      @repository = repository
8
    end
9

  
10

  
11
    def execute
12
      fetch_changesets
13
    end
14

  
15

  
16
    private
17

  
18

  
19
    def logger
20
      RedmineGitolite::Log.get_logger(:git_hooks)
21
    end
22

  
23

  
24
    def fetch_changesets
25
      ## Fetch commits from the repository
26
      y = ""
27

  
28
      logger.info { "Fetching changesets for '#{@repository.redmine_name}' repository ... " }
29
      y << "  - Fetching changesets for '#{@repository.redmine_name}' repository ... "
30

  
31
      begin
32
        @repository.fetch_changesets
33
        logger.info { "Succeeded!" }
34
        y << " [success]\n"
35
      rescue ::Redmine::Scm::Adapters::CommandFailed => e
36
        logger.error { "Failed!" }
37
        logger.error { "Error during fetching changesets : #{e.message}" }
38
        y << " [failure]\n"
39
      rescue => e
40
        logger.error { "Failed!" }
41
        logger.error { "Error after fetching changesets : #{e.message}" }
42
        y << " [failure]\n"
43
      end
44

  
45
      return y
46
    end
47

  
48
  end
49
end
app/services/hooks/webservices.rb
1
module Hooks
2
  class Webservices
3
    unloadable
4

  
5
    include HttpHelper
6

  
7

  
8
    def initialize(repository, payload)
9
      @repository = repository
10
      @project    = repository.project
11
      @payload    = payload
12
    end
13

  
14

  
15
    def execute
16
      call_webservices
17
    end
18

  
19

  
20
    private
21

  
22

  
23
    def logger
24
      RedmineGitolite::Log.get_logger(:git_hooks)
25
    end
26

  
27

  
28
    def call_webservices
29
      y = ""
30

  
31
      ## Post to each post-receive URL
32
      if @repository.post_receive_urls.active.any?
33

  
34
        logger.info { "Notifying post receive urls about changes to this repository :" }
35
        y << "\nNotifying post receive urls about changes to this repository :\n"
36

  
37
        @repository.post_receive_urls.active.each do |post_receive_url|
38
          if payloads = post_receive_url.needs_push(@payload)
39

  
40
            method = (post_receive_url.mode == :github) ? :post : :get
41

  
42
            if method == :post && post_receive_url.split_payloads?
43
              payloads.each do |payload|
44
                logger.info { "Notifying #{post_receive_url.url} for '#{payload[:ref]}' ... " }
45
                y << "  - Notifying #{post_receive_url.url} for '#{payload[:ref]}' ... "
46

  
47
                post_failed, post_message = post_data(post_receive_url.url, payload, :method => method)
48

  
49
                if post_failed
50
                  logger.error { "Failed!" }
51
                  logger.error { "#{post_message}" }
52
                  y << " [failure]\n"
53
                else
54
                  logger.info { "Succeeded!" }
55
                  y << " [success]\n"
56
                end
57
              end
58
            else
59
              logger.info { "Notifying #{post_receive_url.url} ... " }
60
              y << "  - Notifying #{post_receive_url.url} ... "
61

  
62
              post_failed, post_message = post_data(post_receive_url.url, @payload, :method => method)
63

  
64
              if post_failed
65
                logger.error { "Failed!" }
66
                logger.error { "#{post_message}" }
67
                y << " [failure]\n"
68
              else
69
                logger.info { "Succeeded!" }
70
                y << " [success]\n"
71
              end
72
            end
73
          end
74
        end
75
      end
76

  
77
      return y
78
    end
79

  
80
  end
81
end
app/views/gitolite_public_keys/_form.html.erb
1
<div id="validation_messages"><%= error_messages_for 'gitolite_public_key' %></div>
2

  
3
<%= labelled_form_for :gitolite_public_key, gitolite_public_key,
4
                      :url  => {:controller => 'gitolite_public_keys', :action => 'create', :user_id => params[:id], :tab => params[:id]&&'keys'},
5
                      :html => {:method => :post} do |f| %>
6

  
7
  <p><%= f.text_field :title, :label => :label_identifier_can_be_arbitrary, :required => true, :style => 'width: 97%;' %></p>
8

  
9
  <% if can_create_deployment_keys_for_some_project(@user) %>
10
    <p>
11
      <%= f.select :key_type, options_for_select(
12
                                [
13
                                  [ l(:label_user_key), 0 ],
14
                                  [ l(:label_deploy_key), 1 ]
15
                                ],
16
                              ),
17
                              { :required => true, :label => :label_key_type },
18
                              { :class    => 'select_key_type' } %>
19

  
20

  
21
    </p>
22

  
23
    <div id="key_type_options" style="display: none;">
24
      <p>
25
        <%= f.check_box :delete_when_unused, :required => true, :label => :label_deployment_credential_delete_when_unused %>
26
      </p>
27
    </div>
28
  <% end %>
29

  
30
  <p>
31
    <%= f.text_area :key, :label => :label_public_key, :required => true,
32
          :style => "width: 97%; height: 200px; overflow: auto;",
33
          :cols => nil,
34
          :rows => nil %>
35
  </p>
36

  
37

  
38

  
39
  <em><%= l(:label_cut_and_paste) %></em><br /><br />
40
  <%= submit_tag l(:button_create), :name => 'create_button' %>
41
  <%= submit_tag l(:button_cancel), :name => 'cancel_button' %>
42

  
43
<% end %>
app/views/gitolite_public_keys/index.html.erb
1
<%= render :partial => 'gitolite_public_keys/view' %>
app/views/repositories/_edit_bottom.html.erb
1
<% if @repository.is_a?(Repository::Git) %>
2

  
3
  <div id="repository-tabs">
4
    <ul>
5
      <% if user_allowed_to(:view_deployment_keys, @repository.project) %>
6
        <li id="tab-repository_deployment_credentials">
7
          <%= link_to label_with_icon(l(:label_deployment_credentials), 'fa-ticket'),
8
                      repository_deployment_credentials_path(@repository) %>
9
        </li>
10
      <% end %>
11

  
12
      <% if user_allowed_to(:view_repository_git_notifications, @repository.project) %>
13
        <li id="tab-repository_git_notifications">
14
          <%= link_to label_with_icon(l(:label_git_notifications), 'fa-envelope'),
15
                      repository_git_notifications_path(@repository) %>
16
        </li>
17
      <% end %>
18

  
19
      <% if user_allowed_to(:view_repository_mirrors, @repository.project) %>
20
        <li id="tab-repository_mirrors">
21
          <%= link_to label_with_icon(l(:label_repository_mirrors), 'fa-sitemap'),
22
                      repository_mirrors_path(@repository) %>
23
        </li>
24
      <% end %>
25

  
26
      <% if user_allowed_to(:view_repository_post_receive_urls, @repository.project) %>
27
        <li id="tab-repository_post_receive_urls">
28
          <%= link_to label_with_icon(l(:label_post_receive_urls), 'fa-external-link'),
29
                      repository_post_receive_urls_path(@repository) %>
30
        </li>
31
      <% end %>
32

  
33
      <% if user_allowed_to(:view_repository_git_config_keys, @repository.project) %>
34
        <li id="tab-repository_git_config_keys">
35
          <%= link_to label_with_icon(l(:label_git_config_keys), 'fa-th-list'),
36
                      repository_git_config_keys_path(@repository) %>
37
        </li>
38
      <% end %>
39

  
40
      <% if user_allowed_to(:view_repository_protected_branches, @repository.project) %>
41
        <li id="tab-repository_protected_branches">
42
          <%= link_to "<i class=\"fa fa-lock\"></i>".html_safe + l(:label_protected_branches),
43
                      repository_protected_branches_path(@repository) %>
44
        </li>
45
      <% end %>
46
    </ul>
47
  </div>
48

  
49
  <div id="modal-box"></div>
50
  <div id="modal-box-close-only"></div>
51

  
52
  <% content_for :header_tags do %>
53
    <%= stylesheet_link_tag 'font_awesome',                     :plugin => 'redmine_bootstrap_kit' %>
54
    <%= stylesheet_link_tag 'jquery_tag_it',                    :plugin => 'redmine_bootstrap_kit' %>
55
    <%= stylesheet_link_tag 'bootstrap/bootstrap_custom',       :plugin => 'redmine_bootstrap_kit' %>
56
    <%= stylesheet_link_tag 'bootstrap/bootstrap_label',        :plugin => 'redmine_bootstrap_kit' %>
57
    <%= stylesheet_link_tag 'bootstrap/bootstrap_tables',       :plugin => 'redmine_bootstrap_kit' %>
58

  
59
    <%= javascript_include_tag 'jquery_tag_it',                 :plugin => 'redmine_bootstrap_kit' %>
60
    <%= javascript_include_tag 'bootstrap',                     :plugin => 'redmine_bootstrap_kit' %>
61

  
62
    <%= javascript_tag do %>
63

  
64
      function post_mode_change(elem) {
65
        if (!elem) return;
66
        var idx = elem.selectedIndex;
67
        if (idx == 0) {
68
          $('#payload_options').show();
69
        } else {
70
          $('#payload_options').hide();
71
        }
72
      }
73

  
74
      function push_mode_change(elem) {
75
        if (!elem) return;
76
        var idx = elem.selectedIndex;
77
        if (idx == 0) {
78
          $('#ref_spec_options').hide();
79
        } else {
80
          $('#ref_spec_options').show();
81
        }
82
      }
83

  
84
      function key_mode_change(elem) {
85
        if (!elem) return;
86
        var idx = elem.selectedIndex;
87
        if (idx == 0) {
88
          $('#new_key_window').show();
89
        } else {
90
          $('#new_key_window').hide();
91
        }
92
      }
93

  
94
      var modals           = Object();
95
      modals.label_save    = '<%= l(:button_save) %>';
96
      modals.label_cancel  = '<%= l(:button_cancel) %>';
97
      modals.label_ok      = '<%= l(:button_ok) %>';
98
      modals.modal_list    = [];
99
      modals.modal_list[0] = {'source': '.modal-box', 'target': '#modal-box', 'mode': 'standard'};
100
      modals.modal_list[1] = {'source': '.modal-box-close-only', 'target': '#modal-box-close-only', 'mode': 'close-only'};
101

  
102
      $(document).ready(function() {
103
        var all_tabs = $("#repository-tabs li");
104
        var active_tab = '';
105

  
106
        all_tabs.each(function(){
107
          if ($(this).attr('id').replace('tab-', '') == '<%= @tab %>') {
108
            active_tab = all_tabs.index(this);
109
          }
110
        });
111

  
112
        $("#repository-tabs").tabs({
113
          active: active_tab,
114
          activate: function(event, ui) {
115
            var new_tab_name = $(ui.newTab).attr('id').replace('tab-', '');
116
            if ("replaceState" in window.history) {
117
              window.history.replaceState(null, document.title, 'edit?tab=' + new_tab_name);
118
            }
119
          }
120
        });
121
      });
122
    <% end %>
123
  <% end %>
124

  
125
<% end %>
app/views/repositories/_edit_top.html.erb
1
<% if @repository.is_a?(Repository::Git) %>
2
  <div class="git_hosting box">
3
    <h3><%= l(:label_repository_access_url) %></h3>
4
    <%= render :partial => 'common/git_urls', :locals => {:repository => @repository} %>
5
  </div>
6
<% end %>
app/views/repositories/_git_form.html.erb
1
<% content_for :header_tags do %>
2
  <%= stylesheet_link_tag    'bootstrap/bootstrap_switch', :plugin => 'redmine_bootstrap_kit' %>
3
  <%= javascript_include_tag 'plugins/bootstrap_switch',   :plugin => 'redmine_bootstrap_kit' %>
4
  <%= javascript_include_tag 'bootstrap',                  :plugin => 'redmine_bootstrap_kit' %>
5
<% end %>
6

  
7
<%= javascript_tag do %>
8

  
9
  $(document).ready(function() {
10

  
11
    // Actually this takes the parent <p> mark
12
    var default_checkbox = $('#repository_is_default').parent();
13

  
14
    <% if @project.repository.nil? %>
15
      // The default repository is not set, nothing to do...
16

  
17
    <% elsif @project.repository == @repository %>
18
      var content = $('<%= content_tag :p do -%>
19
        <%= hidden_field_tag "repository[is_default]", "1" -%>
20
        <%= content_tag :label, l(:field_repository_is_default) -%>
21
        <%= content_tag :span,  l(:label_yes), :class => 'label label-success' -%>
22
      <% end -%>');
23

  
24
      content.insertAfter(default_checkbox);
25
      default_checkbox.remove();
26
      $('#repository_identifier').parent().remove();
27
    <% else %>
28
      var content = $('<%= content_tag :p do -%>
29
        <%= hidden_field_tag "repository[is_default]", "0" -%>
30
        <%= content_tag :label, l(:field_repository_is_default) -%>
31
        <%= content_tag :span,  l(:label_no), :class => 'label' -%>
32
      <% end -%>');
33

  
34
      content.insertAfter(default_checkbox);
35
      default_checkbox.remove();
36
    <% end %>
37

  
38
  });
39

  
40
<% end %>
41

  
42
<% if @repository.is_a?(Repository::Git) %>
43

  
44
  <%= javascript_tag do %>
45

  
46
    function moveGitOptionsDiv(){
47
      if ( $('#git_hosting_settings').length == 0 ) {
48
        // Set selectors
49
        var original_div = $('#repository_git_options').parent();
50
        var new_div      = $('#repository_git_options');
51

  
52
        // Wrap the original_div in a new div
53
        original_div.wrap('<div id="git_hosting_settings" class="box tabular">');
54

  
55
        // Remove original css class
56
        original_div.removeClass('box tabular');
57

  
58
        // Add new css class
59
        original_div.addClass('split');
60

  
61
        // Insert our div after the original one
62
        new_div.insertAfter(original_div);
63

  
64
        $('<div style="display: block; clear: both;"></div>').insertAfter(new_div);
65

  
66
        new_div.show();
67
      }
68
    }
69

  
70
    $(document).ready(function() {
71
      $('#repository_url').parent().remove();
72
      moveGitOptionsDiv();
73

  
74
      $('.bootstrap-switch').each(function(index, element) {
75
        if (!$(element).children('div').length > 0){
76
          installBootstrapSwitch(element);
77
        }
78
      });
79
    });
80
  <% end %>
81

  
82
  <div id="repository_git_options" class="split" style="display: none;">
83

  
84
    <h3><%= l(:label_repository_options) %></h3>
85

  
86
    <%
87
      selected = "false"
88
      if @repository.extra[:git_daemon]
89
        selected = "true"
90
      elsif @project.is_public && RedmineGitolite::Config.get_setting(:gitolite_daemon_by_default, true)
91
        selected = "true"
92
      end
93
    %>
94

  
95
    <p>
96
      <label><%= l(:label_enable_git_daemon) %></label>
97
      <span class="bootstrap-switch switch-small" data-on="primary" data-off="default" data-on-label="<%= l(:label_yes) %>" data-off-label="<%= l(:label_no) %>">
98
        <%= hidden_field_tag "extra[git_daemon]", "false" %>
99
        <%= check_box_tag "extra[git_daemon]", selected, (selected == "true" ? true : false), disabled: !@project.is_public %>
100
      </span>
101
    </p>
102

  
103
    <% if user_allowed_to(:create_repository_git_notifications, @repository.project) %>
104
      <p>
105
        <label><%= l(:label_enable_git_notify) %></label>
106
        <span class="bootstrap-switch switch-small" data-on="primary" data-off="default" data-on-label="<%= l(:label_yes) %>" data-off-label="<%= l(:label_no) %>">
107
          <%= hidden_field_tag "extra[git_notify]", "false" %>
108
          <%= check_box_tag "extra[git_notify]", @repository.extra[:git_notify], @repository.extra[:git_notify] %>
109
        </span>
110
      </p>
111
    <% end %>
112

  
113
    <% if user_allowed_to(:create_repository_protected_branches, @repository.project) %>
114
      <p>
115
        <label><%= l(:label_enable_protected_branches) %></label>
116
        <span class="bootstrap-switch switch-small" data-on="primary" data-off="default" data-on-label="<%= l(:label_yes) %>" data-off-label="<%= l(:label_no) %>">
117
          <%= hidden_field_tag "extra[protected_branch]", "false" %>
118
          <%= check_box_tag "extra[protected_branch]", @repository.extra[:protected_branch], @repository.extra[:protected_branch] %>
119
        </span>
120
      </p>
121
    <% end %>
122

  
123
    <p>
124
      <%= label_tag  "extra[git_http]", l(:label_enable_smart_http) %>
125
      <%= select_tag "extra[git_http]", options_for_select([
126
                                                              [l(:label_disabled), "0"],
127
                                                              [l(:label_http_only), "3"],
128
                                                              [l(:label_https_only), "1"],
129
                                                              [l(:label_https_and_http), "2"]
130
                                                            ], :selected => @repository.extra[:git_http].to_s) %>
131
    </p>
132

  
133
    <p>
134
      <%= label_tag  "", l(:label_repository_default_branch) %>
135
      <% if !@repository.new_record? && !@repository.branches.empty? %>
136
        <%= select_tag "extra[default_branch]", options_for_select(@repository.branches.collect{ |b| [b.to_s, b.to_s] }, :selected => @repository.branches.find{ |b| b.is_default}.to_s) %>
137
      <% else %>
138
        <span class="label label-info"><%= @repository.extra[:default_branch] %></span>
139
      <% end %>
140
    </p>
141

  
142
    <p>
143
      <%= label_tag  "", l(:label_mirroring_keys_installed) %>
144
      <%= image_tag (RedmineGitolite::GitoliteWrapper.mirroring_keys_installed? ? 'true.png' : 'exclamation.png') %>
145
    </p>
146

  
147
    <% if !@repository.new_record? %>
148
      <p>
149
        <%= label_tag  "", l(:label_repository_exists_in_gitolite) %>
150
        <%= image_tag (@repository.exists_in_gitolite? ? 'true.png' : 'exclamation.png') %>
151
      </p>
152
      <p>
153
        <label><%= l(:label_browse_repository) %></label>
154
        <%= link_to h(@repository.url), {:controller => 'repositories', :action => 'show', :id => @project, :repository_id => @repository.identifier_param} %>
155
      </p>
156
    <% else %>
157
      <%= javascript_tag do %>
158
        $(document).ready(function() {
159
          var content = $('<%= content_tag :p do -%>
160
            <%= hidden_field_tag "repository[create_readme]", "false" -%>
161
            <%= content_tag :label, l(:label_init_repo_with_readme) -%>
162
            <%= check_box_tag "repository[create_readme]", "true", RedmineGitolite::Config.get_setting(:init_repositories_on_create, true) -%>
163
          <% end -%>');
164

  
165
          if ($('#repository_create_readme').length == 0) {
166
            content.insertAfter($('#repository_identifier').parent());
167
          }
168
        });
169
      <% end %>
170
    <% end %>
171

  
172
  </div>
173

  
174
<% end %>
app/views/repositories/_sidebar.html.erb
1
<%= javascript_tag do %>
2
  $(document).ready(function() {
3
    $('#sidebar p').remove();
4
  });
5
<% end %>
6

  
7

  
8

  
9
<ul class="repository git">
10
  <% @repositories.sort.each do |repo| %>
11
      <li class="repository git"><%= link_to h(repo.name), {:controller => 'repositories', :action => 'show', :id => @project, :repository_id => repo.identifier_param, :rev => nil, :path => nil},
12
                                    :class => [ 'repository', (repo == @repository ? 'selected' : ''), @repository.type.split('::')[1].downcase ].join(' ') %>
13
      </li>
14
  <% end %>
15
</ul>
16

  
17
<% if @repository.is_a?(Repository::Git) && RedmineGitolite::Config.get_setting(:show_repositories_url, true) %>
18
  <div class="git_hosting_urls">
19
    <h3><%= l(:label_repository_access_url) %></h3>
20
    <%= render :partial => 'common/git_urls', :locals => {:repository => @repository} %>
21
  </div>
22
<% end %>
23

  
24
<%= render :partial => 'repositories/download_revision' %>
app/views/repository_protected_branches/_form.html.erb
1
<div id="validation_messages_protected_branch"><%= error_messages_for 'protected_branch' %></div>
2

  
3
<div class="box">
4
  <p><%= f.text_field :path,        :required => true, :size => 65, :label => l(:label_branch_path) %></p>
5
  <p><%= f.select     :permissions, options_for_select(RepositoryProtectedBranche::VALID_PERMS, @protected_branch.permissions),
6
                      :required => true,
7
                      :label    => :label_permissions %>
8
  </p>
9

  
10
  <%= hidden_field_tag "repository_protected_branche[user_list][]", "" %>
11

  
12
  <p><label for="repository_protected_branche[user_list]"><%= l(:label_user_list) %> :</label></p>
13
  <ul id="user_list">
14
    <% if @protected_branch.user_list.any? %>
15
      <% @protected_branch.user_list.each do |item| %>
16
        <li><%= item %></li>
17
      <% end %>
18
    <% end %>
19
  </ul>
20
</div>
21

  
22
<%= javascript_tag do %>
23
  var user_list = <%= raw @protected_branch.available_users.to_json %>;
24

  
25
  function loadTagIt(target){
26

  
27
    $('#' + target).gtagit({
28
      autocomplete: {source: function(request, resolve) {
29
          // fetch new values with request.resolve
30
          resolve(user_list);
31
        }
32
      },
33
      afterTagAdded: function(event, ui) {
34
        var value = ui.tag.children('input:hidden').val();
35
        user_list = user_list.filter(function(v) { return v != value;});
36
        $(".ui-dialog-content").dialog("option", "position", ['center', 'center']).animate('slow');
37
      },
38
      afterTagRemoved: function(event, ui) {
39
        var value = ui.tag.children('input:hidden').val();
40
        user_list.push(value);
41
        $(".ui-dialog-content").dialog("option", "position", ['center', 'center']).animate('slow');
42
      },
43
      showAutocompleteOnFocus: true,
44
      placeholderText: '+ add user',
45
      allowDuplicates: false,
46
      caseSensitive: false,
47
      fieldName: 'repository_protected_branche[' + target + '][]',
48
    });
49

  
50
  }
51

  
52
  $(document).ready(function() {
53
    loadTagIt('user_list');
54
  });
55
<% end %>
app/views/repository_protected_branches/edit.html.erb
1
<% if !@is_xhr %>
2
  <h2><%= l(:label_protected_branch_edit) %></h2>
3
<% end %>
4

  
5
<%= labelled_form_for :repository_protected_branche, @protected_branch,
6
                      :url  => repository_protected_branch_path(@repository, @protected_branch),
7
                      :html => { :method => :put, :class => 'tabular', :remote => @is_xhr } do |f| %>
8

  
9
  <%= render :partial => 'form', :locals => { :f => f } %>
10

  
11
  <% if !@is_xhr %>
12
    <%= submit_tag l(:button_save), :disable_with => l(:label_backup_in_progress) %>
13
    <%= link_to l(:button_cancel), url_for(:controller => 'repositories', :action => 'edit', :id => @repository.id) %>
14
  <% end %>
15
<% end %>
app/views/repository_protected_branches/form_error.js.erb
1
$('#validation_messages_protected_branch').html("<%= escape_javascript(error_messages_for 'protected_branch') %>");
app/views/repository_protected_branches/index.html.erb
1
<div>
2

  
3
  <% if user_allowed_to(:create_repository_protected_branches, @project) %>
4
    <div class="contextual">
5
      <%= link_to(l(:label_protected_branch_add), new_repository_protected_branch_path(@repository),
6
                                                  :class => 'icon icon-add modal-box') %>
7

  
8
    </div>
9
  <% end %>
10

  
11
  <h3><%= l(:label_protected_branches) %></h3>
12

  
13
  <% if @repository_protected_branches.any? %>
14

  
15
    <table id="protected_branches" class="table table-hover" data-update-url="<%= sort_repository_protected_branches_url %>">
16
      <thead>
... This diff was truncated because it exceeds the maximum size that can be displayed.
Terms of use | Privacy policy