#446: added ability to create project aliases

This commit is contained in:
Vokhmin Alexey V 2015-01-13 02:06:33 +03:00
parent 442b7f92dd
commit 8580b9a80d
11 changed files with 64 additions and 26 deletions

View File

@ -114,7 +114,9 @@ class Projects::ProjectsController < Projects::BaseController
def fork def fork
owner = (Group.find params[:group] if params[:group].present?) || current_user owner = (Group.find params[:group] if params[:group].present?) || current_user
authorize! :write, owner if owner.class == Group authorize! :write, owner if owner.class == Group
if forked = @project.fork(owner, params[:fork_name]) and forked.valid?
is_alias = params[:alias] == 'true'
if forked = @project.fork(owner, params[:fork_name], is_alias) and forked.valid?
redirect_to forked, notice: t("flash.project.forked") redirect_to forked, notice: t("flash.project.forked")
else else
flash[:warning] = t("flash.project.fork_error") flash[:warning] = t("flash.project.fork_error")

View File

@ -153,7 +153,20 @@ module Git
end end
def fork_git_repo def fork_git_repo
dummy = Grit::Repo.new(path) rescue parent.repo.fork_bare(path, shared: false) dummy = Grit::Repo.new(path) rescue nil
unless dummy
if alias_from_id
aliases_path = File.join(APP_CONFIG['git_path'], 'git_projects', '.aliases')
FileUtils.mkdir_p(aliases_path)
alias_path = File.join(aliases_path, "#{alias_from_id}.git")
if !Dir.exists?(alias_path) && alias_from
FileUtils.mv(alias_from.path, alias_path, force: true)
end
FileUtils.ln_sf alias_path, path
else
parent.repo.fork_bare(path, shared: false)
end
end
write_hook write_hook
end end

View File

@ -17,6 +17,9 @@ class Project < ActiveRecord::Base
belongs_to :owner, polymorphic: true, counter_cache: :own_projects_count belongs_to :owner, polymorphic: true, counter_cache: :own_projects_count
belongs_to :maintainer, class_name: 'User' belongs_to :maintainer, class_name: 'User'
belongs_to :alias_from, class_name: 'Project'
has_many :aliases, class_name: 'Project', foreign_key: 'alias_from_id'
has_many :issues, dependent: :destroy has_many :issues, dependent: :destroy
has_many :pull_requests, dependent: :destroy, foreign_key: 'to_project_id' has_many :pull_requests, dependent: :destroy, foreign_key: 'to_project_id'
has_many :labels, dependent: :destroy has_many :labels, dependent: :destroy
@ -216,13 +219,14 @@ class Project < ActiveRecord::Base
end end
end end
def fork(new_owner, new_name = name) def fork(new_owner, new_name = name, is_alias = false)
new_name = new_name.presence || name new_name = new_name.presence || name
dup.tap do |c| dup.tap do |c|
c.name = new_name c.name = new_name
c.parent_id = id c.parent_id = id
c.owner = new_owner c.alias_from_id = alias_from_id || id if is_alias
c.updated_at = nil; c.created_at = nil # :id = nil c.owner = new_owner
c.updated_at = nil; c.created_at = nil # :id = nil
# Hack to call protected method :) # Hack to call protected method :)
c.send :set_maintainer c.send :set_maintainer
c.save c.save

View File

@ -1,13 +0,0 @@
- is_group = owner.class == Group ? "(#{t 'activerecord.models.group'})" : ''
- full_name = "#{owner.uname}/#{name} #{is_group}"
- if owner.own_projects.exists? name: name
%p.text-center
=t 'layout.projects.already_exists'
=link_to full_name, project_path("#{owner.uname}/#{name}")#, class: 'center-block'
- else
= form_for @project, url: fork_project_path(@project), html: { class: :form, multipart: true, method: :post } do |f|
= hidden_field_tag :group, owner.id if owner.class == Group
= hidden_field_tag :fork_name, name, name: 'fork_name'
=f.submit t('layout.projects.fork_to', to: full_name), class: 'btn btn-primary center-block',
'data-loading-text' => t('layout.processing'), id: 'create_fork'

