diff options
30 files changed, 1313 insertions, 55 deletions
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 21cc6dfdd16..f45fcd4d900 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -30,7 +30,13 @@ class ApplicationController < ActionController::Base protect_from_forgery with: :exception, prepend: true helper_method :can? - helper_method :import_sources_enabled?, :github_import_enabled?, :gitea_import_enabled?, :github_import_configured?, :gitlab_import_enabled?, :gitlab_import_configured?, :bitbucket_import_enabled?, :bitbucket_import_configured?, :google_code_import_enabled?, :fogbugz_import_enabled?, :git_import_enabled?, :gitlab_project_import_enabled? + helper_method :import_sources_enabled?, :github_import_enabled?, + :gitea_import_enabled?, :github_import_configured?, + :gitlab_import_enabled?, :gitlab_import_configured?, + :bitbucket_import_enabled?, :bitbucket_import_configured?, + :google_code_import_enabled?, :fogbugz_import_enabled?, + :git_import_enabled?, :gitlab_project_import_enabled?, + :manifest_import_enabled? rescue_from Encoding::CompatibilityError do |exception| log_exception(exception) @@ -351,6 +357,10 @@ class ApplicationController < ActionController::Base Gitlab::CurrentSettings.import_sources.include?('gitlab_project') end + def manifest_import_enabled? + Group.supports_nested_groups? && Gitlab::CurrentSettings.import_sources.include?('manifest') + end + # U2F (universal 2nd factor) devices need a unique identifier for the application # to perform authentication. # https://developers.yubico.com/U2F/App_ID.html diff --git a/app/controllers/import/manifest_controller.rb b/app/controllers/import/manifest_controller.rb new file mode 100644 index 00000000000..e5a719fa0df --- /dev/null +++ b/app/controllers/import/manifest_controller.rb @@ -0,0 +1,93 @@ +class Import::ManifestController < Import::BaseController + before_action :whitelist_query_limiting, only: [:create] + before_action :verify_import_enabled + before_action :ensure_import_vars, only: [:create, :status] + + def new + end + + def status + @already_added_projects = find_already_added_projects + already_added_import_urls = @already_added_projects.pluck(:import_url) + + @pending_repositories = repositories.to_a.reject do |repository| + already_added_import_urls.include?(repository[:url]) + end + end + + def upload + group = Group.find(params[:group_id]) + + unless can?(current_user, :create_projects, group) + @errors = ["You don't have enough permissions to create projects in the selected group"] + + render :new && return + end + + manifest = Gitlab::ManifestImport::Manifest.new(params[:manifest].tempfile) + + if manifest.valid? + session[:manifest_import_repositories] = manifest.projects + session[:manifest_import_group_id] = group.id + + redirect_to status_import_manifest_path + else + @errors = manifest.errors + + render :new + end + end + + def jobs + render json: find_jobs + end + + def create + repository = repositories.find do |project| + project[:id] == params[:repo_id].to_i + end + + project = Gitlab::ManifestImport::ProjectCreator.new(repository, group, current_user).execute + + if project.persisted? + render json: ProjectSerializer.new.represent(project) + else + render json: { errors: project_save_error(project) }, status: :unprocessable_entity + end + end + + private + + def ensure_import_vars + unless group && repositories.present? + redirect_to(new_import_manifest_path) + end + end + + def group + @group ||= Group.find_by(id: session[:manifest_import_group_id]) + end + + def repositories + @repositories ||= session[:manifest_import_repositories] + end + + def find_jobs + find_already_added_projects.to_json(only: [:id], methods: [:import_status]) + end + + def find_already_added_projects + group.all_projects + .where(import_type: 'manifest') + .where(creator_id: current_user) + .includes(:import_state) + end + + def verify_import_enabled + render_404 unless manifest_import_enabled? + end + + def whitelist_query_limiting + Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-ce/issues/48939') + end +end diff --git a/app/helpers/namespaces_helper.rb b/app/helpers/namespaces_helper.rb index 9be93fa69ae..9008db1b300 100644 --- a/app/helpers/namespaces_helper.rb +++ b/app/helpers/namespaces_helper.rb @@ -3,7 +3,7 @@ module NamespacesHelper params.dig(:project, :namespace_id) || params[:namespace_id] end - def namespaces_options(selected = :current_user, display_path: false, extra_group: nil) + def namespaces_options(selected = :current_user, display_path: false, extra_group: nil, groups_only: false) groups = current_user.manageable_groups .joins(:route) .includes(:route) @@ -20,10 +20,13 @@ module NamespacesHelper options = [] options << options_for_group(groups, display_path: display_path, type: 'group') - options << options_for_group(users, display_path: display_path, type: 'user') - if selected == :current_user && current_user.namespace - selected = current_user.namespace.id + unless groups_only + options << options_for_group(users, display_path: display_path, type: 'user') + + if selected == :current_user && current_user.namespace + selected = current_user.namespace.id + end end grouped_options_for_select(options, selected) diff --git a/app/services/groups/nested_create_service.rb b/app/services/groups/nested_create_service.rb index 5c337a9faa5..c2dfbac5414 100644 --- a/app/services/groups/nested_create_service.rb +++ b/app/services/groups/nested_create_service.rb @@ -1,11 +1,12 @@ module Groups class NestedCreateService < Groups::BaseService - attr_reader :group_path + attr_reader :group_path, :visibility_level def initialize(user, params) @current_user, @params = user, params.dup - @group_path = @params.delete(:group_path) + @visibility_level = @params.delete(:visibility_level) || + Gitlab::CurrentSettings.current_application_settings.default_group_visibility end def execute @@ -36,11 +37,12 @@ module Groups new_params = params.reverse_merge( path: subgroup_name, name: subgroup_name, - parent: last_group + parent: last_group, + visibility_level: visibility_level ) - new_params[:visibility_level] ||= Gitlab::CurrentSettings.current_application_settings.default_group_visibility - last_group = namespace_or_group(partial_path) || Groups::CreateService.new(current_user, new_params).execute + last_group = namespace_or_group(partial_path) || + Groups::CreateService.new(current_user, new_params).execute end last_group diff --git a/app/views/import/_githubish_status.html.haml b/app/views/import/_githubish_status.html.haml index 5e7be5cd37b..f0d1e837317 100644 --- a/app/views/import/_githubish_status.html.haml +++ b/app/views/import/_githubish_status.html.haml @@ -21,23 +21,13 @@ %th= _('Status') %tbody - @already_added_projects.each do |project| - %tr{ id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}" } + %tr{ id: "project_#{project.id}", class: project_status_css_class(project.import_status) } %td = provider_project_link(provider, project.import_source) %td = link_to project.full_path, [project.namespace.becomes(Namespace), project] %td.job-status - - if project.import_status == 'finished' - %span - %i.fa.fa-check - = _('Done') - - elsif project.import_status == 'started' - %i.fa.fa-spinner.fa-spin - = _('Started') - - elsif project.import_status == 'failed' - = _('Failed') - - else - = project.human_import_status_name + = render 'import/project_status', project: project - @repos.each do |repo| %tr{ id: "repo_#{repo.id}", data: { qa: { repo_path: repo.full_name } } } @@ -61,6 +51,6 @@ = has_ci_cd_only_params? ? _('Connect') : _('Import') = icon("spinner spin", class: "loading-icon") -.js-importer-status{ data: { jobs_import_path: "#{url_for([:jobs, :import, provider])}", - import_path: "#{url_for([:import, provider])}", - ci_cd_only: "#{has_ci_cd_only_params?}" } } +.js-importer-status{ data: { jobs_import_path: url_for([:jobs, :import, provider]), + import_path: url_for([:import, provider]), + ci_cd_only: has_ci_cd_only_params?.to_s } } diff --git a/app/views/import/_project_status.html.haml b/app/views/import/_project_status.html.haml new file mode 100644 index 00000000000..280bcbc1e63 --- /dev/null +++ b/app/views/import/_project_status.html.haml @@ -0,0 +1,11 @@ +- case project.import_status +- when 'finished' + = icon('check') + = _('Done') +- when 'started' + = icon("spinner spin") + = _('Started') +- when 'failed' + = _('Failed') +- else + = project.human_import_status_name diff --git a/app/views/import/manifest/_form.html.haml b/app/views/import/manifest/_form.html.haml new file mode 100644 index 00000000000..763beb5958f --- /dev/null +++ b/app/views/import/manifest/_form.html.haml @@ -0,0 +1,23 @@ += form_tag upload_import_manifest_path, multipart: true do + .form-group + = label_tag :group_id, nil, class: 'label-light' do + = _('Group') + .input-group + .input-group-prepend.has-tooltip{ title: root_url } + .input-group-text + = root_url + = select_tag :group_id, namespaces_options(nil, display_path: true, groups_only: true), { class: 'select2 js-select-namespace' } + .form-text.text-muted + = _('Choose the top-level group for your repository imports.') + + .form-group + = label_tag :manifest, class: 'label-light' do + = _('Manifest') + = file_field_tag :manifest, class: 'form-control-file', required: true + .form-text.text-muted + = _('Import multiple repositories by uploading a manifest file.') + = link_to icon('question-circle'), help_page_path('user/project/import/manifest') + + .append-bottom-10 + = submit_tag _('List available repositories'), class: 'btn btn-success' + = link_to _('Cancel'), new_project_path, class: 'btn btn-cancel' diff --git a/app/views/import/manifest/new.html.haml b/app/views/import/manifest/new.html.haml new file mode 100644 index 00000000000..056e4922b9e --- /dev/null +++ b/app/views/import/manifest/new.html.haml @@ -0,0 +1,12 @@ +- page_title "Manifest file import" +- header_title "Projects", root_path + +%h3.page-title + = _('Manifest file import') + +- if @errors.present? + .alert.alert-danger + - @errors.each do |error| + = error + += render 'form' diff --git a/app/views/import/manifest/status.html.haml b/app/views/import/manifest/status.html.haml new file mode 100644 index 00000000000..5b2e1005398 --- /dev/null +++ b/app/views/import/manifest/status.html.haml @@ -0,0 +1,42 @@ +- page_title "Manifest import" +- header_title "Projects", root_path +- provider = 'manifest' + +%h3.page-title + = _('Manifest file import') + +%p + = button_tag class: "btn btn-import btn-success js-import-all" do + = import_all_githubish_repositories_button_label + = icon("spinner spin", class: "loading-icon") + +.table-responsive + %table.table.import-jobs + %thead + %tr + %th= _('Repository URL') + %th= _('To GitLab') + %th= _('Status') + %tbody + - @already_added_projects.each do |project| + %tr{ id: "project_#{project.id}", class: project_status_css_class(project.import_status) } + %td + = project.import_url + %td + = link_to_project project + %td.job-status + = render 'import/project_status', project: project + + - @pending_repositories.each do |repository| + %tr{ id: "repo_#{repository[:id]}" } + %td + = repository[:url] + %td.import-target + = import_project_target(@group.full_path, repository[:path]) + %td.import-actions.job-status + = button_tag class: "btn btn-import js-add-to-import" do + = _('Import') + = icon("spinner spin", class: "loading-icon") + +.js-importer-status{ data: { jobs_import_path: url_for([:jobs, :import, provider]), + import_path: url_for([:import, provider]) } } diff --git a/app/views/projects/_import_project_pane.html.haml b/app/views/projects/_import_project_pane.html.haml index 8f535b9d789..3da6db08580 100644 --- a/app/views/projects/_import_project_pane.html.haml +++ b/app/views/projects/_import_project_pane.html.haml @@ -1,49 +1,62 @@ - active_tab = local_assigns.fetch(:active_tab, 'blank') -- f = local_assigns.fetch(:f) .project-import .form-group.import-btn-container.clearfix - = f.label :visibility_level, class: 'label-light' do #the label here seems wrong + %h5 Import project from .import-buttons - if gitlab_project_import_enabled? .import_gitlab_project.has-tooltip{ data: { container: 'body' } } = link_to new_import_gitlab_project_path, class: 'btn btn_import_gitlab_project project-submit' do = icon('gitlab', text: 'GitLab export') - %div - - if github_import_enabled? + + - if github_import_enabled? + %div = link_to new_import_github_path, class: 'btn js-import-github' do = icon('github', text: 'GitHub') - %div - - if bitbucket_import_enabled? + + - if bitbucket_import_enabled? + %div = link_to status_import_bitbucket_path, class: "btn import_bitbucket #{'how_to_import_link' unless bitbucket_import_configured?}" do = icon('bitbucket', text: 'Bitbucket') - unless bitbucket_import_configured? = render 'bitbucket_import_modal' - %div - - if gitlab_import_enabled? + + - if gitlab_import_enabled? + %div = link_to status_import_gitlab_path, class: "btn import_gitlab #{'how_to_import_link' unless gitlab_import_configured?}" do = icon('gitlab', text: 'GitLab.com') - unless gitlab_import_configured? = render 'gitlab_import_modal' - %div - - if google_code_import_enabled? + + - if google_code_import_enabled? + %div = link_to new_import_google_code_path, class: 'btn import_google_code' do = icon('google', text: 'Google Code') - %div - - if fogbugz_import_enabled? + + - if fogbugz_import_enabled? + %div = link_to new_import_fogbugz_path, class: 'btn import_fogbugz' do = icon('bug', text: 'Fogbugz') - %div - - if gitea_import_enabled? + + - if gitea_import_enabled? + %div = link_to new_import_gitea_path, class: 'btn import_gitea' do = custom_icon('go_logo') Gitea - %div - - if git_import_enabled? + + - if git_import_enabled? + %div %button.btn.js-toggle-button.js-import-git-toggle-button{ type: "button", data: { toggle_open_class: 'active' } } = icon('git', text: 'Repo by URL') + + - if manifest_import_enabled? + %div + = link_to new_import_manifest_path, class: 'btn import_manifest' do + = icon('file-text-o', text: 'Manifest file') + .js-toggle-content.toggle-import-form{ class: ('hide' if active_tab != 'import') } - %hr + = form_for @project, html: { class: 'new_project' } do |f| + %hr = render "shared/import_form", f: f = render 'new_project_fields', f: f, project_name_id: "import-url-name" diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index 5bb1bfb7059..6c363345e38 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -55,13 +55,12 @@ = render 'project_templates', f: f .tab-pane.import-project-pane.js-toggle-container{ id: 'import-project-pane', class: active_when(active_tab == 'import'), role: 'tabpanel' } - = form_for @project, html: { class: 'new_project' } do |f| - - if import_sources_enabled? - = render 'import_project_pane', f: f, active_tab: active_tab - - else - .nothing-here-block - %h4 No import options available - %p Contact an administrator to enable options for importing your project. + - if import_sources_enabled? + = render 'import_project_pane', active_tab: active_tab + - else + .nothing-here-block + %h4 No import options available + %p Contact an administrator to enable options for importing your project. .save-project-loader.d-none .center diff --git a/changelogs/unreleased/dz-manifest-import.yml b/changelogs/unreleased/dz-manifest-import.yml new file mode 100644 index 00000000000..b0d29b0869f --- /dev/null +++ b/changelogs/unreleased/dz-manifest-import.yml @@ -0,0 +1,5 @@ +--- +title: Add ability to import multiple repositories by uploading a manifest file +merge_request: 20304 +author: +type: added diff --git a/config/routes/import.rb b/config/routes/import.rb index c378253bf15..efd0260ff60 100644 --- a/config/routes/import.rb +++ b/config/routes/import.rb @@ -45,4 +45,10 @@ namespace :import do resource :gitlab_project, only: [:create, :new] do post :create end + + resource :manifest, only: [:create, :new], controller: :manifest do + get :status + get :jobs + post :upload + end end diff --git a/doc/api/settings.md b/doc/api/settings.md index e6b207d8746..b6f2101fc7b 100644 --- a/doc/api/settings.md +++ b/doc/api/settings.md @@ -105,7 +105,7 @@ PUT /application/settings | `housekeeping_gc_period` | integer | no | Number of Git pushes after which 'git gc' is run. | | `housekeeping_incremental_repack_period` | integer | no | Number of Git pushes after which an incremental 'git repack' is run. | | `html_emails_enabled` | boolean | no | Enable HTML emails | -| `import_sources` | Array of strings | no | Sources to allow project import from, possible values: "github bitbucket gitlab google_code fogbugz git gitlab_project | +| `import_sources` | Array of strings | no | Sources to allow project import from, possible values: "github bitbucket gitlab google_code fogbugz git gitlab_project manifest | | `koding_enabled` | boolean | no | Enable Koding integration. Default is `false`. | | `koding_url` | string | yes (if `koding_enabled` is `true`) | The Koding instance URL for integration. | | `max_artifacts_size` | integer | no | Maximum artifacts size in MB | diff --git a/doc/user/project/import/img/manifest_status.png b/doc/user/project/import/img/manifest_status.png Binary files differnew file mode 100644 index 00000000000..b706116a2ac --- /dev/null +++ b/doc/user/project/import/img/manifest_status.png diff --git a/doc/user/project/import/img/manifest_upload.png b/doc/user/project/import/img/manifest_upload.png Binary files differnew file mode 100644 index 00000000000..d6bf4b157dd --- /dev/null +++ b/doc/user/project/import/img/manifest_upload.png diff --git a/doc/user/project/import/index.md b/doc/user/project/import/index.md index 72cc58546b7..b55435e5b4f 100644 --- a/doc/user/project/import/index.md +++ b/doc/user/project/import/index.md @@ -11,6 +11,7 @@ 1. [From SVN](svn.md) 1. [From TFS](tfs.md) 1. [From repo by URL](repo_by_url.md) +1. [By uploading a manifest file](manifest.md) In addition to the specific migration documentation above, you can import any Git repository via HTTP from the New Project page. Be aware that if the diff --git a/doc/user/project/import/manifest.md b/doc/user/project/import/manifest.md new file mode 100644 index 00000000000..812ecf05faf --- /dev/null +++ b/doc/user/project/import/manifest.md @@ -0,0 +1,48 @@ +# Import multiple repositories by uploading a manifest file + +GitLab allows you to import all the required git repositories +based a manifest file like the one used by the Android repository. + + +>**Note:** +This feature requires [subgroups](../../group/subgroups/index.md) to be supported by your database. + +You can do it by following next steps: + +1. From your GitLab dashboard click **New project** +1. Switch to the **Import project** tab +1. Click on the **Manifest file** button +1. Provide GitLab with a manifest xml file +1. Select a group you want to import to (you need to create a group first if you don't have one) +1. Click **List available repositories** +1. You will be redirected to the import status page with projects list based on manifest file +1. Check the list and click 'Import all repositories' to start import. + +![Manifest upload](img/manifest_upload.png) + +![Manifest status](img/manifest_status.png) + +### Manifest format + +A manifest must be an XML file. There must be one `remote` tag with `review` attribute +that contains a URL to a git server. Each `project` tag must have `name` and `path` attribute. +GitLab will build URL to the repository by combining URL from `remote` tag with a project name. +A path attribute will be used to represent project path in GitLab system. + +Below is a valid example of manifest file. + +```xml +<manifest> + <remote review="https://android-review.googlesource.com/" /> + + <project path="build/make" name="platform/build" /> + <project path="build/blueprint" name="platform/build/blueprint" /> +</manifest> +``` + +As result next projects will be created: + +| GitLab | Import URL | +|---|---| +| https://gitlab/YOUR_GROUP/build/make | https://android-review.googlesource.com/platform/build | +| https://gitlab/YOUR_GROUP/build/blueprint | https://android-review.googlesource.com/platform/build/blueprint | diff --git a/lib/api/settings.rb b/lib/api/settings.rb index 02ef89f997f..1ca7d23203b 100644 --- a/lib/api/settings.rb +++ b/lib/api/settings.rb @@ -25,7 +25,7 @@ module API optional :default_snippet_visibility, type: String, values: Gitlab::VisibilityLevel.string_values, desc: 'The default snippet visibility' optional :default_group_visibility, type: String, values: Gitlab::VisibilityLevel.string_values, desc: 'The default group visibility' optional :restricted_visibility_levels, type: Array[String], desc: 'Selected levels cannot be used by non-admin users for groups, projects or snippets. If the public level is restricted, user profiles are only visible to logged in users.' - optional :import_sources, type: Array[String], values: %w[github bitbucket gitlab google_code fogbugz git gitlab_project], + optional :import_sources, type: Array[String], values: %w[github bitbucket gitlab google_code fogbugz git gitlab_project manifest], desc: 'Enabled sources for code import during project creation. OmniAuth must be configured for GitHub, Bitbucket, and GitLab.com' optional :disabled_oauth_sign_in_sources, type: Array[String], desc: 'Disable certain OAuth sign-in sources' optional :enabled_git_access_protocol, type: String, values: %w[ssh http nil], desc: 'Allow only the selected protocols to be used for Git access.' diff --git a/lib/gitlab/import_sources.rb b/lib/gitlab/import_sources.rb index 60d5fa4d29a..af9b880ef9e 100644 --- a/lib/gitlab/import_sources.rb +++ b/lib/gitlab/import_sources.rb @@ -16,7 +16,8 @@ module Gitlab ImportSource.new('fogbugz', 'FogBugz', Gitlab::FogbugzImport::Importer), ImportSource.new('git', 'Repo by URL', nil), ImportSource.new('gitlab_project', 'GitLab export', Gitlab::ImportExport::Importer), - ImportSource.new('gitea', 'Gitea', Gitlab::LegacyGithubImport::Importer) + ImportSource.new('gitea', 'Gitea', Gitlab::LegacyGithubImport::Importer), + ImportSource.new('manifest', 'Manifest file', nil) ].freeze class << self diff --git a/lib/gitlab/manifest_import/manifest.rb b/lib/gitlab/manifest_import/manifest.rb new file mode 100644 index 00000000000..4d6034fb956 --- /dev/null +++ b/lib/gitlab/manifest_import/manifest.rb @@ -0,0 +1,81 @@ +# Class to parse manifest file and build a list of repositories for import +# +# <manifest> +# <remote review="https://android-review.googlesource.com/" /> +# <project path="platform-common" name="platform" /> +# <project path="platform/art" name="platform/art" /> +# <project path="platform/device" name="platform/device" /> +# </manifest> +# +# 1. Project path must be uniq and can't be part of other project path. +# For example, you can't have projects with 'foo' and 'foo/bar' paths. +# 2. Remote must be present with review attribute so GitLab knows +# where to fetch source code +module Gitlab + module ManifestImport + class Manifest + attr_reader :parsed_xml, :errors + + def initialize(file) + @parsed_xml = Nokogiri::XML(file) { |config| config.strict } + @errors = [] + rescue Nokogiri::XML::SyntaxError + @errors = ['The uploaded file is not a valid XML file.'] + end + + def projects + raw_projects.each_with_index.map do |project, i| + { + id: i, + name: project['name'], + path: project['path'], + url: repository_url(project['name']) + } + end + end + + def valid? + return false if @errors.any? + + unless validate_remote + @errors << 'Make sure a <remote> tag is present and is valid.' + end + + unless validate_projects + @errors << 'Make sure every <project> tag has name and path attributes.' + end + + @errors.empty? + end + + private + + def validate_remote + remote.present? && URI.parse(remote).host + rescue URI::Error + false + end + + def validate_projects + raw_projects.all? do |project| + project['name'] && project['path'] + end + end + + def repository_url(name) + URI.join(remote, name).to_s + end + + def remote + return @remote if defined?(@remote) + + remote_tag = parsed_xml.css('manifest > remote').first + @remote = remote_tag['review'] if remote_tag + end + + def raw_projects + @raw_projects ||= parsed_xml.css('manifest > project') + end + end + end +end diff --git a/lib/gitlab/manifest_import/project_creator.rb b/lib/gitlab/manifest_import/project_creator.rb new file mode 100644 index 00000000000..b5967c93735 --- /dev/null +++ b/lib/gitlab/manifest_import/project_creator.rb @@ -0,0 +1,41 @@ +module Gitlab + module ManifestImport + class ProjectCreator + attr_reader :repository, :destination, :current_user + + def initialize(repository, destination, current_user) + @repository = repository + @destination = destination + @current_user = current_user + end + + def execute + group_full_path, _, project_path = repository[:path].rpartition('/') + group_full_path = File.join(destination.full_path, group_full_path) if destination + group = create_group_with_parents(group_full_path) + + params = { + import_url: repository[:url], + import_type: 'manifest', + namespace_id: group.id, + path: project_path, + name: project_path, + visibility_level: destination.visibility_level + } + + Projects::CreateService.new(current_user, params).execute + end + + private + + def create_group_with_parents(full_path) + params = { + group_path: full_path, + visibility_level: destination.visibility_level + } + + Groups::NestedCreateService.new(current_user, params).execute + end + end + end +end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 1792302bb0e..eb3433b3ba2 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -981,6 +981,9 @@ msgstr "" msgid "Choose file..." msgstr "" +msgid "Choose the top-level group for your repository imports." +msgstr "" + msgid "Choose which repositories you want to import." msgstr "" @@ -2447,6 +2450,9 @@ msgstr "" msgid "Graph" msgstr "" +msgid "Group" +msgstr "" + msgid "Group CI/CD settings" msgstr "" @@ -2650,6 +2656,9 @@ msgstr "" msgid "Import in progress" msgstr "" +msgid "Import multiple repositories by uploading a manifest file." +msgstr "" + msgid "Import repositories from GitHub" msgstr "" @@ -2859,6 +2868,9 @@ msgstr "" msgid "List" msgstr "" +msgid "List available repositories" +msgstr "" + msgid "List your GitHub repositories" msgstr "" @@ -2898,6 +2910,12 @@ msgstr "" msgid "Manage project labels" msgstr "" +msgid "Manifest" +msgstr "" + +msgid "Manifest file import" +msgstr "" + msgid "Mar" msgstr "" @@ -3920,6 +3938,9 @@ msgstr "" msgid "Repository Settings" msgstr "" +msgid "Repository URL" +msgstr "" + msgid "Repository maintenance" msgstr "" diff --git a/spec/features/import/manifest_import_spec.rb b/spec/features/import/manifest_import_spec.rb new file mode 100644 index 00000000000..e381d073804 --- /dev/null +++ b/spec/features/import/manifest_import_spec.rb @@ -0,0 +1,51 @@ +require 'spec_helper' + +describe 'Import multiple repositories by uploading a manifest file', :js, :postgresql do + include Select2Helper + + let(:user) { create(:admin) } + let(:group) { create(:group) } + + before do + sign_in(user) + + group.add_owner(user) + end + + it 'parses manifest file and list repositories' do + visit new_import_manifest_path + + attach_file('manifest', Rails.root.join('spec/fixtures/aosp_manifest.xml')) + click_on 'List available repositories' + + expect(page).to have_button('Import all repositories') + expect(page).to have_content('https://android-review.googlesource.com/platform/build/blueprint') + end + + it 'imports succesfully imports a project' do + visit new_import_manifest_path + + attach_file('manifest', Rails.root.join('spec/fixtures/aosp_manifest.xml')) + click_on 'List available repositories' + + page.within(first_row) do + click_on 'Import' + + expect(page).to have_content 'Done' + expect(page).to have_content("#{group.full_path}/build/make") + end + end + + it 'renders an error if invalid file was provided' do + visit new_import_manifest_path + + attach_file('manifest', Rails.root.join('spec/fixtures/banana_sample.gif')) + click_on 'List available repositories' + + expect(page).to have_content 'The uploaded file is not a valid XML file.' + end + + def first_row + page.all('table.import-jobs tbody tr')[0] + end +end diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb index df8528e79dd..bbe08ff83ff 100644 --- a/spec/features/projects/new_project_spec.rb +++ b/spec/features/projects/new_project_spec.rb @@ -25,6 +25,22 @@ describe 'New project' do expect(page).to have_link('GitLab export') end + describe 'manifest import option' do + before do + visit new_project_path + + find('#import-project-tab').click + end + + context 'when using postgres', :postgresql do + it { expect(page).to have_link('Manifest file') } + end + + context 'when using mysql', :mysql do + it { expect(page).not_to have_link('Manifest file') } + end + end + context 'Visibility level selector', :js do Gitlab::VisibilityLevel.options.each do |key, level| it "sets selector to #{key}" do @@ -201,5 +217,16 @@ describe 'New project' do expect(current_path).to eq new_import_google_code_path end end + + context 'from manifest file', :postgresql do + before do + first('.import_manifest').click + end + + it 'shows import instructions' do + expect(page).to have_content('Manifest file import') + expect(current_path).to eq new_import_manifest_path + end + end end end diff --git a/spec/fixtures/aosp_manifest.xml b/spec/fixtures/aosp_manifest.xml new file mode 100644 index 00000000000..cfd0094b735 --- /dev/null +++ b/spec/fixtures/aosp_manifest.xml @@ -0,0 +1,685 @@ +<?xml version="1.0" encoding="UTF-8"?> +<manifest> + + <remote name="aosp" + fetch=".." + review="https://android-review.googlesource.com/" /> + <default revision="master" + remote="aosp" + sync-j="4" /> + + <project path="build/make" name="platform/build" groups="pdk" > + <copyfile src="core/root.mk" dest="Makefile" /> + <linkfile src="CleanSpec.mk" dest="build/CleanSpec.mk" /> + <linkfile src="buildspec.mk.default" dest="build/buildspec.mk.default" /> + <linkfile src="core" dest="build/core" /> + <linkfile src="envsetup.sh" dest="build/envsetup.sh" /> + <linkfile src="target" dest="build/target" /> + <linkfile src="tools" dest="build/tools" /> + </project> + <project path="build/blueprint" name="platform/build/blueprint" groups="pdk,tradefed" /> + <project path="build/kati" name="platform/build/kati" groups="pdk,tradefed" /> + <project path="build/soong" name="platform/build/soong" groups="pdk,tradefed" > + <linkfile src="root.bp" dest="Android.bp" /> + <linkfile src="bootstrap.bash" dest="bootstrap.bash" /> + </project> + <project path="art" name="platform/art" groups="pdk" /> + <project path="bionic" name="platform/bionic" groups="pdk" /> + <project path="bootable/recovery" name="platform/bootable/recovery" groups="pdk" /> + <project path="compatibility/cdd" name="platform/compatibility/cdd" groups="pdk" /> + <project path="cts" name="platform/cts" groups="cts,pdk-cw-fs,pdk-fs" /> + <project path="dalvik" name="platform/dalvik" groups="pdk-cw-fs,pdk-fs" /> + <project path="developers/build" name="platform/developers/build" groups="developers" /> + <project path="developers/demos" name="platform/developers/demos" groups="developers" /> + <project path="developers/samples/android" name="platform/developers/samples/android" groups="developers" /> + <project path="development" name="platform/development" groups="developers,pdk-cw-fs,pdk-fs" /> + <project path="device/asus/fugu" name="device/asus/fugu" groups="device,fugu,broadcom_pdk" /> + <project path="device/asus/fugu-kernel" name="device/asus/fugu-kernel" groups="device,fugu,broadcom_pdk" clone-depth="1" /> + <project path="device/common" name="device/common" groups="pdk-cw-fs,pdk" /> + <project path="device/generic/arm64" name="device/generic/arm64" groups="pdk" /> + <project path="device/generic/armv7-a-neon" name="device/generic/armv7-a-neon" groups="pdk" /> + <project path="device/generic/car" name="device/generic/car" groups="pdk" /> + <project path="device/generic/common" name="device/generic/common" groups="pdk" /> + <project path="device/generic/goldfish" name="device/generic/goldfish" groups="pdk" /> + <project path="device/generic/goldfish-opengl" name="device/generic/goldfish-opengl" groups="pdk" /> + <project path="device/generic/mini-emulator-arm64" name="device/generic/mini-emulator-arm64" groups="pdk" /> + <project path="device/generic/mini-emulator-armv7-a-neon" name="device/generic/mini-emulator-armv7-a-neon" groups="pdk" /> + <project path="device/generic/mini-emulator-x86" name="device/generic/mini-emulator-x86" groups="pdk" /> + <project path="device/generic/mini-emulator-x86_64" name="device/generic/mini-emulator-x86_64" groups="pdk" /> + <project path="device/generic/qemu" name="device/generic/qemu" groups="pdk" /> + <project path="device/generic/uml" name="device/generic/uml" groups="device,pdk" /> + <project path="device/generic/x86" name="device/generic/x86" groups="pdk" /> + <project path="device/generic/x86_64" name="device/generic/x86_64" groups="pdk" /> + <project path="device/google/accessory/arduino" name="device/google/accessory/arduino" groups="device,pdk" /> + <project path="device/google/accessory/demokit" name="device/google/accessory/demokit" groups="device,pdk" /> + <project path="device/google/atv" name="device/google/atv" groups="device,broadcom_pdk,generic_fs,pdk" /> + <project path="device/google/contexthub" name="device/google/contexthub" groups="device,marlin,pdk" /> + <project path="device/google/cuttlefish" name="device/google/cuttlefish" groups="device" /> + <project path="device/google/cuttlefish_common" name="device/google/cuttlefish_common" groups="device" /> + <project path="device/google/cuttlefish_kernel" name="device/google/cuttlefish_kernel" groups="device" clone-depth="1" /> + <project path="device/google/dragon" name="device/google/dragon" groups="device,dragon" /> + <project path="device/google/dragon-kernel" name="device/google/dragon-kernel" groups="device,dragon" clone-depth="1" /> + <project path="device/google/marlin" name="device/google/marlin" groups="device,marlin,pdk" /> + <project path="device/google/marlin-kernel" name="device/google/marlin-kernel" groups="device,marlin,pdk" clone-depth="1" /> + <project path="device/google/muskie" name="device/google/muskie" groups="device,muskie" /> + <project path="device/google/taimen" name="device/google/taimen" groups="device,taimen" /> + <project path="device/google/vrservices" name="device/google/vrservices" groups="pdk" clone-depth="1" /> + <project path="device/google/wahoo" name="device/google/wahoo" groups="device,wahoo" /> + <project path="device/google/wahoo-kernel" name="device/google/wahoo-kernel" groups="device,wahoo" clone-depth="1" /> + <project path="device/huawei/angler" name="device/huawei/angler" groups="device,angler,broadcom_pdk" /> + <project path="device/huawei/angler-kernel" name="device/huawei/angler-kernel" groups="device,angler,broadcom_pdk" clone-depth="1" /> + <project path="device/lge/bullhead" name="device/lge/bullhead" groups="device,bullhead" /> + <project path="device/lge/bullhead-kernel" name="device/lge/bullhead-kernel" groups="device,bullhead" clone-depth="1" /> + <project path="device/linaro/bootloader/arm-trusted-firmware" name="device/linaro/bootloader/arm-trusted-firmware" /> + <project path="device/linaro/bootloader/edk2" name="device/linaro/bootloader/edk2" /> + <project path="device/linaro/bootloader/OpenPlatformPkg" name="device/linaro/bootloader/OpenPlatformPkg" /> + <project path="device/linaro/hikey" name="device/linaro/hikey" groups="device,hikey,pdk" /> + <project path="device/linaro/hikey-kernel" name="device/linaro/hikey-kernel" groups="device,hikey,pdk" clone-depth="1" /> + <project path="device/sample" name="device/sample" groups="pdk" /> + <project path="external/aac" name="platform/external/aac" groups="pdk" /> + <project path="external/abi-compliance-checker" name="platform/external/abi-compliance-checker" groups="pdk" /> + <project path="external/abi-dumper" name="platform/external/abi-dumper" groups="pdk" /> + <project path="external/adt-infra" name="platform/external/adt-infra" groups="adt-infra,notdefault,pdk-fs" /> + <project path="external/android-clat" name="platform/external/android-clat" groups="pdk" /> + <project path="external/androidplot" name="platform/external/androidplot" groups="pdk" /> + <project path="external/annotation-tools" name="platform/external/annotation-tools" groups="pdk" /> + <project path="external/ant-glob" name="platform/external/ant-glob" groups="pdk" /> + <project path="external/antlr" name="platform/external/antlr" groups="pdk" /> + <project path="external/apache-commons-math" name="platform/external/apache-commons-math" groups="pdk" /> + <project path="external/apache-harmony" name="platform/external/apache-harmony" groups="pdk" /> + <project path="external/apache-http" name="platform/external/apache-http" groups="pdk" /> + <project path="external/apache-xml" name="platform/external/apache-xml" groups="pdk" /> + <project path="external/archive-patcher" name="platform/external/archive-patcher" groups="pdk" /> + <project path="external/arm-neon-tests" name="platform/external/arm-neon-tests" groups="vendor" /> + <project path="external/autotest" name="platform/external/autotest" groups="pdk-fs" /> + <project path="external/avb" name="platform/external/avb" groups="pdk" /> + <project path="external/bart" name="platform/external/bart" groups="pdk" /> + <project path="external/blktrace" name="platform/external/blktrace" groups="pdk" /> + <project path="external/boringssl" name="platform/external/boringssl" groups="pdk" /> + <project path="external/bouncycastle" name="platform/external/bouncycastle" groups="pdk" /> + <project path="external/brotli" name="platform/external/brotli" groups="pdk" /> + <project path="external/bsdiff" name="platform/external/bsdiff" groups="pdk" /> + <project path="external/bzip2" name="platform/external/bzip2" groups="pdk" /> + <project path="external/caliper" name="platform/external/caliper" groups="pdk" /> + <project path="external/cblas" name="platform/external/cblas" groups="pdk" /> + <project path="external/chromium-libpac" name="platform/external/chromium-libpac" groups="pdk" /> + <project path="external/chromium-trace" name="platform/external/chromium-trace" groups="pdk" /> + <project path="external/chromium-webview" name="platform/external/chromium-webview" groups="pdk" clone-depth="1" /> + <project path="external/clang" name="platform/external/clang" groups="pdk" /> + <project path="external/cldr" name="platform/external/cldr" groups="pdk" /> + <project path="external/cmockery" name="platform/external/cmockery" groups="pdk" /> + <project path="external/cn-cbor" name="platform/external/cn-cbor" groups="pdk" /> + <project path="external/compiler-rt" name="platform/external/compiler-rt" groups="pdk" /> + <project path="external/conscrypt" name="platform/external/conscrypt" groups="pdk" /> + <project path="external/crcalc" name="platform/external/crcalc" groups="pdk" /> + <project path="external/cros/system_api" name="platform/external/cros/system_api" groups="pdk" /> + <project path="external/curl" name="platform/external/curl" groups="pdk" /> + <project path="external/dagger2" name="platform/external/dagger2" groups="pdk" /> + <project path="external/deqp" name="platform/external/deqp" groups="pdk-fs" /> + <project path="external/desugar" name="platform/external/desugar" groups="pdk" /> + <project path="external/devlib" name="platform/external/devlib" groups="pdk" /> + <project path="external/dexmaker" name="platform/external/dexmaker" groups="pdk" /> + <project path="external/dhcpcd-6.8.2" name="platform/external/dhcpcd-6.8.2" groups="pdk" /> + <project path="external/dlmalloc" name="platform/external/dlmalloc" groups="pdk" /> + <project path="external/dng_sdk" name="platform/external/dng_sdk" groups="pdk" /> + <project path="external/dnsmasq" name="platform/external/dnsmasq" groups="pdk" /> + <project path="external/doclava" name="platform/external/doclava" groups="pdk" /> + <project path="external/dokka" name="platform/external/dokka" groups="pdk" /> + <project path="external/drm_hwcomposer" name="platform/external/drm_hwcomposer" groups="drm_hwcomposer,pdk-fs" /> + <project path="external/droiddriver" name="platform/external/droiddriver" groups="pdk" /> + <project path="external/drrickorang" name="platform/external/drrickorang" groups="pdk" /> + <project path="external/dtc" name="platform/external/dtc" groups="pdk"/> + <project path="external/e2fsprogs" name="platform/external/e2fsprogs" groups="pdk" /> + <project path="external/easymock" name="platform/external/easymock" groups="pdk" /> + <project path="external/eigen" name="platform/external/eigen" groups="pdk" /> + <project path="external/elfutils" name="platform/external/elfutils" groups="pdk" /> + <project path="external/emma" name="platform/external/emma" groups="pdk" /> + <project path="external/error_prone" name="platform/external/error_prone" groups="pdk" /> + <project path="external/esd" name="platform/external/esd" groups="pdk" /> + <project path="external/expat" name="platform/external/expat" groups="pdk" /> + <project path="external/eyes-free" name="platform/external/eyes-free" groups="pdk" /> + <project path="external/f2fs-tools" name="platform/external/f2fs-tools" groups="pdk" /> + <project path="external/fdlibm" name="platform/external/fdlibm" groups="pdk" /> + <project path="external/fec" name="platform/external/fec" groups="pdk" /> + <project path="external/flac" name="platform/external/flac" groups="pdk" /> + <project path="external/flatbuffers" name="platform/external/flatbuffers" groups="pdk" /> + <project path="external/fonttools" name="platform/external/fonttools" groups="pdk" /> + <project path="external/freetype" name="platform/external/freetype" groups="pdk" /> + <project path="external/fsck_msdos" name="platform/external/fsck_msdos" groups="pdk" /> + <project path="external/gemmlowp" name="platform/external/gemmlowp" groups="pdk" /> + <project path="external/gflags" name="platform/external/gflags" groups="pdk" /> + <project path="external/giflib" name="platform/external/giflib" groups="pdk,qcom_msm8x26" /> + <project path="external/glide" name="platform/external/glide" groups="pdk" /> + <project path="external/golang-protobuf" name="platform/external/golang-protobuf" groups="pdk" /> + <project path="external/google-benchmark" name="platform/external/google-benchmark" groups="pdk" /> + <project path="external/google-breakpad" name="platform/external/google-breakpad" groups="pdk-fs" /> + <project path="external/google-fonts/carrois-gothic-sc" name="platform/external/google-fonts/carrois-gothic-sc" groups="pdk" /> + <project path="external/google-fonts/coming-soon" name="platform/external/google-fonts/coming-soon" groups="pdk" /> + <project path="external/google-fonts/cutive-mono" name="platform/external/google-fonts/cutive-mono" groups="pdk" /> + <project path="external/google-fonts/dancing-script" name="platform/external/google-fonts/dancing-script" groups="pdk" /> + <project path="external/google-styleguide" name="platform/external/google-styleguide" groups="pdk" /> + <project path="external/google-tv-pairing-protocol" name="platform/external/google-tv-pairing-protocol" groups="pdk" /> + <project path="external/googletest" name="platform/external/googletest" groups="pdk" /> + <project path="external/gptfdisk" name="platform/external/gptfdisk" groups="pdk" /> + <project path="external/guava" name="platform/external/guava" groups="pdk" /> + <project path="external/guice" name="platform/external/guice" groups="pdk" /> + <project path="external/hamcrest" name="platform/external/hamcrest" groups="pdk" /> + <project path="external/harfbuzz_ng" name="platform/external/harfbuzz_ng" groups="pdk,qcom_msm8x26" /> + <project path="external/hyphenation-patterns" name="platform/external/hyphenation-patterns" groups="pdk" /> + <project path="external/icu" name="platform/external/icu" groups="pdk" /> + <project path="external/ImageMagick" name="platform/external/ImageMagick" groups="pdk" /> + <project path="external/ims" name="platform/external/ims" groups="pdk" /> + <project path="external/iproute2" name="platform/external/iproute2" groups="pdk" /> + <project path="external/ipsec-tools" name="platform/external/ipsec-tools" groups="pdk" /> + <project path="external/iptables" name="platform/external/iptables" groups="pdk" /> + <project path="external/iputils" name="platform/external/iputils" groups="pdk" /> + <project path="external/iw" name="platform/external/iw" groups="pdk" /> + <project path="external/jacoco" name="platform/external/jacoco" groups="pdk" /> + <project path="external/jarjar" name="platform/external/jarjar" groups="pdk" /> + <project path="external/javaparser" name="platform/external/javaparser" groups="pdk" /> + <project path="external/javasqlite" name="platform/external/javasqlite" groups="pdk" /> + <project path="external/javassist" name="platform/external/javassist" groups="pdk" /> + <project path="external/jcommander" name="platform/external/jcommander" groups="pdk" /> + <project path="external/jdiff" name="platform/external/jdiff" groups="pdk" /> + <project path="external/jemalloc" name="platform/external/jemalloc" groups="pdk" /> + <project path="external/jline" name="platform/external/jline" groups="pdk,tradefed,pdk-fs" /> + <project path="external/jmdns" name="platform/external/jmdns" groups="pdk" /> + <project path="external/jsilver" name="platform/external/jsilver" groups="pdk" /> + <project path="external/jsmn" name="platform/external/jsmn" groups="pdk" /> + <project path="external/jsoncpp" name="platform/external/jsoncpp" groups="pdk" /> + <project path="external/jsr305" name="platform/external/jsr305" groups="pdk" /> + <project path="external/jsr330" name="platform/external/jsr330" groups="pdk" /> + <project path="external/junit" name="platform/external/junit" groups="pdk" /> + <project path="external/junit-params" name="platform/external/junit-params" groups="pdk" /> + <project path="external/kernel-headers" name="platform/external/kernel-headers" groups="pdk" /> + <project path="external/kmod" name="platform/external/kmod" groups="pdk" /> + <project path="external/kotlinc" name="platform/external/kotlinc" groups="pdk" /> + <project path="external/ksoap2" name="platform/external/ksoap2" groups="pdk" /> + <project path="external/libavc" name="platform/external/libavc" groups="pdk" /> + <project path="external/libbackup" name="platform/external/libbackup" groups="pdk" /> + <project path="external/libbrillo" name="platform/external/libbrillo" groups="pdk" /> + <project path="external/libcap" name="platform/external/libcap" groups="pdk" /> + <project path="external/libcap-ng" name="platform/external/libcap-ng" groups="pdk" /> + <project path="external/libchrome" name="platform/external/libchrome" groups="pdk" /> + <project path="external/libconstrainedcrypto" name="platform/external/libconstrainedcrypto" groups="pdk" /> + <project path="external/libcups" name="platform/external/libcups" groups="pdk-cw-fs,pdk-fs" /> + <project path="external/libcxx" name="platform/external/libcxx" groups="pdk" /> + <project path="external/libcxxabi" name="platform/external/libcxxabi" groups="pdk" /> + <project path="external/libdaemon" name="platform/external/libdaemon" groups="pdk" /> + <project path="external/libdivsufsort" name="platform/external/libdivsufsort" groups="pdk" /> + <project path="external/libdrm" name="platform/external/libdrm" groups="pdk" /> + <project path="external/libedit" name="platform/external/libedit" groups="pdk" /> + <project path="external/libese" name="platform/external/libese" groups="pdk" /> + <project path="external/libevent" name="platform/external/libevent" groups="pdk" /> + <project path="external/libexif" name="platform/external/libexif" groups="pdk" /> + <project path="external/libgsm" name="platform/external/libgsm" groups="pdk" /> + <project path="external/libhevc" name="platform/external/libhevc" groups="pdk" /> + <project path="external/libjpeg-turbo" name="platform/external/libjpeg-turbo" groups="pdk" /> + <project path="external/libldac" name="platform/external/libldac" groups="pdk" /> + <project path="external/libmicrohttpd" name="platform/external/libmicrohttpd" groups="pdk" /> + <project path="external/libmpeg2" name="platform/external/libmpeg2" groups="pdk" /> + <project path="external/libmtp" name="platform/external/libmtp" groups="pdk" /> + <project path="external/libnetfilter_conntrack" name="platform/external/libnetfilter_conntrack" groups="pdk" /> + <project path="external/libnfnetlink" name="platform/external/libnfnetlink" groups="pdk" /> + <project path="external/libnl" name="platform/external/libnl" groups="pdk" /> + <project path="external/libogg" name="platform/external/libogg" groups="pdk" /> + <project path="external/libopus" name="platform/external/libopus" groups="pdk" /> + <project path="external/libpcap" name="platform/external/libpcap" groups="pdk" /> + <project path="external/libphonenumber" name="platform/external/libphonenumber" groups="pdk" /> + <project path="external/libpng" name="platform/external/libpng" groups="pdk" /> + <project path="external/libtextclassifier" name="platform/external/libtextclassifier" groups="pdk" /> + <project path="external/libunwind" name="platform/external/libunwind" groups="pdk" /> + <project path="external/libunwind_llvm" name="platform/external/libunwind_llvm" groups="pdk" /> + <project path="external/libusb" name="platform/external/libusb" groups="pdk" /> + <project path="external/libusb-compat" name="platform/external/libusb-compat" groups="pdk" /> + <project path="external/libvncserver" name="platform/external/libvncserver" groups="pdk" /> + <project path="external/libvorbis" name="platform/external/libvorbis" groups="pdk" /> + <project path="external/libvpx" name="platform/external/libvpx" groups="pdk" /> + <project path="external/libvterm" name="platform/external/libvterm" groups="pdk" /> + <project path="external/libxcam" name="platform/external/libxcam" groups="pdk" /> + <project path="external/libxml2" name="platform/external/libxml2" groups="pdk,libxml2" /> + <project path="external/libyuv" name="platform/external/libyuv" groups="pdk,libyuv" /> + <project path="external/linux-kselftest" name="platform/external/linux-kselftest" groups="vts,pdk" /> + <project path="external/lisa" name="platform/external/lisa" groups="pdk" /> + <project path="external/llvm" name="platform/external/llvm" groups="pdk" /> + <project path="external/lmfit" name="platform/external/lmfit" groups="pdk" /> + <project path="external/ltp" name="platform/external/ltp" groups="vts,pdk" /> + <project path="external/lz4" name="platform/external/lz4" groups="pdk" /> + <project path="external/lzma" name="platform/external/lzma" groups="pdk" /> + <project path="external/markdown" name="platform/external/markdown" groups="pdk" /> + <project path="external/mdnsresponder" name="platform/external/mdnsresponder" groups="pdk" /> + <project path="external/mesa3d" name="platform/external/mesa3d" groups="pdk-cw-fs,pdk-fs" /> + <project path="external/Microsoft-GSL" name="platform/external/Microsoft-GSL" groups="pdk" /> + <project path="external/minijail" name="platform/external/minijail" groups="pdk" /> + <project path="external/mksh" name="platform/external/mksh" groups="pdk" /> + <project path="external/mmc-utils" name="platform/external/mmc-utils" groups="pdk" /> + <project path="external/mockftpserver" name="platform/external/mockftpserver" groups="pdk" /> + <project path="external/mockito" name="platform/external/mockito" groups="pdk" /> + <project path="external/mockwebserver" name="platform/external/mockwebserver" groups="pdk" /> + <project path="external/modp_b64" name="platform/external/modp_b64" groups="pdk" /> + <project path="external/mp4parser" name="platform/external/mp4parser" groups="pdk" /> + <project path="external/mtpd" name="platform/external/mtpd" groups="pdk" /> + <project path="external/nanohttpd" name="platform/external/nanohttpd" groups="pdk" /> + <project path="external/nanopb-c" name="platform/external/nanopb-c" groups="pdk" /> + <project path="external/naver-fonts" name="platform/external/naver-fonts" groups="pdk" /> + <project path="external/neven" name="platform/external/neven" groups="pdk" /> + <project path="external/nfacct" name="platform/external/nfacct" groups="pdk" /> + <project path="external/nist-pkits" name="platform/external/nist-pkits" groups="pdk" /> + <project path="external/nist-sip" name="platform/external/nist-sip" groups="pdk" /> + <project path="external/noto-fonts" name="platform/external/noto-fonts" groups="pdk" /> + <project path="external/oauth" name="platform/external/oauth" groups="pdk" /> + <project path="external/objenesis" name="platform/external/objenesis" groups="pdk" /> + <project path="external/oj-libjdwp" name="platform/external/oj-libjdwp" groups="pdk" /> + <project path="external/okhttp" name="platform/external/okhttp" groups="pdk" /> + <project path="external/one-true-awk" name="platform/external/one-true-awk" groups="pdk" /> + <project path="external/opencv" name="platform/external/opencv" groups="pdk-cw-fs,pdk-fs" /> + <project path="external/owasp/sanitizer" name="platform/external/owasp/sanitizer" groups="pdk" /> + <project path="external/parameter-framework" name="platform/external/parameter-framework" groups="pdk" /> + <project path="external/pcre" name="platform/external/pcre" groups="pdk" /> + <project path="external/pdfium" name="platform/external/pdfium" groups="pdk" /> + <project path="external/perf_data_converter" name="platform/external/perf_data_converter" groups="pdk" /> + <project path="external/perfetto" name="platform/external/perfetto" groups="pdk" /> + <project path="external/piex" name="platform/external/piex" groups="pdk" /> + <project path="external/ply" name="platform/external/ply" groups="pdk" /> + <project path="external/ppp" name="platform/external/ppp" groups="pdk" /> + <project path="external/proguard" name="platform/external/proguard" groups="pdk" /> + <project path="external/protobuf" name="platform/external/protobuf" groups="pdk" /> + <project path="external/puffin" name="platform/external/puffin" groups="pdk" /> + <project path="external/python/appdirs" name="platform/external/python/appdirs" groups="vts,pdk" /> + <project path="external/python/cachetools" name="platform/external/python/cachetools" groups="vts,pdk" /> + <project path="external/python/cpython2" name="platform/external/python/cpython2" groups="pdk" /> + <project path="external/python/cpython3" name="platform/external/python/cpython3" groups="pdk" /> + <project path="external/python/dateutil" name="platform/external/python/dateutil" groups="pdk" /> + <project path="external/python/dill" name="platform/external/python/dill" groups="vts,pdk" /> + <project path="external/python/enum" name="platform/external/python/enum" groups="vts,pdk" /> + <project path="external/python/enum34" name="platform/external/python/enum34" groups="vts,pdk" /> + <project path="external/python/future" name="platform/external/python/future" groups="vts,pdk" /> + <project path="external/python/futures" name="platform/external/python/futures" groups="vts,pdk" /> + <project path="external/python/gapic-google-cloud-pubsub-v1" name="platform/external/python/gapic-google-cloud-pubsub-v1" groups="vts,pdk" /> + <project path="external/python/google-api-python-client" name="platform/external/python/google-api-python-client" groups="vts,pdk" /> + <project path="external/python/google-auth" name="platform/external/python/google-auth" groups="vts,pdk" /> + <project path="external/python/google-auth-httplib2" name="platform/external/python/google-auth-httplib2" groups="vts,pdk" /> + <project path="external/python/google-cloud-core" name="platform/external/python/google-cloud-core" groups="vts,pdk" /> + <project path="external/python/google-cloud-pubsub" name="platform/external/python/google-cloud-pubsub" groups="vts,pdk" /> + <project path="external/python/google-gax" name="platform/external/python/google-gax" groups="vts,pdk" /> + <project path="external/python/googleapis" name="platform/external/python/googleapis" groups="vts,pdk" /> + <project path="external/python/grpc-google-iam-v1" name="platform/external/python/grpc-google-iam-v1" groups="vts,pdk" /> + <project path="external/python/grpcio" name="platform/external/python/grpcio" groups="vts,pdk" /> + <project path="external/python/httplib2" name="platform/external/python/httplib2" groups="vts,pdk" /> + <project path="external/python/matplotlib" name="platform/external/python/matplotlib" groups="vts,pdk" /> + <project path="external/python/numpy" name="platform/external/python/numpy" groups="vts,pdk" /> + <project path="external/python/oauth2client" name="platform/external/python/oauth2client" groups="vts,pdk" /> + <project path="external/python/olefile" name="platform/external/python/olefile" groups="vts,pdk" /> + <project path="external/python/packaging" name="platform/external/python/packaging" groups="vts,pdk" /> + <project path="external/python/parse" name="platform/external/python/parse" groups="vts,pdk" /> + <project path="external/python/Pillow" name="platform/external/python/Pillow" groups="vts,pdk" /> + <project path="external/python/ply" name="platform/external/python/ply" groups="vts,pdk" /> + <project path="external/python/proto-google-cloud-pubsub-v1" name="platform/external/python/proto-google-cloud-pubsub-v1" groups="vts,pdk" /> + <project path="external/python/protobuf" name="platform/external/python/protobuf" groups="vts,pdk" /> + <project path="external/python/pyasn1" name="platform/external/python/pyasn1" groups="vts,pdk" /> + <project path="external/python/pyasn1-modules" name="platform/external/python/pyasn1-modules" groups="vts,pdk" /> + <project path="external/python/pyparsing" name="platform/external/python/pyparsing" groups="vts,pdk" /> + <project path="external/python/requests" name="platform/external/python/requests" groups="vts,pdk" /> + <project path="external/python/rsa" name="platform/external/python/rsa" groups="vts,pdk" /> + <project path="external/python/scipy" name="platform/external/python/scipy" groups="vts,pdk" /> + <project path="external/python/setuptools" name="platform/external/python/setuptools" groups="vts,pdk" /> + <project path="external/python/six" name="platform/external/python/six" groups="vts,pdk" /> + <project path="external/python/uritemplates" name="platform/external/python/uritemplates" groups="vts,pdk" /> + <project path="external/replicaisland" name="platform/external/replicaisland" groups="pdk" /> + <project path="external/rmi4utils" name="platform/external/rmi4utils" groups="pdk" /> + <project path="external/robolectric" name="platform/external/robolectric" groups="pdk-cw-fs,pdk-fs" /> + <project path="external/roboto-fonts" name="platform/external/roboto-fonts" groups="pdk" /> + <project path="external/rootdev" name="platform/external/rootdev" groups="pdk" /> + <project path="external/safe-iop" name="platform/external/safe-iop" groups="pdk" /> + <project path="external/scapy" name="platform/external/scapy" groups="pdk-fs" /> + <project path="external/scrypt" name="platform/external/scrypt" groups="pdk" /> + <project path="external/seccomp-tests" name="platform/external/seccomp-tests" groups="pdk" /> + <project path="external/selinux" name="platform/external/selinux" groups="pdk" /> + <project path="external/sfntly" name="platform/external/sfntly" groups="pdk,qcom_msm8x26" /> + <project path="external/shaderc/spirv-headers" name="platform/external/shaderc/spirv-headers" groups="pdk" /> + <project path="external/shflags" name="platform/external/shflags" groups="pdk" /> + <project path="external/skia" name="platform/external/skia" groups="pdk,qcom_msm8x26" /> + <project path="external/sl4a" name="platform/external/sl4a" groups="pdk" /> + <project path="external/slf4j" name="platform/external/slf4j" groups="pdk" /> + <project path="external/smali" name="platform/external/smali" groups="pdk" /> + <project path="external/snakeyaml" name="platform/external/snakeyaml" groups="pdk" /> + <project path="external/sonic" name="platform/external/sonic" groups="pdk" /> + <project path="external/sonivox" name="platform/external/sonivox" groups="pdk" /> + <project path="external/speex" name="platform/external/speex" groups="pdk" /> + <project path="external/spirv-llvm" name="platform/external/spirv-llvm" groups="pdk" /> + <project path="external/sqlite" name="platform/external/sqlite" groups="pdk" /> + <project path="external/squashfs-tools" name="platform/external/squashfs-tools" groups="pdk" /> + <project path="external/strace" name="platform/external/strace" groups="pdk" /> + <project path="external/stressapptest" name="platform/external/stressapptest" groups="pdk" /> + <project path="external/subsampling-scale-image-view" name="platform/external/subsampling-scale-image-view" clone-depth="1" /> + <project path="external/swiftshader" name="platform/external/swiftshader" groups="pdk" /> + <project path="external/syslinux" name="platform/external/syslinux" groups="pdk" /> + <project path="external/tagsoup" name="platform/external/tagsoup" groups="pdk" /> + <project path="external/tcpdump" name="platform/external/tcpdump" groups="pdk" /> + <project path="external/tensorflow" name="platform/external/tensorflow" groups="pdk" /> + <project path="external/testng" name="platform/external/testng" groups="pdk" /> + <project path="external/tinyalsa" name="platform/external/tinyalsa" groups="pdk" /> + <project path="external/tinycompress" name="platform/external/tinycompress" groups="pdk" /> + <project path="external/tinyxml" name="platform/external/tinyxml" groups="pdk" /> + <project path="external/tinyxml2" name="platform/external/tinyxml2" groups="pdk" /> + <project path="external/toolchain-utils" name="platform/external/toolchain-utils" /> + <project path="external/toybox" name="platform/external/toybox" groups="pdk" /> + <project path="external/tpm2" name="platform/external/tpm2" groups="pdk" /> + <project path="external/trappy" name="platform/external/trappy" groups="pdk" /> + <project path="external/tremolo" name="platform/external/tremolo" groups="pdk" /> + <project path="external/turbine" name="platform/external/turbine" groups="pdk" /> + <project path="external/unicode" name="platform/external/unicode" groups="pdk" /> + <project path="external/universal-tween-engine" name="platform/external/universal-tween-engine" /> + <project path="external/v4l2_codec2" name="platform/external/v4l2_codec2" groups="pdk" /> + <project path="external/v8" name="platform/external/v8" groups="pdk" /> + <project path="external/valgrind" name="platform/external/valgrind" groups="pdk" /> + <project path="external/vboot_reference" name="platform/external/vboot_reference" groups="vboot,pdk-fs" /> + <project path="external/vixl" name="platform/external/vixl" groups="pdk" /> + <project path="external/vogar" name="platform/external/vogar" groups="pdk" /> + <project path="external/volley" name="platform/external/volley" groups="pdk" /> + <project path="external/vulkan-validation-layers" name="platform/external/vulkan-validation-layers" groups="pdk" /> + <project path="external/walt" name="platform/external/walt" groups="pdk" /> + <project path="external/webp" name="platform/external/webp" groups="pdk,qcom_msm8x26" /> + <project path="external/webrtc" name="platform/external/webrtc" groups="pdk" /> + <project path="external/webview_support_interfaces" name="platform/external/webview_support_interfaces" groups="pdk" /> + <project path="external/wpa_supplicant_8" name="platform/external/wpa_supplicant_8" groups="pdk" /> + <project path="external/wycheproof" name="platform/external/wycheproof" groups="pdk" /> + <project path="external/x264" name="platform/external/x264" groups="pdk" /> + <project path="external/xmlrpcpp" name="platform/external/xmlrpcpp" groups="pdk" /> + <project path="external/xmp_toolkit" name="platform/external/xmp_toolkit" groups="pdk" /> + <project path="external/xz-embedded" name="platform/external/xz-embedded" groups="pdk" /> + <project path="external/zlib" name="platform/external/zlib" groups="pdk" /> + <project path="external/zopfli" name="platform/external/zopfli" groups="pdk" /> + <project path="external/zxing" name="platform/external/zxing" groups="pdk" /> + <project path="frameworks/av" name="platform/frameworks/av" groups="pdk" /> + <project path="frameworks/base" name="platform/frameworks/base" groups="pdk-cw-fs,pdk-fs" /> + <project path="frameworks/compile/libbcc" name="platform/frameworks/compile/libbcc" groups="pdk" /> + <project path="frameworks/compile/mclinker" name="platform/frameworks/compile/mclinker" groups="pdk" /> + <project path="frameworks/compile/slang" name="platform/frameworks/compile/slang" groups="pdk" /> + <project path="frameworks/data-binding" name="platform/frameworks/data-binding" groups="pdk-cw-fs,pdk-fs" /> + <project path="frameworks/ex" name="platform/frameworks/ex" groups="pdk-cw-fs,pdk-fs" /> + <project path="frameworks/hardware/interfaces" name="platform/frameworks/hardware/interfaces" groups="pdk" /> + <project path="frameworks/layoutlib" name="platform/frameworks/layoutlib" groups="pdk-cw-fs,pdk-fs" /> + <project path="frameworks/minikin" name="platform/frameworks/minikin" groups="pdk-cw-fs,pdk-fs" /> + <project path="frameworks/ml" name="platform/frameworks/ml" groups="pdk" /> + <project path="frameworks/multidex" name="platform/frameworks/multidex" groups="pdk-cw-fs,pdk-fs" /> + <project path="frameworks/native" name="platform/frameworks/native" groups="pdk" /> + <project path="frameworks/opt/bitmap" name="platform/frameworks/opt/bitmap" groups="pdk-fs" /> + <project path="frameworks/opt/calendar" name="platform/frameworks/opt/calendar" groups="pdk-cw-fs,pdk-fs" /> + <project path="frameworks/opt/car/services" name="platform/frameworks/opt/car/services" groups="pdk-fs" /> + <project path="frameworks/opt/chips" name="platform/frameworks/opt/chips" groups="pdk-cw-fs,pdk-fs" /> + <project path="frameworks/opt/colorpicker" name="platform/frameworks/opt/colorpicker" groups="pdk-cw-fs,pdk-fs" /> + <project path="frameworks/opt/datetimepicker" name="platform/frameworks/opt/datetimepicker" groups="pdk-cw-fs,pdk-fs" /> + <project path="frameworks/opt/inputmethodcommon" name="platform/frameworks/opt/inputmethodcommon" groups="pdk-cw-fs,pdk-fs" /> + <project path="frameworks/opt/net/ethernet" name="platform/frameworks/opt/net/ethernet" groups="pdk-fs" /> + <project path="frameworks/opt/net/ims" name="platform/frameworks/opt/net/ims" groups="frameworks_ims,pdk-cw-fs,pdk-fs" /> + <project path="frameworks/opt/net/lowpan" name="platform/frameworks/opt/net/lowpan" groups="pdk-fs" /> + <project path="frameworks/opt/net/voip" name="platform/frameworks/opt/net/voip" groups="pdk-cw-fs,pdk-fs" /> + <project path="frameworks/opt/net/wifi" name="platform/frameworks/opt/net/wifi" groups="pdk" /> + <project path="frameworks/opt/photoviewer" name="platform/frameworks/opt/photoviewer" groups="pdk-cw-fs,pdk-fs" /> + <project path="frameworks/opt/setupwizard" name="platform/frameworks/opt/setupwizard" groups="pdk-cw-fs,pdk-fs" /> + <project path="frameworks/opt/telephony" name="platform/frameworks/opt/telephony" groups="pdk" /> + <project path="frameworks/opt/timezonepicker" name="platform/frameworks/opt/timezonepicker" groups="pdk-cw-fs,pdk-fs" /> + <project path="frameworks/opt/vcard" name="platform/frameworks/opt/vcard" groups="pdk-cw-fs,pdk-fs" /> + <project path="frameworks/rs" name="platform/frameworks/rs" groups="pdk" /> + <project path="frameworks/support" name="platform/frameworks/support" groups="pdk-cw-fs,pdk-fs" /> + <project path="frameworks/webview" name="platform/frameworks/webview" groups="pdk-cw-fs,pdk-fs" /> + <project path="frameworks/wilhelm" name="platform/frameworks/wilhelm" groups="pdk-cw-fs,pdk-fs" /> + <project path="hardware/akm" name="platform/hardware/akm" groups="pdk" /> + <project path="hardware/broadcom/libbt" name="platform/hardware/broadcom/libbt" groups="pdk" /> + <project path="hardware/broadcom/wlan" name="platform/hardware/broadcom/wlan" groups="pdk,broadcom_wlan" /> + <project path="hardware/google/apf" name="platform/hardware/google/apf" groups="pdk" /> + <project path="hardware/google/easel" name="platform/hardware/google/easel" groups="pdk,easel" /> + <project path="hardware/google/interfaces" name="platform/hardware/google/interfaces" groups="pdk" /> + <project path="hardware/intel/audio_media" name="platform/hardware/intel/audio_media" groups="intel,pdk" /> + <project path="hardware/intel/bootstub" name="platform/hardware/intel/bootstub" groups="intel,pdk" /> + <project path="hardware/intel/common/libmix" name="platform/hardware/intel/common/libmix" groups="intel,pdk" /> + <project path="hardware/intel/common/libstagefrighthw" name="platform/hardware/intel/common/libstagefrighthw" groups="intel,pdk" /> + <project path="hardware/intel/common/libva" name="platform/hardware/intel/common/libva" groups="intel,pdk" /> + <project path="hardware/intel/common/libwsbm" name="platform/hardware/intel/common/libwsbm" groups="intel,pdk" /> + <project path="hardware/intel/common/omx-components" name="platform/hardware/intel/common/omx-components" groups="intel,pdk" /> + <project path="hardware/intel/common/utils" name="platform/hardware/intel/common/utils" groups="intel,pdk" /> + <project path="hardware/intel/common/wrs_omxil_core" name="platform/hardware/intel/common/wrs_omxil_core" groups="intel,pdk" /> + <project path="hardware/intel/img/hwcomposer" name="platform/hardware/intel/img/hwcomposer" groups="intel,pdk" /> + <project path="hardware/intel/img/psb_headers" name="platform/hardware/intel/img/psb_headers" groups="intel,pdk" /> + <project path="hardware/intel/img/psb_video" name="platform/hardware/intel/img/psb_video" groups="intel,pdk" /> + <project path="hardware/interfaces" name="platform/hardware/interfaces" groups="pdk" /> + <project path="hardware/invensense" name="platform/hardware/invensense" groups="invensense,pdk" /> + <project path="hardware/libhardware" name="platform/hardware/libhardware" groups="pdk" /> + <project path="hardware/libhardware_legacy" name="platform/hardware/libhardware_legacy" groups="pdk" /> + <project path="hardware/marvell/bt" name="platform/hardware/marvell/bt" groups="marvell_bt,pdk" /> + <project path="hardware/nxp/nfc" name="platform/hardware/nxp/nfc" groups="pdk" /> + <project path="hardware/nxp/secure_element" name="platform/hardware/nxp/secure_element" groups="pdk" /> + <project path="hardware/qcom/audio" name="platform/hardware/qcom/audio" groups="qcom,qcom_audio,pdk" /> + <project path="hardware/qcom/bootctrl" name="platform/hardware/qcom/bootctrl" groups="pdk" /> + <project path="hardware/qcom/bt" name="platform/hardware/qcom/bt" groups="qcom,pdk" /> + <project path="hardware/qcom/camera" name="platform/hardware/qcom/camera" groups="qcom_camera,pdk" /> + <project path="hardware/qcom/data/ipacfg-mgr" name="platform/hardware/qcom/data/ipacfg-mgr" groups="qcom,pdk" /> + <project path="hardware/qcom/display" name="platform/hardware/qcom/display" groups="pdk,qcom,qcom_display" /> + <project path="hardware/qcom/gps" name="platform/hardware/qcom/gps" groups="qcom,qcom_gps,pdk" /> + <project path="hardware/qcom/keymaster" name="platform/hardware/qcom/keymaster" groups="qcom,qcom_keymaster,pdk" /> + <project path="hardware/qcom/media" name="platform/hardware/qcom/media" groups="qcom,pdk" /> + <project path="hardware/qcom/msm8960" name="platform/hardware/qcom/msm8960" groups="qcom_msm8960,pdk" /> + <project path="hardware/qcom/msm8994" name="platform/hardware/qcom/msm8994" groups="qcom_msm8994,pdk" /> + <project path="hardware/qcom/msm8996" name="platform/hardware/qcom/msm8996" groups="qcom_msm8996,pdk" /> + <project path="hardware/qcom/msm8998" name="platform/hardware/qcom/msm8998" groups="qcom_msm8998,pdk" /> + <project path="hardware/qcom/msm8x09" name="platform/hardware/qcom/msm8x09" groups="qcom_msm8x09" /> + <project path="hardware/qcom/msm8x26" name="platform/hardware/qcom/msm8x26" groups="qcom_msm8x26,pdk" /> + <project path="hardware/qcom/msm8x27" name="platform/hardware/qcom/msm8x27" groups="qcom_msm8x27,pdk" /> + <project path="hardware/qcom/msm8x84" name="platform/hardware/qcom/msm8x84" groups="qcom_msm8x84,pdk" /> + <project path="hardware/qcom/neuralnetworks/hvxservice" name="platform/hardware/qcom/neuralnetworks/hvxservice" groups="wahoo" /> + <project path="hardware/qcom/power" name="platform/hardware/qcom/power" groups="qcom,pdk" /> + <project path="hardware/qcom/wlan" name="platform/hardware/qcom/wlan" groups="qcom_wlan,pdk" /> + <project path="hardware/ril" name="platform/hardware/ril" groups="pdk" /> + <project path="hardware/st/nfc" name="platform/hardware/st/nfc" groups="pdk" /> + <project path="kernel/configs" name="kernel/configs" groups="vts,pdk" /> + <project path="kernel/tests" name="kernel/tests" /> + <project path="libcore" name="platform/libcore" groups="pdk" /> + <project path="libnativehelper" name="platform/libnativehelper" groups="pdk" /> + <project path="packages/apps/BasicSmsReceiver" name="platform/packages/apps/BasicSmsReceiver" groups="pdk-cw-fs,pdk-fs" /> + <project path="packages/apps/Bluetooth" name="platform/packages/apps/Bluetooth" groups="pdk-cw-fs,pdk-fs" /> + <project path="packages/apps/Browser2" name="platform/packages/apps/Browser2" groups="pdk-fs" /> + <project path="packages/apps/Calendar" name="platform/packages/apps/Calendar" groups="pdk-fs" /> + <project path="packages/apps/Camera2" name="platform/packages/apps/Camera2" groups="pdk-fs" /> + <project path="packages/apps/Car/Dialer" name="platform/packages/apps/Car/Dialer" groups="pdk-fs" /> + <project path="packages/apps/Car/Hvac" name="platform/packages/apps/Car/Hvac" groups="pdk-fs" /> + <project path="packages/apps/Car/LatinIME" name="platform/packages/apps/Car/LatinIME" groups="pdk-fs" /> + <project path="packages/apps/Car/Launcher" name="platform/packages/apps/Car/Launcher" groups="pdk-fs" /> + <project path="packages/apps/Car/LensPicker" name="platform/packages/apps/Car/LensPicker" groups="pdk-fs" /> + <project path="packages/apps/Car/libs" name="platform/packages/apps/Car/libs" groups="pdk-fs" /> + <project path="packages/apps/Car/LocalMediaPlayer" name="platform/packages/apps/Car/LocalMediaPlayer" groups="pdk-fs" /> + <project path="packages/apps/Car/Media" name="platform/packages/apps/Car/Media" groups="pdk-fs" /> + <project path="packages/apps/Car/Messenger" name="platform/packages/apps/Car/Messenger" groups="pdk-fs" /> + <project path="packages/apps/Car/Overview" name="platform/packages/apps/Car/Overview" groups="pdk-fs" /> + <project path="packages/apps/Car/Radio" name="platform/packages/apps/Car/Radio" groups="pdk-fs" /> + <project path="packages/apps/Car/Settings" name="platform/packages/apps/Car/Settings" groups="pdk-fs" /> + <project path="packages/apps/Car/Stream" name="platform/packages/apps/Car/Stream" groups="pdk-fs" /> + <project path="packages/apps/Car/SystemUpdater" name="platform/packages/apps/Car/SystemUpdater" groups="pdk-fs" /> + <project path="packages/apps/CarrierConfig" name="platform/packages/apps/CarrierConfig" groups="pdk-cw-fs,pdk-fs" /> + <project path="packages/apps/CellBroadcastReceiver" name="platform/packages/apps/CellBroadcastReceiver" groups="pdk-cw-fs,pdk-fs" /> + <project path="packages/apps/CertInstaller" name="platform/packages/apps/CertInstaller" groups="pdk-cw-fs,pdk-fs" /> + <project path="packages/apps/Contacts" name="platform/packages/apps/Contacts" groups="pdk-fs" /> + <project path="packages/apps/DeskClock" name="platform/packages/apps/DeskClock" groups="pdk-fs" /> + <project path="packages/apps/DevCamera" name="platform/packages/apps/DevCamera" groups="pdk" /> + <project path="packages/apps/Dialer" name="platform/packages/apps/Dialer" groups="pdk-fs" /> + <project path="packages/apps/DocumentsUI" name="platform/packages/apps/DocumentsUI" groups="pdk-cw-fs,pdk-fs" /> + <project path="packages/apps/Email" name="platform/packages/apps/Email" groups="pdk-fs" /> + <project path="packages/apps/EmergencyInfo" name="platform/packages/apps/EmergencyInfo" groups="pdk-fs" /> + <project path="packages/apps/ExactCalculator" name="platform/packages/apps/ExactCalculator" groups="pdk-fs" /> + <project path="packages/apps/Gallery" name="platform/packages/apps/Gallery" groups="pdk-fs" /> + <project path="packages/apps/Gallery2" name="platform/packages/apps/Gallery2" groups="pdk-fs" /> + <project path="packages/apps/HTMLViewer" name="platform/packages/apps/HTMLViewer" groups="pdk-fs" /> + <project path="packages/apps/KeyChain" name="platform/packages/apps/KeyChain" groups="pdk-fs" /> + <project path="packages/apps/Launcher2" name="platform/packages/apps/Launcher2" groups="pdk-fs" /> + <project path="packages/apps/Launcher3" name="platform/packages/apps/Launcher3" groups="pdk-fs" /> + <project path="packages/apps/LegacyCamera" name="platform/packages/apps/LegacyCamera" groups="pdk-fs" /> + <project path="packages/apps/ManagedProvisioning" name="platform/packages/apps/ManagedProvisioning" groups="pdk-fs" /> + <project path="packages/apps/Messaging" name="platform/packages/apps/Messaging" groups="pdk-fs" /> + <project path="packages/apps/Music" name="platform/packages/apps/Music" groups="pdk-fs" /> + <project path="packages/apps/MusicFX" name="platform/packages/apps/MusicFX" groups="pdk-fs" /> + <project path="packages/apps/Nfc" name="platform/packages/apps/Nfc" groups="apps_nfc,pdk-fs" /> + <project path="packages/apps/OneTimeInitializer" name="platform/packages/apps/OneTimeInitializer" groups="pdk-fs" /> + <project path="packages/apps/PackageInstaller" name="platform/packages/apps/PackageInstaller" groups="pdk-cw-fs,pdk-fs" /> + <project path="packages/apps/PhoneCommon" name="platform/packages/apps/PhoneCommon" groups="pdk-cw-fs,pdk-fs" /> + <project path="packages/apps/Protips" name="platform/packages/apps/Protips" groups="pdk-fs" /> + <project path="packages/apps/Provision" name="platform/packages/apps/Provision" groups="pdk-fs" /> + <project path="packages/apps/QuickSearchBox" name="platform/packages/apps/QuickSearchBox" groups="pdk-fs" /> + <project path="packages/apps/SafetyRegulatoryInfo" name="platform/packages/apps/SafetyRegulatoryInfo" groups="pdk-fs" /> + <project path="packages/apps/SecureElement" name="platform/packages/apps/SecureElement" groups="apps_se,pdk-fs" /> + <project path="packages/apps/Settings" name="platform/packages/apps/Settings" groups="pdk-fs" /> + <project path="packages/apps/SoundRecorder" name="platform/packages/apps/SoundRecorder" groups="pdk-fs" /> + <project path="packages/apps/SpareParts" name="platform/packages/apps/SpareParts" groups="pdk-fs" /> + <project path="packages/apps/Stk" name="platform/packages/apps/Stk" groups="apps_stk,pdk-fs" /> + <project path="packages/apps/StorageManager" name="platform/packages/apps/StorageManager" groups="pdk-fs" /> + <project path="packages/apps/Tag" name="platform/packages/apps/Tag" groups="pdk-fs" /> + <project path="packages/apps/Terminal" name="platform/packages/apps/Terminal" groups="pdk-fs" /> + <project path="packages/apps/Test/connectivity" name="platform/packages/apps/Test/connectivity" groups="pdk" /> + <project path="packages/apps/TimeZoneData" name="platform/packages/apps/TimeZoneData" groups="pdk" /> + <project path="packages/apps/TimeZoneUpdater" name="platform/packages/apps/TimeZoneUpdater" groups="pdk" /> + <project path="packages/apps/Traceur" name="platform/packages/apps/Traceur" groups="pdk-fs" /> + <project path="packages/apps/TvSettings" name="platform/packages/apps/TvSettings" groups="pdk-fs" /> + <project path="packages/apps/TV" name="platform/packages/apps/TV" /> + <project path="packages/apps/UnifiedEmail" name="platform/packages/apps/UnifiedEmail" groups="pdk-fs" /> + <project path="packages/apps/WallpaperPicker" name="platform/packages/apps/WallpaperPicker" groups="pdk-fs" /> + <project path="packages/experimental" name="platform/packages/experimental" /> + <project path="packages/inputmethods/LatinIME" name="platform/packages/inputmethods/LatinIME" groups="pdk-fs" /> + <project path="packages/inputmethods/OpenWnn" name="platform/packages/inputmethods/OpenWnn" groups="pdk-fs" /> + <project path="packages/providers/ApplicationsProvider" name="platform/packages/providers/ApplicationsProvider" groups="pdk-fs" /> + <project path="packages/providers/BlockedNumberProvider" name="platform/packages/providers/BlockedNumberProvider" groups="pdk-fs" /> + <project path="packages/providers/BookmarkProvider" name="platform/packages/providers/BookmarkProvider" groups="pdk-fs" /> + <project path="packages/providers/CalendarProvider" name="platform/packages/providers/CalendarProvider" groups="pdk-cw-fs,pdk-fs" /> + <project path="packages/providers/CallLogProvider" name="platform/packages/providers/CallLogProvider" groups="pdk-fs" /> + <project path="packages/providers/ContactsProvider" name="platform/packages/providers/ContactsProvider" groups="pdk-cw-fs,pdk-fs" /> + <project path="packages/providers/DownloadProvider" name="platform/packages/providers/DownloadProvider" groups="pdk-cw-fs,pdk-fs" /> + <project path="packages/providers/MediaProvider" name="platform/packages/providers/MediaProvider" groups="pdk-cw-fs,pdk-fs" /> + <project path="packages/providers/PartnerBookmarksProvider" name="platform/packages/providers/PartnerBookmarksProvider" groups="pdk-fs" /> + <project path="packages/providers/TelephonyProvider" name="platform/packages/providers/TelephonyProvider" groups="pdk-cw-fs,pdk-fs" /> + <project path="packages/providers/TvProvider" name="platform/packages/providers/TvProvider" groups="pdk-fs" /> + <project path="packages/providers/UserDictionaryProvider" name="platform/packages/providers/UserDictionaryProvider" groups="pdk-cw-fs,pdk-fs" /> + <project path="packages/screensavers/Basic" name="platform/packages/screensavers/Basic" groups="pdk-fs" /> + <project path="packages/screensavers/PhotoTable" name="platform/packages/screensavers/PhotoTable" groups="pdk-fs" /> + <project path="packages/screensavers/WebView" name="platform/packages/screensavers/WebView" groups="pdk-fs" /> + <project path="packages/services/BuiltInPrintService" name="platform/packages/services/BuiltInPrintService" groups="pdk-cw-fs,pdk-fs" /> + <project path="packages/services/Car" name="platform/packages/services/Car" groups="pdk-cw-fs,pdk-fs" /> + <project path="packages/services/Mms" name="platform/packages/services/Mms" groups="pdk-cw-fs,pdk-fs" /> + <project path="packages/services/NetworkRecommendation" name="platform/packages/services/NetworkRecommendation" groups="pdk-fs" /> + <project path="packages/services/Telecomm" name="platform/packages/services/Telecomm" groups="pdk-cw-fs,pdk-fs" /> + <project path="packages/services/Telephony" name="platform/packages/services/Telephony" groups="pdk-cw-fs,pdk-fs" /> + <project path="packages/wallpapers/LivePicker" name="platform/packages/wallpapers/LivePicker" groups="pdk-fs" /> + <project path="pdk" name="platform/pdk" groups="pdk" /> + <project path="platform_testing" name="platform/platform_testing" groups="pdk-fs,pdk-cw-fs,cts" /> + <project path="prebuilts/abi-dumps/ndk" name="platform/prebuilts/abi-dumps/ndk" groups="pdk-fs" clone-depth="1" /> + <project path="prebuilts/abi-dumps/vndk" name="platform/prebuilts/abi-dumps/vndk" groups="pdk-fs" clone-depth="1" /> + <project path="prebuilts/android-emulator" name="platform/prebuilts/android-emulator" groups="pdk-fs" clone-depth="1" /> + <project path="prebuilts/build-tools" name="platform/prebuilts/build-tools" groups="pdk" clone-depth="1" /> + <project path="prebuilts/checkstyle" name="platform/prebuilts/checkstyle" groups="pdk" clone-depth="1" /> + <project path="prebuilts/clang-tools" name="platform/prebuilts/clang-tools" groups="pdk" clone-depth="1" /> + <project path="prebuilts/clang/host/darwin-x86" name="platform/prebuilts/clang/host/darwin-x86" groups="pdk,darwin" clone-depth="1" /> + <project path="prebuilts/clang/host/linux-x86" name="platform/prebuilts/clang/host/linux-x86" groups="pdk" clone-depth="1" /> + <project path="prebuilts/deqp" name="platform/prebuilts/deqp" groups="pdk-fs" clone-depth="1" /> + <project path="prebuilts/devtools" name="platform/prebuilts/devtools" groups="pdk-fs" clone-depth="1" /> + <project path="prebuilts/gcc/darwin-x86/aarch64/aarch64-linux-android-4.9" name="platform/prebuilts/gcc/darwin-x86/aarch64/aarch64-linux-android-4.9" groups="pdk,darwin,arm" clone-depth="1" /> + <project path="prebuilts/gcc/darwin-x86/arm/arm-linux-androideabi-4.9" name="platform/prebuilts/gcc/darwin-x86/arm/arm-linux-androideabi-4.9" groups="pdk,darwin,arm" clone-depth="1" /> + <project path="prebuilts/gcc/darwin-x86/host/i686-apple-darwin-4.2.1" name="platform/prebuilts/gcc/darwin-x86/host/i686-apple-darwin-4.2.1" groups="pdk,darwin" clone-depth="1" /> + <project path="prebuilts/gcc/darwin-x86/mips/mips64el-linux-android-4.9" name="platform/prebuilts/gcc/darwin-x86/mips/mips64el-linux-android-4.9" groups="pdk,darwin,mips" clone-depth="1" /> + <project path="prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.9" name="platform/prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.9" groups="pdk,darwin,x86" clone-depth="1" /> + <project path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9" groups="pdk,linux,arm" clone-depth="1" /> + <project path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9" groups="pdk,linux,arm" clone-depth="1" /> + <project path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8" groups="pdk,linux" clone-depth="1" /> + <project path="prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8" name="platform/prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8" groups="pdk-fs" clone-depth="1" /> + <project path="prebuilts/gcc/linux-x86/mips/mips64el-linux-android-4.9" name="platform/prebuilts/gcc/linux-x86/mips/mips64el-linux-android-4.9" groups="pdk,linux,mips" clone-depth="1" /> + <project path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9" name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9" groups="pdk,linux,x86" clone-depth="1" /> + <project path="prebuilts/gdb/darwin-x86" name="platform/prebuilts/gdb/darwin-x86" groups="darwin" clone-depth="1" /> + <project path="prebuilts/gdb/linux-x86" name="platform/prebuilts/gdb/linux-x86" groups="linux" clone-depth="1" /> + <project path="prebuilts/go/darwin-x86" name="platform/prebuilts/go/darwin-x86" groups="darwin,pdk,tradefed" clone-depth="1" /> + <project path="prebuilts/go/linux-x86" name="platform/prebuilts/go/linux-x86" groups="linux,pdk,tradefed" clone-depth="1" /> + <project path="prebuilts/gradle-plugin" name="platform/prebuilts/gradle-plugin" groups="pdk-cw-fs,pdk-fs" clone-depth="1" /> + <project path="prebuilts/jdk/jdk8" name="platform/prebuilts/jdk/jdk8" groups="pdk" clone-depth="1" /> + <project path="prebuilts/jdk/jdk9" name="platform/prebuilts/jdk/jdk9" groups="pdk" clone-depth="1" /> + <project path="prebuilts/libs/libedit" name="platform/prebuilts/libs/libedit" groups="pdk-cw-fs,pdk-fs" clone-depth="1" /> + <project path="prebuilts/maven_repo/android" name="platform/prebuilts/maven_repo/android" groups="pdk-cw-fs,pdk-fs" clone-depth="1" /> + <project path="prebuilts/maven_repo/bumptech" name="platform/prebuilts/maven_repo/bumptech" groups="pdk-cw-fs,pdk-fs" clone-depth="1" /> + <project path="prebuilts/maven_repo/google-play-service-client-libraries-3p" name="platform/prebuilts/maven_repo/google-play-service-client-libraries-3p" clone-depth="1" /> + <project path="prebuilts/misc" name="platform/prebuilts/misc" groups="pdk" clone-depth="1" /> + <project path="prebuilts/ndk" name="platform/prebuilts/ndk" groups="pdk" clone-depth="1" /> + <project path="prebuilts/python/darwin-x86/2.7.5" name="platform/prebuilts/python/darwin-x86/2.7.5" groups="darwin,pdk,pdk-cw-fs,pdk-fs" clone-depth="1" /> + <project path="prebuilts/python/linux-x86/2.7.5" name="platform/prebuilts/python/linux-x86/2.7.5" groups="linux,pdk,pdk-cw-fs,pdk-fs" clone-depth="1" /> + <project path="prebuilts/qemu-kernel" name="platform/prebuilts/qemu-kernel" groups="pdk" clone-depth="1" /> + <project path="prebuilts/r8" name="platform/prebuilts/r8" groups="pdk" clone-depth="1" /> + <project path="prebuilts/sdk" name="platform/prebuilts/sdk" groups="pdk" clone-depth="1" /> + <project path="prebuilts/tools" name="platform/prebuilts/tools" groups="pdk,tools" clone-depth="1" /> + <project path="sdk" name="platform/sdk" groups="pdk-cw-fs,pdk-fs" /> + <project path="system/bt" name="platform/system/bt" groups="pdk" /> + <project path="system/ca-certificates" name="platform/system/ca-certificates" groups="pdk" /> + <project path="system/chre" name="platform/system/chre" groups="pdk" /> + <project path="system/connectivity/wificond" name="platform/system/connectivity/wificond" groups="pdk" /> + <project path="system/connectivity/wifilogd" name="platform/system/connectivity/wifilogd" groups="pdk" /> + <project path="system/core" name="platform/system/core" groups="pdk" /> + <project path="system/extras" name="platform/system/extras" groups="pdk" /> + <project path="system/gatekeeper" name="platform/system/gatekeeper" groups="pdk" /> + <project path="system/hardware/interfaces" name="platform/system/hardware/interfaces" groups="pdk" /> + <project path="system/hwservicemanager" name="platform/system/hwservicemanager" groups="pdk" /> + <project path="system/iot/attestation" name="platform/system/iot/attestation" groups="pdk" /> + <project path="system/keymaster" name="platform/system/keymaster" groups="pdk" /> + <project path="system/libfmq" name="platform/system/libfmq" groups="pdk" /> + <project path="system/libhidl" name="platform/system/libhidl" groups="pdk" /> + <project path="system/libhwbinder" name="platform/system/libhwbinder" groups="pdk" /> + <project path="system/libufdt" name="platform/system/libufdt" groups="pdk" /> + <project path="system/libvintf" name="platform/system/libvintf" groups="pdk" /> + <project path="system/media" name="platform/system/media" groups="pdk" /> + <project path="system/netd" name="platform/system/netd" groups="pdk" /> + <project path="system/nfc" name="platform/system/nfc" groups="pdk" /> + <project path="system/nvram" name="platform/system/nvram" groups="pdk" /> + <project path="system/security" name="platform/system/security" groups="pdk" /> + <project path="system/sepolicy" name="platform/system/sepolicy" groups="pdk" /> + <project path="system/timezone" name="platform/system/timezone" groups="pdk" /> + <project path="system/tools/aidl" name="platform/system/tools/aidl" groups="pdk-cw-fs,pdk-fs" /> + <project path="system/tools/bpt" name="platform/system/tools/bpt" groups="pdk" /> + <project path="system/tools/hidl" name="platform/system/tools/hidl" groups="pdk" /> + <project path="system/update_engine" name="platform/system/update_engine" groups="pdk" /> + <project path="system/vold" name="platform/system/vold" groups="pdk" /> + <project path="test/framework" name="platform/test/framework" groups="vts,pdk" /> + <project path="test/mlts/benchmark" name="platform/test/mlts/benchmark" groups="pdk" /> + <project path="test/mlts/models" name="platform/test/mlts/models" groups="pdk" /> + <project path="test/sts" name="platform/test/sts" groups="sts,pdk" /> + <project path="test/vti/alert" name="platform/test/vti/alert" groups="vts,pdk" /> + <project path="test/vti/dashboard" name="platform/test/vti/dashboard" groups="vts,pdk" /> + <project path="test/vti/fuzz_test_serving" name="platform/test/vti/fuzz_test_serving" groups="vts,pdk" /> + <project path="test/vti/test_serving" name="platform/test/vti/test_serving" groups="vts,pdk" /> + <project path="test/vts" name="platform/test/vts" groups="vts,pdk" /> + <project path="test/vts-testcase/fuzz" name="platform/test/vts-testcase/fuzz" groups="vts,pdk" /> + <project path="test/vts-testcase/hal" name="platform/test/vts-testcase/hal" groups="vts,pdk" /> + <project path="test/vts-testcase/hal-trace" name="platform/test/vts-testcase/hal-trace" groups="vts,pdk" /> + <project path="test/vts-testcase/kernel" name="platform/test/vts-testcase/kernel" groups="vts,pdk" /> + <project path="test/vts-testcase/nbu" name="platform/test/vts-testcase/nbu" groups="vts,pdk" /> + <project path="test/vts-testcase/performance" name="platform/test/vts-testcase/performance" groups="vts,pdk" /> + <project path="test/vts-testcase/security" name="platform/test/vts-testcase/security" groups="vts,pdk" /> + <project path="test/vts-testcase/vndk" name="platform/test/vts-testcase/vndk" groups="vts,pdk" /> + <project path="toolchain/benchmark" name="toolchain/benchmark" /> + <project path="toolchain/binutils" name="toolchain/binutils" groups="pdk" /> + <project path="toolchain/pgo-profiles" name="toolchain/pgo-profiles" groups="pdk" /> + <project path="tools/acloud" name="platform/tools/acloud" groups="tools,vts,pdk,tradefed" /> + <project path="tools/adt/idea" name="platform/tools/adt/idea" groups="notdefault,tools" /> + <project path="tools/apksig" name="platform/tools/apksig" groups="pdk,tradefed" /> + <project path="tools/apkzlib" name="platform/tools/apkzlib" groups="pdk,tradefed" /> + <project path="tools/base" name="platform/tools/base" groups="notdefault,tools" /> + <project path="tools/build" name="platform/tools/build" groups="notdefault,tools" /> + <project path="tools/dexter" name="platform/tools/dexter" groups="tools,pdk-fs" /> + <project path="tools/external/fat32lib" name="platform/tools/external/fat32lib" groups="tools" /> + <project path="tools/external/gradle" name="platform/tools/external/gradle" groups="tools" clone-depth="1" /> + <project path="tools/idea" name="platform/tools/idea" groups="notdefault,tools" /> + <project path="tools/loganalysis" name="platform/tools/loganalysis" groups="nopresubmit,pdk,tradefed" /> + <project path="tools/metalava" name="platform/tools/metalava" groups="tools" /> + <project path="tools/motodev" name="platform/tools/motodev" groups="notdefault,motodev" /> + <project path="tools/repohooks" name="platform/tools/repohooks" groups="adt-infra,cts,developers,motodev,pdk,tools,tradefed" /> + <project path="tools/security" name="platform/tools/security" groups="pdk,tools" /> + <project path="tools/studio/cloud" name="platform/tools/studio/cloud" groups="notdefault,tools" /> + <project path="tools/swt" name="platform/tools/swt" groups="notdefault,tools" /> + <project path="tools/test/connectivity" name="platform/tools/test/connectivity" groups="pdk" /> + <project path="tools/test/graphicsbenchmark" name="platform/tools/test/graphicsbenchmark" groups="pdk" /> + <project path="tools/tradefederation/core" name="platform/tools/tradefederation" groups="pdk,tradefed" /> + <project path="tools/tradefederation/contrib" name="platform/tools/tradefederation/contrib" groups="pdk,tradefed" /> + + <repo-hooks in-project="platform/tools/repohooks" enabled-list="pre-upload" /> + +</manifest> diff --git a/spec/helpers/namespaces_helper_spec.rb b/spec/helpers/namespaces_helper_spec.rb index 460d3b6a7e4..343e140f5fb 100644 --- a/spec/helpers/namespaces_helper_spec.rb +++ b/spec/helpers/namespaces_helper_spec.rb @@ -28,6 +28,16 @@ describe NamespacesHelper do expect(options).not_to include(admin_group.name) expect(options).to include(user_group.name) + expect(options).to include(user.name) + end + + it 'returns only groups if groups_only option is true' do + allow(helper).to receive(:current_user).and_return(user) + + options = helper.namespaces_options(nil, groups_only: true) + + expect(options).not_to include(user.name) + expect(options).to include(user_group.name) end context 'when nested groups are available', :nested_groups do diff --git a/spec/lib/gitlab/import_sources_spec.rb b/spec/lib/gitlab/import_sources_spec.rb index 10341486512..25827423914 100644 --- a/spec/lib/gitlab/import_sources_spec.rb +++ b/spec/lib/gitlab/import_sources_spec.rb @@ -12,7 +12,8 @@ describe Gitlab::ImportSources do 'FogBugz' => 'fogbugz', 'Repo by URL' => 'git', 'GitLab export' => 'gitlab_project', - 'Gitea' => 'gitea' + 'Gitea' => 'gitea', + 'Manifest file' => 'manifest' } expect(described_class.options).to eq(expected) @@ -31,6 +32,7 @@ describe Gitlab::ImportSources do git gitlab_project gitea + manifest ) expect(described_class.values).to eq(expected) @@ -63,7 +65,8 @@ describe Gitlab::ImportSources do 'fogbugz' => Gitlab::FogbugzImport::Importer, 'git' => nil, 'gitlab_project' => Gitlab::ImportExport::Importer, - 'gitea' => Gitlab::LegacyGithubImport::Importer + 'gitea' => Gitlab::LegacyGithubImport::Importer, + 'manifest' => nil } import_sources.each do |name, klass| @@ -82,7 +85,8 @@ describe Gitlab::ImportSources do 'fogbugz' => 'FogBugz', 'git' => 'Repo by URL', 'gitlab_project' => 'GitLab export', - 'gitea' => 'Gitea' + 'gitea' => 'Gitea', + 'manifest' => 'Manifest file' } import_sources.each do |name, title| diff --git a/spec/lib/gitlab/manifest_import/manifest_spec.rb b/spec/lib/gitlab/manifest_import/manifest_spec.rb new file mode 100644 index 00000000000..ab305fb2316 --- /dev/null +++ b/spec/lib/gitlab/manifest_import/manifest_spec.rb @@ -0,0 +1,46 @@ +require 'spec_helper' + +describe Gitlab::ManifestImport::Manifest, :postgresql do + let(:file) { File.open(Rails.root.join('spec/fixtures/aosp_manifest.xml')) } + let(:manifest) { described_class.new(file) } + + describe '#valid?' do + context 'valid file' do + it { expect(manifest.valid?).to be true } + end + + context 'missing or invalid attributes' do + let(:file) { Tempfile.new('foo') } + + before do + content = <<~EOS + <manifest> + <remote review="invalid-url" /> + <project name="platform/build"/> + </manifest> + EOS + + file.write(content) + file.rewind + end + + it { expect(manifest.valid?).to be false } + + describe 'errors' do + before do + manifest.valid? + end + + it { expect(manifest.errors).to include('Make sure a <remote> tag is present and is valid.') } + it { expect(manifest.errors).to include('Make sure every <project> tag has name and path attributes.') } + end + end + end + + describe '#projects' do + it { expect(manifest.projects.size).to eq(660) } + it { expect(manifest.projects[0][:name]).to eq('platform/build') } + it { expect(manifest.projects[0][:path]).to eq('build/make') } + it { expect(manifest.projects[0][:url]).to eq('https://android-review.googlesource.com/platform/build') } + end +end diff --git a/spec/lib/gitlab/manifest_import/project_creator_spec.rb b/spec/lib/gitlab/manifest_import/project_creator_spec.rb new file mode 100644 index 00000000000..1d01d437535 --- /dev/null +++ b/spec/lib/gitlab/manifest_import/project_creator_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' + +describe Gitlab::ManifestImport::ProjectCreator, :postgresql do + let(:group) { create(:group) } + let(:user) { create(:user) } + let(:repository) do + { + path: 'device/common', + url: 'https://android-review.googlesource.com/device/common' + } + end + + before do + group.add_owner(user) + end + + subject { described_class.new(repository, group, user) } + + describe '#execute' do + it { expect(subject.execute).to be_a(Project) } + it { expect { subject.execute }.to change { Project.count }.by(1) } + it { expect { subject.execute }.to change { Group.count }.by(1) } + + it 'creates project with valid full path and import url' do + subject.execute + + project = Project.last + + expect(project.full_path).to eq(File.join(group.path, 'device/common')) + expect(project.import_url).to eq('https://android-review.googlesource.com/device/common') + end + end +end |