1#!/usr/bin/env python
2# Copyright 2016 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""
7Uploads or downloads third party libraries to or from google cloud storage.
8
9This script will only work for Android checkouts.
10"""
11
12import argparse
13import logging
14import os
15import sys
16
17
18sys.path.append(os.path.abspath(
19    os.path.join(os.path.dirname(__file__), os.pardir)))
20from pylib import constants
21from pylib.constants import host_paths
22
23sys.path.append(
24    os.path.abspath(
25        os.path.join(host_paths.DIR_SOURCE_ROOT, 'third_party', 'depot_tools')))
26import download_from_google_storage
27import upload_to_google_storage
28
29
30def _AddBasicArguments(parser):
31  parser.add_argument(
32      '--sdk-root', default=constants.ANDROID_SDK_ROOT,
33      help='base path to the Android SDK root')
34  parser.add_argument(
35      '-v', '--verbose', action='store_true', help='print debug information')
36  parser.add_argument(
37      '-b', '--bucket-path', required=True,
38      help='The path of the lib file in Google Cloud Storage.')
39  parser.add_argument(
40      '-l', '--local-path', required=True,
41      help='The base path of the third_party directory')
42
43
44def _CheckPaths(bucket_path, local_path):
45  if bucket_path.startswith('gs://'):
46    bucket_url = bucket_path
47  else:
48    bucket_url = 'gs://%s' % bucket_path
49  local_path = os.path.join(host_paths.DIR_SOURCE_ROOT, local_path)
50  if not os.path.isdir(local_path):
51    raise IOError(
52        'The library local path is not a valid directory: %s' % local_path)
53  return bucket_url, local_path
54
55
56def _CheckFileList(local_path, file_list):
57  local_path = os.path.abspath(local_path)
58  abs_path_list = [os.path.abspath(f) for f in file_list]
59  for f in abs_path_list:
60    if os.path.commonprefix([f, local_path]) != local_path:
61      raise IOError(
62          '%s in the arguments is not descendant of the specified directory %s'
63          % (f, local_path))
64  return abs_path_list
65
66
67def _PurgeSymlinks(local_path):
68  for dirpath, _, filenames in os.walk(local_path):
69    for f in filenames:
70      path = os.path.join(dirpath, f)
71      if os.path.islink(path):
72        os.remove(path)
73
74
75def Upload(arguments):
76  """Upload files in a third_party directory to google storage"""
77  bucket_url, local_path = _CheckPaths(arguments.bucket_path,
78                                       arguments.local_path)
79  file_list = _CheckFileList(local_path, arguments.file_list)
80  return upload_to_google_storage.upload_to_google_storage(
81      input_filenames=file_list,
82      base_url=bucket_url,
83      gsutil=arguments.gsutil,
84      force=False,
85      use_md5=False,
86      num_threads=1,
87      skip_hashing=False,
88      gzip=None)
89
90
91def Download(arguments):
92  """Download files based on sha1 files in a third_party dir from gcs"""
93  bucket_url, local_path = _CheckPaths(arguments.bucket_path,
94                                       arguments.local_path)
95  _PurgeSymlinks(local_path)
96  return download_from_google_storage.download_from_google_storage(
97      local_path,
98      bucket_url,
99      gsutil=arguments.gsutil,
100      num_threads=1,
101      directory=True,
102      recursive=True,
103      force=False,
104      output=None,
105      ignore_errors=False,
106      sha1_file=None,
107      verbose=arguments.verbose,
108      auto_platform=False,
109      extract=False)
110
111
112def main(argv):
113  parser = argparse.ArgumentParser()
114  subparsers = parser.add_subparsers(title='commands')
115  download_parser = subparsers.add_parser(
116      'download', help='download the library from the cloud storage')
117  _AddBasicArguments(download_parser)
118  download_parser.set_defaults(func=Download)
119
120  upload_parser = subparsers.add_parser(
121      'upload', help='find all jar files in a third_party directory and ' +
122                     'upload them to cloud storage')
123  _AddBasicArguments(upload_parser)
124  upload_parser.set_defaults(func=Upload)
125  upload_parser.add_argument(
126      '-f', '--file-list', nargs='+', required=True,
127      help='A list of base paths for files in third_party to upload.')
128
129  arguments = parser.parse_args(argv)
130  if not os.path.isdir(arguments.sdk_root):
131    logging.debug('Did not find the Android SDK root directory at "%s".',
132                  arguments.sdk_root)
133    logging.info('Skipping, not on an android checkout.')
134    return 0
135
136  arguments.gsutil = download_from_google_storage.Gsutil(
137      download_from_google_storage.GSUTIL_DEFAULT_PATH)
138  return arguments.func(arguments)
139
140
141if __name__ == '__main__':
142  sys.exit(main(sys.argv[1:]))
143