Milan Verespej | ccccef6 | 2019-06-18 15:50:40 +0200 | [diff] [blame] | 1 | #! /usr/bin/env python |
| 2 | # -*- coding: utf-8 -*- |
| 3 | |
| 4 | # COPYRIGHT NOTICE STARTS HERE |
| 5 | |
| 6 | # Copyright 2019 © Samsung Electronics Co., Ltd. |
| 7 | # |
| 8 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 9 | # you may not use this file except in compliance with the License. |
| 10 | # You may obtain a copy of the License at |
| 11 | # |
| 12 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 13 | # |
| 14 | # Unless required by applicable law or agreed to in writing, software |
| 15 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 17 | # See the License for the specific language governing permissions and |
| 18 | # limitations under the License. |
| 19 | |
| 20 | # COPYRIGHT NOTICE ENDS HERE |
| 21 | |
| 22 | import argparse |
| 23 | import datetime |
| 24 | import logging |
| 25 | import os |
| 26 | import shutil |
| 27 | import subprocess |
| 28 | import sys |
| 29 | import timeit |
| 30 | |
| 31 | from command_downloader import CommandDownloader |
| 32 | |
| 33 | log = logging.getLogger(name=__name__) |
| 34 | |
| 35 | |
| 36 | class GitDownloader(CommandDownloader): |
| 37 | def __init__(self, *list_args): |
| 38 | super().__init__('git repositories', 'git', *list_args) |
| 39 | |
| 40 | @property |
| 41 | def check_table(self): |
| 42 | """ |
| 43 | Table with information which items from lists are downloaded |
| 44 | """ |
| 45 | self.missing() |
| 46 | header = ['Name', 'Branch', 'Downloaded'] |
| 47 | return self._check_table(header, {'Name': 'l'}, |
| 48 | ((*item.split(), self._downloaded(item)) for item |
| 49 | in self._data_list)) |
| 50 | |
| 51 | @staticmethod |
| 52 | def _download_item(item): |
| 53 | repo, branch = item[0].split() |
| 54 | dst = '{}/{}'.format(item[1], repo) |
| 55 | command = 'git clone -b {} --single-branch https://{} --bare {}'.format(branch, |
| 56 | repo, |
| 57 | dst) |
| 58 | if os.path.exists(dst): |
| 59 | log.warning('File or directory exists {} removing and cloning' |
| 60 | ' to be sure it is latest.'.format(dst)) |
| 61 | if os.path.isfile(dst): |
| 62 | os.remove(dst) |
| 63 | elif os.path.isdir(dst): |
| 64 | shutil.rmtree(dst) |
| 65 | |
| 66 | log.info('Running: {}'.format(command)) |
| 67 | log.info( |
| 68 | subprocess.check_output(command.split(), stderr=subprocess.STDOUT).decode()) |
| 69 | log.info('Downloaded: {}'.format(repo)) |
| 70 | |
| 71 | def _is_missing(self, item): |
| 72 | """ |
| 73 | Check if item is missing (not cloned) |
| 74 | :param item: item to check |
| 75 | :return: True if not present 'maybe' if directory exists |
| 76 | """ |
| 77 | dst = '{}/{}'.format(self._data_list[item], item.split()[0]) |
| 78 | if os.path.exists(dst): |
| 79 | # it is bare repo who knows |
| 80 | return 'maybe' |
| 81 | return True |
| 82 | |
| 83 | def _downloaded(self, item): |
| 84 | """ |
| 85 | Check if item is present (cloned) |
| 86 | :param item: item to check |
| 87 | :return: True if not cloned 'maybe' if directory exists |
| 88 | """ |
| 89 | missing = self._is_missing(item) |
| 90 | if missing != 'maybe': |
| 91 | return False |
| 92 | # It is bare repo so who knows if it is latest version |
| 93 | return 'maybe' |
| 94 | |
| 95 | def missing(self): |
| 96 | """ |
| 97 | Check for missing data (not downloaded) |
| 98 | :return: dictionary of missing items |
| 99 | """ |
| 100 | self._missing = {item: dst for item, dst in self._data_list.items()} |
| 101 | return self._missing |
| 102 | |
| 103 | |
| 104 | def run_cli(): |
| 105 | """ |
| 106 | Run as cli tool |
| 107 | """ |
| 108 | parser = argparse.ArgumentParser(description='Download git repositories from list') |
| 109 | parser.add_argument('git_list', metavar='git-list', |
| 110 | help='File with list of npm packages to download.') |
| 111 | parser.add_argument('--output-dir', '-o', default=os.getcwd(), |
| 112 | help='Download destination') |
| 113 | parser.add_argument('--check', '-c', action='store_true', default=False, |
| 114 | help='Check mode') |
| 115 | |
| 116 | args = parser.parse_args() |
| 117 | |
| 118 | logging.basicConfig(stream=sys.stdout, level=logging.INFO, format='%(message)s') |
| 119 | |
| 120 | downloader = GitDownloader([args.git_list, args.output_dir]) |
| 121 | if args.check: |
| 122 | log.info('Check mode. No download will be executed.') |
| 123 | log.info(downloader.check_table) |
| 124 | sys.exit(0) |
| 125 | |
| 126 | timer_start = timeit.default_timer() |
| 127 | try: |
| 128 | downloader.download() |
| 129 | except RuntimeError: |
| 130 | sys.exit(1) |
| 131 | finally: |
| 132 | log.info('Downloading finished in {}'.format( |
| 133 | datetime.timedelta(seconds=timeit.default_timer() - timer_start))) |
| 134 | |
| 135 | |
| 136 | if __name__ == '__main__': |
| 137 | run_cli() |