View File

@ -0,0 +1,22 @@
- is_group = owner.class == Group ? "(#{t 'activerecord.models.group'})" : ''
- full_name = "#{owner.uname}/#{name} #{is_group}"
- if owner.own_projects.exists? name: name
p.text-center
=> t('layout.projects.already_exists')
= link_to full_name, project_path("#{owner.uname}/#{name}")
- else
= form_for @project, url: fork_project_path(@project), html: { class: :form, multipart: true, method: :post } do |f|
= hidden_field_tag :group, owner.id if owner.class == Group
= hidden_field_tag :fork_name, name, name: 'fork_name'
= hidden_field_tag :alias, '{{create_alias}}'
.btn-group.btn-group-justified ng-init='create_alias = false'
.btn-group
= f.submit t('layout.projects.fork_to', to: full_name),
class: 'btn btn-primary center-block',
'data-loading-text' => t('layout.processing'), id: 'create_fork'
.btn-group
= f.submit t('layout.projects.create_alias_for', for: full_name),
class: 'btn btn-primary center-block',
ng_click: 'create_alias = true',
'data-loading-text' => t('layout.processing'), id: 'create_fork'

View File

@ -1,5 +0,0 @@
=render 'projects/git/base/choose_fork', owner: current_user, name: name
%hr
- Group.can_own_project(current_user).each do |group|
=render 'projects/git/base/choose_fork', owner: group, name: name
%hr

View File

@ -0,0 +1,5 @@
== render 'projects/git/base/choose_fork', owner: current_user, name: name
hr
- Group.can_own_project(current_user).each do |group|
== render 'projects/git/base/choose_fork', owner: group, name: name
hr

View File

@ -21,6 +21,7 @@ en:
edit: Settings edit: Settings
fork_and_edit: Fork fork_and_edit: Fork
fork_to: Fork to %{to} fork_to: Fork to %{to}
create_alias_for: Create alias for %{for}
fork_modal_header: Where do you want to fork this project? fork_modal_header: Where do you want to fork this project?
already_exists: Project already exists already_exists: Project already exists
unexisted_project: Project not exists unexisted_project: Project not exists

View File

@ -21,6 +21,7 @@ ru:
edit: Настройки edit: Настройки
fork_and_edit: Клонировать fork_and_edit: Клонировать
fork_to: Клонировать в %{to} fork_to: Клонировать в %{to}
create_alias_for: Создать ссылку для %{for}
fork_modal_header: Куда Вы хотите клонировать проект? fork_modal_header: Куда Вы хотите клонировать проект?
already_exists: Проект уже существует already_exists: Проект уже существует
unexisted_project: Проект не существует unexisted_project: Проект не существует

View File

@ -0,0 +1,6 @@
class AddAliasFromToProjects < ActiveRecord::Migration
def change
add_column :projects, :alias_from_id, :integer
add_index :projects, :alias_from_id
end
end

View File

@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20141015193923) do ActiveRecord::Schema.define(version: 20150112204757) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@ -173,6 +173,8 @@ ActiveRecord::Schema.define(version: 20141015193923) do
t.string "owner_uname", null: false t.string "owner_uname", null: false
t.boolean "architecture_dependent", default: false, null: false t.boolean "architecture_dependent", default: false, null: false
t.integer "autostart_status" t.integer "autostart_status"
t.integer "alias_from_id"
t.index ["alias_from_id"], :name => "index_projects_on_alias_from_id"
t.index ["name", "owner_id", "owner_type"], :name => "index_projects_on_name_and_owner_id_and_owner_type", :unique => true, :case_sensitive => false t.index ["name", "owner_id", "owner_type"], :name => "index_projects_on_name_and_owner_id_and_owner_type", :unique => true, :case_sensitive => false
end end