summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG2
-rw-r--r--Gemfile2
-rw-r--r--app/controllers/application_controller.rb6
-rw-r--r--app/controllers/import/gitlab_projects_controller.rb42
-rw-r--r--app/controllers/projects_controller.rb25
-rw-r--r--app/models/application_setting.rb2
-rw-r--r--app/models/todo.rb4
-rw-r--r--app/views/import/gitlab_projects/new.html.haml20
-rw-r--r--app/views/import/gitlab_projects/status.html.haml0
-rw-r--r--app/views/projects/new.html.haml22
-rw-r--r--config/routes.rb2
-rw-r--r--features/dashboard/new_project.feature2
-rw-r--r--features/steps/dashboard/new_project.rb5
-rw-r--r--lib/gitlab/current_settings.rb2
-rw-r--r--lib/gitlab/import_export/import_service.rb12
-rw-r--r--lib/gitlab/import_sources.rb3
-rw-r--r--spec/features/projects/import_export/import_file_spec.rb48
-rw-r--r--spec/features/projects/import_export/test_project_export.tar.gzbin0 -> 672360 bytes
18 files changed, 189 insertions, 10 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 364690286e1..e7f38c93be9 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -176,6 +176,8 @@ v 8.8.0
- API support for the 'since' and 'until' operators on commit requests (Paco Guzman)
- Fix Gravatar hint in user profile when Gravatar is disabled. !3988 (Artem Sidorenko)
- Expire repository exists? and has_visible_content? caches after a push if necessary
+ - Fix unintentional filtering bug in issues sorted by milestone due (Takuya Noguchi)
+ - GitLab project import and export functionality
- Fix unintentional filtering bug in Issue/MR sorted by milestone due (Takuya Noguchi)
- Fix adding a todo for private group members (Ahmad Sherif)
- Bump ace-rails-ap gem version from 2.0.1 to 4.0.2 which upgrades Ace Editor from 1.1.2 to 1.2.3
diff --git a/Gemfile b/Gemfile
index b2660144f2b..d5634bcaa62 100644
--- a/Gemfile
+++ b/Gemfile
@@ -218,7 +218,7 @@ gem 'jquery-turbolinks', '~> 2.1.0'
gem 'addressable', '~> 2.3.8'
gem 'bootstrap-sass', '~> 3.3.0'
-gem 'font-awesome-rails', '~> 4.2'
+gem 'font-awesome-rails', '~> 4.6.1'
gem 'gitlab_emoji', '~> 0.3.0'
gem 'gon', '~> 6.0.1'
gem 'jquery-atwho-rails', '~> 1.3.2'
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index cd6ae507cf1..726acbdb3ed 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -24,7 +24,7 @@ class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
helper_method :abilities, :can?, :current_application_settings
- helper_method :import_sources_enabled?, :github_import_enabled?, :github_import_configured?, :gitlab_import_enabled?, :gitlab_import_configured?, :bitbucket_import_enabled?, :bitbucket_import_configured?, :gitorious_import_enabled?, :google_code_import_enabled?, :fogbugz_import_enabled?, :git_import_enabled?
+ helper_method :import_sources_enabled?, :github_import_enabled?, :github_import_configured?, :gitlab_import_enabled?, :gitlab_import_configured?, :bitbucket_import_enabled?, :bitbucket_import_configured?, :gitorious_import_enabled?, :google_code_import_enabled?, :fogbugz_import_enabled?, :git_import_enabled?, :gitlab_project_import_enabled?
rescue_from Encoding::CompatibilityError do |exception|
log_exception(exception)
@@ -326,6 +326,10 @@ class ApplicationController < ActionController::Base
current_application_settings.import_sources.include?('git')
end
+ def gitlab_project_import_enabled?
+ current_application_settings.import_sources.include?('gitlab_project')
+ end
+
def two_factor_authentication_required?
current_application_settings.require_two_factor_authentication
end
diff --git a/app/controllers/import/gitlab_projects_controller.rb b/app/controllers/import/gitlab_projects_controller.rb
new file mode 100644
index 00000000000..a4ac55cd2a4
--- /dev/null
+++ b/app/controllers/import/gitlab_projects_controller.rb
@@ -0,0 +1,42 @@
+class Import::GitlabProjectsController < Import::BaseController
+ before_action :verify_gitlab_project_import_enabled
+ before_action :verify_project_and_namespace_access
+
+ rescue_from OAuth::Error, with: :gitlab_project_unauthorized
+
+ def new
+ @namespace_id = project_params[:namespace_id]
+ @path = project_params[:path]
+ end
+
+ def create
+ @project = Project.create_from_import_job(current_user_id: current_user.id,
+ tmp_file: File.expand_path(params[:file].path),
+ namespace_id: project_params[:namespace_id],
+ project_path: project_params[:path])
+
+ redirect_to dashboard_projects_path
+ end
+
+ private
+
+ def verify_project_and_namespace_access
+ unless namespace_access?
+ render_403
+ end
+ end
+
+ def namespace_access?
+ current_user.can?(:create_projects, Namespace.find(project_params[:namespace_id]))
+ end
+
+ def verify_gitlab_project_import_enabled
+ render_404 unless gitlab_project_import_enabled?
+ end
+
+ def project_params
+ params.permit(
+ :path, :namespace_id,
+ )
+ end
+end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index a6479c42d94..5c657290046 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -7,7 +7,7 @@ class ProjectsController < Projects::ApplicationController
before_action :assign_ref_vars, :tree, only: [:show], if: :repo_exists?
# Authorize
- before_action :authorize_admin_project!, only: [:edit, :update, :housekeeping]
+ before_action :authorize_admin_project!, only: [:edit, :update, :housekeeping, :download_export, :export]
before_action :event_filter, only: [:show, :activity]
layout :determine_layout
@@ -185,6 +185,23 @@ class ProjectsController < Projects::ApplicationController
)
end
+ def export
+ @project.add_export_job(current_user_id: current_user.id)
+
+ redirect_to(
+ edit_project_path(@project),
+ notice: "Project export successfully started"
+ )
+ end
+
+ def download_export
+ if export_project_path
+ send_file export_project_path, disposition: 'attachment'
+ else
+ render_404
+ end
+ end
+
def toggle_star
current_user.toggle_star(@project)
@project.reload
@@ -247,4 +264,10 @@ class ProjectsController < Projects::ApplicationController
def get_id
project.repository.root_ref
end
+
+ def export_project_path
+ # TODO: move this, probably to ImportExport and refactor
+ folder = File.join(Settings.shared['path'], 'tmp/project_exports', @project.path_with_namespace)
+ Dir.glob("#{folder}/*export.tar.gz").max_by {|f| File.ctime(f)}
+ end
end
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index a744f937918..b2fb54ba5e7 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -123,7 +123,7 @@ class ApplicationSetting < ActiveRecord::Base
default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'],
default_snippet_visibility: Settings.gitlab.default_projects_features['visibility_level'],
restricted_signup_domains: Settings.gitlab['restricted_signup_domains'],
- import_sources: ['github','bitbucket','gitlab','gitorious','google_code','fogbugz','git'],
+ import_sources: ['github','bitbucket','gitlab','gitorious','google_code','fogbugz','git', 'gitlab_project'],
shared_runners_enabled: Settings.gitlab_ci['shared_runners_enabled'],
max_artifacts_size: Settings.artifacts['max_size'],
require_two_factor_authentication: false,
diff --git a/app/models/todo.rb b/app/models/todo.rb
index 3a091373329..b0401463269 100644
--- a/app/models/todo.rb
+++ b/app/models/todo.rb
@@ -45,6 +45,10 @@ class Todo < ActiveRecord::Base
target_type == "Commit"
end
+ def for_project?
+ target_type == "Project"
+ end
+
# override to return commits, which are not active record
def target
if for_commit?
diff --git a/app/views/import/gitlab_projects/new.html.haml b/app/views/import/gitlab_projects/new.html.haml
new file mode 100644
index 00000000000..d93ae42c1bf
--- /dev/null
+++ b/app/views/import/gitlab_projects/new.html.haml
@@ -0,0 +1,20 @@
+- page_title "GitLab Import"
+- header_title "Projects", root_path
+%h3.page-title
+ %i.fa.fa-gitlab
+ Import projects from GitLab
+%hr
+
+= form_tag import_gitlab_project_path, class: 'form-horizontal', multipart: true do
+ %p
+ To get started add your exported project file below:
+ .form-group
+ = hidden_field_tag :namespace_id, @namespace_id
+ = hidden_field_tag :path, @path
+ = label_tag :file, class: 'control-label' do
+ %span GitLab project export
+ .col-sm-10
+ = file_field_tag :file, class: ''
+
+ .form-actions
+ = submit_tag 'Continue to the next step', class: 'btn btn-create'
diff --git a/app/views/import/gitlab_projects/status.html.haml b/app/views/import/gitlab_projects/status.html.haml
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/app/views/import/gitlab_projects/status.html.haml
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index f9ac16b32f3..79ef9284268 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -88,7 +88,12 @@
- if git_import_enabled?
= link_to "#", class: 'btn js-toggle-button import_git' do
%i.fa.fa-git
- %span Any repo by URL
+ %span Repo by URL
+
+ - if gitlab_project_import_enabled?
+ = link_to new_import_gitlab_project_path, class: 'btn import_gitlab_project project-submit' do
+ %i.fa.fa-gitlab
+ %span GitLab project
.js-toggle-content.hide
= render "shared/import_form", f: f
@@ -122,3 +127,18 @@
$('.modal-header .close').bind('click', function() {
$(".modal").hide();
});
+ $('.import_gitlab_project').bind('click', function() {
+ var _href = $("a.import_gitlab_project").attr("href");
+ $(".import_gitlab_project").attr("href", _href + '?namespace_id=' + $("#project_namespace_id").val() + '&path=' + $("#project_path").val());
+ });
+ $('.import_gitlab_project').attr('disabled',true)
+ $('.import_gitlab_project').attr('title', 'Project path required.');
+ $('#project_path').keyup(function(){
+ if($(this).val().length !=0) {
+ $('.import_gitlab_project').attr('disabled', false);
+ $('.import_gitlab_project').attr('title','');
+ } else {
+ $('.import_gitlab_project').attr('disabled',true);
+ $('.import_gitlab_project').attr('title', 'Project path required.');
+ }
+ })
diff --git a/config/routes.rb b/config/routes.rb
index e2492fbab46..bc1112de0f5 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -454,6 +454,8 @@ Rails.application.routes.draw do
post :housekeeping
post :toggle_star
post :markdown_preview
+ post :export
+ post :download_export
get :autocomplete_sources
get :activity
end
diff --git a/features/dashboard/new_project.feature b/features/dashboard/new_project.feature
index 76392068357..56b4a639c01 100644
--- a/features/dashboard/new_project.feature
+++ b/features/dashboard/new_project.feature
@@ -14,7 +14,7 @@ Background:
@javascript
Scenario: I should see instructions on how to import from Git URL
Given I see "New Project" page
- When I click on "Any repo by URL"
+ When I click on "Repo by URL"
Then I see instructions on how to import from Git URL
@javascript
diff --git a/features/steps/dashboard/new_project.rb b/features/steps/dashboard/new_project.rb
index a0aad66184d..ad20201c2c5 100644
--- a/features/steps/dashboard/new_project.rb
+++ b/features/steps/dashboard/new_project.rb
@@ -19,7 +19,8 @@ class Spinach::Features::NewProject < Spinach::FeatureSteps
expect(page).to have_link('GitLab.com')
expect(page).to have_link('Gitorious.org')
expect(page).to have_link('Google Code')
- expect(page).to have_link('Any repo by URL')
+ expect(page).to have_link('Repo by URL')
+ expect(page).to have_link('GitLab project')
end
step 'I click on "Import project from GitHub"' do
@@ -36,7 +37,7 @@ class Spinach::Features::NewProject < Spinach::FeatureSteps
end
end
- step 'I click on "Any repo by URL"' do
+ step 'I click on "Repo by URL"' do
first('.import_git').click
end
diff --git a/lib/gitlab/current_settings.rb b/lib/gitlab/current_settings.rb
index 5e7532f57ae..38c0f1aba47 100644
--- a/lib/gitlab/current_settings.rb
+++ b/lib/gitlab/current_settings.rb
@@ -36,7 +36,7 @@ module Gitlab
default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'],
default_snippet_visibility: Settings.gitlab.default_projects_features['visibility_level'],
restricted_signup_domains: Settings.gitlab['restricted_signup_domains'],
- import_sources: ['github','bitbucket','gitlab','gitorious','google_code','fogbugz','git'],
+ import_sources: ['github','bitbucket','gitlab','gitorious','google_code','fogbugz','git', 'gitlab_project'],
shared_runners_enabled: Settings.gitlab_ci['shared_runners_enabled'],
max_artifacts_size: Settings.artifacts['max_size'],
require_two_factor_authentication: false,
diff --git a/lib/gitlab/import_export/import_service.rb b/lib/gitlab/import_export/import_service.rb
index db71f72efec..95d4fb17ead 100644
--- a/lib/gitlab/import_export/import_service.rb
+++ b/lib/gitlab/import_export/import_service.rb
@@ -64,6 +64,18 @@ module Gitlab
def wiki_repo_path
File.join(@shared.export_path, 'project.wiki.bundle')
end
+
+ def attributes_for_todo
+ { user_id: @current_user.id,
+ project_id: project_tree.project.id,
+ target_type: 'Project',
+ target: project_tree.project,
+ action: Todo::IMPORTED,
+ author_id: @current_user.id,
+ state: :pending,
+ target_id: project_tree.project.id
+ }
+ end
end
end
end
diff --git a/lib/gitlab/import_sources.rb b/lib/gitlab/import_sources.rb
index ccfdfbe73e8..4cae819d356 100644
--- a/lib/gitlab/import_sources.rb
+++ b/lib/gitlab/import_sources.rb
@@ -20,7 +20,8 @@ module Gitlab
'Gitorious.org' => 'gitorious',
'Google Code' => 'google_code',
'FogBugz' => 'fogbugz',
- 'Any repo by URL' => 'git',
+ 'Repo by URL' => 'git',
+ 'GitLab project' => 'gitlab_project'
}
end
diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb
new file mode 100644
index 00000000000..03298149b60
--- /dev/null
+++ b/spec/features/projects/import_export/import_file_spec.rb
@@ -0,0 +1,48 @@
+require 'spec_helper'
+
+feature 'project import', feature: true, js: true do
+ include Select2Helper
+
+ let(:user) { create(:admin) }
+ let!(:namespace) { create(:namespace, name: "asd", owner: user) }
+ let(:file) { File.join(Rails.root, 'spec', 'features', 'projects', 'import_export', 'test_project_export.tar.gz') }
+ let(:export_path) { "#{Dir::tmpdir}/import_file_spec" }
+ let(:project) { Project.last }
+
+ background do
+ allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path)
+ login_as(user)
+ end
+
+ after(:each) do
+ FileUtils.rm_rf(export_path, secure: true)
+ end
+
+ scenario 'user imports an exported project successfully' do
+ expect(Project.all.count).to be_zero
+
+ visit new_project_path
+
+ select2('2', from: '#project_namespace_id')
+ fill_in :project_path, with:'test-project-path', visible: true
+ click_link 'GitLab project'
+
+ expect(page).to have_content('GitLab project export')
+ expect(URI.parse(current_url).query).to eq('namespace_id=2&path=test-project-path')
+
+ attach_file('file', file)
+
+ click_on 'Continue to the next step' # import starts
+
+ expect(project).not_to be_nil
+ expect(project.issues).not_to be_empty
+ expect(project.merge_requests).not_to be_empty
+ expect(project.repo_exists?).to be true
+ expect(wiki_exists?).to be true
+ end
+
+ def wiki_exists?
+ wiki = ProjectWiki.new(project)
+ File.exists?(wiki.repository.path_to_repo) && !wiki.repository.empty?
+ end
+end
diff --git a/spec/features/projects/import_export/test_project_export.tar.gz b/spec/features/projects/import_export/test_project_export.tar.gz
new file mode 100644
index 00000000000..b85055070d8
--- /dev/null
+++ b/spec/features/projects/import_export/test_project_export.tar.gz
Binary files differ