Class: Redmine::Scm::Adapters::MercurialAdapter
- Inherits:
-
AbstractAdapter
- Object
- AbstractAdapter
- Redmine::Scm::Adapters::MercurialAdapter
- Defined in:
- lib/redmine/scm/adapters/mercurial_adapter.rb
Constant Summary
- HG_BIN =
Mercurial executable name
"hg"
- TEMPLATES_DIR =
File.dirname(__FILE__) + "/mercurial"
- TEMPLATE_NAME =
"hg-template"
- TEMPLATE_EXTENSION =
"tmpl"
Class Method Summary
- + (Object) client_version
- + (Object) hgversion
- + (Object) hgversion_from_command_line
- + (Object) template_path
- + (Object) template_path_for(version)
Instance Method Summary
- - (Object) annotate(path, identifier = nil)
- - (Object) cat(path, identifier = nil)
- - (Object) diff(path, identifier_from, identifier_to = nil)
- - (Object) entries(path = nil, identifier = nil)
- - (Object) info
-
- (Object) revisions(path = nil, identifier_from = nil, identifier_to = nil, options = {})
Fetch the revisions by using a template file that makes Mercurial produce a xml output.
Methods inherited from AbstractAdapter
#adapter_name, #branches, client_version_above?, client_version_string, #default_branch, #entry, #initialize, #properties, #root_url, #shell_quote, #supports_annotate?, #supports_cat?, #tags, #url, #with_leading_slash, #with_trailling_slash, #without_leading_slash, #without_trailling_slash
Constructor Details
This class inherits a constructor from Redmine::Scm::Adapters::AbstractAdapter
Class Method Details
+ (Object) client_version
32 33 34 |
# File 'lib/redmine/scm/adapters/mercurial_adapter.rb', line 32 def client_version @@client_version ||= (hgversion || []) end |
+ (Object) hgversion
36 37 38 39 40 41 42 43 44 |
# File 'lib/redmine/scm/adapters/mercurial_adapter.rb', line 36 def hgversion # The hg version is expressed either as a # release number (eg 0.9.5 or 1.0) or as a revision # id composed of 12 hexa characters. theversion = hgversion_from_command_line if theversion.match(/^\d+(\.\d+)+/) theversion.split(".").collect(&:to_i) end end |
+ (Object) hgversion_from_command_line
46 47 48 |
# File 'lib/redmine/scm/adapters/mercurial_adapter.rb', line 46 def hgversion_from_command_line %x{#{HG_BIN} --version}.match(/\(version (.*)\)/)[1] end |
+ (Object) template_path
50 51 52 |
# File 'lib/redmine/scm/adapters/mercurial_adapter.rb', line 50 def template_path @@template_path ||= template_path_for(client_version) end |
+ (Object) template_path_for(version)
54 55 56 57 58 59 60 61 |
# File 'lib/redmine/scm/adapters/mercurial_adapter.rb', line 54 def template_path_for(version) if ((version <=> [0,9,5]) > 0) || version.empty? ver = "1.0" else ver = "0.9.5" end "#{TEMPLATES_DIR}/#{TEMPLATE_NAME}-#{ver}.#{TEMPLATE_EXTENSION}" end |
Instance Method Details
- (Object) annotate(path, identifier = nil)
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/redmine/scm/adapters/mercurial_adapter.rb', line 185 def annotate(path, identifier=nil) path ||= '' cmd = "#{HG_BIN} -R #{target('')}" cmd << " annotate -n -u" cmd << " -r " + (identifier ? identifier.to_s : "tip") cmd << " -r #{identifier.to_i}" if identifier cmd << " #{target(path)}" blame = Annotate.new shellout(cmd) do |io| io.each_line do |line| next unless line =~ %r{^([^:]+)\s(\d+):(.*)$} blame.add_line($3.rstrip, Revision.new(:identifier => $2.to_i, :author => $1.strip)) end end return nil if $? && $?.exitstatus != 0 blame end |
- (Object) cat(path, identifier = nil)
172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/redmine/scm/adapters/mercurial_adapter.rb', line 172 def cat(path, identifier=nil) cmd = "#{HG_BIN} -R #{target('')} cat" cmd << " -r " + (identifier ? identifier.to_s : "tip") cmd << " #{target(path)}" cat = nil shellout(cmd) do |io| io.binmode cat = io.read end return nil if $? && $?.exitstatus != 0 cat end |
- (Object) diff(path, identifier_from, identifier_to = nil)
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/redmine/scm/adapters/mercurial_adapter.rb', line 153 def diff(path, identifier_from, identifier_to=nil) path ||= '' if identifier_to identifier_to = identifier_to.to_i else identifier_to = identifier_from.to_i - 1 end cmd = "#{HG_BIN} -R #{target('')} diff -r #{identifier_to} -r #{identifier_from} --nodates" cmd << " -I #{target(path)}" unless path.empty? diff = [] shellout(cmd) do |io| io.each_line do |line| diff << line end end return nil if $? && $?.exitstatus != 0 diff end |
- (Object) entries(path = nil, identifier = nil)
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/redmine/scm/adapters/mercurial_adapter.rb', line 79 def entries(path=nil, identifier=nil) path ||= '' entries = Entries.new cmd = "#{HG_BIN} -R #{target('')} --cwd #{target('')} locate" cmd << " -r " + (identifier ? identifier.to_s : "tip") cmd << " " + shell_quote("path:#{path}") unless path.empty? shellout(cmd) do |io| io.each_line do |line| # HG uses antislashs as separator on Windows line = line.gsub(/\\/, "/") if path.empty? or e = line.gsub!(%r{^#{with_trailling_slash(path)}},'') e ||= line e = e.chomp.split(%r{[\/\\]}) entries << Entry.new({:name => e.first, :path => (path.nil? or path.empty? ? e.first : "#{with_trailling_slash(path)}#{e.first}"), :kind => (e.size > 1 ? 'dir' : 'file'), :lastrev => Revision.new }) unless e.empty? || entries.detect{|entry| entry.name == e.first} end end end return nil if $? && $?.exitstatus != 0 entries.sort_by_name end |
- (Object) info
64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/redmine/scm/adapters/mercurial_adapter.rb', line 64 def info cmd = "#{HG_BIN} -R #{target('')} root" root_url = nil shellout(cmd) do |io| root_url = io.gets end return nil if $? && $?.exitstatus != 0 info = Info.new({:root_url => root_url.chomp, :lastrev => revisions(nil,nil,nil,{:limit => 1}).last }) info rescue CommandFailed return nil end |
- (Object) revisions(path = nil, identifier_from = nil, identifier_to = nil, options = {})
Fetch the revisions by using a template file that makes Mercurial produce a xml output.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/redmine/scm/adapters/mercurial_adapter.rb', line 106 def revisions(path=nil, identifier_from=nil, identifier_to=nil, ={}) revisions = Revisions.new cmd = "#{HG_BIN} --debug --encoding utf8 -R #{target('')} log -C --style #{shell_quote self.class.template_path}" if identifier_from && identifier_to cmd << " -r #{identifier_from.to_i}:#{identifier_to.to_i}" elsif identifier_from cmd << " -r #{identifier_from.to_i}:" end cmd << " --limit #{options[:limit].to_i}" if [:limit] cmd << " #{path}" if path shellout(cmd) do |io| begin # HG doesn't close the XML Document... doc = REXML::Document.new(io.read << "</log>") doc.elements.each("log/logentry") do |logentry| paths = [] copies = logentry.get_elements('paths/path-copied') logentry.elements.each("paths/path") do |path| # Detect if the added file is a copy if path.attributes['action'] == 'A' and c = copies.find{ |e| e.text == path.text } from_path = c.attributes['copyfrom-path'] from_rev = logentry.attributes['revision'] end paths << {:action => path.attributes['action'], :path => "/#{path.text}", :from_path => from_path ? "/#{from_path}" : nil, :from_revision => from_rev ? from_rev : nil } end paths.sort! { |x,y| x[:path] <=> y[:path] } revisions << Revision.new({:identifier => logentry.attributes['revision'], :scmid => logentry.attributes['node'], :author => (logentry.elements['author'] ? logentry.elements['author'].text : ""), :time => Time.parse(logentry.elements['date'].text).localtime, :message => logentry.elements['msg'].text, :paths => paths }) end rescue logger.debug($!) end end return nil if $? && $?.exitstatus != 0 revisions end |