Merged r1307 to r1369 from trunk.

git-svn-id: http://redmine.rubyforge.org/svn/branches/0.7-stable@1370 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
Jean-Philippe Lang
2008-04-28 10:36:12 +00:00
parent be071deae2
commit 10191813ec
139 changed files with 1936 additions and 874 deletions
+1 -1
View File
@@ -1134,7 +1134,7 @@ class RedCloth < String
ALLOWED_TAGS = %w(redpre pre code)
def escape_html_tags(text)
text.gsub!(%r{<((\/?)(\w+))}) {|m| ALLOWED_TAGS.include?($3) ? "<#{$1}" : "&lt;#{$1}" }
text.gsub!(%r{<(\/?(\w+)[^>\n]*)(>?)}) {|m| ALLOWED_TAGS.include?($2) ? "<#{$1}#{$3}" : "&lt;#{$1}#{'&gt;' if $3}" }
end
end
+1
View File
@@ -1,6 +1,7 @@
require 'redmine/access_control'
require 'redmine/menu_manager'
require 'redmine/mime_type'
require 'redmine/core_ext'
require 'redmine/themes'
require 'redmine/plugin'
+1
View File
@@ -0,0 +1 @@
Dir[File.dirname(__FILE__) + "/core_ext/*.rb"].each { |file| require(file) }
+5
View File
@@ -0,0 +1,5 @@
require File.dirname(__FILE__) + '/string/conversions'
class String #:nodoc:
include Redmine::CoreExtensions::String::Conversions
end
@@ -0,0 +1,40 @@
# redMine - project management software
# Copyright (C) 2008 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
module Redmine #:nodoc:
module CoreExtensions #:nodoc:
module String #:nodoc:
# Custom string conversions
module Conversions
# Parses hours format and returns a float
def to_hours
s = self.dup
s.strip!
unless s =~ %r{^[\d\.,]+$}
# 2:30 => 2.5
s.gsub!(%r{^(\d+):(\d+)$}) { $1.to_i + $2.to_i / 60.0 }
# 2h30, 2h, 30m => 2.5, 2, 0.5
s.gsub!(%r{^((\d+)\s*(h|hours?))?\s*((\d+)\s*(m|min)?)?$}) { |m| ($1 || $4) ? ($2.to_i + $5.to_i / 60.0) : m[0] }
end
# 2,5 => 2.5
s.gsub!(',', '.')
s.to_f
end
end
end
end
end
+11 -2
View File
@@ -59,8 +59,17 @@ module Redmine
# Returns the entry identified by path and revision identifier
# or nil if entry doesn't exist in the repository
def entry(path=nil, identifier=nil)
e = entries(path, identifier)
e ? e.first : nil
parts = path.to_s.split(%r{[\/\\]}).select {|n| !n.blank?}
search_path = parts[0..-2].join('/')
search_name = parts[-1]
if search_path.blank? && search_name.blank?
# Root entry
Entry.new(:path => '', :kind => 'dir')
else
# Search for the entry in the parent directory
es = entries(search_path, identifier)
es ? es.detect {|e| e.name == search_name} : nil
end
end
# Returns an Entries collection
@@ -44,18 +44,6 @@ module Redmine
return nil
end
# Returns the entry identified by path and revision identifier
# or nil if entry doesn't exist in the repository
def entry(path=nil, identifier=nil)
path ||= ''
parts = path.split(%r{[\/\\]}).select {|p| !p.blank?}
if parts.size > 0
parent = parts[0..-2].join('/')
entries = entries(parent, identifier)
entries ? entries.detect {|e| e.name == parts.last} : nil
end
end
# Returns an Entries collection
# or nil if the given path doesn't exist in the repository
def entries(path=nil, identifier=nil)
+3 -10
View File
@@ -55,15 +55,6 @@ module Redmine
def get_previous_revision(revision)
CvsRevisionHelper.new(revision).prevRev
end
# Returns the entry identified by path and revision identifier
# or nil if entry doesn't exist in the repository
# this method returns all revisions from one single SCM-Entry
def entry(path=nil, identifier="HEAD")
e = entries(path, identifier)
logger.debug("<cvs-result> #{e.first.inspect}") if e
e ? e.first : nil
end
# Returns an Entries collection
# or nil if the given path doesn't exist in the repository
@@ -72,7 +63,9 @@ module Redmine
logger.debug "<cvs> entries '#{path}' with identifier '#{identifier}'"
path_with_project="#{url}#{with_leading_slash(path)}"
entries = Entries.new
cmd = "#{CVS_BIN} -d #{root_url} rls -ed #{path_with_project}"
cmd = "#{CVS_BIN} -d #{root_url} rls -ed"
cmd << " -D \"#{time_to_cvstime(identifier)}\"" if identifier
cmd << " #{path_with_project}"
shellout(cmd) do |io|
io.each_line(){|line|
fields=line.chop.split('/',-1)
+3 -8
View File
@@ -40,20 +40,15 @@ module Redmine
rev ? Info.new({:root_url => @url, :lastrev => rev.last}) : nil
end
# Returns the entry identified by path and revision identifier
# or nil if entry doesn't exist in the repository
def entry(path=nil, identifier=nil)
e = entries(path, identifier)
e ? e.first : 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_prefix = (path.blank? ? '' : "#{path}/")
path = '.' if path.blank?
entries = Entries.new
cmd = "#{DARCS_BIN} annotate --repodir #{@url} --xml-output #{path}"
cmd = "#{DARCS_BIN} annotate --repodir #{@url} --xml-output"
cmd << " --match \"hash #{identifier}\"" if identifier
cmd << " #{path}"
shellout(cmd) do |io|
begin
doc = REXML::Document.new(io)
+1 -9
View File
@@ -79,7 +79,7 @@ module Redmine
rev = Revision.new({:identifier => changeset[:commit],
:scmid => changeset[:commit],
:author => changeset[:author],
:time => Time.parse(changeset[:date]),
:time => (changeset[:date] ? Time.parse(changeset[:date]) : nil),
:message => changeset[:description],
:paths => files
})
@@ -132,14 +132,6 @@ module Redmine
entries.sort_by_name
end
def entry(path=nil, identifier=nil)
path ||= ''
search_path = path.split('/')[0..-2].join('/')
entry_name = path.split('/').last
e = entries(search_path, identifier)
e ? e.detect{|entry| entry.name == entry_name} : nil
end
def revisions(path, identifier_from, identifier_to, options={})
revisions = Revisions.new
cmd = "#{GIT_BIN} --git-dir #{target('')} log --raw "
+44 -22
View File
@@ -59,14 +59,6 @@ module Redmine
return nil if $? && $?.exitstatus != 0
entries.sort_by_name
end
def entry(path=nil, identifier=nil)
path ||= ''
search_path = path.split('/')[0..-2].join('/')
entry_name = path.split('/').last
e = entries(search_path, identifier)
e ? e.detect{|entry| entry.name == entry_name} : nil
end
def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
revisions = Revisions.new
@@ -88,13 +80,7 @@ module Redmine
value = $2
if parsing_descr && line_feeds > 1
parsing_descr = false
revisions << Revision.new({:identifier => changeset[:changeset].split(':').first.to_i,
:scmid => changeset[:changeset].split(':').last,
:author => changeset[:user],
:time => Time.parse(changeset[:date]),
:message => changeset[:description],
:paths => changeset[:files].to_s.split.collect{|path| {:action => 'X', :path => "/#{path}"}}
})
revisions << build_revision_from_changeset(changeset)
changeset = {}
end
if !parsing_descr
@@ -111,13 +97,8 @@ module Redmine
line_feeds += 1 if line.chomp.empty?
end
end
revisions << Revision.new({:identifier => changeset[:changeset].split(':').first.to_i,
:scmid => changeset[:changeset].split(':').last,
:author => changeset[:user],
:time => Time.parse(changeset[:date]),
:message => changeset[:description],
:paths => changeset[:files].to_s.split.collect{|path| {:action => 'X', :path => "/#{path}"}}
})
# Add the last changeset if there is one left
revisions << build_revision_from_changeset(changeset) if changeset[:date]
end
return nil if $? && $?.exitstatus != 0
revisions
@@ -171,6 +152,47 @@ module Redmine
return nil if $? && $?.exitstatus != 0
blame
end
private
# Builds a revision objet from the changeset returned by hg command
def build_revision_from_changeset(changeset)
rev_id = changeset[:changeset].to_s.split(':').first.to_i
# Changes
paths = (rev_id == 0) ?
# Can't get changes for revision 0 with hg status
changeset[:files].to_s.split.collect{|path| {:action => 'A', :path => "/#{path}"}} :
status(rev_id)
Revision.new({:identifier => rev_id,
:scmid => changeset[:changeset].to_s.split(':').last,
:author => changeset[:user],
:time => Time.parse(changeset[:date]),
:message => changeset[:description],
:paths => paths
})
end
# Returns the file changes for a given revision
def status(rev_id)
cmd = "#{HG_BIN} -R #{target('')} status --rev #{rev_id.to_i - 1}:#{rev_id.to_i}"
result = []
shellout(cmd) do |io|
io.each_line do |line|
action, file = line.chomp.split
next unless action && file
file.gsub!("\\", "/")
case action
when 'R'
result << { :action => 'D' , :path => "/#{file}" }
else
result << { :action => action, :path => "/#{file}" }
end
end
end
result
end
end
end
end
+6 -15
View File
@@ -51,18 +51,11 @@ module Redmine
return nil
end
# Returns the entry identified by path and revision identifier
# or nil if entry doesn't exist in the repository
def entry(path=nil, identifier=nil)
e = entries(path, identifier)
e ? e.first : 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 = 'HEAD' unless identifier and identifier > 0
identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
entries = Entries.new
cmd = "#{SVN_BIN} list --xml #{target(path)}@#{identifier}"
cmd << credentials_string
@@ -94,8 +87,8 @@ module Redmine
def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
path ||= ''
identifier_from = 'HEAD' unless identifier_from and identifier_from.to_i > 0
identifier_to = 1 unless identifier_to and identifier_to.to_i > 0
identifier_from = (identifier_from and identifier_from.to_i > 0) ? identifier_from.to_i : "HEAD"
identifier_to = (identifier_to and identifier_to.to_i > 0) ? identifier_to.to_i : 1
revisions = Revisions.new
cmd = "#{SVN_BIN} log --xml -r #{identifier_from}:#{identifier_to}"
cmd << credentials_string
@@ -131,11 +124,9 @@ module Redmine
def diff(path, identifier_from, identifier_to=nil, type="inline")
path ||= ''
if identifier_to and identifier_to.to_i > 0
identifier_to = identifier_to.to_i
else
identifier_to = identifier_from.to_i - 1
end
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 = "#{SVN_BIN} diff -r "
cmd << "#{identifier_to}:"
cmd << "#{identifier_from}"
+16 -13
View File
@@ -77,21 +77,24 @@ module Redmine
content_tag('dl', out)
end
desc "Include a wiki page. Example:\n\n !{{include(Foo)}}"
desc "Include a wiki page. Example:\n\n !{{include(Foo)}}\n\nor to include a page of a specific project wiki:\n\n !{{include(projectname:Foo)}}"
macro :include do |obj, args|
if @project && !@project.wiki.nil?
page = @project.wiki.find_page(args.first)
if page && page.content
@included_wiki_pages ||= []
raise 'Circular inclusion detected' if @included_wiki_pages.include?(page.title)
@included_wiki_pages << page.title
out = textilizable(page.content, :text)
@included_wiki_pages.pop
out
else
raise "Page #{args.first} doesn't exist"
end
project = @project
title = args.first.to_s
if title =~ %r{^([^\:]+)\:(.*)$}
project_identifier, title = $1, $2
project = Project.find_by_identifier(project_identifier) || Project.find_by_name(project_identifier)
end
raise 'Unknow project' unless project && User.current.allowed_to?(:view_wiki_pages, project)
raise 'No wiki for this project' unless !project.wiki.nil?
page = project.wiki.find_page(title)
raise "Page #{args.first} doesn't exist" unless page && page.content
@included_wiki_pages ||= []
raise 'Circular inclusion detected' if @included_wiki_pages.include?(page.title)
@included_wiki_pages << page.title
out = textilizable(page.content, :text, :attachments => page.attachments)
@included_wiki_pages.pop
out
end
end
end