diff options
-rw-r--r-- | Gemfile | 2 | ||||
-rw-r--r-- | Gemfile.lock | 4 | ||||
-rw-r--r-- | app/controllers/application_controller.rb | 6 | ||||
-rw-r--r-- | app/controllers/import/gitlab_projects_controller.rb | 42 | ||||
-rw-r--r-- | app/controllers/projects_controller.rb | 25 | ||||
-rw-r--r-- | app/models/application_setting.rb | 2 | ||||
-rw-r--r-- | app/views/import/gitlab_projects/new.html.haml | 20 | ||||
-rw-r--r-- | app/views/import/gitlab_projects/status.html.haml | 0 | ||||
-rw-r--r-- | app/views/projects/edit.html.haml | 16 | ||||
-rw-r--r-- | app/views/projects/new.html.haml | 22 | ||||
-rw-r--r-- | config/routes.rb | 2 | ||||
-rw-r--r-- | features/dashboard/new_project.feature | 2 | ||||
-rw-r--r-- | features/steps/dashboard/new_project.rb | 5 | ||||
-rw-r--r-- | lib/gitlab/current_settings.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/import_sources.rb | 3 | ||||
-rw-r--r-- | spec/features/projects/import_export/import_file_spec.rb | 48 | ||||
-rw-r--r-- | spec/features/projects/import_export/test_project_export.tar.gz | bin | 0 -> 339482 bytes |
17 files changed, 189 insertions, 12 deletions
@@ -213,7 +213,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/Gemfile.lock b/Gemfile.lock index fe083c2b566..32104a591e1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -322,7 +322,7 @@ GEM fog-xml (0.1.2) fog-core nokogiri (~> 1.5, >= 1.5.11) - font-awesome-rails (4.5.0.1) + font-awesome-rails (4.6.1.0) railties (>= 3.2, < 5.1) foreman (0.78.0) thor (~> 0.19.1) @@ -934,7 +934,7 @@ DEPENDENCIES flay flog fog (~> 1.36.0) - font-awesome-rails (~> 4.2) + font-awesome-rails (~> 4.6.1) foreman fuubar (~> 2.0.0) gemnasium-gitlab-service (~> 0.2) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 17b3f49aed1..cbdd241818f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -23,7 +23,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) @@ -325,6 +325,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 3768efe142a..980cae65f84 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 @@ -190,6 +190,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 @@ -251,4 +268,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 72ec91d2909..1ca8a515577 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -151,7 +151,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/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/edit.html.haml b/app/views/projects/edit.html.haml index 76a4f41193c..251fba474af 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -132,6 +132,22 @@ = link_to 'Housekeeping', housekeeping_namespace_project_path(@project.namespace, @project), method: :post, class: "btn btn-default" + .panel.panel-default + .panel-heading Export project + .errors-holder + .panel-body + %p + Downloads a compressed version of the project that can be imported. + %br + + .form-actions + = link_to 'Generate new export', export_namespace_project_path(@project.namespace, @project), + method: :post, class: "btn btn-default" + + = link_to 'Download export', download_export_namespace_project_path(@project.namespace, @project), + method: :post, class: "btn btn-default" + + - if can? current_user, :archive_project, @project - if @project.archived? .panel.panel-success diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index a4c6094c69a..f9d9216f626 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 ad44c8f05b2..a528e0b4940 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -443,6 +443,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 f44d1b3a44e..688e780c13d 100644 --- a/lib/gitlab/current_settings.rb +++ b/lib/gitlab/current_settings.rb @@ -29,7 +29,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_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 Binary files differnew file mode 100644 index 00000000000..4f2ec49e9b5 --- /dev/null +++ b/spec/features/projects/import_export/test_project_export.tar.gz |