Commit 2f83794d authored by Douwe Maan's avatar Douwe Maan

Merge branch 'dz-manifest-import' into 'master'

Add manifest import

See merge request gitlab-org/gitlab-ce!20304
parents 94627fd7 751e1786
......@@ -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
......
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
......@@ -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)
......
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
......
......@@ -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 } }
- case project.import_status
- when 'finished'
= icon('check')
= _('Done')
- when 'started'
= icon("spinner spin")
= _('Started')
- when 'failed'
= _('Failed')
- else
= project.human_import_status_name
= 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'
- 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'
- 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]) } }
- 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"
......@@ -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
......
---
title: Add ability to import multiple repositories by uploading a manifest file
merge_request: 20304
author:
type: added
......@@ -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
......@@ -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 |
......
......@@ -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
......
# 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 |
......@@ -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.'
......
......@@ -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
......
# 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
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
......@@ -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 ""
......
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
......@@ -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
<?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>
......@@ -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
......
......@@ -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|
......
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
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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment