Merge pull request #552 from opf/feature/rails3_repair_regexes

[WIP] use \A and \z instead of ^ and $ in ruby regexes
pull/554/head
meeee 11 years ago
commit 80e200415b
  1. 2
      app/controllers/api/v2/planning_elements_controller.rb
  2. 2
      app/controllers/api/v2/projects_controller.rb
  3. 2
      app/controllers/application_controller.rb
  4. 2
      app/controllers/custom_fields_controller.rb
  5. 2
      app/controllers/search_controller.rb
  6. 2
      app/controllers/work_packages/auto_completes_controller.rb
  7. 10
      app/helpers/application_helper.rb
  8. 2
      app/helpers/journals_helper.rb
  9. 2
      app/helpers/repositories_helper.rb
  10. 2
      app/helpers/sort_helper.rb
  11. 4
      app/mailers/user_mailer.rb
  12. 10
      app/models/attachment.rb
  13. 2
      app/models/changeset.rb
  14. 2
      app/models/custom_field.rb
  15. 4
      app/models/custom_value.rb
  16. 6
      app/models/mail_handler.rb
  17. 2
      app/models/planning_element_type_color.rb
  18. 8
      app/models/project.rb
  19. 6
      app/models/query.rb
  20. 4
      app/models/repository.rb
  21. 2
      app/models/repository/subversion.rb
  22. 4
      app/models/user.rb
  23. 4
      app/models/version.rb
  24. 4
      app/models/wiki.rb
  25. 2
      app/models/wiki_menu_item.rb
  26. 2
      app/models/wiki_page.rb
  27. 4
      app/models/work_package/pdf_exporter.rb
  28. 2
      config/initializers/10-patches.rb
  29. 2
      db/migrate/000_aggregated_migrations.rb
  30. 2
      db/migrate/migration_utils/journal_migrator_concerns.rb
  31. 2
      db/migrate/migration_utils/legacy_journal_migrator.rb
  32. 1
      doc/CHANGELOG.md
  33. 2
      extra/mail_handler/rdm-mailhandler.rb
  34. 8
      extra/svn/reposman.rb
  35. 2
      lib/chili_project/database.rb
  36. 6
      lib/open_project/themes/theme.rb
  37. 4
      lib/plugins/acts_as_journalized/lib/acts_as_journalized.rb
  38. 2
      lib/plugins/acts_as_journalized/lib/journal_formatter/named_association.rb
  39. 2
      lib/plugins/acts_as_journalized/lib/journal_formatter/proc.rb
  40. 2
      lib/plugins/acts_as_journalized/lib/redmine/acts/journalized/configuration.rb
  41. 2
      lib/plugins/rfpdf/lib/fpdf/makefont.rb
  42. 2
      lib/redmine/mime_type.rb
  43. 4
      lib/redmine/scm/adapters/abstract_adapter.rb
  44. 2
      lib/redmine/scm/adapters/filesystem_adapter.rb
  45. 2
      lib/redmine/scm/adapters/subversion_adapter.rb
  46. 2
      lib/redmine/views/my_page/block.rb
  47. 2
      lib/tasks/code.rake
  48. 12
      lib/tasks/copyright.rake
  49. 2
      lib/tasks/cucumber.rake
  50. 4
      lib/tasks/locales.rake
  51. 6
      lib/tasks/plugins.rake
  52. 2
      lib/tasks/testing.rake
  53. 2
      spec/helpers/pagination_helper_spec.rb
  54. 2
      test/unit/attachment_test.rb
  55. 2
      test/unit/lib/redmine/plugin_test.rb
  56. 2
      test/unit/lib/redmine/unified_diff_test.rb

@ -147,7 +147,7 @@ module Api
def find_multiple_projects
# find_project_by_project_id
ids, identifiers = params[:project_id].split(/,/).map(&:strip).partition { |s| s =~ /^\d*$/ }
ids, identifiers = params[:project_id].split(/,/).map(&:strip).partition { |s| s =~ /\A\d*\z/ }
ids = ids.map(&:to_i).sort
identifiers = identifiers.sort

@ -36,7 +36,7 @@ module Api
options = {:order => 'lft'}
if params[:ids]
ids, identifiers = params[:ids].split(/,/).map(&:strip).partition { |s| s =~ /^\d*$/ }
ids, identifiers = params[:ids].split(/,/).map(&:strip).partition { |s| s =~ /\A\d*\z/ }
ids = ids.map(&:to_i).sort
identifiers = identifiers.sort

