Merge changes Iee382756,I473f022c
[oom/offline-installer.git] / build / download / git_downloader.py
1 #! /usr/bin/env python3
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()