From 8e70a2f81e6c533fcf30b38a7182bec97378f992 Mon Sep 17 00:00:00 2001 From: Philipp Tessenow Date: Mon, 28 Oct 2013 13:59:05 +0100 Subject: [PATCH 1/2] add changelog entry [skip ci] --- doc/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 93a6ffbe5e6..93c9aba0f0f 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -49,6 +49,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 From 444546e2e860a8875969b07bce58e66a73d2df54 Mon Sep 17 00:00:00 2001 From: Philipp Tessenow Date: Mon, 28 Oct 2013 12:21:28 +0100 Subject: [PATCH 2/2] use \A and \z instead of ^ and $ in ruby regexes --- .../api/v2/planning_elements_controller.rb | 2 +- app/controllers/api/v2/projects_controller.rb | 2 +- app/controllers/application_controller.rb | 2 +- app/controllers/custom_fields_controller.rb | 2 +- app/controllers/search_controller.rb | 2 +- .../work_packages/auto_completes_controller.rb | 2 +- app/helpers/application_helper.rb | 10 +++++----- app/helpers/journals_helper.rb | 2 +- app/helpers/repositories_helper.rb | 2 +- app/helpers/sort_helper.rb | 2 +- app/mailers/user_mailer.rb | 4 ++-- app/models/attachment.rb | 10 +++++----- app/models/changeset.rb | 2 +- app/models/custom_field.rb | 2 +- app/models/custom_value.rb | 4 ++-- app/models/mail_handler.rb | 6 +++--- app/models/planning_element_type_color.rb | 2 +- app/models/project.rb | 8 ++++---- app/models/query.rb | 6 +++--- app/models/repository.rb | 4 ++-- app/models/repository/subversion.rb | 2 +- app/models/user.rb | 4 ++-- app/models/version.rb | 4 ++-- app/models/wiki.rb | 4 ++-- app/models/wiki_menu_item.rb | 2 +- app/models/wiki_page.rb | 2 +- app/models/work_package/pdf_exporter.rb | 4 ++-- config/initializers/10-patches.rb | 2 +- db/migrate/000_aggregated_migrations.rb | 2 +- .../migration_utils/journal_migrator_concerns.rb | 2 +- .../migration_utils/legacy_journal_migrator.rb | 2 +- extra/mail_handler/rdm-mailhandler.rb | 2 +- extra/svn/reposman.rb | 8 ++++---- lib/chili_project/database.rb | 2 +- lib/open_project/themes/theme.rb | 6 +++--- .../acts_as_journalized/lib/acts_as_journalized.rb | 4 ++-- .../lib/journal_formatter/named_association.rb | 2 +- .../lib/journal_formatter/proc.rb | 2 +- .../lib/redmine/acts/journalized/configuration.rb | 2 +- lib/plugins/rfpdf/lib/fpdf/makefont.rb | 2 +- lib/redmine/mime_type.rb | 2 +- lib/redmine/scm/adapters/abstract_adapter.rb | 4 ++-- lib/redmine/scm/adapters/filesystem_adapter.rb | 2 +- lib/redmine/scm/adapters/subversion_adapter.rb | 2 +- lib/redmine/views/my_page/block.rb | 2 +- lib/tasks/code.rake | 2 +- lib/tasks/copyright.rake | 12 ++++++------ lib/tasks/cucumber.rake | 2 +- lib/tasks/locales.rake | 4 ++-- lib/tasks/plugins.rake | 6 +++--- lib/tasks/testing.rake | 2 +- spec/helpers/pagination_helper_spec.rb | 2 +- test/unit/attachment_test.rb | 2 +- test/unit/lib/redmine/plugin_test.rb | 2 +- test/unit/lib/redmine/unified_diff_test.rb | 2 +- 55 files changed, 92 insertions(+), 92 deletions(-) diff --git a/app/controllers/api/v2/planning_elements_controller.rb b/app/controllers/api/v2/planning_elements_controller.rb index a5df5cc11ce..20cb7ddd7eb 100644 --- a/app/controllers/api/v2/planning_elements_controller.rb +++ b/app/controllers/api/v2/planning_elements_controller.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 diff --git a/app/controllers/api/v2/projects_controller.rb b/app/controllers/api/v2/projects_controller.rb index 7fc72cbaaa3..26a9ed32783 100644 --- a/app/controllers/api/v2/projects_controller.rb +++ b/app/controllers/api/v2/projects_controller.rb @@ -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 diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c117a101d80..3d48507521a 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -530,7 +530,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]) diff --git a/app/controllers/custom_fields_controller.rb b/app/controllers/custom_fields_controller.rb index 6974d89a952..ea05cb6f207 100644 --- a/app/controllers/custom_fields_controller.rb +++ b/app/controllers/custom_fields_controller.rb @@ -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 diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 2ed1665ccd3..3a6b701778f 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -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 diff --git a/app/controllers/work_packages/auto_completes_controller.rb b/app/controllers/work_packages/auto_completes_controller.rb index f23f1d06551..d7ebcc4b57c 100644 --- a/app/controllers/work_packages/auto_completes_controller.rb +++ b/app/controllers/work_packages/auto_completes_controller.rb @@ -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, diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 039c3876607..93369bd55a7 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -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', :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 diff --git a/app/helpers/journals_helper.rb b/app/helpers/journals_helper.rb index 1f4fdde2fa9..b84298bc93d 100644 --- a/app/helpers/journals_helper.rb +++ b/app/helpers/journals_helper.rb @@ -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', diff --git a/app/helpers/repositories_helper.rb b/app/helpers/repositories_helper.rb index d8fb7961e56..69be5209a25 100644 --- a/app/helpers/repositories_helper.rb +++ b/app/helpers/repositories_helper.rb @@ -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) diff --git a/app/helpers/sort_helper.rb b/app/helpers/sort_helper.rb index b9b79b258bf..b6acef9c608 100644 --- a/app/helpers/sort_helper.rb +++ b/app/helpers/sort_helper.rb @@ -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" diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 477c2acc491..0ebe35e09ce 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -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 diff --git a/app/models/attachment.rb b/app/models/attachment.rb index edf589e1a65..bd68fab58ce 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -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! diff --git a/app/models/changeset.rb b/app/models/changeset.rb index f16a2d224d1..05844c4b3c3 100644 --- a/app/models/changeset.rb +++ b/app/models/changeset.rb @@ -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 diff --git a/app/models/custom_field.rb b/app/models/custom_field.rb index 734fb586dc7..b999af4ee8d 100644 --- a/app/models/custom_field.rb +++ b/app/models/custom_field.rb @@ -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 diff --git a/app/models/custom_value.rb b/app/models/custom_value.rb index f13d2e8f3cd..73bf3cc9983 100644 --- a/app/models/custom_value.rb +++ b/app/models/custom_value.rb @@ -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 diff --git a/app/models/mail_handler.rb b/app/models/mail_handler.rb index 05c200399e0..ef72304ae40 100644 --- a/app/models/mail_handler.rb +++ b/app/models/mail_handler.rb @@ -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? diff --git a/app/models/planning_element_type_color.rb b/app/models/planning_element_type_color.rb index c6d362b4a31..ff984d3e972 100644 --- a/app/models/planning_element_type_color.rb +++ b/app/models/planning_element_type_color.rb @@ -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. diff --git a/app/models/project.rb b/app/models/project.rb index a5da51877b3..aec2b2fd156 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -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 diff --git a/app/models/query.rb b/app/models/query.rb index 205b5cfab6b..fe8cdbc4190 100644 --- a/app/models/query.rb +++ b/app/models/query.rb @@ -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' diff --git a/app/models/repository.rb b/app/models/repository.rb index ed8fa41bbe3..8654587a49a 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -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? diff --git a/app/models/repository/subversion.rb b/app/models/repository/subversion.rb index b44f909851e..a3e738270b4 100644 --- a/app/models/repository/subversion.rb +++ b/app/models/repository/subversion.rb @@ -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 diff --git a/app/models/user.rb b/app/models/user.rb index 71f9c41ab60..54e50c30ca3 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -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 diff --git a/app/models/version.rb b/app/models/version.rb index 37e57b3f351..518bfc569db 100644 --- a/app/models/version.rb +++ b/app/models/version.rb @@ -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 diff --git a/app/models/wiki.rb b/app/models/wiki.rb index 5b8be730cd7..6e757536da4 100644 --- a/app/models/wiki.rb +++ b/app/models/wiki.rb @@ -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 diff --git a/app/models/wiki_menu_item.rb b/app/models/wiki_menu_item.rb index 402a88afad0..3accc221b6c 100644 --- a/app/models/wiki_menu_item.rb +++ b/app/models/wiki_menu_item.rb @@ -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 diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 67c6b182d55..e6ac96ae486 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -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 diff --git a/app/models/work_package/pdf_exporter.rb b/app/models/work_package/pdf_exporter.rb index 11939e7c258..6d613c9d752 100644 --- a/app/models/work_package/pdf_exporter.rb +++ b/app/models/work_package/pdf_exporter.rb @@ -362,7 +362,7 @@ module WorkPackage::PdfExporter def textstring(s) # Format a text string - if s =~ /^ 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 diff --git a/db/migrate/000_aggregated_migrations.rb b/db/migrate/000_aggregated_migrations.rb index 8507e6b4ab3..857671cdbb9 100644 --- a/db/migrate/000_aggregated_migrations.rb +++ b/db/migrate/000_aggregated_migrations.rb @@ -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 diff --git a/db/migrate/migration_utils/journal_migrator_concerns.rb b/db/migrate/migration_utils/journal_migrator_concerns.rb index 0854d7ed36e..da3ffc5fcff 100644 --- a/db/migrate/migration_utils/journal_migrator_concerns.rb +++ b/db/migrate/migration_utils/journal_migrator_concerns.rb @@ -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 diff --git a/db/migrate/migration_utils/legacy_journal_migrator.rb b/db/migrate/migration_utils/legacy_journal_migrator.rb index 9f7f5210104..b536517f040 100644 --- a/db/migrate/migration_utils/legacy_journal_migrator.rb +++ b/db/migrate/migration_utils/legacy_journal_migrator.rb @@ -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 diff --git a/extra/mail_handler/rdm-mailhandler.rb b/extra/mail_handler/rdm-mailhandler.rb index 95ecd3c9b81..5550f3f8547 100644 --- a/extra/mail_handler/rdm-mailhandler.rb +++ b/extra/mail_handler/rdm-mailhandler.rb @@ -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}" } diff --git a/extra/svn/reposman.rb b/extra/svn/reposman.rb index d40c0fb3a79..9789e97688b 100755 --- a/extra/svn/reposman.rb +++ b/extra/svn/reposman.rb @@ -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 diff --git a/lib/chili_project/database.rb b/lib/chili_project/database.rb index 08137739643..9a7aa772c4d 100644 --- a/lib/chili_project/database.rb +++ b/lib/chili_project/database.rb @@ -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 diff --git a/lib/open_project/themes/theme.rb b/lib/open_project/themes/theme.rb index 020a9fc79bf..b093946a071 100644 --- a/lib/open_project/themes/theme.rb +++ b/lib/open_project/themes/theme.rb @@ -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 diff --git a/lib/plugins/acts_as_journalized/lib/acts_as_journalized.rb b/lib/plugins/acts_as_journalized/lib/acts_as_journalized.rb index adef03824c5..5ed3b047b3a 100644 --- a/lib/plugins/acts_as_journalized/lib/acts_as_journalized.rb +++ b/lib/plugins/acts_as_journalized/lib/acts_as_journalized.rb @@ -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 diff --git a/lib/plugins/acts_as_journalized/lib/journal_formatter/named_association.rb b/lib/plugins/acts_as_journalized/lib/journal_formatter/named_association.rb index 374d37a43c3..64ee1648edf 100644 --- a/lib/plugins/acts_as_journalized/lib/journal_formatter/named_association.rb +++ b/lib/plugins/acts_as_journalized/lib/journal_formatter/named_association.rb @@ -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| diff --git a/lib/plugins/acts_as_journalized/lib/journal_formatter/proc.rb b/lib/plugins/acts_as_journalized/lib/journal_formatter/proc.rb index bb4d3d31d7c..ba87a5b14b1 100644 --- a/lib/plugins/acts_as_journalized/lib/journal_formatter/proc.rb +++ b/lib/plugins/acts_as_journalized/lib/journal_formatter/proc.rb @@ -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 diff --git a/lib/plugins/acts_as_journalized/lib/redmine/acts/journalized/configuration.rb b/lib/plugins/acts_as_journalized/lib/redmine/acts/journalized/configuration.rb index 64fb359ad38..31cf05e6ace 100644 --- a/lib/plugins/acts_as_journalized/lib/redmine/acts/journalized/configuration.rb +++ b/lib/plugins/acts_as_journalized/lib/redmine/acts/journalized/configuration.rb @@ -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) diff --git a/lib/plugins/rfpdf/lib/fpdf/makefont.rb b/lib/plugins/rfpdf/lib/fpdf/makefont.rb index 91aa69d285a..2bf080f721e 100644 --- a/lib/plugins/rfpdf/lib/fpdf/makefont.rb +++ b/lib/plugins/rfpdf/lib/fpdf/makefont.rb @@ -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' diff --git a/lib/redmine/mime_type.rb b/lib/redmine/mime_type.rb index ca5a5a4419c..6e89c13ad0f 100644 --- a/lib/redmine/mime_type.rb +++ b/lib/redmine/mime_type.rb @@ -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 diff --git a/lib/redmine/scm/adapters/abstract_adapter.rb b/lib/redmine/scm/adapters/abstract_adapter.rb index 871d086ce0c..37cebc945a4 100644 --- a/lib/redmine/scm/adapters/abstract_adapter.rb +++ b/lib/redmine/scm/adapters/abstract_adapter.rb @@ -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 diff --git a/lib/redmine/scm/adapters/filesystem_adapter.rb b/lib/redmine/scm/adapters/filesystem_adapter.rb index abfd4d52206..0730ba5a8f9 100644 --- a/lib/redmine/scm/adapters/filesystem_adapter.rb +++ b/lib/redmine/scm/adapters/filesystem_adapter.rb @@ -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 << diff --git a/lib/redmine/scm/adapters/subversion_adapter.rb b/lib/redmine/scm/adapters/subversion_adapter.rb index d88b1d8abfa..a5bf73dcecc 100644 --- a/lib/redmine/scm/adapters/subversion_adapter.rb +++ b/lib/redmine/scm/adapters/subversion_adapter.rb @@ -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(/[?<>\*]/, '')) diff --git a/lib/redmine/views/my_page/block.rb b/lib/redmine/views/my_page/block.rb index e3937bcccc2..e47b207989a 100644 --- a/lib/redmine/views/my_page/block.rb +++ b/lib/redmine/views/my_page/block.rb @@ -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 diff --git a/lib/tasks/code.rake b/lib/tasks/code.rake index a817f362d5c..20a956faaee 100644 --- a/lib/tasks/code.rake +++ b/lib/tasks/code.rake @@ -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 diff --git a/lib/tasks/copyright.rake b/lib/tasks/copyright.rake index e98b7061006..b05539ee305 100644 --- a/lib/tasks/copyright.rake +++ b/lib/tasks/copyright.rake @@ -75,17 +75,17 @@ namespace :copyright do def copyright_regexp(format) case format when :ruby, :rb - /^(?#![^\n]+\n)?#--\s*copyright.*?\+\+/m + /\A(?#![^\n]+\n)?#--\s*copyright.*?\+\+/m when :js, :css - /^(?#![^\n]+\n)?\/\/--\s*copyright.*?\/\/\+\+/m + /\A(?#![^\n]+\n)?\/\/--\s*copyright.*?\/\/\+\+/m when :erb - /^(?#![^\n]+\n)?<%#--\s*copyright.*?\+\+#%>/m + /\A(?#![^\n]+\n)?<%#--\s*copyright.*?\+\+#%>/m when :rdoc - /(?)?-{10}\n={4} copyright\n\n[\s\S]*?\+\+\n-{10}\n$/ + /(?)?-{10}\n={4} copyright\n\n[\s\S]*?\+\+\n-{10}\n\z/ when :md, :html - /^(?#![^\n]+\n)?/m + /\A(?#![^\n]+\n)?/m when :sql - /^(?#![^\n]+\n)?-- --\s*copyright.*?\+\+/m + /\A(?#![^\n]+\n)?-- --\s*copyright.*?\+\+/m else raise "Undefined format #{format}" end diff --git a/lib/tasks/cucumber.rake b/lib/tasks/cucumber.rake index 5df47bd7f29..c157de3620c 100644 --- a/lib/tasks/cucumber.rake +++ b/lib/tasks/cucumber.rake @@ -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' diff --git a/lib/tasks/locales.rake b/lib/tasks/locales.rake index 73e39290c54..46c8f912f51 100644 --- a/lib/tasks/locales.rake +++ b/lib/tasks/locales.rake @@ -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 diff --git a/lib/tasks/plugins.rake b/lib/tasks/plugins.rake index 19d4a2b5435..88df213241e 100644 --- a/lib/tasks/plugins.rake +++ b/lib/tasks/plugins.rake @@ -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 diff --git a/lib/tasks/testing.rake b/lib/tasks/testing.rake index 6d6f1111f0e..8dfd20788af 100644 --- a/lib/tasks/testing.rake +++ b/lib/tasks/testing.rake @@ -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 diff --git a/spec/helpers/pagination_helper_spec.rb b/spec/helpers/pagination_helper_spec.rb index 15f97a54998..af78d567989 100644 --- a/spec/helpers/pagination_helper_spec.rb +++ b/spec/helpers/pagination_helper_spec.rb @@ -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 diff --git a/test/unit/attachment_test.rb b/test/unit/attachment_test.rb index b82ce73dd45..fb2b08cd147 100644 --- a/test/unit/attachment_test.rb +++ b/test/unit/attachment_test.rb @@ -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] diff --git a/test/unit/lib/redmine/plugin_test.rb b/test/unit/lib/redmine/plugin_test.rb index 44eb2e45174..d521482e9fa 100644 --- a/test/unit/lib/redmine/plugin_test.rb +++ b/test/unit/lib/redmine/plugin_test.rb @@ -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 diff --git a/test/unit/lib/redmine/unified_diff_test.rb b/test/unit/lib/redmine/unified_diff_test.rb index c400ea45b6c..d949c3f5288 100644 --- a/test/unit/lib/redmine/unified_diff_test.rb +++ b/test/unit/lib/redmine/unified_diff_test.rb @@ -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