@ -520,7 +520,7 @@ class ApplicationController < ActionController::Base
if value
parts = value.split(/,\s*/)
parts.each {|part|
if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
if m = %r{\A([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?\z}.match(part)
val = m[1]
q = (m[2] or 1).to_f
tmp.push([val, q])

@ -40,7 +40,7 @@ class CustomFieldsController < ApplicationController
def new
@custom_field = begin
if params[:type].to_s.match(/.+CustomField$/)
if params[:type].to_s.match(/.+CustomField\z/)
params[:type].to_s.constantize.new(params[:custom_field])
end
rescue

@ -54,7 +54,7 @@ class SearchController < ApplicationController
begin; offset = params[:offset].to_time if params[:offset]; rescue; end
# quick jump to an work_package
if @question.match(/^#?(\d+)$/) && WorkPackage.visible.find_by_id($1.to_i)
if @question.match(/\A#?(\d+)\z/) && WorkPackage.visible.find_by_id($1.to_i)
redirect_to work_package_path(:id => $1)
return
end

@ -37,7 +37,7 @@ class WorkPackages::AutoCompletesController < ApplicationController
if q.present?
query = (params[:scope] == "all" && Setting.cross_project_work_package_relations?) ? WorkPackage : @project.work_packages
@work_packages |= query.visible.find_all_by_id(q.to_i) if q =~ /^\d+$/
@work_packages |= query.visible.find_all_by_id(q.to_i) if q =~ /\A\d+\z/
@work_packages |= query.visible.find(:all,
limit: 10,

@ -625,7 +625,7 @@ module ApplicationHelper
link_project = project
esc, all, page, title = $1, $2, $3, $5
if esc.nil?
if page =~ /^([^\:]+)\:(.*)$/
if page =~ /\A([^\:]+)\:(.*)\z/
link_project = Project.find_by_identifier($1) || Project.find_by_name($1)
page = $2
title ||= $1 if page.blank?
@ -634,7 +634,7 @@ module ApplicationHelper
if link_project && link_project.wiki
# extract anchor
anchor = nil
if page =~ /^(.+?)\#(.+)$/
if page =~ /\A(.+?)\#(.+)\z/
page, anchor = $1, $2
end
# check if page exists
@ -739,7 +739,7 @@ module ApplicationHelper
end
elsif sep == ':'
# removes the double quotes if any
name = identifier.gsub(%r{^"(.*)"$}, "\\1")
name = identifier.gsub(%r{\A"(.*)"\z}, "\\1")
case prefix
when 'version'
if project && version = project.versions.visible.find_by_name(name)
@ -754,7 +754,7 @@ module ApplicationHelper
end
when 'source', 'export'
if project && project.repository && User.current.allowed_to?(:browse_repository, project)
name =~ %r{^[/\\]*(.*?)(@([0-9a-f]+))?(#(L\d+))?$}
name =~ %r{\A[/\\]*(.*?)(@([0-9a-f]+))?(#(L\d+))?\z}
path, rev, anchor = $1, $3, $5
link = link_to h("#{project_prefix}#{prefix}:#{name}"), {:controller => '/repositories', :action => 'entry', :project_id => project,
:path => to_path_param(path),
@ -855,7 +855,7 @@ module ApplicationHelper
end
def label_tag_for(name, option_tags = nil, options = {})
label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
label_text = l(("field_"+field.to_s.gsub(/\_id\z/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
content_tag("label", label_text)
end

@ -93,7 +93,7 @@ module JournalsHelper
# it assumes that there is a quoted action on the controller
# currently rendering the view
# the quote link should somehow be supplied
controller_name = controller.class.to_s.underscore.gsub(/_controller$/,"").to_sym
controller_name = controller.class.to_s.underscore.gsub(/_controller\z/,"").to_sym
l << link_to(image_tag('webalys/quote.png', :alt => l(:button_quote), :title => l(:button_quote)),
{ :controller => controller_name,
:action => 'quoted',

@ -210,7 +210,7 @@ module RepositoriesHelper
end
def without_leading_slash(path)
path.gsub(%r{^/+}, '')
path.gsub(%r{\A/+}, '')
end
def subversion_field_tags(form, repository)

@ -152,7 +152,7 @@ module SortHelper
# Appends DESC to the sort criterion unless it has a fixed order
def append_desc(criterion)
if criterion =~ / (asc|desc)$/i
if criterion =~ / (asc|desc)\z/i
criterion
else
"#{criterion} DESC"

@ -279,7 +279,7 @@ class UserMailer < ActionMailer::Base
end
hash = "openproject.#{object.class.name.demodulize.underscore}-#{object.id}.#{timestamp.strftime("%Y%m%d%H%M%S")}"
host = Setting.mail_from.to_s.gsub(%r{^.*@}, '')
host = Setting.mail_from.to_s.gsub(%r{\A.*@}, '')
host = "#{::Socket.gethostname}.openproject" if host.empty?
"#{hash}@#{host}"
end
@ -312,7 +312,7 @@ private
if Redmine::Utils.relative_url_root.blank?
Setting.host_name
else
Setting.host_name.to_s.gsub(%r{\/.*$}, '')
Setting.host_name.to_s.gsub(%r{\/.*\z}, '')
end
end

@ -150,7 +150,7 @@ class Attachment < ActiveRecord::Base
end
def image?
self.filename =~ /\.(jpe?g|gif|png)$/i
self.filename =~ /\.(jpe?g|gif|png)\z/i
end
def is_text?
@ -158,7 +158,7 @@ class Attachment < ActiveRecord::Base
end
def is_diff?
self.filename =~ /\.(patch|diff)$/i
self.filename =~ /\.(patch|diff)\z/i
end
# Returns true if the file is readable
@ -197,7 +197,7 @@ private
def sanitize_filename(value)
# get only the filename, not the whole path
just_filename = value.gsub(/^.*(\\|\/)/, '')
just_filename = value.gsub(/\A.*(\\|\/)/, '')
# NOTE: File.basename doesn't work right with Windows paths on Unix
# INCORRECT: just_filename = File.basename(value.gsub('\\\\', '/'))
@ -209,12 +209,12 @@ private
def self.disk_filename(filename)
timestamp = DateTime.now.strftime("%y%m%d%H%M%S")
ascii = ''
if filename =~ %r{^[a-zA-Z0-9_\.\-]*$}
if filename =~ %r{\A[a-zA-Z0-9_\.\-]*\z}
ascii = filename
else
ascii = Digest::MD5.hexdigest(filename)
# keep the extension if any
ascii << $1 if filename =~ %r{(\.[a-zA-Z0-9]+)$}
ascii << $1 if filename =~ %r{(\.[a-zA-Z0-9]+)\z}
end
while File.exist?(File.join(@@storage_path, "#{timestamp}_#{ascii}"))
timestamp.succ!

@ -250,7 +250,7 @@ class Changeset < ActiveRecord::Base
end
def split_comments
comments =~ /\A(.+?)\r?\n(.*)$/m
comments =~ /\A(.+?)\r?\n(.*)\z/m
@short_comments = $1 || comments
@long_comments = $2.to_s.strip
return @short_comments, @long_comments

@ -204,7 +204,7 @@ class CustomField < ActiveRecord::Base
end
def self.customized_class
self.name =~ /^(.+)CustomField$/
self.name =~ /\A(.+)CustomField\z/
begin; $1.constantize; rescue nil; end
end

@ -82,11 +82,11 @@ protected
# Format specific validations
case custom_field.field_format
when 'int'
errors.add(:value, :not_a_number) unless value =~ /^[+-]?\d+$/
errors.add(:value, :not_a_number) unless value =~ /\A[+-]?\d+\z/
when 'float'
begin; Kernel.Float(value); rescue; errors.add(:value, :invalid) end
when 'date'
errors.add(:value, :not_a_date) unless value =~ /^\d{4}-\d{2}-\d{2}$/
errors.add(:value, :not_a_date) unless value =~ /\A\d{4}-\d{2}-\d{2}\z/
when 'list'
errors.add(:value, :inclusion) unless custom_field.possible_values.include?(value)
end

@ -57,7 +57,7 @@ class MailHandler < ActionMailer::Base
cattr_accessor :ignored_emails_headers
@@ignored_emails_headers = {
'X-Auto-Response-Suppress' => 'oof',
'Auto-Submitted' => /^auto-/
'Auto-Submitted' => /\Aauto-/
}
# Processes incoming emails
@ -363,7 +363,7 @@ class MailHandler < ActionMailer::Base
user.random_password!
user.language = Setting.default_language
names = fullname.blank? ? email_address.gsub(/@.*$/, '').split('.') : fullname.split
names = fullname.blank? ? email_address.gsub(/@.*\z/, '').split('.') : fullname.split
user.firstname = names.shift
user.lastname = names.join(' ')
user.lastname = '-' if user.lastname.blank?
@ -381,7 +381,7 @@ class MailHandler < ActionMailer::Base
def self.create_user_from_email(email)
from = email.header['from'].to_s
addr, name = from, nil
if m = from.match(/^"?(.+?)"?\s+<(.+@.+)>$/)
if m = from.match(/\A"?(.+?)"?\s+<(.+@.+)>\z/)
addr, name = m[2], m[1]
end
if addr.present?

@ -45,7 +45,7 @@ class PlanningElementTypeColor < ActiveRecord::Base
validates_presence_of :name, :hexcode
validates_length_of :name, :maximum => 255, :unless => lambda { |e| e.name.blank? }
validates_format_of :hexcode, :with => /^#[0-9A-F]{6}$/, :unless => lambda { |e| e.hexcode.blank? }
validates_format_of :hexcode, :with => /\A#[0-9A-F]{6}\z/, :unless => lambda { |e| e.hexcode.blank? }
def self.ms_project_colors
# Colors should be limited to the ones in MS Project.

@ -99,7 +99,7 @@ class Project < ActiveRecord::Base
validates_length_of :homepage, :maximum => 255
validates_length_of :identifier, :in => 1..IDENTIFIER_MAX_LENGTH
# donwcase letters, digits, dashes but not digits only
validates_format_of :identifier, :with => /^(?!\d+$)[a-z0-9\-_]*$/, :if => Proc.new { |p| p.identifier_changed? }
validates_format_of :identifier, :with => /\A(?!\d+$)[a-z0-9\-_]*\z/, :if => Proc.new { |p| p.identifier_changed? }
# reserved words
validates_exclusion_of :identifier, :in => RESERVED_IDENTIFIERS
@ -408,7 +408,7 @@ class Project < ActiveRecord::Base
end
def self.find(*args)
if args.first && args.first.is_a?(String) && !args.first.match(/^\d*$/)
if args.first && args.first.is_a?(String) && !args.first.match(/\A\d*\z/)
project = find_by_identifier(*args)
raise ActiveRecord::RecordNotFound, "Couldn't find Project with identifier=#{args.first}" if project.nil?
project
@ -425,7 +425,7 @@ class Project < ActiveRecord::Base
def to_param
# id is used for projects with a numeric identifier (compatibility)
@to_param ||= (identifier.to_s =~ %r{^\d*$} ? id : identifier)
@to_param ||= (identifier.to_s =~ %r{\A\d*\z} ? id : identifier)
end
def active?
@ -633,7 +633,7 @@ class Project < ActiveRecord::Base
when summary.present?
summary
when description.present?
description.gsub(/^(.{#{length}}[^\n\r]*).*$/m, '\1...').strip
description.gsub(/\A(.{#{length}}[^\n\r]*).*\z/m, '\1...').strip
else
""
end

@ -246,7 +246,7 @@ class Query < ActiveRecord::Base
def add_short_filter(field, expression)
return unless expression
parms = expression.scan(/^(o|c|!\*|!|\*)?(.*)$/).first
parms = expression.scan(/\A(o|c|!\*|!|\*)?(.*)\z/).first
add_filter field, (parms[0] || "="), [parms[1] || ""]
end
@ -273,7 +273,7 @@ class Query < ActiveRecord::Base
def label_for(field)
label = available_filters[field][:name] if available_filters.has_key?(field)
label ||= field.gsub(/\_id$/, "")
label ||= field.gsub(/\_id\z/, "")
end
def available_columns
@ -442,7 +442,7 @@ class Query < ActiveRecord::Base
end
sql = ''
if field =~ /^cf_(\d+)$/
if field =~ /\Acf_(\d+)\z/
# custom field
db_table = CustomValue.table_name
db_field = 'value'

@ -150,7 +150,7 @@ class Repository < ActiveRecord::Base
def find_changeset_by_name(name)
name = name.to_s
return nil if name.blank?
changesets.find(:first, :conditions => (name.match(/^\d*$/) ? ["revision = ?", name] : ["revision LIKE ?", name + '%']))
changesets.find(:first, :conditions => (name.match(/\A\d*\z/) ? ["revision = ?", name] : ["revision LIKE ?", name + '%']))
end
def latest_changeset
@ -211,7 +211,7 @@ class Repository < ActiveRecord::Base
c = changesets.find(:first, :conditions => {:committer => committer}, :include => :user)
if c && c.user
user = c.user
elsif committer.strip =~ /^([^<]+)(<(.*)>)?$/
elsif committer.strip =~ /\A([^<]+)(<(.*)>)?\z/
username, email = $1.strip, $3
u = User.find_by_login(username)
u ||= User.find_by_mail(email) unless email.blank?

@ -32,7 +32,7 @@ require 'redmine/scm/adapters/subversion_adapter'
class Repository::Subversion < Repository
attr_protected :root_url
validates_presence_of :url
validates_format_of :url, :with => /^(http|https|svn(\+[^\s:\/\\]+)?|file):\/\/.+/i
validates_format_of :url, :with => /\A(http|https|svn(\+[^\s:\/\\]+)?|file):\/\/.+/i
def self.scm_adapter_class
Redmine::Scm::Adapters::SubversionAdapter

@ -140,10 +140,10 @@ class User < Principal
validates_uniqueness_of :login, :if => Proc.new { |user| !user.login.blank? }, :case_sensitive => false
validates_uniqueness_of :mail, :allow_blank => true, :case_sensitive => false
# Login must contain lettres, numbers, underscores only
validates_format_of :login, :with => /^[a-z0-9_\-@\.]*$/i
validates_format_of :login, :with => /\A[a-z0-9_\-@\.]*\z/i
validates_length_of :login, :maximum => 256
validates_length_of :firstname, :lastname, :maximum => 30
validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :allow_blank => true
validates_format_of :mail, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, :allow_blank => true
validates_length_of :mail, :maximum => 60, :allow_nil => true
validates_confirmation_of :password, :allow_nil => true
validates_inclusion_of :mail_notification, :in => MAIL_NOTIFICATION_OPTIONS.collect(&:first), :allow_blank => true

@ -42,8 +42,8 @@ class Version < ActiveRecord::Base
validates_presence_of :name
validates_uniqueness_of :name, :scope => [:project_id]
validates_length_of :name, :maximum => 60
validates_format_of :effective_date, :with => /^\d{4}-\d{2}-\d{2}$/, :message => :not_a_date, :allow_nil => true
validates_format_of :start_date, :with => /^\d{4}-\d{2}-\d{2}$/, :message => :not_a_date, :allow_nil => true
validates_format_of :effective_date, :with => /\A\d{4}-\d{2}-\d{2}\z/, :message => :not_a_date, :allow_nil => true
validates_format_of :start_date, :with => /\A\d{4}-\d{2}-\d{2}\z/, :message => :not_a_date, :allow_nil => true
validates_inclusion_of :status, :in => VERSION_STATUSES
validates_inclusion_of :sharing, :in => VERSION_SHARINGS
validate :validate_start_date_before_effective_date

@ -46,7 +46,7 @@ class Wiki < ActiveRecord::Base
attr_protected :project_id
validates_presence_of :start_page
validates_format_of :start_page, :with => /^[^,\.\/\?\;\|\:]*$/
validates_format_of :start_page, :with => /\A[^,\.\/\?\;\|\:]*\z/
safe_attributes 'start_page'
@ -87,7 +87,7 @@ class Wiki < ActiveRecord::Base
# Wiki.find_page("foo:bar")
def self.find_page(title, options = {})
project = options[:project]
if title.to_s =~ %r{^([^\:]+)\:(.*)$}
if title.to_s =~ %r{\A([^\:]+)\:(.*)\z}
project_identifier, title = $1, $2
project = Project.find_by_identifier(project_identifier) || Project.find_by_name(project_identifier)
end

@ -42,7 +42,7 @@ class WikiMenuItem < ActiveRecord::Base
attr_accessible :name, :title
validates_presence_of :title
validates_format_of :title, :with => /^[^,\.\/\?\;\|\:]*$/
validates_format_of :title, :with => /\A[^,\.\/\?\;\|\:]*\z/
validates_uniqueness_of :title, :scope => :wiki_id
validates_presence_of :name

@ -49,7 +49,7 @@ class WikiPage < ActiveRecord::Base
attr_accessor :redirect_existing_links
validates_presence_of :title
validates_format_of :title, :with => /^[^,\.\/\?\;\|\s]*$/
validates_format_of :title, :with => /\A[^,\.\/\?\;\|\s]*\z/
validates_uniqueness_of :title, :scope => :wiki_id, :case_sensitive => false
validates_associated :content

@ -362,7 +362,7 @@ module WorkPackage::PdfExporter
def textstring(s)
# Format a text string
if s =~ /^</ # This means the string is hex-dumped.
if s =~ /\A</ # This means the string is hex-dumped.
return s
else
return '('+escape(s)+')'
@ -416,7 +416,7 @@ module WorkPackage::PdfExporter
def textstring(s)
# Format a text string
if s =~ /^</ # This means the string is hex-dumped.
if s =~ /\A</ # This means the string is hex-dumped.
return s
else
return '('+escape(s)+')'

@ -37,7 +37,7 @@ module ActiveRecord
def self.human_attribute_name(attr, options = {})
begin
options_with_raise = {:raise => true, :default => false}.merge options
attr = attr.to_s.gsub(/_id$/, '')
attr = attr.to_s.gsub(/_id\z/, '')
super(attr, options_with_raise)
rescue I18n::MissingTranslationData => e
included_in_general_attributes = I18n.t('attributes').keys.map(&:to_s).include? attr

@ -863,7 +863,7 @@ class AggregatedMigrations < ActiveRecord::Migration
def aggregated_versions
@@aggregated_versions ||= @@migrations.split.map do |m|
m.gsub(/_.*$/, '').to_i
m.gsub(/_.*\z/, '').to_i
end
end

@ -97,7 +97,7 @@ module Migration
# attachments123 if the attachment was added
# attachments_123 if the attachment was removed
#
@attachment_key_regexp ||= /attachments_?(\d+)$/
@attachment_key_regexp ||= /attachments_?(\d+)\z/
end
end

@ -58,7 +58,7 @@ module Migration
MESSAGE
end
self.journable_class ||= self.type.gsub(/Journal$/, "")
self.journable_class ||= self.type.gsub(/Journal\z/, "")
end
def run

@ -53,6 +53,7 @@ See doc/COPYRIGHT.rdoc for more details.
* `#2548` Migrated core settings
* `#2557` Highlight changes of any work package attribute available in the timelines table
* `#2559` Migrate existing IssueCustomFields to WorkPackageCustomFields
* `#2575` Regular expressions should use \A and \z instead of ^ and $
* Fix compatibility with old mail configuration
## 3.0.0pre22

@ -149,7 +149,7 @@ class RedmineMailHandler
end
def submit(email)
uri = url.gsub(%r{/*$}, '') + '/mail_handler'
uri = url.gsub(%r{/*\z}, '') + '/mail_handler'
headers = { 'User-Agent' => "Redmine mail handler/#{VERSION}" }

@ -150,7 +150,7 @@ if $command.nil?
end
end
$svn_url += "/" if $svn_url and not $svn_url.match(/\/$/)
$svn_url += "/" if $svn_url and not $svn_url.match(/\/\z/)
if ($redmine_host.empty? or $repos_base.empty?)
puts "Required argument missing. Type 'reposman.rb --help' for usage."
@ -173,8 +173,8 @@ end
log("querying Redmine for projects...", :level => 1);
$redmine_host.gsub!(/^/, "http://") unless $redmine_host.match("^https?://")
$redmine_host.gsub!(/\/$/, '')
$redmine_host.gsub!(/\A/, "http://") unless $redmine_host.match("\Ahttps?://")
$redmine_host.gsub!(/\/\z/, '')
Project.site = "#{$redmine_host}/sys";
@ -226,7 +226,7 @@ projects.each do |project|
if project.identifier.empty?
log("\tno identifier for project #{project.name}")
next
elsif not project.identifier.match(/^[a-z0-9\-_]+$/)
elsif not project.identifier.match(/\A[a-z0-9\-_]+\z/)
log("\tinvalid identifier for project #{project.name} : #{project.identifier}");
next;
end

@ -76,7 +76,7 @@ module ChiliProject
version = ActiveRecord::Base.connection.select_value('SELECT VERSION()')
when :postgresql
version = ActiveRecord::Base.connection.select_value('SELECT version()')
raw ? version : version.match(/^PostgreSQL (\S+)/i)[1]
raw ? version : version.match(/\APostgreSQL (\S+)/i)[1]
when :sqlite
if Object.const_defined?('RUBY_ENGINE') && ::RUBY_ENGINE == 'jruby'
Jdbc::SQLite3::VERSION

@ -65,13 +65,13 @@ module OpenProject
# 'OpenProject::Themes::GoofyTheme' => :'goofy'
def identifier
@identifier ||= self.class.to_s.gsub(/Theme$/, '').demodulize.underscore.dasherize.to_sym
@identifier ||= self.class.to_s.gsub(/Theme\z/, '').demodulize.underscore.dasherize.to_sym
end
attr_writer :identifier
# 'OpenProject::Themes::GoofyTheme' => 'Goofy'
def name
@name ||= self.class.to_s.gsub(/Theme$/, '').demodulize.titleize
@name ||= self.class.to_s.gsub(/Theme\z/, '').demodulize.titleize
end
def stylesheet_manifest
@ -103,7 +103,7 @@ module OpenProject
source.in?(overridden_images)
end
URI_REGEXP = %r{^[-a-z]+://|^(?:cid|data):|^//}
URI_REGEXP = %r{\A[-a-z]+://|\A(?:cid|data):|\A//}
def path_to_image(source)
return source if source =~ URI_REGEXP

@ -165,9 +165,9 @@ module Redmine
options.each_pair do |k, v|
case
when k.to_s =~ /^activity_(.+)$/
when k.to_s =~ /\Aactivity_(.+)\z/
activity_hash[$1.to_sym] = v
when k.to_s =~ /^event_(.+)$/
when k.to_s =~ /\Aevent_(.+)\z/
event_hash[$1.to_sym] = v
else
journal_hash[k.to_sym] = v

@ -51,7 +51,7 @@ class JournalFormatter::NamedAssociation < JournalFormatter::Attribute
end
def format_values(values, key, options)
field = key.to_s.gsub(/\_id$/, "").to_sym
field = key.to_s.gsub(/\_id\z/, "").to_sym
klass = class_from_field(field)
values.map do |value|

@ -44,7 +44,7 @@ class JournalFormatter::Proc < JournalFormatter::Attribute
end
def format_values(values, key)
field = key.to_s.gsub(/\_id$/, "")
field = key.to_s.gsub(/\_id\z/, "")
values.map do |value|
self.class.proc.call value, @journal.journable, field

@ -95,7 +95,7 @@ module Redmine::Acts::Journalized
# the method name (sans "=") as the key. If given a getter method name, will attempt to
# a value from the +options+ hash for that key. If the key doesn't exist, defers to +super+.
def method_missing(symbol, *args)
if (method = symbol.to_s).sub!(/\=$/, '')
if (method = symbol.to_s).sub!(/\=\z/, '')
options[method.to_sym] = args.first
else
options.fetch(method.to_sym, super)

@ -1665,7 +1665,7 @@ def MakeFont(fontfile, afmfile, enc = 'cp1252', patch = {}, type = 'TrueType')
# Find font type
if fontfile then
ext = File.extname(fontfile).downcase.sub(/^\./, '')
ext = File.extname(fontfile).downcase.sub(/\A\./, '')
if ext == 'ttf' then
type = 'TrueType'

@ -90,7 +90,7 @@ module Redmine
# returns mime type for name or nil if unknown
def self.of(name)
return nil unless name
m = name.to_s.match(/(^|\.)([^\.]+)$/)
m = name.to_s.match(/(\A|\.)([^\.]+)\z/)
EXTENSIONS[m[2].downcase] if m
end

@ -170,7 +170,7 @@ module Redmine
def without_leading_slash(path)
path ||= ''
path.gsub(%r{^/+}, '')
path.gsub(%r{\A/+}, '')
end
def without_trailling_slash(path)
@ -190,7 +190,7 @@ module Redmine
def target(path)
path ||= ''
base = path.match(/^\//) ? root_url : url
base = path.match(/\A\//) ? root_url : url
shell_quote("#{base}/#{path}".gsub(/[?<>\*]/, ''))
end

@ -78,7 +78,7 @@ module Redmine
e1 = scm_encode(@path_encoding, 'UTF-8', e_utf8)
if File.exist?(t1) and # paranoid test
%w{file directory}.include?(File.ftype(t1)) and # avoid special types
not File.basename(e1).match(/^\.+$/) # avoid . and ..
not File.basename(e1).match(/\A\.+\z/) # avoid . and ..
p1 = File.readable?(t1) ? relative_path : ""
utf_8_path = scm_encode('UTF-8', @path_encoding, p1)
entries <<

@ -283,7 +283,7 @@ module Redmine
end
def target(path = '')
base = path.match(/^\//) ? root_url : url
base = path.match(/\A\//) ? root_url : url
uri = "#{base}/#{path}"
uri = URI.escape(URI.escape(uri), '[]')
shell_quote(uri.gsub(/[?<>\*]/, ''))

@ -48,7 +48,7 @@ module Redmine
end
end.compact
).inject({}) do |h,file|
name = File.basename(file).split('.').first.gsub(/^_/, '')
name = File.basename(file).split('.').first.gsub(/\A_/, '')
h[name] = ("label_" + name).to_sym
h
end

@ -40,7 +40,7 @@ namespace :code do
# handle files in chunks of 50 to avoid too long command lines
while (slice = files.slice!(0, 50)).present?
system('ruby', '-i', '-pe', 'gsub(/\s+$/,"\n")', *slice)
system('ruby', '-i', '-pe', 'gsub(/\s+\z/,"\n")', *slice)
end
end
end

@ -75,17 +75,17 @@ namespace :copyright do
def copyright_regexp(format)
case format
when :ruby, :rb
/^(?<shebang>#![^\n]+\n)?#--\s*copyright.*?\+\+/m
/\A(?<shebang>#![^\n]+\n)?#--\s*copyright.*?\+\+/m
when :js, :css
/^(?<shebang>#![^\n]+\n)?\/\/--\s*copyright.*?\/\/\+\+/m
/\A(?<shebang>#![^\n]+\n)?\/\/--\s*copyright.*?\/\/\+\+/m
when :erb
/^(?<shebang>#![^\n]+\n)?<%#--\s*copyright.*?\+\+#%>/m
/\A(?<shebang>#![^\n]+\n)?<%#--\s*copyright.*?\+\+#%>/m
when :rdoc
/(?<shebang>)?-{10}\n={4} copyright\n\n[\s\S]*?\+\+\n-{10}\n$/
/(?<shebang>)?-{10}\n={4} copyright\n\n[\s\S]*?\+\+\n-{10}\n\z/
when :md, :html
/^(?<shebang>#![^\n]+\n)?<!----\s*copyright.*?\+\+-->/m
/\A(?<shebang>#![^\n]+\n)?<!----\s*copyright.*?\+\+-->/m
when :sql
/^(?<shebang>#![^\n]+\n)?-- --\s*copyright.*?\+\+/m
/\A(?<shebang>#![^\n]+\n)?-- --\s*copyright.*?\+\+/m
else
raise "Undefined format #{format}"
end

@ -33,7 +33,7 @@
# files.
unless ARGV.any? {|a| a =~ /^gems/} # Don't load anything when running the gems:* tasks
unless ARGV.any? {|a| a =~ /\Agems/} # Don't load anything when running the gems:* tasks
begin
require 'shellwords'

@ -55,7 +55,7 @@ namespace :locales do
missing_keys.each do |key|
{key => en_strings[key]}.to_yaml.each_line do |line|
next if line =~ /^---/ || line.empty?
next if line =~ /\A---/ || line.empty?
puts " #{line}"
lang << " #{line}"
end
@ -136,7 +136,7 @@ END_DESC
File.open(path, 'a') do |file|
adds.each do |kv|
Hash[*kv].to_yaml.each_line do |line|
file.puts " #{line}" unless (line =~ /^---/ || line.empty?)
file.puts " #{line}" unless (line =~ /\A---/ || line.empty?)
end
end
end

@ -46,9 +46,9 @@ class PluginSourceAnnotationExtractor < SourceAnnotationExtractor
results.update(find_in(item))
elsif item =~ /(hook|test)\.rb/
# skip
elsif item =~ /\.(builder|(r(?:b|xml|js)))$/
results.update(extract_annotations_from(item, /\s*(#{tag})\(?\s*(.*)$/))
elsif item =~ /\.(rhtml|erb)$/
elsif item =~ /\.(builder|(r(?:b|xml|js)))\z/
results.update(extract_annotations_from(item, /\s*(#{tag})\(?\s*(.*)\z/))
elsif item =~ /\.(rhtml|erb)\z/
results.update(extract_annotations_from(item, /<%=\s*\s*(#{tag})\(?\s*(.*?)\s*%>/))
end
end

@ -73,7 +73,7 @@ namespace :test do
task :update do
require 'fileutils'
Dir.glob("tmp/test/*_repository").each do |dir|
next unless File.basename(dir) =~ %r{^(.+)_repository$} && File.directory?(dir)
next unless File.basename(dir) =~ %r{\A(.+)_repository\z} && File.directory?(dir)
scm = $1
next unless fixture = Dir.glob("test/fixtures/repositories/#{scm}_repository.*").first
next if File.stat(dir).ctime > File.stat(fixture).mtime

@ -146,7 +146,7 @@ describe PaginationHelper do
let(:total_entries) { 0 }
it "should be empty" do
pagination.should have_selector(".pagination", :text => /^$/)
pagination.should have_selector(".pagination", :text => /\A\z/)
end
end
end

@ -63,7 +63,7 @@ class AttachmentTest < ActiveSupport::TestCase
end
def test_diskfilename
assert Attachment.disk_filename("test_file.txt") =~ /^\d{12}_test_file.txt$/
assert Attachment.disk_filename("test_file.txt") =~ /\A\d{12}_test_file.txt\z/
assert_equal 'test_file.txt', Attachment.disk_filename("test_file.txt")[13..-1]
assert_equal '770c509475505f37c2b8fb6030434d6b.txt', Attachment.disk_filename("test_accentué.txt")[13..-1]
assert_equal 'f8139524ebb8f32e51976982cd20a85d', Attachment.disk_filename("test_accentué")[13..-1]

@ -83,7 +83,7 @@ class Redmine::PluginTest < ActiveSupport::TestCase
requires_openproject('< 0.9', ">= 98.0.0")
end
test.assert requires_openproject("~> #{Redmine::VERSION.to_semver.gsub(/\d+$/, '0')}")
test.assert requires_openproject("~> #{Redmine::VERSION.to_semver.gsub(/\d+\z/, '0')}")
end
end

@ -38,7 +38,7 @@ class Redmine::UnifiedDiffTest < ActiveSupport::TestCase
diff = Redmine::UnifiedDiff.new(read_diff_fixture('subversion.diff'))
# number of files
assert_equal 4, diff.size
assert diff.detect {|file| file.file_name =~ %r{^config/settings.yml}}
assert diff.detect {|file| file.file_name =~ %r{\Aconfig/settings.yml}}
end
def test_truncate_diff

Loading…
Cancel
Save