Commit 0c65112d authored by James Lopez's avatar James Lopez

modify github import JS and controller so we can now specify a namespace and/or name for a project.

- Fixed and added specs.
- Added different namespace options depending on user privilages
- Updated docs.
parent 95b9421a
...@@ -147,6 +147,7 @@ v 8.12.0 (unreleased) ...@@ -147,6 +147,7 @@ v 8.12.0 (unreleased)
- Refactor the triggers page and documentation !6217 - Refactor the triggers page and documentation !6217
- Show values of CI trigger variables only when clicked (Katarzyna Kobierska Ula Budziszewska) - Show values of CI trigger variables only when clicked (Katarzyna Kobierska Ula Budziszewska)
- Use default clone protocol on "check out, review, and merge locally" help page URL - Use default clone protocol on "check out, review, and merge locally" help page URL
- Let the user choose a namespace and name on GitHub imports
- API for Ci Lint !5953 (Katarzyna Kobierska Urszula Budziszewska) - API for Ci Lint !5953 (Katarzyna Kobierska Urszula Budziszewska)
- Allow bulk update merge requests from merge requests index page - Allow bulk update merge requests from merge requests index page
- Ensure validation messages are shown within the milestone form - Ensure validation messages are shown within the milestone form
......
...@@ -14,20 +14,20 @@ ...@@ -14,20 +14,20 @@
$btn = $(e.currentTarget); $btn = $(e.currentTarget);
$tr = $btn.closest('tr'); $tr = $btn.closest('tr');
$target_field = $tr.find('.import-target'); $target_field = $tr.find('.import-target');
$namespace_input = $target_field.find('input'); $namespace_input = $target_field.find('.js-select-namespace option:selected');
id = $tr.attr('id').replace('repo_', ''); id = $tr.attr('id').replace('repo_', '');
target_namespace = null; target_namespace = null;
new_name = null;
if ($namespace_input.length > 0) { if ($namespace_input.length > 0) {
target_namespace = $namespace_input.prop('value'); target_namespace = $namespace_input[0].innerHTML;
$target_field.empty().append(target_namespace + "/" + ($target_field.data('project_name'))); new_name = $target_field.find('#path').prop('value');
$target_field.empty().append(target_namespace + "/" + new_name);
} }
$btn.disable().addClass('is-loading'); $btn.disable().addClass('is-loading');
return $.post(_this.import_url, { return $.post(_this.import_url, {
repo_id: id, repo_id: id,
target_namespace: target_namespace target_namespace: target_namespace,
new_name: new_name
}, { }, {
dataType: 'script' dataType: 'script'
}); });
......
...@@ -770,3 +770,9 @@ pre.light-well { ...@@ -770,3 +770,9 @@ pre.light-well {
} }
} }
} }
.input-group {
.project-path {
padding: 0;
}
}
\ No newline at end of file
...@@ -40,11 +40,12 @@ class Import::GithubController < Import::BaseController ...@@ -40,11 +40,12 @@ class Import::GithubController < Import::BaseController
def create def create
@repo_id = params[:repo_id].to_i @repo_id = params[:repo_id].to_i
repo = client.repo(@repo_id) repo = client.repo(@repo_id)
@project_name = repo.name @project_name = params[:new_name].presence || repo.name
@target_namespace = find_or_create_namespace(repo.owner.login, client.user.login) namespace_path = params[:target_namespace].presence || current_user.namespace_path
@target_namespace = find_or_create_namespace(namespace_path, current_user.namespace_path)
if current_user.can?(:create_projects, @target_namespace) if current_user.can?(:create_projects, @target_namespace)
@project = Gitlab::GithubImport::ProjectCreator.new(repo, @target_namespace, current_user, access_params).execute @project = Gitlab::GithubImport::ProjectCreator.new(repo, @project_name, @target_namespace, current_user, access_params).execute
else else
render 'unauthorized' render 'unauthorized'
end end
......
module NamespacesHelper module NamespacesHelper
def namespaces_options(selected = :current_user, display_path: false) def namespaces_options(selected = :current_user, extra_groups = [], display_path: false)
groups = current_user.owned_groups + current_user.masters_groups groups = current_user.owned_groups + current_user.masters_groups
groups += process_extra_groups(extra_groups) if extra_groups.any?
users = [current_user.namespace] users = [current_user.namespace]
data_attr_group = { 'data-options-parent' => 'groups' } data_attr_group = { 'data-options-parent' => 'groups' }
...@@ -25,6 +28,15 @@ module NamespacesHelper ...@@ -25,6 +28,15 @@ module NamespacesHelper
grouped_options_for_select(options, selected) grouped_options_for_select(options, selected)
end end
def process_extra_groups(extra_groups)
# Remove duplicate groups - we either keep the ones that exist for the user
# (already in groups) or ignore those that do not belong to the user.
duplicated_groups = extra_groups.map { |name| Namespace.where(name: name).map(&:name) }
extra_groups = extra_groups - duplicated_groups.flatten
extra_groups.map { |name| Group.new(name: name) }
end
def namespace_icon(namespace, size = 40) def namespace_icon(namespace, size = 40)
if namespace.kind_of?(Group) if namespace.kind_of?(Group)
group_icon(namespace) group_icon(namespace)
......
...@@ -45,7 +45,18 @@ ...@@ -45,7 +45,18 @@
%td %td
= github_project_link(repo.full_name) = github_project_link(repo.full_name)
%td.import-target %td.import-target
= import_project_target(repo.owner.login, repo.name) %fieldset.row
.input-group
.col-xs-11.col-sm-5.project-path
- if current_user.can_select_namespace? && !current_user.can_create_group?
= select_tag :namespace_id, namespaces_options(params[:namespace_id] || :current_user, display_path: true), {class: 'project-path select2 js-select-namespace', tabindex: 1}
- elsif current_user.can_create_group?
= select_tag :namespace_id, namespaces_options(params[:namespace_id] || :current_user, [repo.owner.login]), {class: 'project-path select2 js-select-namespace', tabindex: 1}
- else
= text_field_tag :path, current_user.namespace_path, class: "form-control", tabindex: 2, autofocus: true, disabled: true
.col-xs-12.col-sm-6.project-path
= text_field_tag :path, repo.name, class: "form-control", tabindex: 2, autofocus: true, required: true
%td.import-actions.job-status %td.import-actions.job-status
= button_tag class: "btn btn-import js-add-to-import" do = button_tag class: "btn btn-import js-add-to-import" do
Import Import
......
...@@ -106,6 +106,11 @@ If you want, you can import all your GitHub projects in one go by hitting ...@@ -106,6 +106,11 @@ If you want, you can import all your GitHub projects in one go by hitting
![GitHub importer page](img/import_projects_from_github_importer.png) ![GitHub importer page](img/import_projects_from_github_importer.png)
---
You can also choose a different name for the project and a different namespace,
if you have the privileges to do so.
[gh-import]: ../../integration/github.md "GitHub integration" [gh-import]: ../../integration/github.md "GitHub integration"
[new-project]: ../../gitlab-basics/create-project.md "How to create a new project in GitLab" [new-project]: ../../gitlab-basics/create-project.md "How to create a new project in GitLab"
[gh-integration]: #authorize-access-to-your-repositories-using-the-github-integration [gh-integration]: #authorize-access-to-your-repositories-using-the-github-integration
......
...@@ -3,8 +3,9 @@ module Gitlab ...@@ -3,8 +3,9 @@ module Gitlab
class ProjectCreator class ProjectCreator
attr_reader :repo, :namespace, :current_user, :session_data attr_reader :repo, :namespace, :current_user, :session_data
def initialize(repo, namespace, current_user, session_data) def initialize(repo, name, namespace, current_user, session_data)
@repo = repo @repo = repo
@name = name
@namespace = namespace @namespace = namespace
@current_user = current_user @current_user = current_user
@session_data = session_data @session_data = session_data
...@@ -13,8 +14,8 @@ module Gitlab ...@@ -13,8 +14,8 @@ module Gitlab
def execute def execute
project = ::Projects::CreateService.new( project = ::Projects::CreateService.new(
current_user, current_user,
name: repo.name, name: @name,
path: repo.name, path: @name,
description: repo.description, description: repo.description,
namespace_id: namespace.id, namespace_id: namespace.id,
visibility_level: repo.private ? Gitlab::VisibilityLevel::PRIVATE : ApplicationSetting.current.default_project_visibility, visibility_level: repo.private ? Gitlab::VisibilityLevel::PRIVATE : ApplicationSetting.current.default_project_visibility,
......
...@@ -124,8 +124,8 @@ describe Import::GithubController do ...@@ -124,8 +124,8 @@ describe Import::GithubController do
context "when the GitHub user and GitLab user's usernames match" do context "when the GitHub user and GitLab user's usernames match" do
it "takes the current user's namespace" do it "takes the current user's namespace" do
expect(Gitlab::GithubImport::ProjectCreator). expect(Gitlab::GithubImport::ProjectCreator).
to receive(:new).with(github_repo, user.namespace, user, access_params). to receive(:new).with(github_repo, github_repo.name, user.namespace, user, access_params).
and_return(double(execute: true)) and_return(double(execute: true))
post :create, format: :js post :create, format: :js
end end
...@@ -136,8 +136,8 @@ describe Import::GithubController do ...@@ -136,8 +136,8 @@ describe Import::GithubController do
it "takes the current user's namespace" do it "takes the current user's namespace" do
expect(Gitlab::GithubImport::ProjectCreator). expect(Gitlab::GithubImport::ProjectCreator).
to receive(:new).with(github_repo, user.namespace, user, access_params). to receive(:new).with(github_repo, github_repo.name, user.namespace, user, access_params).
and_return(double(execute: true)) and_return(double(execute: true))
post :create, format: :js post :create, format: :js
end end
...@@ -158,8 +158,8 @@ describe Import::GithubController do ...@@ -158,8 +158,8 @@ describe Import::GithubController do
context "when the namespace is owned by the GitLab user" do context "when the namespace is owned by the GitLab user" do
it "takes the existing namespace" do it "takes the existing namespace" do
expect(Gitlab::GithubImport::ProjectCreator). expect(Gitlab::GithubImport::ProjectCreator).
to receive(:new).with(github_repo, existing_namespace, user, access_params). to receive(:new).with(github_repo, github_repo.name, existing_namespace, user, access_params).
and_return(double(execute: true)) and_return(double(execute: true))
post :create, format: :js post :create, format: :js
end end
...@@ -171,9 +171,10 @@ describe Import::GithubController do ...@@ -171,9 +171,10 @@ describe Import::GithubController do
existing_namespace.save existing_namespace.save
end end
it "doesn't create a project" do it "creates a project using user's namespace" do
expect(Gitlab::GithubImport::ProjectCreator). expect(Gitlab::GithubImport::ProjectCreator).
not_to receive(:new) to receive(:new).with(github_repo, github_repo.name, user.namespace, user, access_params).
and_return(double(execute: true))
post :create, format: :js post :create, format: :js
end end
...@@ -186,15 +187,15 @@ describe Import::GithubController do ...@@ -186,15 +187,15 @@ describe Import::GithubController do
expect(Gitlab::GithubImport::ProjectCreator). expect(Gitlab::GithubImport::ProjectCreator).
to receive(:new).and_return(double(execute: true)) to receive(:new).and_return(double(execute: true))
expect { post :create, format: :js }.to change(Namespace, :count).by(1) expect { post :create, target_namespace: github_repo.name, format: :js }.to change(Namespace, :count).by(1)
end end
it "takes the new namespace" do it "takes the new namespace" do
expect(Gitlab::GithubImport::ProjectCreator). expect(Gitlab::GithubImport::ProjectCreator).
to receive(:new).with(github_repo, an_instance_of(Group), user, access_params). to receive(:new).with(github_repo, github_repo.name, an_instance_of(Group), user, access_params).
and_return(double(execute: true)) and_return(double(execute: true))
post :create, format: :js post :create, target_namespace: github_repo.name, format: :js
end end
end end
...@@ -212,13 +213,34 @@ describe Import::GithubController do ...@@ -212,13 +213,34 @@ describe Import::GithubController do
it "takes the current user's namespace" do it "takes the current user's namespace" do
expect(Gitlab::GithubImport::ProjectCreator). expect(Gitlab::GithubImport::ProjectCreator).
to receive(:new).with(github_repo, user.namespace, user, access_params). to receive(:new).with(github_repo, github_repo.name, user.namespace, user, access_params).
and_return(double(execute: true)) and_return(double(execute: true))
post :create, format: :js post :create, format: :js
end end
end end
end end
context 'user has chosen a namespace and name for the project' do
let(:test_namespace) { create(:namespace, name: 'test_namespace', owner: user) }
let(:test_name) { 'test_name' }
it 'takes the selected namespace and name' do
expect(Gitlab::GithubImport::ProjectCreator).
to receive(:new).with(github_repo, test_name, test_namespace, user, access_params).
and_return(double(execute: true))
post :create, { target_namespace: test_namespace.name, new_name: test_name, format: :js }
end
it 'takes the selected name and default namespace' do
expect(Gitlab::GithubImport::ProjectCreator).
to receive(:new).with(github_repo, test_name, user.namespace, user, access_params).
and_return(double(execute: true))
post :create, { new_name: test_name, format: :js }
end
end
end end
end end
end end
...@@ -13,7 +13,7 @@ describe Gitlab::GithubImport::ProjectCreator, lib: true do ...@@ -13,7 +13,7 @@ describe Gitlab::GithubImport::ProjectCreator, lib: true do
) )
end end
subject(:service) { described_class.new(repo, namespace, user, github_access_token: 'asdffg') } subject(:service) { described_class.new(repo, repo.name, namespace, user, github_access_token: 'asdffg') }
before do before do
namespace.add_owner(user) namespace.add_owner(user)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment