summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG4
-rw-r--r--app/controllers/projects/imports_controller.rb49
-rw-r--r--app/controllers/projects/repositories_controller.rb9
-rw-r--r--app/controllers/projects_controller.rb46
-rw-r--r--app/models/project.rb23
-rw-r--r--app/services/projects/create_service.rb50
-rw-r--r--app/views/projects/create.js.haml13
-rw-r--r--app/views/projects/import.html.haml31
-rw-r--r--app/views/projects/imports/new.html.haml21
-rw-r--r--app/views/projects/imports/show.html.haml9
-rw-r--r--app/views/projects/new.html.haml2
-rw-r--r--app/views/projects/no_repo.html.haml22
-rw-r--r--config/routes.rb5
-rw-r--r--features/steps/shared/project.rb2
-rw-r--r--spec/factories/projects.rb18
15 files changed, 196 insertions, 108 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 85178d0dfd7..fd902050913 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -7,8 +7,8 @@ v 7.6.0
- Add optional Sidekiq MemoryKiller middleware (enabled via SIDEKIQ_MAX_RSS env variable)
-
-
- -
- -
+ - Create project with repository in synchrony
+ - Added ability to create empty repo or import existing one if project does not have repository
-
-
-
diff --git a/app/controllers/projects/imports_controller.rb b/app/controllers/projects/imports_controller.rb
new file mode 100644
index 00000000000..b8350642804
--- /dev/null
+++ b/app/controllers/projects/imports_controller.rb
@@ -0,0 +1,49 @@
+class Projects::ImportsController < Projects::ApplicationController
+ # Authorize
+ before_filter :authorize_admin_project!
+ before_filter :require_no_repo
+ before_filter :redirect_if_progress, except: :show
+
+ def new
+ end
+
+ def create
+ @project.import_url = params[:project][:import_url]
+
+ if @project.save
+ @project.reload
+
+ if @project.import_failed?
+ @project.import_retry
+ else
+ @project.import_start
+ end
+ end
+
+ redirect_to project_import_path(@project)
+ end
+
+ def show
+ unless @project.import_in_progress?
+ if @project.import_finished?
+ redirect_to(@project) and return
+ else
+ redirect_to new_project_import_path(@project) and return
+ end
+ end
+ end
+
+ private
+
+ def require_no_repo
+ if @project.repository_exists?
+ redirect_to(@project) and return
+ end
+ end
+
+ def redirect_if_progress
+ if @project.import_in_progress?
+ redirect_to project_import_path(@project) and return
+ end
+ end
+end
diff --git a/app/controllers/projects/repositories_controller.rb b/app/controllers/projects/repositories_controller.rb
index bcd14a1c847..3a90c1c806d 100644
--- a/app/controllers/projects/repositories_controller.rb
+++ b/app/controllers/projects/repositories_controller.rb
@@ -1,7 +1,14 @@
class Projects::RepositoriesController < Projects::ApplicationController
# Authorize
before_filter :authorize_download_code!
- before_filter :require_non_empty_project
+ before_filter :require_non_empty_project, except: :create
+ before_filter :authorize_admin_project!, only: :create
+
+ def create
+ @project.create_repository
+
+ redirect_to @project
+ end
def archive
unless can?(current_user, :download_code, @project)
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index b3181fa310e..fbd9e5f2a5b 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -4,7 +4,7 @@ class ProjectsController < ApplicationController
before_filter :repository, except: [:new, :create]
# Authorize
- before_filter :authorize_admin_project!, only: [:edit, :update, :destroy, :transfer, :archive, :unarchive, :retry_import]
+ before_filter :authorize_admin_project!, only: [:edit, :update, :destroy, :transfer, :archive, :unarchive]
layout 'navless', only: [:new, :create, :fork]
before_filter :set_title, only: [:new, :create]
@@ -19,10 +19,11 @@ class ProjectsController < ApplicationController
def create
@project = ::Projects::CreateService.new(current_user, project_params).execute
- flash[:notice] = 'Project was successfully created.' if @project.saved?
- respond_to do |format|
- format.js
+ if @project.saved?
+ redirect_to project_path(@project), notice: 'Project was successfully created.'
+ else
+ render 'new'
end
end
@@ -47,7 +48,7 @@ class ProjectsController < ApplicationController
def show
if @project.import_in_progress?
- redirect_to import_project_path(@project)
+ redirect_to project_import_path(@project)
return
end
@@ -60,37 +61,20 @@ class ProjectsController < ApplicationController
respond_to do |format|
format.html do
- if @project.empty_repo?
- render "projects/empty", layout: user_layout
+ if @project.repository_exists?
+ if @project.empty_repo?
+ render "projects/empty", layout: user_layout
+ else
+ @last_push = current_user.recent_push(@project.id) if current_user
+ render :show, layout: user_layout
+ end
else
- @last_push = current_user.recent_push(@project.id) if current_user
- render :show, layout: user_layout
+ render "projects/no_repo", layout: user_layout
end
end
- format.json { pager_json("events/_events", @events.count) }
- end
- end
- def import
- if @project.import_finished?
- redirect_to @project
- return
- end
- end
-
- def retry_import
- unless @project.import_failed?
- redirect_to import_project_path(@project)
- end
-
- @project.import_url = project_params[:import_url]
-
- if @project.save
- @project.reload
- @project.import_retry
+ format.json { pager_json("events/_events", @events.count) }
end
-
- redirect_to import_project_path(@project)
end
def destroy
diff --git a/app/models/project.rb b/app/models/project.rb
index d2576bb85d0..daf4bdd0aad 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -136,7 +136,7 @@ class Project < ActiveRecord::Base
state_machine :import_status, initial: :none do
event :import_start do
- transition :none => :started
+ transition [:none, :finished] => :started
end
event :import_finish do
@@ -586,4 +586,25 @@ class Project < ActiveRecord::Base
def origin_merge_requests
merge_requests.where(source_project_id: self.id)
end
+
+ def create_repository
+ if gitlab_shell.add_repository(path_with_namespace)
+ true
+ else
+ errors.add(:base, "Failed to create repository")
+ false
+ end
+ end
+
+ def repository_exists?
+ !!repository.exists?
+ end
+
+ def create_wiki
+ ProjectWiki.new(self, self.owner).wiki
+ true
+ rescue ProjectWiki::CouldNotCreateWikiError => ex
+ errors.add(:base, "Failed create wiki")
+ false
+ end
end
diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb
index 12386792aab..3672b623806 100644
--- a/app/services/projects/create_service.rb
+++ b/app/services/projects/create_service.rb
@@ -37,35 +37,22 @@ module Projects
@project.creator = current_user
- if @project.save
- log_info("#{@project.owner.name} created a new project \"#{@project.name_with_namespace}\"")
- system_hook_service.execute_hooks_for(@project, :create)
+ Project.transaction do
+ @project.save
- unless @project.group
- @project.team << [current_user, :master]
- end
-
- @project.update_column(:last_activity_at, @project.created_at)
-
- if @project.import?
- @project.import_start
- else
- GitlabShellWorker.perform_async(
- :add_repository,
- @project.path_with_namespace
- )
+ unless @project.import?
+ unless @project.create_repository
+ raise 'Failed to create repository'
+ end
end
+ end
+ if @project.persisted?
if @project.wiki_enabled?
- begin
- # force the creation of a wiki,
- ProjectWiki.new(@project, @project.owner).wiki
- rescue ProjectWiki::CouldNotCreateWikiError => ex
- # Prevent project observer crash
- # if failed to create wiki
- nil
- end
+ @project.create_wiki
end
+
+ after_create_actions
end
@project
@@ -84,5 +71,20 @@ module Projects
namespace = Namespace.find_by(id: namespace_id)
current_user.can?(:create_projects, namespace)
end
+
+ def after_create_actions
+ log_info("#{@project.owner.name} created a new project \"#{@project.name_with_namespace}\"")
+ system_hook_service.execute_hooks_for(@project, :create)
+
+ unless @project.group
+ @project.team << [current_user, :master]
+ end
+
+ @project.update_column(:last_activity_at, @project.created_at)
+
+ if @project.import?
+ @project.import_start
+ end
+ end
end
end
diff --git a/app/views/projects/create.js.haml b/app/views/projects/create.js.haml
deleted file mode 100644
index 89710d3a09a..00000000000
--- a/app/views/projects/create.js.haml
+++ /dev/null
@@ -1,13 +0,0 @@
-- if @project.saved?
- - if @project.import?
- :plain
- location.href = "#{import_project_path(@project)}";
- - else
- :plain
- location.href = "#{project_path(@project)}";
-- else
- :plain
- $(".project-edit-errors").html("#{escape_javascript(render('errors'))}");
- $('.project-submit').enable();
- $('.save-project-loader').hide();
- $('.project-edit-container').show();
diff --git a/app/views/projects/import.html.haml b/app/views/projects/import.html.haml
deleted file mode 100644
index 4513c89e784..00000000000
--- a/app/views/projects/import.html.haml
+++ /dev/null
@@ -1,31 +0,0 @@
-- if @project.import_in_progress?
- .save-project-loader
- .center
- %h2
- %i.fa.fa-spinner.fa-spin
- Import in progress.
- %p.monospace git clone --bare #{hidden_pass_url(@project.import_url)}
- %p Please wait while we import the repository for you. Refresh at will.
- :javascript
- new ProjectImport();
-
-- elsif @project.import_failed?
- .save-project-loader
- .center
- %h2
- Import failed. Retry?
- %hr
- - if can?(current_user, :admin_project, @project)
- = form_for @project, url: retry_import_project_path(@project), method: :put, html: { class: 'form-horizontal' } do |f|
- .form-group.import-url-data
- = f.label :import_url, class: 'control-label' do
- %span Import existing git repo
- .col-sm-10
- = f.text_field :import_url, class: 'form-control', placeholder: 'https://github.com/randx/six.git'
- .bs-callout.bs-callout-info
- This URL must be publicly accessible or you can add a username and password like this: https://username:password@gitlab.com/company/project.git.
- %br
- The import will time out after 4 minutes. For big repositories, use a clone/push combination.
- For SVN repositories, check #{link_to "this migrating from SVN doc.", "http://doc.gitlab.com/ce/workflow/migrating_from_svn.html"}
- .form-actions
- = f.submit 'Retry import', class: "btn btn-create", tabindex: 4
diff --git a/app/views/projects/imports/new.html.haml b/app/views/projects/imports/new.html.haml
new file mode 100644
index 00000000000..6c3083e49f5
--- /dev/null
+++ b/app/views/projects/imports/new.html.haml
@@ -0,0 +1,21 @@
+%h3.page-title
+ - if @project.import_failed?
+ Import failed. Retry?
+ - else
+ Import repository
+
+%hr
+
+= form_for @project, url: project_import_path(@project), method: :post, html: { class: 'form-horizontal' } do |f|
+ .form-group.import-url-data
+ = f.label :import_url, class: 'control-label' do
+ %span Import existing git repo
+ .col-sm-10
+ = f.text_field :import_url, class: 'form-control', placeholder: 'https://github.com/randx/six.git'
+ .bs-callout.bs-callout-info
+ This URL must be publicly accessible or you can add a username and password like this: https://username:password@gitlab.com/company/project.git.
+ %br
+ The import will time out after 4 minutes. For big repositories, use a clone/push combination.
+ For SVN repositories, check #{link_to "this migrating from SVN doc.", "http://doc.gitlab.com/ce/workflow/migrating_from_svn.html"}
+ .form-actions
+ = f.submit 'Start import', class: "btn btn-create", tabindex: 4
diff --git a/app/views/projects/imports/show.html.haml b/app/views/projects/imports/show.html.haml
new file mode 100644
index 00000000000..2d1fdafed24
--- /dev/null
+++ b/app/views/projects/imports/show.html.haml
@@ -0,0 +1,9 @@
+.save-project-loader
+ .center
+ %h2
+ %i.fa.fa-spinner.fa-spin
+ Import in progress.
+ %p.monospace git clone --bare #{hidden_pass_url(@project.import_url)}
+ %p Please wait while we import the repository for you. Refresh at will.
+ :javascript
+ new ProjectImport();
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index f5cd0f21e01..e77ef84f51c 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -3,7 +3,7 @@
= render 'projects/errors'
.project-edit-content
- = form_for @project, remote: true, html: { class: 'new_project form-horizontal' } do |f|
+ = form_for @project, html: { class: 'new_project form-horizontal' } do |f|
.form-group.project-name-holder
= f.label :name, class: 'control-label' do
%strong Project name
diff --git a/app/views/projects/no_repo.html.haml b/app/views/projects/no_repo.html.haml
new file mode 100644
index 00000000000..dd576243510
--- /dev/null
+++ b/app/views/projects/no_repo.html.haml
@@ -0,0 +1,22 @@
+%h2
+ %i.fa.fa-warning
+ No repository
+
+%p.slead
+ The repository for this project does not exist.
+ %br
+ This means you can not push code until you create an empty repository or import existing one.
+%hr
+
+.no-repo-actions
+ = link_to project_repository_path(@project), method: :post, class: 'btn btn-primary' do
+ Create empty bare repository
+
+ %strong.prepend-left-10.append-right-10 or
+
+ = link_to new_project_import_path(@project), class: 'btn' do
+ Import repository
+
+- if can? current_user, :remove_project, @project
+ .prepend-top-20
+ = link_to 'Remove project', @project, data: { confirm: remove_project_message(@project)}, method: :delete, class: "btn btn-remove pull-right"
diff --git a/config/routes.rb b/config/routes.rb
index 470fe7f4dc1..723104daf13 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -186,8 +186,6 @@ Gitlab::Application.routes.draw do
post :upload_image
post :toggle_star
get :autocomplete_sources
- get :import
- put :retry_import
end
scope module: :projects do
@@ -232,8 +230,9 @@ Gitlab::Application.routes.draw do
end
resource :fork, only: [:new, :create]
+ resource :import, only: [:new, :create, :show]
- resource :repository, only: [:show] do
+ resource :repository, only: [:show, :create] do
member do
get "archive", constraints: { format: Gitlab::Regex.archive_formats_regex }
end
diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb
index bd7e6e1d8b3..0bd5653538c 100644
--- a/features/steps/shared/project.rb
+++ b/features/steps/shared/project.rb
@@ -131,7 +131,7 @@ module SharedProject
end
step 'public empty project "Empty Public Project"' do
- create :empty_project, :public, name: "Empty Public Project"
+ create :project_empty_repo, :public, name: "Empty Public Project"
end
step 'project "Community" has comments' do
diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb
index 23314b3b1a4..60eb73e4a95 100644
--- a/spec/factories/projects.rb
+++ b/spec/factories/projects.rb
@@ -27,6 +27,10 @@
#
FactoryGirl.define do
+ # Project without repository
+ #
+ # Project does not have bare repository.
+ # Use this factory if you dont need repository in tests
factory :empty_project, class: 'Project' do
sequence(:name) { |n| "project#{n}" }
path { name.downcase.gsub(/\s/, '_') }
@@ -47,6 +51,20 @@ FactoryGirl.define do
end
end
+ # Project with empty repository
+ #
+ # This is a case when you just created a project
+ # but not pushed any code there yet
+ factory :project_empty_repo, parent: :empty_project do
+ after :create do |project|
+ project.create_repository
+ end
+ end
+
+ # Project with test repository
+ #
+ # Test repository source can be found at
+ # https://gitlab.com/gitlab-org/gitlab-test
factory :project, parent: :empty_project do
path { 'gitlabhq' }