1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
#!/usr/bin/env vpython3
# Copyright 2017 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import errno
import logging
import os
import shutil
import sys
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..'))
import devil_chromium # pylint: disable=unused-import
from devil.utils import cmd_helper
from devil.utils import parallelizer
def _MakeDirsIfAbsent(path):
try:
os.makedirs(path)
except OSError as err:
if err.errno != errno.EEXIST or not os.path.isdir(path):
raise
class MavenDownloader:
'''
Downloads and installs the requested artifacts from the Google Maven repo.
The artifacts are expected to be specified in the format
"group_id:artifact_id:version:file_type", as the default file type is JAR
but most Android libraries are provided as AARs, which would otherwise fail
downloading. See Install()
'''
# Remote repository to download the artifacts from. The support library and
# Google Play service are only distributed there, but third party libraries
# could use Maven Central or JCenter for example. The default Maven remote
# is Maven Central.
_REMOTE_REPO = 'https://maven.google.com'
# Default Maven repository.
_DEFAULT_REPO_PATH = os.path.join(
os.path.expanduser('~'), '.m2', 'repository')
def __init__(self, debug=False):
self._repo_path = MavenDownloader._DEFAULT_REPO_PATH
self._remote_url = MavenDownloader._REMOTE_REPO
self._debug = debug
def Install(self, target_repo, artifacts, include_poms=False):
logging.info('Installing %d artifacts...', len(artifacts))
downloaders = [_SingleArtifactDownloader(self, artifact, target_repo)
for artifact in artifacts]
if self._debug:
for downloader in downloaders:
downloader.Run(include_poms)
else:
parallelizer.SyncParallelizer(downloaders).Run(include_poms)
logging.info('%d artifacts installed to %s', len(artifacts), target_repo)
@property
def repo_path(self):
return self._repo_path
@property
def remote_url(self):
return self._remote_url
@property
def debug(self):
return self._debug
class _SingleArtifactDownloader:
'''Handles downloading and installing a single Maven artifact.'''
_POM_FILE_TYPE = 'pom'
def __init__(self, download_manager, artifact, target_repo):
self._download_manager = download_manager
self._artifact = artifact
self._target_repo = target_repo
def Run(self, include_pom=False):
parts = self._artifact.split(':')
if len(parts) != 4:
raise Exception('Artifacts expected as '
'"group_id:artifact_id:version:file_type".')
group_id, artifact_id, version, file_type = parts
self._InstallArtifact(group_id, artifact_id, version, file_type)
if include_pom and file_type != _SingleArtifactDownloader._POM_FILE_TYPE:
self._InstallArtifact(group_id, artifact_id, version,
_SingleArtifactDownloader._POM_FILE_TYPE)
def _InstallArtifact(self, group_id, artifact_id, version, file_type):
logging.debug('Processing %s', self._artifact)
download_relpath = self._DownloadArtifact(
group_id, artifact_id, version, file_type)
logging.debug('Downloaded.')
install_path = self._ImportArtifact(download_relpath)
logging.debug('Installed %s', os.path.relpath(install_path))
def _DownloadArtifact(self, group_id, artifact_id, version, file_type):
'''
Downloads the specified artifact using maven, to its standard location, see
MavenDownloader._DEFAULT_REPO_PATH.
'''
cmd = ['mvn',
'org.apache.maven.plugins:maven-dependency-plugin:RELEASE:get',
'-DremoteRepositories={}'.format(self._download_manager.remote_url),
'-Dartifact={}:{}:{}:{}'.format(group_id, artifact_id, version,
file_type)]
stdout = None if self._download_manager.debug else open(os.devnull, 'wb')
try:
ret_code = cmd_helper.Call(cmd, stdout=stdout)
if ret_code != 0:
raise Exception('Command "{}" failed'.format(' '.join(cmd)))
except OSError as e:
if e.errno == errno.ENOENT:
raise Exception('mvn command not found. Please install Maven.') from e
raise
return os.path.join(os.path.join(*group_id.split('.')),
artifact_id,
version,
'{}-{}.{}'.format(artifact_id, version, file_type))
def _ImportArtifact(self, artifact_path):
src_dir = os.path.join(self._download_manager.repo_path, artifact_path)
dst_dir = os.path.join(self._target_repo, os.path.dirname(artifact_path))
_MakeDirsIfAbsent(dst_dir)
shutil.copy(src_dir, dst_dir)
return dst_dir
|