Patch #26391 » 0001-Drop-Darcs-support.patch
| app/helpers/repositories_helper.rb | ||
|---|---|---|
| 157 | 157 |
:onchange => "this.name='repository[password]';")) |
| 158 | 158 |
end |
| 159 | 159 | |
| 160 |
def darcs_field_tags(form, repository) |
|
| 161 |
content_tag('p', form.text_field(
|
|
| 162 |
:url, :label => l(:field_path_to_repository), |
|
| 163 |
:size => 60, :required => true, |
|
| 164 |
:disabled => !repository.safe_attribute?('url')) +
|
|
| 165 |
scm_path_info_tag(repository)) + |
|
| 166 |
scm_log_encoding_tag(form, repository) |
|
| 167 |
end |
|
| 168 | ||
| 169 | 160 |
def mercurial_field_tags(form, repository) |
| 170 | 161 |
content_tag('p', form.text_field(
|
| 171 | 162 |
:url, :label => l(:field_path_to_repository), |
| ... | ... | |
| 279 | 270 |
} |
| 280 | 271 |
end |
| 281 | 272 |
heads.sort! { |head1, head2| head1.to_s <=> head2.to_s }
|
| 282 |
space = nil
|
|
| 273 |
space = nil |
|
| 283 | 274 |
heads.each do |head| |
| 284 | 275 |
if commits_by_scmid.include? head.scmid |
| 285 | 276 |
space = index_head((space || -1) + 1, head, commits_by_scmid) |
| app/models/repository/darcs.rb | ||
|---|---|---|
| 1 |
# Redmine - project management software |
|
| 2 |
# Copyright (C) 2006-2017 Jean-Philippe Lang |
|
| 3 |
# |
|
| 4 |
# This program is free software; you can redistribute it and/or |
|
| 5 |
# modify it under the terms of the GNU General Public License |
|
| 6 |
# as published by the Free Software Foundation; either version 2 |
|
| 7 |
# of the License, or (at your option) any later version. |
|
| 8 |
# |
|
| 9 |
# This program is distributed in the hope that it will be useful, |
|
| 10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
# GNU General Public License for more details. |
|
| 13 |
# |
|
| 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 |
|
| 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
| 17 | ||
| 18 |
require 'redmine/scm/adapters/darcs_adapter' |
|
| 19 | ||
| 20 |
class Repository::Darcs < Repository |
|
| 21 |
validates_presence_of :url, :log_encoding |
|
| 22 | ||
| 23 |
def self.human_attribute_name(attribute_key_name, *args) |
|
| 24 |
attr_name = attribute_key_name.to_s |
|
| 25 |
if attr_name == "url" |
|
| 26 |
attr_name = "path_to_repository" |
|
| 27 |
end |
|
| 28 |
super(attr_name, *args) |
|
| 29 |
end |
|
| 30 | ||
| 31 |
def self.scm_adapter_class |
|
| 32 |
Redmine::Scm::Adapters::DarcsAdapter |
|
| 33 |
end |
|
| 34 | ||
| 35 |
def self.scm_name |
|
| 36 |
'Darcs' |
|
| 37 |
end |
|
| 38 | ||
| 39 |
def supports_directory_revisions? |
|
| 40 |
true |
|
| 41 |
end |
|
| 42 | ||
| 43 |
def entry(path=nil, identifier=nil) |
|
| 44 |
patch = identifier.nil? ? nil : changesets.find_by_revision(identifier) |
|
| 45 |
scm.entry(path, patch.nil? ? nil : patch.scmid) |
|
| 46 |
end |
|
| 47 | ||
| 48 |
def scm_entries(path=nil, identifier=nil) |
|
| 49 |
patch = nil |
|
| 50 |
if ! identifier.nil? |
|
| 51 |
patch = changesets.find_by_revision(identifier) |
|
| 52 |
return nil if patch.nil? |
|
| 53 |
end |
|
| 54 |
entries = scm.entries(path, patch.nil? ? nil : patch.scmid) |
|
| 55 |
if entries |
|
| 56 |
entries.each do |entry| |
|
| 57 |
# Search the DB for the entry's last change |
|
| 58 |
if entry.lastrev && !entry.lastrev.scmid.blank? |
|
| 59 |
changeset = changesets.find_by_scmid(entry.lastrev.scmid) |
|
| 60 |
end |
|
| 61 |
if changeset |
|
| 62 |
entry.lastrev.identifier = changeset.revision |
|
| 63 |
entry.lastrev.name = changeset.revision |
|
| 64 |
entry.lastrev.time = changeset.committed_on |
|
| 65 |
entry.lastrev.author = changeset.committer |
|
| 66 |
end |
|
| 67 |
end |
|
| 68 |
end |
|
| 69 |
entries |
|
| 70 |
end |
|
| 71 |
protected :scm_entries |
|
| 72 | ||
| 73 |
def cat(path, identifier=nil) |
|
| 74 |
patch = identifier.nil? ? nil : changesets.find_by_revision(identifier.to_s) |
|
| 75 |
scm.cat(path, patch.nil? ? nil : patch.scmid) |
|
| 76 |
end |
|
| 77 | ||
| 78 |
def diff(path, rev, rev_to) |
|
| 79 |
patch_from = changesets.find_by_revision(rev) |
|
| 80 |
return nil if patch_from.nil? |
|
| 81 |
patch_to = changesets.find_by_revision(rev_to) if rev_to |
|
| 82 |
if path.blank? |
|
| 83 |
path = patch_from.filechanges.collect{|change| change.path}.join(' ')
|
|
| 84 |
end |
|
| 85 |
patch_from ? scm.diff(path, patch_from.scmid, patch_to ? patch_to.scmid : nil) : nil |
|
| 86 |
end |
|
| 87 | ||
| 88 |
def fetch_changesets |
|
| 89 |
scm_info = scm.info |
|
| 90 |
if scm_info |
|
| 91 |
db_last_id = latest_changeset ? latest_changeset.scmid : nil |
|
| 92 |
next_rev = latest_changeset ? latest_changeset.revision.to_i + 1 : 1 |
|
| 93 |
# latest revision in the repository |
|
| 94 |
scm_revision = scm_info.lastrev.scmid |
|
| 95 |
unless changesets.find_by_scmid(scm_revision) |
|
| 96 |
revisions = scm.revisions('', db_last_id, nil, :with_path => true)
|
|
| 97 |
transaction do |
|
| 98 |
revisions.reverse_each do |revision| |
|
| 99 |
changeset = Changeset.create(:repository => self, |
|
| 100 |
:revision => next_rev, |
|
| 101 |
:scmid => revision.scmid, |
|
| 102 |
:committer => revision.author, |
|
| 103 |
:committed_on => revision.time, |
|
| 104 |
:comments => revision.message) |
|
| 105 |
revision.paths.each do |change| |
|
| 106 |
changeset.create_change(change) |
|
| 107 |
end |
|
| 108 |
next_rev += 1 |
|
| 109 |
end if revisions |
|
| 110 |
end |
|
| 111 |
end |
|
| 112 |
end |
|
| 113 |
end |
|
| 114 |
end |
|
| config/configuration.yml.example | ||
|---|---|---|
| 99 | 99 |
# scm_git_command: /usr/local/bin/git # (default: git) |
| 100 | 100 |
# scm_cvs_command: cvs # (default: cvs) |
| 101 | 101 |
# scm_bazaar_command: bzr.exe # (default: bzr) |
| 102 |
# scm_darcs_command: darcs-1.0.9-i386-linux # (default: darcs) |
|
| 103 | 102 |
# |
| 104 | 103 |
scm_subversion_command: |
| 105 | 104 |
scm_mercurial_command: |
| 106 | 105 |
scm_git_command: |
| 107 | 106 |
scm_cvs_command: |
| 108 | 107 |
scm_bazaar_command: |
| 109 |
scm_darcs_command: |
|
| 110 | 108 | |
| 111 | 109 |
# SCM paths validation. |
| 112 | 110 |
# |
| ... | ... | |
| 132 | 130 |
scm_git_path_regexp: |
| 133 | 131 |
scm_cvs_path_regexp: |
| 134 | 132 |
scm_bazaar_path_regexp: |
| 135 |
scm_darcs_path_regexp: |
|
| 136 | 133 |
scm_filesystem_path_regexp: |
| 137 | 134 | |
| 138 | 135 |
# Absolute path to the SCM commands errors (stderr) log file. |
| config/settings.yml | ||
|---|---|---|
| 119 | 119 |
serialized: true |
| 120 | 120 |
default: |
| 121 | 121 |
- Subversion |
| 122 |
- Darcs |
|
| 123 | 122 |
- Mercurial |
| 124 | 123 |
- Cvs |
| 125 | 124 |
- Bazaar |
| extra/svn/reposman.rb | ||
|---|---|---|
| 6 | 6 |
require 'rubygems' |
| 7 | 7 | |
| 8 | 8 |
Version = "1.5" |
| 9 |
SUPPORTED_SCM = %w( Subversion Darcs Mercurial Bazaar Git Filesystem )
|
|
| 9 |
SUPPORTED_SCM = %w( Subversion Mercurial Bazaar Git Filesystem ) |
|
| 10 | 10 | |
| 11 | 11 |
$verbose = 0 |
| 12 | 12 |
$quiet = false |
| ... | ... | |
| 71 | 71 |
opts.separator("")
|
| 72 | 72 |
opts.separator("Manages your repositories with Redmine.")
|
| 73 | 73 |
opts.separator("")
|
| 74 |
opts.separator("Required arguments:")
|
|
| 74 |
opts.separator("Required arguments:")
|
|
| 75 | 75 |
opts.on("-s", "--svn-dir DIR", "use DIR as base directory for svn repositories") {|v| $repos_base = v}
|
| 76 | 76 |
opts.on("-r", "--redmine-host HOST","assume Redmine is hosted on HOST. Examples:",
|
| 77 | 77 |
" -r redmine.example.net", |
| ... | ... | |
| 81 | 81 |
"(you can use --key-file option as an alternative)") {|v| $api_key = v}
|
| 82 | 82 |
opts.separator("")
|
| 83 | 83 |
opts.separator("Options:")
|
| 84 |
opts.on("-o", "--owner OWNER", "owner of the repository. using the rails login",
|
|
| 84 |
opts.on("-o", "--owner OWNER", "owner of the repository. using the rails login",
|
|
| 85 | 85 |
"allows users to browse the repository within", |
| 86 | 86 |
"Redmine even for private projects. If you want to", |
| 87 | 87 |
"share repositories through Redmine.pm, you need", |
| ... | ... | |
| 109 | 109 |
"This command override the default creation for", |
| 110 | 110 |
"git and subversion.") {|v| $command = v}
|
| 111 | 111 |
opts.on( "--key-file FILE", "path to a file that contains the Redmine API key", |
| 112 |
"(use this option instead of --key if you don't",
|
|
| 112 |
"(use this option instead of --key if you don't", |
|
| 113 | 113 |
"want the key to appear in the command line)") {|v| read_key_from_file(v)}
|
| 114 | 114 |
opts.on("-t", "--test", "only show what should be done") {$test = true}
|
| 115 | 115 |
opts.on("-f", "--force", "force repository creation even if the project", "repository is already declared in Redmine") {$force = true}
|
| lib/redmine.rb | ||
|---|---|---|
| 66 | 66 |
require 'redmine/plugin' |
| 67 | 67 | |
| 68 | 68 |
Redmine::Scm::Base.add "Subversion" |
| 69 |
Redmine::Scm::Base.add "Darcs" |
|
| 70 | 69 |
Redmine::Scm::Base.add "Mercurial" |
| 71 | 70 |
Redmine::Scm::Base.add "Cvs" |
| 72 | 71 |
Redmine::Scm::Base.add "Bazaar" |
| lib/redmine/scm/adapters/darcs_adapter.rb | ||
|---|---|---|
| 1 |
# Redmine - project management software |
|
| 2 |
# Copyright (C) 2006-2017 Jean-Philippe Lang |
|
| 3 |
# |
|
| 4 |
# This program is free software; you can redistribute it and/or |
|
| 5 |
# modify it under the terms of the GNU General Public License |
|
| 6 |
# as published by the Free Software Foundation; either version 2 |
|
| 7 |
# of the License, or (at your option) any later version. |
|
| 8 |
# |
|
| 9 |
# This program is distributed in the hope that it will be useful, |
|
| 10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
# GNU General Public License for more details. |
|
| 13 |
# |
|
| 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 |
|
| 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
| 17 | ||
| 18 |
require 'redmine/scm/adapters/abstract_adapter' |
|
| 19 |
require 'rexml/document' |
|
| 20 | ||
| 21 |
module Redmine |
|
| 22 |
module Scm |
|
| 23 |
module Adapters |
|
| 24 |
class DarcsAdapter < AbstractAdapter |
|
| 25 |
# Darcs executable name |
|
| 26 |
DARCS_BIN = Redmine::Configuration['scm_darcs_command'] || "darcs" |
|
| 27 | ||
| 28 |
class << self |
|
| 29 |
def client_command |
|
| 30 |
@@bin ||= DARCS_BIN |
|
| 31 |
end |
|
| 32 | ||
| 33 |
def sq_bin |
|
| 34 |
@@sq_bin ||= shell_quote_command |
|
| 35 |
end |
|
| 36 | ||
| 37 |
def client_version |
|
| 38 |
@@client_version ||= (darcs_binary_version || []) |
|
| 39 |
end |
|
| 40 | ||
| 41 |
def client_available |
|
| 42 |
!client_version.empty? |
|
| 43 |
end |
|
| 44 | ||
| 45 |
def darcs_binary_version |
|
| 46 |
darcsversion = darcs_binary_version_from_command_line.dup.force_encoding('ASCII-8BIT')
|
|
| 47 |
if m = darcsversion.match(%r{\A(.*?)((\d+\.)+\d+)})
|
|
| 48 |
m[2].scan(%r{\d+}).collect(&:to_i)
|
|
| 49 |
end |
|
| 50 |
end |
|
| 51 | ||
| 52 |
def darcs_binary_version_from_command_line |
|
| 53 |
shellout("#{sq_bin} --version") { |io| io.read }.to_s
|
|
| 54 |
end |
|
| 55 |
end |
|
| 56 | ||
| 57 |
def initialize(url, root_url=nil, login=nil, password=nil, |
|
| 58 |
path_encoding=nil) |
|
| 59 |
@url = url |
|
| 60 |
@root_url = url |
|
| 61 |
end |
|
| 62 | ||
| 63 |
def supports_cat? |
|
| 64 |
# cat supported in darcs 2.0.0 and higher |
|
| 65 |
self.class.client_version_above?([2, 0, 0]) |
|
| 66 |
end |
|
| 67 | ||
| 68 |
# Get info about the darcs repository |
|
| 69 |
def info |
|
| 70 |
rev = revisions(nil,nil,nil,{:limit => 1})
|
|
| 71 |
rev ? Info.new({:root_url => @url, :lastrev => rev.last}) : nil
|
|
| 72 |
end |
|
| 73 | ||
| 74 |
# Returns an Entries collection |
|
| 75 |
# or nil if the given path doesn't exist in the repository |
|
| 76 |
def entries(path=nil, identifier=nil, options={})
|
|
| 77 |
path_prefix = (path.blank? ? '' : "#{path}/")
|
|
| 78 |
if path.blank? |
|
| 79 |
path = ( self.class.client_version_above?([2, 2, 0]) ? @url : '.' ) |
|
| 80 |
end |
|
| 81 |
entries = Entries.new |
|
| 82 |
cmd = "#{self.class.sq_bin} annotate --repodir #{shell_quote @url} --xml-output"
|
|
| 83 |
cmd << " --match #{shell_quote("hash #{identifier}")}" if identifier
|
|
| 84 |
cmd << " #{shell_quote path}"
|
|
| 85 |
shellout(cmd) do |io| |
|
| 86 |
begin |
|
| 87 |
doc = REXML::Document.new(io) |
|
| 88 |
if doc.root.name == 'directory' |
|
| 89 |
doc.elements.each('directory/*') do |element|
|
|
| 90 |
next unless ['file', 'directory'].include? element.name |
|
| 91 |
entries << entry_from_xml(element, path_prefix) |
|
| 92 |
end |
|
| 93 |
elsif doc.root.name == 'file' |
|
| 94 |
entries << entry_from_xml(doc.root, path_prefix) |
|
| 95 |
end |
|
| 96 |
rescue |
|
| 97 |
end |
|
| 98 |
end |
|
| 99 |
return nil if $? && $?.exitstatus != 0 |
|
| 100 |
entries.compact! |
|
| 101 |
entries.sort_by_name |
|
| 102 |
end |
|
| 103 | ||
| 104 |
def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
|
|
| 105 |
path = '.' if path.blank? |
|
| 106 |
revisions = Revisions.new |
|
| 107 |
cmd = "#{self.class.sq_bin} changes --repodir #{shell_quote @url} --xml-output"
|
|
| 108 |
cmd << " --from-match #{shell_quote("hash #{identifier_from}")}" if identifier_from
|
|
| 109 |
cmd << " --last #{options[:limit].to_i}" if options[:limit]
|
|
| 110 |
shellout(cmd) do |io| |
|
| 111 |
begin |
|
| 112 |
doc = REXML::Document.new(io) |
|
| 113 |
doc.elements.each("changelog/patch") do |patch|
|
|
| 114 |
message = patch.elements['name'].text |
|
| 115 |
message << "\n" + patch.elements['comment'].text.gsub(/\*\*\*END OF DESCRIPTION\*\*\*.*\z/m, '') if patch.elements['comment'] |
|
| 116 |
revisions << Revision.new({:identifier => nil,
|
|
| 117 |
:author => patch.attributes['author'], |
|
| 118 |
:scmid => patch.attributes['hash'], |
|
| 119 |
:time => Time.parse(patch.attributes['local_date']), |
|
| 120 |
:message => message, |
|
| 121 |
:paths => (options[:with_path] ? get_paths_for_patch(patch.attributes['hash']) : nil) |
|
| 122 |
}) |
|
| 123 |
end |
|
| 124 |
rescue |
|
| 125 |
end |
|
| 126 |
end |
|
| 127 |
return nil if $? && $?.exitstatus != 0 |
|
| 128 |
revisions |
|
| 129 |
end |
|
| 130 | ||
| 131 |
def diff(path, identifier_from, identifier_to=nil) |
|
| 132 |
path = '*' if path.blank? |
|
| 133 |
cmd = "#{self.class.sq_bin} diff --repodir #{shell_quote @url}"
|
|
| 134 |
if identifier_to.nil? |
|
| 135 |
cmd << " --match #{shell_quote("hash #{identifier_from}")}"
|
|
| 136 |
else |
|
| 137 |
cmd << " --to-match #{shell_quote("hash #{identifier_from}")}"
|
|
| 138 |
cmd << " --from-match #{shell_quote("hash #{identifier_to}")}"
|
|
| 139 |
end |
|
| 140 |
cmd << " -u #{shell_quote path}"
|
|
| 141 |
diff = [] |
|
| 142 |
shellout(cmd) do |io| |
|
| 143 |
io.each_line do |line| |
|
| 144 |
diff << line |
|
| 145 |
end |
|
| 146 |
end |
|
| 147 |
return nil if $? && $?.exitstatus != 0 |
|
| 148 |
diff |
|
| 149 |
end |
|
| 150 | ||
| 151 |
def cat(path, identifier=nil) |
|
| 152 |
cmd = "#{self.class.sq_bin} show content --repodir #{shell_quote @url}"
|
|
| 153 |
cmd << " --match #{shell_quote("hash #{identifier}")}" if identifier
|
|
| 154 |
cmd << " #{shell_quote path}"
|
|
| 155 |
cat = nil |
|
| 156 |
shellout(cmd) do |io| |
|
| 157 |
io.binmode |
|
| 158 |
cat = io.read |
|
| 159 |
end |
|
| 160 |
return nil if $? && $?.exitstatus != 0 |
|
| 161 |
cat |
|
| 162 |
end |
|
| 163 | ||
| 164 |
private |
|
| 165 | ||
| 166 |
# Returns an Entry from the given XML element |
|
| 167 |
# or nil if the entry was deleted |
|
| 168 |
def entry_from_xml(element, path_prefix) |
|
| 169 |
modified_element = element.elements['modified'] |
|
| 170 |
if modified_element.elements['modified_how'].text.match(/removed/) |
|
| 171 |
return nil |
|
| 172 |
end |
|
| 173 | ||
| 174 |
Entry.new({:name => element.attributes['name'],
|
|
| 175 |
:path => path_prefix + element.attributes['name'], |
|
| 176 |
:kind => element.name == 'file' ? 'file' : 'dir', |
|
| 177 |
:size => nil, |
|
| 178 |
:lastrev => Revision.new({
|
|
| 179 |
:identifier => nil, |
|
| 180 |
:scmid => modified_element.elements['patch'].attributes['hash'] |
|
| 181 |
}) |
|
| 182 |
}) |
|
| 183 |
end |
|
| 184 | ||
| 185 |
def get_paths_for_patch(hash) |
|
| 186 |
paths = get_paths_for_patch_raw(hash) |
|
| 187 |
if self.class.client_version_above?([2, 4]) |
|
| 188 |
orig_paths = paths |
|
| 189 |
paths = [] |
|
| 190 |
add_paths = [] |
|
| 191 |
add_paths_name = [] |
|
| 192 |
mod_paths = [] |
|
| 193 |
other_paths = [] |
|
| 194 |
orig_paths.each do |path| |
|
| 195 |
if path[:action] == 'A' |
|
| 196 |
add_paths << path |
|
| 197 |
add_paths_name << path[:path] |
|
| 198 |
elsif path[:action] == 'M' |
|
| 199 |
mod_paths << path |
|
| 200 |
else |
|
| 201 |
other_paths << path |
|
| 202 |
end |
|
| 203 |
end |
|
| 204 |
add_paths_name.each do |add_path| |
|
| 205 |
mod_paths.delete_if { |m| m[:path] == add_path }
|
|
| 206 |
end |
|
| 207 |
paths.concat add_paths |
|
| 208 |
paths.concat mod_paths |
|
| 209 |
paths.concat other_paths |
|
| 210 |
end |
|
| 211 |
paths |
|
| 212 |
end |
|
| 213 | ||
| 214 |
# Retrieve changed paths for a single patch |
|
| 215 |
def get_paths_for_patch_raw(hash) |
|
| 216 |
cmd = "#{self.class.sq_bin} annotate --repodir #{shell_quote @url} --summary --xml-output"
|
|
| 217 |
cmd << " --match #{shell_quote("hash #{hash}")} "
|
|
| 218 |
paths = [] |
|
| 219 |
shellout(cmd) do |io| |
|
| 220 |
begin |
|
| 221 |
# Darcs xml output has multiple root elements in this case (tested with darcs 1.0.7) |
|
| 222 |
# A root element is added so that REXML doesn't raise an error |
|
| 223 |
doc = REXML::Document.new("<fake_root>" + io.read + "</fake_root>")
|
|
| 224 |
doc.elements.each('fake_root/summary/*') do |modif|
|
|
| 225 |
paths << {:action => modif.name[0,1].upcase,
|
|
| 226 |
:path => "/" + modif.text.chomp.gsub(/^\s*/, '') |
|
| 227 |
} |
|
| 228 |
end |
|
| 229 |
rescue |
|
| 230 |
end |
|
| 231 |
end |
|
| 232 |
paths |
|
| 233 |
rescue CommandFailed |
|
| 234 |
paths |
|
| 235 |
end |
|
| 236 |
end |
|
| 237 |
end |
|
| 238 |
end |
|
| 239 |
end |
|
| lib/tasks/testing.rake | ||
|---|---|---|
| 26 | 26 |
FileUtils.mkdir_p Rails.root + '/tmp/test' |
| 27 | 27 |
end |
| 28 | 28 | |
| 29 |
supported_scms = [:subversion, :cvs, :bazaar, :mercurial, :git, :darcs, :filesystem]
|
|
| 29 |
supported_scms = [:subversion, :cvs, :bazaar, :mercurial, :git, :filesystem] |
|
| 30 | 30 | |
| 31 | 31 |
desc "Creates a test subversion repository" |
| 32 | 32 |
task :subversion => :create_dir do |
| test/functional/repositories_darcs_controller_test.rb | ||
|---|---|---|
| 1 |
# Redmine - project management software |
|
| 2 |
# Copyright (C) 2006-2017 Jean-Philippe Lang |
|
| 3 |
# |
|
| 4 |
# This program is free software; you can redistribute it and/or |
|
| 5 |
# modify it under the terms of the GNU General Public License |
|
| 6 |
# as published by the Free Software Foundation; either version 2 |
|
| 7 |
# of the License, or (at your option) any later version. |
|
| 8 |
# |
|
| 9 |
# This program is distributed in the hope that it will be useful, |
|
| 10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
# GNU General Public License for more details. |
|
| 13 |
# |
|
| 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 |
|
| 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
| 17 | ||
| 18 |
require File.expand_path('../../test_helper', __FILE__)
|
|
| 19 | ||
| 20 |
class RepositoriesDarcsControllerTest < Redmine::ControllerTest |
|
| 21 |
tests RepositoriesController |
|
| 22 | ||
| 23 |
fixtures :projects, :users, :email_addresses, :roles, :members, :member_roles, |
|
| 24 |
:repositories, :enabled_modules |
|
| 25 | ||
| 26 |
REPOSITORY_PATH = Rails.root.join('tmp/test/darcs_repository').to_s
|
|
| 27 |
PRJ_ID = 3 |
|
| 28 |
NUM_REV = 6 |
|
| 29 | ||
| 30 |
def setup |
|
| 31 |
User.current = nil |
|
| 32 |
@project = Project.find(PRJ_ID) |
|
| 33 |
@repository = Repository::Darcs.create( |
|
| 34 |
:project => @project, |
|
| 35 |
:url => REPOSITORY_PATH, |
|
| 36 |
:log_encoding => 'UTF-8' |
|
| 37 |
) |
|
| 38 |
assert @repository |
|
| 39 |
end |
|
| 40 | ||
| 41 |
if File.directory?(REPOSITORY_PATH) |
|
| 42 |
def test_get_new |
|
| 43 |
@request.session[:user_id] = 1 |
|
| 44 |
@project.repository.destroy |
|
| 45 |
get :new, :params => {
|
|
| 46 |
:project_id => 'subproject1', |
|
| 47 |
:repository_scm => 'Darcs' |
|
| 48 |
} |
|
| 49 |
assert_response :success |
|
| 50 |
assert_select 'select[name=?]', 'repository_scm' do |
|
| 51 |
assert_select 'option[value=?][selected=selected]', 'Darcs' |
|
| 52 |
end |
|
| 53 |
end |
|
| 54 | ||
| 55 |
def test_browse_root |
|
| 56 |
assert_equal 0, @repository.changesets.count |
|
| 57 |
@repository.fetch_changesets |
|
| 58 |
@project.reload |
|
| 59 |
assert_equal NUM_REV, @repository.changesets.count |
|
| 60 |
get :show, :params => {
|
|
| 61 |
:id => PRJ_ID |
|
| 62 |
} |
|
| 63 |
assert_select 'table.entries tbody' do |
|
| 64 |
assert_select 'tr', 3 |
|
| 65 |
assert_select 'tr.dir td.filename a', :text => 'images' |
|
| 66 |
assert_select 'tr.dir td.filename a', :text => 'sources' |
|
| 67 |
assert_select 'tr.file td.filename a', :text => 'README' |
|
| 68 |
end |
|
| 69 |
end |
|
| 70 | ||
| 71 |
def test_browse_directory |
|
| 72 |
assert_equal 0, @repository.changesets.count |
|
| 73 |
@repository.fetch_changesets |
|
| 74 |
@project.reload |
|
| 75 |
assert_equal NUM_REV, @repository.changesets.count |
|
| 76 |
get :show, :params => {
|
|
| 77 |
:id => PRJ_ID, |
|
| 78 |
:path => repository_path_hash(['images'])[:param] |
|
| 79 |
} |
|
| 80 |
assert_response :success |
|
| 81 |
assert_select 'table.entries tbody' do |
|
| 82 |
assert_select 'tr', 2 |
|
| 83 |
assert_select 'tr.file td.filename a', :text => 'delete.png' |
|
| 84 |
assert_select 'tr.file td.filename a', :text => 'edit.png' |
|
| 85 |
end |
|
| 86 |
end |
|
| 87 | ||
| 88 |
def test_browse_at_given_revision |
|
| 89 |
assert_equal 0, @repository.changesets.count |
|
| 90 |
@repository.fetch_changesets |
|
| 91 |
@project.reload |
|
| 92 |
assert_equal NUM_REV, @repository.changesets.count |
|
| 93 |
get :show, :params => {
|
|
| 94 |
:id => PRJ_ID, |
|
| 95 |
:path => repository_path_hash(['images'])[:param], |
|
| 96 |
:rev => 1 |
|
| 97 |
} |
|
| 98 |
assert_response :success |
|
| 99 |
assert_select 'table.entries tbody' do |
|
| 100 |
assert_select 'tr', 1 |
|
| 101 |
assert_select 'tr.file td.filename a', :text => 'delete.png' |
|
| 102 |
end |
|
| 103 |
end |
|
| 104 | ||
| 105 |
def test_changes |
|
| 106 |
assert_equal 0, @repository.changesets.count |
|
| 107 |
@repository.fetch_changesets |
|
| 108 |
@project.reload |
|
| 109 |
assert_equal NUM_REV, @repository.changesets.count |
|
| 110 |
get :changes, :params => {
|
|
| 111 |
:id => PRJ_ID, |
|
| 112 |
:path => repository_path_hash(['images', 'edit.png'])[:param] |
|
| 113 |
} |
|
| 114 |
assert_response :success |
|
| 115 |
assert_select 'h2', :text => /edit.png/ |
|
| 116 |
end |
|
| 117 | ||
| 118 |
def test_diff |
|
| 119 |
assert_equal 0, @repository.changesets.count |
|
| 120 |
@repository.fetch_changesets |
|
| 121 |
@project.reload |
|
| 122 |
assert_equal NUM_REV, @repository.changesets.count |
|
| 123 |
# Full diff of changeset 5 |
|
| 124 |
['inline', 'sbs'].each do |dt| |
|
| 125 |
get :diff, :params => {
|
|
| 126 |
:id => PRJ_ID, |
|
| 127 |
:rev => 5, |
|
| 128 |
:type => dt |
|
| 129 |
} |
|
| 130 |
assert_response :success |
|
| 131 |
# Line 22 removed |
|
| 132 |
assert_select 'th.line-num:contains(22) ~ td.diff_out', :text => /def remove/ |
|
| 133 |
end |
|
| 134 |
end |
|
| 135 | ||
| 136 |
def test_destroy_valid_repository |
|
| 137 |
@request.session[:user_id] = 1 # admin |
|
| 138 |
assert_equal 0, @repository.changesets.count |
|
| 139 |
@repository.fetch_changesets |
|
| 140 |
@project.reload |
|
| 141 |
assert_equal NUM_REV, @repository.changesets.count |
|
| 142 | ||
| 143 |
assert_difference 'Repository.count', -1 do |
|
| 144 |
delete :destroy, :params => {
|
|
| 145 |
:id => @repository.id |
|
| 146 |
} |
|
| 147 |
end |
|
| 148 |
assert_response 302 |
|
| 149 |
@project.reload |
|
| 150 |
assert_nil @project.repository |
|
| 151 |
end |
|
| 152 | ||
| 153 |
def test_destroy_invalid_repository |
|
| 154 |
@request.session[:user_id] = 1 # admin |
|
| 155 |
@project.repository.destroy |
|
| 156 |
@repository = Repository::Darcs.create!( |
|
| 157 |
:project => @project, |
|
| 158 |
:url => "/invalid", |
|
| 159 |
:log_encoding => 'UTF-8' |
|
| 160 |
) |
|
| 161 |
@repository.fetch_changesets |
|
| 162 |
@project.reload |
|
| 163 |
assert_equal 0, @repository.changesets.count |
|
| 164 | ||
| 165 |
assert_difference 'Repository.count', -1 do |
|
| 166 |
delete :destroy, :params => {
|
|
| 167 |
:id => @repository.id |
|
| 168 |
} |
|
| 169 |
end |
|
| 170 |
assert_response 302 |
|
| 171 |
@project.reload |
|
| 172 |
assert_nil @project.repository |
|
| 173 |
end |
|
| 174 |
else |
|
| 175 |
puts "Darcs test repository NOT FOUND. Skipping functional tests !!!" |
|
| 176 |
def test_fake; assert true end |
|
| 177 |
end |
|
| 178 |
end |
|
| test/unit/helpers/application_helper_test.rb | ||
|---|---|---|
| 606 | 606 |
end |
| 607 | 607 | |
| 608 | 608 |
# TODO: Bazaar commit id contains mail address, so it contains '@' and '_'. |
| 609 |
def test_redmine_links_darcs_commit |
|
| 610 |
changeset_link = link_to('20080308225258-98289-abcd456efg.gz',
|
|
| 611 |
{
|
|
| 612 |
:controller => 'repositories', |
|
| 613 |
:action => 'revision', |
|
| 614 |
:id => 'subproject1', |
|
| 615 |
:rev => '123', |
|
| 616 |
}, |
|
| 617 |
:class => 'changeset', :title => 'test commit') |
|
| 618 |
to_test = {
|
|
| 619 |
'commit:20080308225258-98289-abcd456efg.gz' => changeset_link, |
|
| 620 |
} |
|
| 621 |
@project = Project.find(3) |
|
| 622 |
r = Repository::Darcs.create!( |
|
| 623 |
:project => @project, :url => '/tmp/test/darcs', |
|
| 624 |
:log_encoding => 'UTF-8') |
|
| 625 |
assert r |
|
| 626 |
c = Changeset.new(:repository => r, |
|
| 627 |
:committed_on => Time.now, |
|
| 628 |
:revision => '123', |
|
| 629 |
:scmid => '20080308225258-98289-abcd456efg.gz', |
|
| 630 |
:comments => 'test commit') |
|
| 631 |
assert( c.save ) |
|
| 632 |
to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
|
|
| 633 |
end |
|
| 634 | ||
| 635 | 609 |
def test_redmine_links_mercurial_commit |
| 636 | 610 |
changeset_link_rev = link_to('r123',
|
| 637 | 611 |
{
|
| test/unit/lib/redmine/scm/adapters/darcs_adapter_test.rb | ||
|---|---|---|
| 1 |
# Redmine - project management software |
|
| 2 |
# Copyright (C) 2006-2017 Jean-Philippe Lang |
|
| 3 |
# |
|
| 4 |
# This program is free software; you can redistribute it and/or |
|
| 5 |
# modify it under the terms of the GNU General Public License |
|
| 6 |
# as published by the Free Software Foundation; either version 2 |
|
| 7 |
# of the License, or (at your option) any later version. |
|
| 8 |
# |
|
| 9 |
# This program is distributed in the hope that it will be useful, |
|
| 10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
# GNU General Public License for more details. |
|
| 13 |
# |
|
| 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 |
|
| 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
| 17 | ||
| 18 |
require File.expand_path('../../../../../../test_helper', __FILE__)
|
|
| 19 | ||
| 20 |
class DarcsAdapterTest < ActiveSupport::TestCase |
|
| 21 |
REPOSITORY_PATH = Rails.root.join('tmp/test/darcs_repository').to_s
|
|
| 22 | ||
| 23 |
if File.directory?(REPOSITORY_PATH) |
|
| 24 |
def setup |
|
| 25 |
@adapter = Redmine::Scm::Adapters::DarcsAdapter.new(REPOSITORY_PATH) |
|
| 26 |
end |
|
| 27 | ||
| 28 |
def test_darcsversion |
|
| 29 |
to_test = { "1.0.9 (release)\n" => [1,0,9] ,
|
|
| 30 |
"2.2.0 (release)\n" => [2,2,0] } |
|
| 31 |
to_test.each do |s, v| |
|
| 32 |
test_darcsversion_for(s, v) |
|
| 33 |
end |
|
| 34 |
end |
|
| 35 | ||
| 36 |
def test_revisions |
|
| 37 |
id1 = '20080308225258-98289-761f654d669045eabee90b91b53a21ce5593cadf.gz' |
|
| 38 |
revs = @adapter.revisions('', nil, nil, {:with_path => true})
|
|
| 39 |
assert_equal 6, revs.size |
|
| 40 |
assert_equal id1, revs[5].scmid |
|
| 41 |
paths = revs[5].paths |
|
| 42 |
assert_equal 5, paths.size |
|
| 43 |
assert_equal 'A', paths[0][:action] |
|
| 44 |
assert_equal '/README', paths[0][:path] |
|
| 45 |
assert_equal 'A', paths[1][:action] |
|
| 46 |
assert_equal '/images', paths[1][:path] |
|
| 47 |
end |
|
| 48 | ||
| 49 |
private |
|
| 50 | ||
| 51 |
def test_darcsversion_for(darcsversion, version) |
|
| 52 |
@adapter.class.expects(:darcs_binary_version_from_command_line).returns(darcsversion) |
|
| 53 |
assert_equal version, @adapter.class.darcs_binary_version |
|
| 54 |
end |
|
| 55 | ||
| 56 |
else |
|
| 57 |
puts "Darcs test repository NOT FOUND. Skipping unit tests !!!" |
|
| 58 |
def test_fake; assert true end |
|
| 59 |
end |
|
| 60 |
end |
|
| test/unit/repository_darcs_test.rb | ||
|---|---|---|
| 1 |
# Redmine - project management software |
|
| 2 |
# Copyright (C) 2006-2017 Jean-Philippe Lang |
|
| 3 |
# |
|
| 4 |
# This program is free software; you can redistribute it and/or |
|
| 5 |
# modify it under the terms of the GNU General Public License |
|
| 6 |
# as published by the Free Software Foundation; either version 2 |
|
| 7 |
# of the License, or (at your option) any later version. |
|
| 8 |
# |
|
| 9 |
# This program is distributed in the hope that it will be useful, |
|
| 10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
# GNU General Public License for more details. |
|
| 13 |
# |
|
| 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 |
|
| 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
| 17 | ||
| 18 |
require File.expand_path('../../test_helper', __FILE__)
|
|
| 19 | ||
| 20 |
class RepositoryDarcsTest < ActiveSupport::TestCase |
|
| 21 |
fixtures :projects |
|
| 22 | ||
| 23 |
include Redmine::I18n |
|
| 24 | ||
| 25 |
REPOSITORY_PATH = Rails.root.join('tmp/test/darcs_repository').to_s
|
|
| 26 |
NUM_REV = 6 |
|
| 27 | ||
| 28 |
def setup |
|
| 29 |
@project = Project.find(3) |
|
| 30 |
@repository = Repository::Darcs.create( |
|
| 31 |
:project => @project, |
|
| 32 |
:url => REPOSITORY_PATH, |
|
| 33 |
:log_encoding => 'UTF-8' |
|
| 34 |
) |
|
| 35 |
assert @repository |
|
| 36 |
end |
|
| 37 | ||
| 38 |
def test_blank_path_to_repository_error_message |
|
| 39 |
set_language_if_valid 'en' |
|
| 40 |
repo = Repository::Darcs.new( |
|
| 41 |
:project => @project, |
|
| 42 |
:identifier => 'test', |
|
| 43 |
:log_encoding => 'UTF-8' |
|
| 44 |
) |
|
| 45 |
assert !repo.save |
|
| 46 |
assert_include "Path to repository cannot be blank", |
|
| 47 |
repo.errors.full_messages |
|
| 48 |
end |
|
| 49 | ||
| 50 |
def test_blank_path_to_repository_error_message_fr |
|
| 51 |
set_language_if_valid 'fr' |
|
| 52 |
str = "Chemin du d\xc3\xa9p\xc3\xb4t doit \xc3\xaatre renseign\xc3\xa9(e)".force_encoding('UTF-8')
|
|
| 53 |
repo = Repository::Darcs.new( |
|
| 54 |
:project => @project, |
|
| 55 |
:url => "", |
|
| 56 |
:identifier => 'test', |
|
| 57 |
:log_encoding => 'UTF-8' |
|
| 58 |
) |
|
| 59 |
assert !repo.save |
|
| 60 |
assert_include str, repo.errors.full_messages |
|
| 61 |
end |
|
| 62 | ||
| 63 |
if File.directory?(REPOSITORY_PATH) |
|
| 64 |
def test_fetch_changesets_from_scratch |
|
| 65 |
assert_equal 0, @repository.changesets.count |
|
| 66 |
@repository.fetch_changesets |
|
| 67 |
@project.reload |
|
| 68 | ||
| 69 |
assert_equal NUM_REV, @repository.changesets.count |
|
| 70 |
assert_equal 13, @repository.filechanges.count |
|
| 71 |
assert_equal "Initial commit.", @repository.changesets.find_by_revision('1').comments
|
|
| 72 |
end |
|
| 73 | ||
| 74 |
def test_fetch_changesets_incremental |
|
| 75 |
assert_equal 0, @repository.changesets.count |
|
| 76 |
@repository.fetch_changesets |
|
| 77 |
@project.reload |
|
| 78 |
assert_equal NUM_REV, @repository.changesets.count |
|
| 79 | ||
| 80 |
# Remove changesets with revision > 3 |
|
| 81 |
@repository.changesets.each {|c| c.destroy if c.revision.to_i > 3}
|
|
| 82 |
@project.reload |
|
| 83 |
@repository.reload |
|
| 84 |
assert_equal 3, @repository.changesets.count |
|
| 85 | ||
| 86 |
@repository.fetch_changesets |
|
| 87 |
@project.reload |
|
| 88 |
assert_equal NUM_REV, @repository.changesets.count |
|
| 89 |
end |
|
| 90 | ||
| 91 |
def test_entries |
|
| 92 |
entries = @repository.entries |
|
| 93 |
assert_kind_of Redmine::Scm::Adapters::Entries, entries |
|
| 94 |
end |
|
| 95 | ||
| 96 |
def test_entries_invalid_revision |
|
| 97 |
assert_equal 0, @repository.changesets.count |
|
| 98 |
@repository.fetch_changesets |
|
| 99 |
@project.reload |
|
| 100 |
assert_equal NUM_REV, @repository.changesets.count |
|
| 101 |
assert_nil @repository.entries('', '123')
|
|
| 102 |
end |
|
| 103 | ||
| 104 |
def test_deleted_files_should_not_be_listed |
|
| 105 |
assert_equal 0, @repository.changesets.count |
|
| 106 |
@repository.fetch_changesets |
|
| 107 |
@project.reload |
|
| 108 |
assert_equal NUM_REV, @repository.changesets.count |
|
| 109 |
entries = @repository.entries('sources')
|
|
| 110 |
assert entries.detect {|e| e.name == 'watchers_controller.rb'}
|
|
| 111 |
assert_nil entries.detect {|e| e.name == 'welcome_controller.rb'}
|
|
| 112 |
end |
|
| 113 | ||
| 114 |
def test_cat |
|
| 115 |
if @repository.scm.supports_cat? |
|
| 116 |
assert_equal 0, @repository.changesets.count |
|
| 117 |
@repository.fetch_changesets |
|
| 118 |
@project.reload |
|
| 119 |
assert_equal NUM_REV, @repository.changesets.count |
|
| 120 |
cat = @repository.cat("sources/welcome_controller.rb", 2)
|
|
| 121 |
assert_not_nil cat |
|
| 122 |
assert cat.include?('class WelcomeController < ApplicationController')
|
|
| 123 |
end |
|
| 124 |
end |
|
| 125 |
else |
|
| 126 |
puts "Darcs test repository NOT FOUND. Skipping unit tests !!!" |
|
| 127 |
def test_fake; assert true end |
|
| 128 |
end |
|
| 129 |
end |
|
| test/unit/repository_test.rb | ||
|---|---|---|
| 221 | 221 | |
| 222 | 222 |
def test_should_not_create_with_disabled_scm |
| 223 | 223 |
# disable Subversion |
| 224 |
with_settings :enabled_scm => ['Darcs', 'Git'] do
|
|
| 224 |
with_settings :enabled_scm => ['Mercurial', 'Git'] do
|
|
| 225 | 225 |
repository = Repository::Subversion.new( |
| 226 | 226 |
:project => Project.find(3), :url => "svn://localhost") |
| 227 | 227 |
assert !repository.save |
| ... | ... | |
| 280 | 280 |
:project => Project.find( 4 ), |
| 281 | 281 |
:url => '/foo/bar/baz' ) |
| 282 | 282 |
comment = <<-COMMENT |
| 283 |
This is a loooooooooooooooooooooooooooong comment
|
|
| 284 |
|
|
| 285 |
|
|
| 283 |
This is a loooooooooooooooooooooooooooong comment |
|
| 284 | ||
| 285 | ||
| 286 | 286 |
COMMENT |
| 287 | 287 |
changeset = Changeset.new( |
| 288 | 288 |
:comments => comment, :commit_date => Time.now, |