Mercurial > hg > soundsoftware-site
comparison lib/redmine/scm/adapters/bazaar_adapter.rb @ 511:107d36338b70 live
Merge from branch "cannam"
author | Chris Cannam |
---|---|
date | Thu, 14 Jul 2011 10:43:07 +0100 |
parents | cbce1fd3b1b7 |
children | cbb26bc654de |
comparison
equal
deleted
inserted
replaced
451:a9f6345cb43d | 511:107d36338b70 |
---|---|
1 # redMine - project management software | 1 # Redmine - project management software |
2 # Copyright (C) 2006-2007 Jean-Philippe Lang | 2 # Copyright (C) 2006-2011 Jean-Philippe Lang |
3 # | 3 # |
4 # This program is free software; you can redistribute it and/or | 4 # This program is free software; you can redistribute it and/or |
5 # modify it under the terms of the GNU General Public License | 5 # modify it under the terms of the GNU General Public License |
6 # as published by the Free Software Foundation; either version 2 | 6 # as published by the Free Software Foundation; either version 2 |
7 # of the License, or (at your option) any later version. | 7 # of the License, or (at your option) any later version. |
8 # | 8 # |
9 # This program is distributed in the hope that it will be useful, | 9 # This program is distributed in the hope that it will be useful, |
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 # GNU General Public License for more details. | 12 # GNU General Public License for more details. |
13 # | 13 # |
14 # You should have received a copy of the GNU General Public License | 14 # You should have received a copy of the GNU General Public License |
15 # along with this program; if not, write to the Free Software | 15 # along with this program; if not, write to the Free Software |
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
17 | 17 |
18 require 'redmine/scm/adapters/abstract_adapter' | 18 require 'redmine/scm/adapters/abstract_adapter' |
19 | 19 |
20 module Redmine | 20 module Redmine |
21 module Scm | 21 module Scm |
22 module Adapters | 22 module Adapters |
23 class BazaarAdapter < AbstractAdapter | 23 class BazaarAdapter < AbstractAdapter |
24 | 24 |
25 # Bazaar executable name | 25 # Bazaar executable name |
26 BZR_BIN = "bzr" | 26 BZR_BIN = Redmine::Configuration['scm_bazaar_command'] || "bzr" |
27 | 27 |
28 class << self | |
29 def client_command | |
30 @@bin ||= BZR_BIN | |
31 end | |
32 | |
33 def sq_bin | |
34 @@sq_bin ||= shell_quote(BZR_BIN) | |
35 end | |
36 | |
37 def client_version | |
38 @@client_version ||= (scm_command_version || []) | |
39 end | |
40 | |
41 def client_available | |
42 !client_version.empty? | |
43 end | |
44 | |
45 def scm_command_version | |
46 scm_version = scm_version_from_command_line.dup | |
47 if scm_version.respond_to?(:force_encoding) | |
48 scm_version.force_encoding('ASCII-8BIT') | |
49 end | |
50 if m = scm_version.match(%r{\A(.*?)((\d+\.)+\d+)}) | |
51 m[2].scan(%r{\d+}).collect(&:to_i) | |
52 end | |
53 end | |
54 | |
55 def scm_version_from_command_line | |
56 shellout("#{sq_bin} --version") { |io| io.read }.to_s | |
57 end | |
58 end | |
59 | |
28 # Get info about the repository | 60 # Get info about the repository |
29 def info | 61 def info |
30 cmd = "#{BZR_BIN} revno #{target('')}" | 62 cmd = "#{self.class.sq_bin} revno #{target('')}" |
31 info = nil | 63 info = nil |
32 shellout(cmd) do |io| | 64 shellout(cmd) do |io| |
33 if io.read =~ %r{^(\d+)\r?$} | 65 if io.read =~ %r{^(\d+)\r?$} |
34 info = Info.new({:root_url => url, | 66 info = Info.new({:root_url => url, |
35 :lastrev => Revision.new({ | 67 :lastrev => Revision.new({ |
41 return nil if $? && $?.exitstatus != 0 | 73 return nil if $? && $?.exitstatus != 0 |
42 info | 74 info |
43 rescue CommandFailed | 75 rescue CommandFailed |
44 return nil | 76 return nil |
45 end | 77 end |
46 | 78 |
47 # Returns an Entries collection | 79 # Returns an Entries collection |
48 # or nil if the given path doesn't exist in the repository | 80 # or nil if the given path doesn't exist in the repository |
49 def entries(path=nil, identifier=nil) | 81 def entries(path=nil, identifier=nil, options={}) |
50 path ||= '' | 82 path ||= '' |
51 entries = Entries.new | 83 entries = Entries.new |
52 cmd = "#{BZR_BIN} ls -v --show-ids" | 84 cmd = "#{self.class.sq_bin} ls -v --show-ids" |
53 identifier = -1 unless identifier && identifier.to_i > 0 | 85 identifier = -1 unless identifier && identifier.to_i > 0 |
54 cmd << " -r#{identifier.to_i}" | 86 cmd << " -r#{identifier.to_i}" |
55 cmd << " #{target(path)}" | 87 cmd << " #{target(path)}" |
56 shellout(cmd) do |io| | 88 shellout(cmd) do |io| |
57 prefix = "#{url}/#{path}".gsub('\\', '/') | 89 prefix = "#{url}/#{path}".gsub('\\', '/') |
58 logger.debug "PREFIX: #{prefix}" | 90 logger.debug "PREFIX: #{prefix}" |
59 re = %r{^V\s+(#{Regexp.escape(prefix)})?(\/?)([^\/]+)(\/?)\s+(\S+)\r?$} | 91 re = %r{^V\s+(#{Regexp.escape(prefix)})?(\/?)([^\/]+)(\/?)\s+(\S+)\r?$} |
69 end | 101 end |
70 return nil if $? && $?.exitstatus != 0 | 102 return nil if $? && $?.exitstatus != 0 |
71 logger.debug("Found #{entries.size} entries in the repository for #{target(path)}") if logger && logger.debug? | 103 logger.debug("Found #{entries.size} entries in the repository for #{target(path)}") if logger && logger.debug? |
72 entries.sort_by_name | 104 entries.sort_by_name |
73 end | 105 end |
74 | 106 |
75 def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={}) | 107 def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={}) |
76 path ||= '' | 108 path ||= '' |
77 identifier_from = 'last:1' unless identifier_from and identifier_from.to_i > 0 | 109 identifier_from = (identifier_from and identifier_from.to_i > 0) ? identifier_from.to_i : 'last:1' |
78 identifier_to = 1 unless identifier_to and identifier_to.to_i > 0 | 110 identifier_to = (identifier_to and identifier_to.to_i > 0) ? identifier_to.to_i : 1 |
79 revisions = Revisions.new | 111 revisions = Revisions.new |
80 cmd = "#{BZR_BIN} log -v --show-ids -r#{identifier_to.to_i}..#{identifier_from} #{target(path)}" | 112 cmd = "#{self.class.sq_bin} log -v --show-ids -r#{identifier_to}..#{identifier_from} #{target(path)}" |
81 shellout(cmd) do |io| | 113 shellout(cmd) do |io| |
82 revision = nil | 114 revision = nil |
83 parsing = nil | 115 parsing = nil |
84 io.each_line do |line| | 116 io.each_line do |line| |
85 if line =~ /^----/ | 117 if line =~ /^----/ |
86 revisions << revision if revision | 118 revisions << revision if revision |
87 revision = Revision.new(:paths => [], :message => '') | 119 revision = Revision.new(:paths => [], :message => '') |
88 parsing = nil | 120 parsing = nil |
89 else | 121 else |
90 next unless revision | 122 next unless revision |
91 | |
92 if line =~ /^revno: (\d+)($|\s\[merge\]$)/ | 123 if line =~ /^revno: (\d+)($|\s\[merge\]$)/ |
93 revision.identifier = $1.to_i | 124 revision.identifier = $1.to_i |
94 elsif line =~ /^committer: (.+)$/ | 125 elsif line =~ /^committer: (.+)$/ |
95 revision.author = $1.strip | 126 revision.author = $1.strip |
96 elsif line =~ /^revision-id:(.+)$/ | 127 elsif line =~ /^revision-id:(.+)$/ |
130 revisions << revision if revision | 161 revisions << revision if revision |
131 end | 162 end |
132 return nil if $? && $?.exitstatus != 0 | 163 return nil if $? && $?.exitstatus != 0 |
133 revisions | 164 revisions |
134 end | 165 end |
135 | 166 |
136 def diff(path, identifier_from, identifier_to=nil) | 167 def diff(path, identifier_from, identifier_to=nil) |
137 path ||= '' | 168 path ||= '' |
138 if identifier_to | 169 if identifier_to |
139 identifier_to = identifier_to.to_i | 170 identifier_to = identifier_to.to_i |
140 else | 171 else |
141 identifier_to = identifier_from.to_i - 1 | 172 identifier_to = identifier_from.to_i - 1 |
142 end | 173 end |
143 cmd = "#{BZR_BIN} diff -r#{identifier_to}..#{identifier_from} #{target(path)}" | 174 if identifier_from |
175 identifier_from = identifier_from.to_i | |
176 end | |
177 cmd = "#{self.class.sq_bin} diff -r#{identifier_to}..#{identifier_from} #{target(path)}" | |
144 diff = [] | 178 diff = [] |
145 shellout(cmd) do |io| | 179 shellout(cmd) do |io| |
146 io.each_line do |line| | 180 io.each_line do |line| |
147 diff << line | 181 diff << line |
148 end | 182 end |
149 end | 183 end |
150 #return nil if $? && $?.exitstatus != 0 | 184 #return nil if $? && $?.exitstatus != 0 |
151 diff | 185 diff |
152 end | 186 end |
153 | 187 |
154 def cat(path, identifier=nil) | 188 def cat(path, identifier=nil) |
155 cmd = "#{BZR_BIN} cat" | 189 cmd = "#{self.class.sq_bin} cat" |
156 cmd << " -r#{identifier.to_i}" if identifier && identifier.to_i > 0 | 190 cmd << " -r#{identifier.to_i}" if identifier && identifier.to_i > 0 |
157 cmd << " #{target(path)}" | 191 cmd << " #{target(path)}" |
158 cat = nil | 192 cat = nil |
159 shellout(cmd) do |io| | 193 shellout(cmd) do |io| |
160 io.binmode | 194 io.binmode |
161 cat = io.read | 195 cat = io.read |
162 end | 196 end |
163 return nil if $? && $?.exitstatus != 0 | 197 return nil if $? && $?.exitstatus != 0 |
164 cat | 198 cat |
165 end | 199 end |
166 | 200 |
167 def annotate(path, identifier=nil) | 201 def annotate(path, identifier=nil) |
168 cmd = "#{BZR_BIN} annotate --all" | 202 cmd = "#{self.class.sq_bin} annotate --all" |
169 cmd << " -r#{identifier.to_i}" if identifier && identifier.to_i > 0 | 203 cmd << " -r#{identifier.to_i}" if identifier && identifier.to_i > 0 |
170 cmd << " #{target(path)}" | 204 cmd << " #{target(path)}" |
171 blame = Annotate.new | 205 blame = Annotate.new |
172 shellout(cmd) do |io| | 206 shellout(cmd) do |io| |
173 author = nil | 207 author = nil |
174 identifier = nil | 208 identifier = nil |
175 io.each_line do |line| | 209 io.each_line do |line| |
176 next unless line =~ %r{^(\d+) ([^|]+)\| (.*)$} | 210 next unless line =~ %r{^(\d+) ([^|]+)\| (.*)$} |
177 blame.add_line($3.rstrip, Revision.new(:identifier => $1.to_i, :author => $2.strip)) | 211 rev = $1 |
212 blame.add_line($3.rstrip, | |
213 Revision.new( | |
214 :identifier => rev, | |
215 :revision => rev, | |
216 :author => $2.strip | |
217 )) | |
178 end | 218 end |
179 end | 219 end |
180 return nil if $? && $?.exitstatus != 0 | 220 return nil if $? && $?.exitstatus != 0 |
181 blame | 221 blame |
182 end | 222 end |