diff options
-rw-r--r-- | CHANGELOG | 1 | ||||
-rw-r--r-- | db/migrate/20160129135155_remove_dot_atom_path_ending_of_projects.rb | 90 | ||||
-rw-r--r-- | lib/gitlab/regex.rb | 4 | ||||
-rw-r--r-- | spec/controllers/projects_controller_spec.rb | 8 |
4 files changed, 101 insertions, 2 deletions
diff --git a/CHANGELOG b/CHANGELOG index 7a70516173c..fbc73589bd1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -21,6 +21,7 @@ v 8.5.0 (unreleased) - Revert "Add IP check against DNSBLs at account sign-up" - Deprecate API "merge_request/:merge_request_id/comments". Use "merge_requests/:merge_request_id/notes" instead - Deprecate API "merge_request/:merge_request_id/...". Use "merge_requests/:merge_request_id/..." instead + - Prevent parse error when name of project ends with .atom and prevent path issues - Mark inline difference between old and new paths when a file is renamed v 8.4.3 diff --git a/db/migrate/20160129135155_remove_dot_atom_path_ending_of_projects.rb b/db/migrate/20160129135155_remove_dot_atom_path_ending_of_projects.rb new file mode 100644 index 00000000000..0bc23f5627f --- /dev/null +++ b/db/migrate/20160129135155_remove_dot_atom_path_ending_of_projects.rb @@ -0,0 +1,90 @@ +class RemoveDotAtomPathEndingOfProjects < ActiveRecord::Migration + include Gitlab::ShellAdapter + + class ProjectPath + attr_reader :old_path, :id + + def initialize(old_path, id) + @old_path = old_path + @id = id + end + + def clean_path + @_clean_path ||= PathCleaner.clean(@old_path) + end + end + + class PathCleaner + def initialize(path) + @path = path + end + + def self.clean(*args) + new(*args).clean + end + + def clean + path = cleaned_path + count = 0 + while path_exists?(path) + path = "#{cleaned_path}#{count}" + count += 1 + end + path + end + + def cleaned_path + @_cleaned_path ||= @path.gsub(/\.atom\z/, '-atom') + end + + def path_exists?(path) + Project.find_by_path(path) + end + end + + def projects_with_dot_atom + select_all("SELECT id, path FROM projects WHERE lower(path) LIKE '%.atom'") + end + + def up + projects_with_dot_atom.each do |project| + binding.pry + project_path = ProjectPath.new(project['path'], project['id']) + clean_path(project_path) if move_path(project_path) + end + end + + private + + def clean_path(project_path) + execute "UPDATE projects SET path = '#{project_path.clean_path}' WHERE id = #{project.id}" + end + + #TODO: Fix this + def move_path(project_path) + # Based on RemovePeriodsAtEndsOfUsernames + # Don't attempt to move if original path only contains periods. + return if project_path.clean_path =~ /\A\.+\z/ + if gitlab_shell.mv_namespace(project_path.old_path, project_path.clean_path) + # If repositories moved successfully we need to remove old satellites + # and send update instructions to users. + # However we cannot allow rollback since we moved namespace dir + # So we basically we mute exceptions in next actions + begin + gitlab_shell.rm_satellites(project_path.old_path) + # We cannot send update instructions since models and mailers + # can't safely be used from migrations as they may be written for + # later versions of the database. + # send_update_instructions + rescue + # Returning false does not rollback after_* transaction but gives + # us information about failing some of tasks + false + end + else + # if we cannot move namespace directory we should avoid + # db changes in order to prevent out of sync between db and fs + false + end + end +end diff --git a/lib/gitlab/regex.rb b/lib/gitlab/regex.rb index 5c35c5b1450..ace906a6f59 100644 --- a/lib/gitlab/regex.rb +++ b/lib/gitlab/regex.rb @@ -34,12 +34,12 @@ module Gitlab def project_path_regex - @project_path_regex ||= /\A[a-zA-Z0-9_.][a-zA-Z0-9_\-\.]*(?<!\.git)\z/.freeze + @project_path_regex ||= /\A[a-zA-Z0-9_.][a-zA-Z0-9_\-\.]*(?<!\.git|\.atom)\z/.freeze end def project_path_regex_message "can contain only letters, digits, '_', '-' and '.'. " \ - "Cannot start with '-' or end in '.git'" \ + "Cannot start with '-', end in '.git' or end in '.atom'" \ end diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index 665526fde93..245cf96d644 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -86,6 +86,14 @@ describe ProjectsController do end end end + + context "when the url contains .atom" do + let(:public_project_with_dot_atom) { create(:project, :public, name: 'my.atom', path: 'my.atom') } + + it 'expect an error creating the project' do + expect { public_project_with_dot_atom }.to raise_error(ActiveRecord::RecordInvalid) + end + end end describe "#destroy" do |