tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

maven_downloader.py (4831B)


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