Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
O
OHR Support
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
97
Issues
97
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
OHR Support
Commits
dd596d6d
Commit
dd596d6d
authored
Apr 18, 2012
by
Enrique García Cota
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
first release with git and svn
parent
59f92c97
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
229 additions
and
208 deletions
+229
-208
abstract_adapter.rb
lib/redmine/scm/adapters/abstract_adapter.rb
+25
-16
bazaar_adapter.rb
lib/redmine/scm/adapters/bazaar_adapter.rb
+1
-1
cvs_adapter.rb
lib/redmine/scm/adapters/cvs_adapter.rb
+1
-1
darcs_adapter.rb
lib/redmine/scm/adapters/darcs_adapter.rb
+1
-1
filesystem_adapter.rb
lib/redmine/scm/adapters/filesystem_adapter.rb
+1
-1
git_adapter.rb
lib/redmine/scm/adapters/git_adapter.rb
+85
-77
mercurial_adapter.rb
lib/redmine/scm/adapters/mercurial_adapter.rb
+1
-1
subversion_adapter.rb
lib/redmine/scm/adapters/subversion_adapter.rb
+114
-110
No files found.
lib/redmine/scm/adapters/abstract_adapter.rb
View file @
dd596d6d
...
...
@@ -143,6 +143,10 @@ module Redmine
return
nil
end
def
save_entry_to_temp_file
(
path
,
identifier
)
return
nil
end
def
with_leading_slash
(
path
)
path
||=
''
(
path
[
0
,
1
]
!=
"/"
)
?
"/
#{
path
}
"
:
path
...
...
@@ -183,34 +187,39 @@ module Redmine
self
.
class
.
logger
end
def
shellout
(
cmd
,
&
block
)
self
.
class
.
shellout
(
cmd
,
&
block
)
def
shellout
(
cmd
,
output_path
=
nil
,
&
block
)
self
.
class
.
shellout
(
cmd
,
output_path
,
&
block
)
end
def
self
.
logger
RAILS_DEFAULT_LOGGER
end
def
self
.
shellout
(
cmd
,
&
block
)
logger
.
debug
"Shelling out:
#{
strip_credential
(
cmd
)
}
"
if
logger
&&
logger
.
debug?
if
Rails
.
env
==
'development'
# Capture stderr when running in dev environment
cmd
=
"
#{
cmd
}
2>>
#{
RAILS_ROOT
}
/log/scm.stderr.log"
end
def
self
.
process_cmd
(
cmd
,
output_path
)
cmd
=
Rails
.
env
==
'development'
?
"
#{
cmd
}
2>>
#{
RAILS_ROOT
}
/log/scm.stderr.log"
:
cmd
cmd
=
"
#{
cmd
}
>>
#{
output_path
}
"
if
output_path
.
present?
cmd
end
def
self
.
get_reading_mode_for_ruby_version
RUBY_VERSION
<
'1.9'
?
'r+'
:
'r+:ASCII-8BIT'
end
def
self
.
shellout
(
cmd
,
output_path
=
nil
,
&
block
)
logger
.
debug
(
"Shelling out:
#{
strip_credential
(
cmd
)
}
"
)
if
logger
&&
logger
.
respond_to?
(
:debug
)
cmd
=
process_cmd
(
cmd
,
output_path
)
mode
=
get_reading_mode_for_ruby_version
begin
if
RUBY_VERSION
<
'1.9'
mode
=
"r+"
else
mode
=
"r+:ASCII-8BIT"
end
result
=
nil
IO
.
popen
(
cmd
,
mode
)
do
|
io
|
io
.
close_write
block
.
call
(
io
)
if
block_given?
result
=
block
.
call
(
io
)
if
block_given?
end
result
rescue
Errno
::
ENOENT
=>
e
msg
=
strip_credential
(
e
.
message
)
# The command failed, log it and re-raise
logger
.
error
(
"SCM command failed, make sure that your SCM binary (eg. svn) is in PATH (
#{
ENV
[
'PATH'
]
}
):
#{
strip_credential
(
cmd
)
}
\n
with:
#{
msg
}
"
)
cmd
=
strip_credential
(
cmd
)
logger
.
error
(
"SCM command failed, make sure that your SCM binary (eg. svn) is in PATH (
#{
ENV
[
'PATH'
]
}
):
#{
cmd
}
\n
with:
#{
msg
}
"
)
raise
CommandFailed
.
new
(
msg
)
end
end
...
...
lib/redmine/scm/adapters/bazaar_adapter.rb
View file @
dd596d6d
...
...
@@ -12,7 +12,7 @@
# See doc/COPYRIGHT.rdoc for more details.
#++
require
'redmine/scm/adapters/abstract_adapter'
require
_dependency
'redmine/scm/adapters/abstract_adapter'
module
Redmine
module
Scm
...
...
lib/redmine/scm/adapters/cvs_adapter.rb
View file @
dd596d6d
...
...
@@ -12,7 +12,7 @@
# See doc/COPYRIGHT.rdoc for more details.
#++
require
'redmine/scm/adapters/abstract_adapter'
require
_dependency
'redmine/scm/adapters/abstract_adapter'
module
Redmine
module
Scm
...
...
lib/redmine/scm/adapters/darcs_adapter.rb
View file @
dd596d6d
...
...
@@ -12,7 +12,7 @@
# See doc/COPYRIGHT.rdoc for more details.
#++
require
'redmine/scm/adapters/abstract_adapter'
require
_dependency
'redmine/scm/adapters/abstract_adapter'
require
'rexml/document'
module
Redmine
...
...
lib/redmine/scm/adapters/filesystem_adapter.rb
View file @
dd596d6d
...
...
@@ -12,7 +12,7 @@
# See doc/COPYRIGHT.rdoc for more details.
#++
require
'redmine/scm/adapters/abstract_adapter'
require
_dependency
'redmine/scm/adapters/abstract_adapter'
require
'find'
module
Redmine
...
...
lib/redmine/scm/adapters/git_adapter.rb
View file @
dd596d6d
...
...
@@ -12,7 +12,7 @@
# See doc/COPYRIGHT.rdoc for more details.
#++
require
'redmine/scm/adapters/abstract_adapter'
require
_dependency
'redmine/scm/adapters/abstract_adapter'
module
Redmine
module
Scm
...
...
@@ -24,9 +24,6 @@ module Redmine
# Git executable name
GIT_BIN
=
Redmine
::
Configuration
[
'scm_git_command'
]
||
"git"
unless
defined?
(
GIT_BIN
)
# raised if scm command exited with error, e.g. unknown revision.
class
ScmCommandAborted
<
CommandFailed
;
end
class
<<
self
def
client_command
@@bin
||=
GIT_BIN
...
...
@@ -75,26 +72,22 @@ module Redmine
def
branches
return
@branches
if
@branches
@branches
=
[]
cmd_args
=
%w|branch --no-color|
scm_cmd
(
*
cmd_args
)
do
|
io
|
scm_cmd
(
cmd_args
)
do
|
io
|
@branches
=
[]
io
.
each_line
do
|
line
|
@branches
<<
line
.
match
(
'\s*\*?\s*(.*)$'
)[
1
]
end
@branches
.
sort!
end
@branches
.
sort!
rescue
ScmCommandAborted
nil
end
def
tags
return
@tags
if
@tags
cmd_args
=
%w|tag|
scm_cmd
(
*
cmd_args
)
do
|
io
|
scm_cmd
(
cmd_args
)
do
|
io
|
@tags
=
io
.
readlines
.
sort!
.
map
{
|
t
|
t
.
strip
}
end
rescue
ScmCommandAborted
nil
end
def
default_branch
...
...
@@ -106,11 +99,14 @@ module Redmine
def
entries
(
path
=
nil
,
identifier
=
nil
)
path
||=
''
p
=
scm_iconv
(
@path_encoding
,
'UTF-8'
,
path
)
entries
=
Entries
.
new
cmd_args
=
%w|ls-tree -l|
cmd_args
<<
"HEAD:
#{
p
}
"
if
identifier
.
nil?
cmd_args
<<
"
#{
identifier
}
:
#{
p
}
"
if
identifier
scm_cmd
(
*
cmd_args
)
do
|
io
|
scm_cmd
(
cmd_args
)
do
|
io
|
entries
=
Entries
.
new
io
.
each_line
do
|
line
|
e
=
line
.
chomp
.
to_s
if
e
=~
/^\d+\s+(\w+)\s+([0-9a-f]{40})\s+([0-9-]+)\t(.+)$/
...
...
@@ -124,18 +120,20 @@ module Redmine
full_path
=
p
.
empty?
?
name
:
"
#{
p
}
/
#{
name
}
"
n
=
scm_iconv
(
'UTF-8'
,
@path_encoding
,
name
)
full_p
=
scm_iconv
(
'UTF-8'
,
@path_encoding
,
full_path
)
entries
<<
Entry
.
new
({
:name
=>
n
,
:path
=>
full_p
,
:kind
=>
(
type
==
"tree"
)
?
'dir'
:
'file'
,
:size
=>
(
type
==
"tree"
)
?
nil
:
size
,
:lastrev
=>
@flag_report_last_commit
?
lastrev
(
full_path
,
identifier
)
:
Revision
.
new
})
unless
entries
.
detect
{
|
entry
|
entry
.
name
==
name
}
unless
entries
.
detect
{
|
entry
|
entry
.
name
==
name
}
entries
<<
Entry
.
new
({
:name
=>
n
,
:path
=>
full_p
,
:kind
=>
(
type
==
"tree"
)
?
'dir'
:
'file'
,
:size
=>
(
type
==
"tree"
)
?
nil
:
size
,
:lastrev
=>
@flag_report_last_commit
?
lastrev
(
full_path
,
identifier
)
:
Revision
.
new
})
end
end
end
entries
.
sort_by_name
end
entries
.
sort_by_name
rescue
ScmCommandAborted
nil
end
def
lastrev
(
path
,
rev
)
...
...
@@ -143,9 +141,9 @@ module Redmine
cmd_args
=
%w|log --no-color --encoding=UTF-8 --date=iso --pretty=fuller --no-merges -n 1|
cmd_args
<<
rev
if
rev
cmd_args
<<
"--"
<<
path
unless
path
.
empty?
lines
=
[]
scm_cmd
(
*
cmd_args
)
{
|
io
|
lines
=
io
.
readlines
}
begin
lines
=
scm_cmd
(
cmd_args
)
{
|
io
|
io
.
readlines
}
if
lines
begin
id
=
lines
[
0
].
split
[
1
]
author
=
lines
[
1
].
match
(
'Author:\s+(.*)$'
)[
1
]
time
=
Time
.
parse
(
lines
[
4
].
match
(
'CommitDate:\s+(.*)$'
)[
1
])
...
...
@@ -157,17 +155,17 @@ module Redmine
:time
=>
time
,
:message
=>
nil
,
:paths
=>
nil
})
rescue
NoMethodError
=>
e
})
rescue
NoMethodError
=>
e
logger
.
error
(
"The revision '
#{
path
}
' has a wrong format"
)
return
nil
end
end
rescue
ScmCommandAborted
nil
end
def
revisions
(
path
,
identifier_from
,
identifier_to
,
options
=
{})
revisions
=
Revisions
.
new
cmd_args
=
%w|log --no-color --encoding=UTF-8 --raw --date=iso --pretty=fuller|
cmd_args
<<
"--reverse"
if
options
[
:reverse
]
cmd_args
<<
"--all"
if
options
[
:all
]
...
...
@@ -179,7 +177,7 @@ module Redmine
cmd_args
<<
"--since='
#{
options
[
:since
].
strftime
(
"%Y-%m-%d %H:%M:%S"
)
}
'"
if
options
[
:since
]
cmd_args
<<
"--"
<<
scm_iconv
(
@path_encoding
,
'UTF-8'
,
path
)
if
path
&&
!
path
.
empty?
scm_cmd
*
cmd_args
do
|
io
|
scm_cmd
cmd_args
do
|
io
|
files
=
[]
changeset
=
{}
parsing_descr
=
0
#0: not parsing desc or files, 1: parsing desc, 2: parsing files
...
...
@@ -255,10 +253,9 @@ module Redmine
revisions
<<
revision
end
end
revisions
end
revisions
rescue
ScmCommandAborted
revisions
end
def
diff
(
path
,
identifier_from
,
identifier_to
=
nil
)
...
...
@@ -271,14 +268,12 @@ module Redmine
end
cmd_args
<<
"--"
<<
scm_iconv
(
@path_encoding
,
'UTF-8'
,
path
)
unless
path
.
empty?
diff
=
[]
scm_cmd
*
cmd_args
do
|
io
|
scm_cmd
cmd_args
do
|
io
|
io
.
each_line
do
|
line
|
diff
<<
line
end
diff
end
diff
rescue
ScmCommandAborted
nil
end
def
annotate
(
path
,
identifier
=
nil
)
...
...
@@ -286,34 +281,36 @@ module Redmine
cmd_args
=
%w|blame|
cmd_args
<<
"-p"
<<
identifier
<<
"--"
<<
scm_iconv
(
@path_encoding
,
'UTF-8'
,
path
)
blame
=
Annotate
.
new
content
=
nil
scm_cmd
(
*
cmd_args
)
{
|
io
|
io
.
binmode
;
content
=
io
.
read
}
# git annotates binary files
if
content
.
respond_to?
(
"is_binary_data?"
)
&&
content
.
is_binary_data?
# Ruby 1.8.x and <1.9.2
return
nil
elsif
content
.
respond_to?
(
:force_encoding
)
&&
(
content
.
dup
.
force_encoding
(
"UTF-8"
)
!=
content
.
dup
.
force_encoding
(
"BINARY"
))
# Ruby 1.9.2
# TODO: need to handle edge cases of non-binary content that isn't UTF-8
return
nil
content
=
scm_cmd
(
cmd_args
)
do
|
io
|
io
.
binmode
io
.
read
end
identifier
=
''
# git shows commit author on the first occurrence only
authors_by_commit
=
{}
content
.
split
(
"
\n
"
).
each
do
|
line
|
if
line
=~
/^([0-9a-f]{39,40})\s.*/
identifier
=
$1
elsif
line
=~
/^author (.+)/
authors_by_commit
[
identifier
]
=
$1
.
strip
elsif
line
=~
/^\t(.*)/
blame
.
add_line
(
$1
,
Revision
.
new
(
:identifier
=>
identifier
,
:author
=>
authors_by_commit
[
identifier
]))
identifier
=
''
author
=
''
if
content
# git annotates binary files
if
content
.
respond_to?
(
"is_binary_data?"
)
&&
content
.
is_binary_data?
# Ruby 1.8.x and <1.9.2
return
nil
elsif
content
.
respond_to?
(
:force_encoding
)
&&
(
content
.
dup
.
force_encoding
(
"UTF-8"
)
!=
content
.
dup
.
force_encoding
(
"BINARY"
))
# Ruby 1.9.2
# TODO: need to handle edge cases of non-binary content that isn't UTF-8
return
nil
end
identifier
=
''
# git shows commit author on the first occurrence only
authors_by_commit
=
{}
content
.
split
(
"
\n
"
).
each
do
|
line
|
if
line
=~
/^([0-9a-f]{39,40})\s.*/
identifier
=
$1
elsif
line
=~
/^author (.+)/
authors_by_commit
[
identifier
]
=
$1
.
strip
elsif
line
=~
/^\t(.*)/
blame
.
add_line
(
$1
,
Revision
.
new
(
:identifier
=>
identifier
,
:author
=>
authors_by_commit
[
identifier
]))
identifier
=
''
author
=
''
end
end
blame
end
blame
rescue
ScmCommandAborted
nil
end
def
cat
(
path
,
identifier
=
nil
)
...
...
@@ -322,14 +319,18 @@ module Redmine
end
cmd_args
=
%w|show --no-color|
cmd_args
<<
"
#{
identifier
}
:
#{
scm_iconv
(
@path_encoding
,
'UTF-8'
,
path
)
}
"
cat
=
nil
scm_cmd
(
*
cmd_args
)
do
|
io
|
scm_cmd
(
cmd_args
)
do
|
io
|
io
.
binmode
cat
=
io
.
read
io
.
read
end
cat
rescue
ScmCommandAborted
nil
end
def
save_entry_to_temp_file
(
path
,
identifier
)
f
=
Tempfile
.
new
(
path
.
split
(
"/"
).
last
,
File
.
join
(
Rails
.
root
,
'tmp'
))
cmd_args
=
%w|show --no-color|
cmd_args
<<
"
#{
identifier
}
:
#{
scm_iconv
(
@path_encoding
,
'UTF-8'
,
path
)
}
"
scm_cmd
(
cmd_args
,
f
.
path
)
f
end
class
Revision
<
Redmine
::
Scm
::
Adapters
::
Revision
...
...
@@ -339,20 +340,27 @@ module Redmine
end
end
def
scm_cmd
(
*
args
,
&
block
)
private
def
scm_cmd
(
cmd_args
,
output_path
=
nil
,
&
block
)
cmd
=
build_scm_cmd
(
cmd_args
)
begin
ret
=
shellout
(
cmd
,
output_path
,
&
block
)
rescue
Exception
=>
e
logger
.
error
(
"Error executing Git:
#{
e
.
message
}
"
)
end
return
nil
if
$?
&&
$?
.
exitstatus
!=
0
ret
end
# returns the string that will represent the command for shelling out
def
build_scm_cmd
(
args
)
repo_path
=
root_url
||
url
full_args
=
[
GIT_BIN
,
'--git-dir'
,
repo_path
]
if
self
.
class
.
client_version_above?
([
1
,
7
,
2
])
full_args
<<
'-c'
<<
'core.quotepath=false'
end
full_args
+=
args
ret
=
shellout
(
full_args
.
map
{
|
e
|
shell_quote
e
.
to_s
}.
join
(
' '
),
&
block
)
if
$?
&&
$?
.
exitstatus
!=
0
raise
ScmCommandAborted
,
"git exited with non-zero status:
#{
$?
.
exitstatus
}
"
end
ret
(
full_args
+
args
).
map
{
|
e
|
shell_quote
e
.
to_s
}.
join
(
' '
)
end
private
:scm_cmd
end
end
end
...
...
lib/redmine/scm/adapters/mercurial_adapter.rb
View file @
dd596d6d
...
...
@@ -12,7 +12,7 @@
# See doc/COPYRIGHT.rdoc for more details.
#++
require
'redmine/scm/adapters/abstract_adapter'
require
_dependency
'redmine/scm/adapters/abstract_adapter'
require
'cgi'
module
Redmine
...
...
lib/redmine/scm/adapters/subversion_adapter.rb
View file @
dd596d6d
...
...
@@ -12,7 +12,7 @@
# See doc/COPYRIGHT.rdoc for more details.
#++
require
'redmine/scm/adapters/abstract_adapter'
require
_dependency
'redmine/scm/adapters/abstract_adapter'
require
'uri'
module
Redmine
...
...
@@ -57,194 +57,198 @@ module Redmine
# Get info about the svn repository
def
info
cmd
=
"
#{
self
.
class
.
sq_bin
}
info --xml
#{
target
}
"
cmd
<<
credentials_string
info
=
nil
shellout
(
cmd
)
do
|
io
|
cmd_args
=
[
'info'
,
'--xml'
,
target
,
credentials_string
]
scm_cmd
(
cmd_args
)
do
|
io
|
output
=
io
.
read
if
output
.
respond_to?
(
:force_encoding
)
output
.
force_encoding
(
'UTF-8'
)
end
begin
doc
=
ActiveSupport
::
XmlMini
.
parse
(
output
)
#root_url = doc.elements["info/entry/repository/root"].text
info
=
Info
.
new
({
:root_url
=>
doc
[
'info'
][
'entry'
][
'repository'
][
'root'
][
'__content__'
],
:lastrev
=>
Revision
.
new
({
:identifier
=>
doc
[
'info'
][
'entry'
][
'commit'
][
'revision'
],
:time
=>
Time
.
parse
(
doc
[
'info'
][
'entry'
][
'commit'
][
'date'
][
'__content__'
]).
localtime
,
:author
=>
(
doc
[
'info'
][
'entry'
][
'commit'
][
'author'
]
?
doc
[
'info'
][
'entry'
][
'commit'
][
'author'
][
'__content__'
]
:
""
)
})
})
rescue
end
doc
=
ActiveSupport
::
XmlMini
.
parse
(
output
)
#root_url = doc.elements["info/entry/repository/root"].text
Info
.
new
({
:root_url
=>
doc
[
'info'
][
'entry'
][
'repository'
][
'root'
][
'__content__'
],
:lastrev
=>
Revision
.
new
({
:identifier
=>
doc
[
'info'
][
'entry'
][
'commit'
][
'revision'
],
:time
=>
Time
.
parse
(
doc
[
'info'
][
'entry'
][
'commit'
][
'date'
][
'__content__'
]).
localtime
,
:author
=>
(
doc
[
'info'
][
'entry'
][
'commit'
][
'author'
]
?
doc
[
'info'
][
'entry'
][
'commit'
][
'author'
][
'__content__'
]
:
""
)
})
})
end
return
nil
if
$?
&&
$?
.
exitstatus
!=
0
info
rescue
CommandFailed
return
nil
end
# Returns an Entries collection
# or nil if the given path doesn't exist in the repository
def
entries
(
path
=
nil
,
identifier
=
nil
)
path
||=
''
identifier
=
(
identifier
and
identifier
.
to_i
>
0
)
?
identifier
.
to_i
:
"HEAD"
identifier
=
initialize_identifier
(
identifier
)
entries
=
Entries
.
new
cmd
=
"
#{
self
.
class
.
sq_bin
}
list --xml
#{
target
(
path
)
}
@
#{
identifier
}
"
cmd
<<
credentials_string
shellout
(
cmd
)
do
|
io
|
cmd_args
=
[
'list'
,
'--xml'
,
"
#{
target
(
path
)
}
@
#{
identifier
}
"
,
credentials_string
]
scm_cmd
(
cmd_args
)
do
|
io
|
output
=
io
.
read
if
output
.
respond_to?
(
:force_encoding
)
output
.
force_encoding
(
'UTF-8'
)
end
begin
doc
=
ActiveSupport
::
XmlMini
.
parse
(
output
)
each_xml_element
(
doc
[
'lists'
][
'list'
],
'entry'
)
do
|
entry
|
commit
=
entry
[
'commit'
]
commit_date
=
commit
[
'date'
]
# Skip directory if there is no commit date (usually that
# means that we don't have read access to it)
next
if
entry
[
'kind'
]
==
'dir'
&&
commit_date
.
nil?
name
=
entry
[
'name'
][
'__content__'
]
entries
<<
Entry
.
new
({
:name
=>
URI
.
unescape
(
name
),
:path
=>
((
path
.
empty?
?
""
:
"
#{
path
}
/"
)
+
name
),
:kind
=>
entry
[
'kind'
],
:size
=>
((
s
=
entry
[
'size'
])
?
s
[
'__content__'
].
to_i
:
nil
),
:lastrev
=>
Revision
.
new
({
:identifier
=>
commit
[
'revision'
],
:time
=>
Time
.
parse
(
commit_date
[
'__content__'
].
to_s
).
localtime
,
:author
=>
((
a
=
commit
[
'author'
])
?
a
[
'__content__'
]
:
nil
)
})
doc
=
ActiveSupport
::
XmlMini
.
parse
(
output
)
each_xml_element
(
doc
[
'lists'
][
'list'
],
'entry'
)
do
|
entry
|
commit
=
entry
[
'commit'
]
commit_date
=
commit
[
'date'
]
# Skip directory if there is no commit date (usually that
# means that we don't have read access to it)
next
if
entry
[
'kind'
]
==
'dir'
&&
commit_date
.
nil?
name
=
entry
[
'name'
][
'__content__'
]
entries
<<
Entry
.
new
({
:name
=>
URI
.
unescape
(
name
),
:path
=>
((
path
.
empty?
?
""
:
"
#{
path
}
/"
)
+
name
),
:kind
=>
entry
[
'kind'
],
:size
=>
((
s
=
entry
[
'size'
])
?
s
[
'__content__'
].
to_i
:
nil
),
:lastrev
=>
Revision
.
new
({
:identifier
=>
commit
[
'revision'
],
:time
=>
Time
.
parse
(
commit_date
[
'__content__'
].
to_s
).
localtime
,
:author
=>
((
a
=
commit
[
'author'
])
?
a
[
'__content__'
]
:
nil
)
})
end
rescue
Exception
=>
e
logger
.
error
(
"Error parsing svn output:
#{
e
.
message
}
"
)
logger
.
error
(
"Output was:
\n
#{
output
}
"
)
})
end
logger
.
debug
(
"Found
#{
entries
.
size
}
entries in the repository for
#{
target
(
path
)
}
"
)
if
logger
&&
logger
.
debug?
entries
.
sort_by_name
end
return
nil
if
$?
&&
$?
.
exitstatus
!=
0
logger
.
debug
(
"Found
#{
entries
.
size
}
entries in the repository for
#{
target
(
path
)
}
"
)
if
logger
&&
logger
.
debug?
entries
.
sort_by_name
end
def
properties
(
path
,
identifier
=
nil
)
# proplist xml output supported in svn 1.5.0 and higher
return
nil
unless
self
.
class
.
client_version_above?
([
1
,
5
,
0
])
identifier
=
(
identifier
and
identifier
.
to_i
>
0
)
?
identifier
.
to_i
:
"HEAD"
cmd
=
"
#{
self
.
class
.
sq_bin
}
proplist --verbose --xml
#{
target
(
path
)
}
@
#{
identifier
}
"
cmd
<<
credentials_string
identifier
=
initialize_identifier
(
identifier
)
cmd_args
=
[
'proplist'
,
'--verbose'
,
'--xml'
,
"
#{
target
(
path
)
}
@
#{
identifier
}
"
,
credentials_string
]
properties
=
{}
s
hellout
(
cmd
)
do
|
io
|
s
cm_cmd
(
cmd_args
)
do
|
io
|
output
=
io
.
read
if
output
.
respond_to?
(
:force_encoding
)
output
.
force_encoding
(
'UTF-8'
)
end
begin
doc
=
ActiveSupport
::
XmlMini
.
parse
(
output
)
each_xml_element
(
doc
[
'properties'
][
'target'
],
'property'
)
do
|
property
|
properties
[
property
[
'name'
]
]
=
property
[
'__content__'
].
to_s
end
rescue
doc
=
ActiveSupport
::
XmlMini
.
parse
(
output
)
each_xml_element
(
doc
[
'properties'
][
'target'
],
'property'
)
do
|
property
|
properties
[
property
[
'name'
]
]
=
property
[
'__content__'
].
to_s
end
properties
end
return
nil
if
$?
&&
$?
.
exitstatus
!=
0
properties
end
def
revisions
(
path
=
nil
,
identifier_from
=
nil
,
identifier_to
=
nil
,
options
=
{})
path
||=
''
identifier_from
=
(
identifier_from
&&
identifier_from
.
to_i
>
0
)
?
identifier_from
.
to_i
:
"HEAD"
identifier_to
=
(
identifier_to
&&
identifier_to
.
to_i
>
0
)
?
identifier_to
.
to_i
:
1
identifier_from
=
initialize_identifier
(
identifier_from
)
identifier_to
=
initialize_identifier
(
identifier_to
,
1
)
cmd_args
=
[
'log'
,
'--xml'
,
'-r'
,
"
#{
identifier_from
}
:
#{
identifier_to
}
"
,
credentials_string
]
cmd_args
<<
" --verbose "
if
options
[
:with_paths
]
cmd_args
<<
" --limit
#{
options
[
:limit
].
to_i
}
"
if
options
[
:limit
]
cmd_args
<<
target
(
path
)
revisions
=
Revisions
.
new
cmd
=
"
#{
self
.
class
.
sq_bin
}
log --xml -r
#{
identifier_from
}
:
#{
identifier_to
}
"
cmd
<<
credentials_string
cmd
<<
" --verbose "
if
options
[
:with_paths
]
cmd
<<
" --limit
#{
options
[
:limit
].
to_i
}
"
if
options
[
:limit
]
cmd
<<
' '
+
target
(
path
)
shellout
(
cmd
)
do
|
io
|
scm_cmd
(
cmd_args
)
do
|
io
|
output
=
io
.
read
if
output
.
respond_to?
(
:force_encoding
)
output
.
force_encoding
(
'UTF-8'
)
end
begin
doc
=
ActiveSupport
::
XmlMini
.
parse
(
output
)
each_xml_element
(
doc
[
'log'
],
'logentry'
)
do
|
logentry
|
paths
=
[]
doc
=
ActiveSupport
::
XmlMini
.
parse
(
output
)
each_xml_element
(
doc
[
'log'
],
'logentry'
)
do
|
logentry
|
paths
=
[]
if
logentry
[
'paths'
]
&&
logentry
[
'paths'
][
'path'
]
each_xml_element
(
logentry
[
'paths'
],
'path'
)
do
|
path
|
paths
<<
{
:action
=>
path
[
'action'
],
:path
=>
path
[
'__content__'
],
:from_path
=>
path
[
'copyfrom-path'
],
:from_revision
=>
path
[
'copyfrom-rev'
]
}
end
if
logentry
[
'paths'
]
&&
logentry
[
'paths'
][
'path'
]
paths
.
sort!
{
|
x
,
y
|
x
[
:path
]
<=>
y
[
:path
]
}
revisions
<<
Revision
.
new
({
:identifier
=>
logentry
[
'revision'
],
:author
=>
(
logentry
[
'author'
]
?
logentry
[
'author'
][
'__content__'
]
:
""
),
:time
=>
Time
.
parse
(
logentry
[
'date'
][
'__content__'
].
to_s
).
localtime
,
:message
=>
logentry
[
'msg'
][
'__content__'
],
:paths
=>
paths
})
end
end
rescue
paths
.
sort!
{
|
x
,
y
|
x
[
:path
]
<=>
y
[
:path
]
}
revisions
<<
Revision
.
new
({
:identifier
=>
logentry
[
'revision'
],
:author
=>
(
logentry
[
'author'
]
?
logentry
[
'author'
][
'__content__'
]
:
""
),
:time
=>
Time
.
parse
(
logentry
[
'date'
][
'__content__'
].
to_s
).
localtime
,
:message
=>
logentry
[
'msg'
][
'__content__'
],
:paths
=>
paths
})
end
revisions
end
return
nil
if
$?
&&
$?
.
exitstatus
!=
0
revisions
end
def
diff
(
path
,
identifier_from
,
identifier_to
=
nil
,
type
=
"inline"
)
path
||=
''
identifier_from
=
(
identifier_from
and
identifier_from
.
to_i
>
0
)
?
identifier_from
.
to_i
:
''
identifier_to
=
(
identifier_to
and
identifier_to
.
to_i
>
0
)
?
identifier_to
.
to_i
:
(
identifier_from
.
to_i
-
1
)
cmd
=
"
#{
self
.
class
.
sq_bin
}
diff -r "
cmd
<<
"
#{
identifier_to
}
:"
cmd
<<
"
#{
identifier_from
}
"
cmd
<<
"
#{
target
(
path
)
}
@
#{
identifier_from
}
"
cmd
<<
credentials_string
identifier_from
=
initialize_identifier
(
identifier_from
,
''
)
identifier_to
=
initialize_identifier
(
identifier_to
,
identifier_from
.
to_i
-
1
)
cmd_args
=
[
"diff -r"
,
"
#{
identifier_to
}
:
#{
identifier_from
}
"
,
"
#{
target
(
path
)
}
@
#{
identifier_from
}
"
,
credentials_string
]
diff
=
[]
s
hellout
(
cmd
)
do
|
io
|
s
cm_cmd
(
cmd_args
)
do
|
io
|
io
.
each_line
do
|
line
|
diff
<<
line
end
diff
end
return
nil
if
$?
&&
$?
.
exitstatus
!=
0
diff
end
def
cat
(
path
,
identifier
=
nil
)
identifier
=
(
identifier
and
identifier
.
to_i
>
0
)
?
identifier
.
to_i
:
"HEAD"
cmd
=
"
#{
self
.
class
.
sq_bin
}
cat
#{
target
(
path
)
}
@
#{
identifier
}
"
cmd
<<
credentials_string
cat
=
nil
shellout
(
cmd
)
do
|
io
|
identifier
=
initialize_identifier
(
identifier
)
cmd_args
=
[
'cat'
,
"
#{
target
(
path
)
}
@
#{
identifier
}
"
,
credentials_string
]
scm_cmd
(
cmd_args
)
do
|
io
|
io
.
binmode
cat
=
io
.
read
io
.
read
end
return
nil
if
$?
&&
$?
.
exitstatus
!=
0
cat
end
def
save_entry_to_temp_file
(
path
,
identifier
)
f
=
Tempfile
.
new
(
path
.
split
(
"/"
).
last
,
File
.
join
(
Rails
.
root
,
'tmp'
))
identifier
=
initialize_identifier
(
identifier
)
cmd_args
=
[
'cat'
,
"
#{
target
(
path
)
}
@
#{
identifier
}
"
,
credentials_string
]
scm_cmd
(
cmd_args
,
f
.
path
)
f
end
def
annotate
(
path
,
identifier
=
nil
)
identifier
=
(
identifier
and
identifier
.
to_i
>
0
)
?
identifier
.
to_i
:
"HEAD"
cmd
=
"
#{
self
.
class
.
sq_bin
}
blame
#{
target
(
path
)
}
@
#{
identifier
}
"
cmd
<<
credentials_string
identifier
=
initialize_identifier
(
identifier
)
cmd_args
=
[
'blame'
,
"
#{
target
(
path
)
}
@
#{
identifier
}
"
,
credentials_string
]
blame
=
Annotate
.
new
s
hellout
(
cmd
)
do
|
io
|
s
cm_cmd
(
cmd_args
)
do
|
io
|
io
.
each_line
do
|
line
|
next
unless
line
=~
%r{^
\s
*(
\d
+)
\s
*(
\S
+)
\s
(.*)$}
blame
.
add_line
(
$3
.
rstrip
,
Revision
.
new
(
:identifier
=>
$1
.
to_i
,
:author
=>
$2
.
strip
))
end
blame
end
return
nil
if
$?
&&
$?
.
exitstatus
!=
0
blame
end
private
def
initialize_identifier
(
identifier
,
default
=
"HEAD"
)
(
identifier
&&
identifier
.
to_i
>
0
)
?
identifier
.
to_i
:
default
end
def
scm_cmd
(
cmd_args
,
output_path
=
nil
,
&
block
)
cmd
=
build_scm_cmd
(
cmd_args
)
begin
ret
=
shellout
(
cmd
,
output_path
,
&
block
)
rescue
Exception
=>
e
logger
.
error
(
"Error executing SVN:
#{
e
.
message
}
"
)
end
return
nil
if
$?
&&
$?
.
exitstatus
!=
0
ret
end
# returns the string that will represent the command for shelling out
def
build_scm_cmd
(
args
)
([
self
.
class
.
sq_bin
]
+
args
).
join
(
' '
)
end
def
credentials_string
str
=
''
str
<<
" --username
#{
shell_quote
(
@login
)
}
"
unless
@login
.
blank?
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment