blob: eee64f1c2f45d2db0ac48af43cdce0854cd53285 [file] [log] [blame]
Haibo Huang24950e72018-06-29 14:53:39 -07001# Copyright (C) 2018 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14"""Module to check updates from Git upstream."""
15
16
17import datetime
18
19import fileutils
20import git_utils
21import metadata_pb2 # pylint: disable=import-error
Haibo Huang0d3810f2018-08-31 20:44:25 -070022import updater_utils
Haibo Huang24950e72018-06-29 14:53:39 -070023
24
25class GitUpdater():
26 """Updater for Git upstream."""
27
28 def __init__(self, url, proj_path, metadata):
29 if url.type != metadata_pb2.URL.GIT:
30 raise ValueError('Only support GIT upstream.')
31 self.proj_path = proj_path
32 self.metadata = metadata
33 self.upstream_url = url
34 self.upstream_remote_name = None
35 self.android_remote_name = None
Haibo Huang0d3810f2018-08-31 20:44:25 -070036 self.new_version = None
Haibo Huang24950e72018-06-29 14:53:39 -070037
38 def _setup_remote(self):
39 remotes = git_utils.list_remotes(self.proj_path)
40 for name, url in remotes.items():
41 if url == self.upstream_url.value:
42 self.upstream_remote_name = name
43
44 # Guess android remote name.
45 if '/platform/external/' in url:
46 self.android_remote_name = name
47
48 if self.upstream_remote_name is None:
49 self.upstream_remote_name = "update_origin"
50 git_utils.add_remote(self.proj_path, self.upstream_remote_name,
51 self.upstream_url.value)
52
53 git_utils.fetch(self.proj_path,
54 [self.upstream_remote_name, self.android_remote_name])
55
56 def check(self):
57 """Checks upstream and returns whether a new version is available."""
58
59 self._setup_remote()
Haibo Huang0d3810f2018-08-31 20:44:25 -070060 if git_utils.is_commit(self.metadata.third_party.version):
61 # Update to remote head.
Haibo Huang39aaab62019-01-25 12:23:03 -080062 self._check_head()
63 else:
64 # Update to latest version tag.
65 self._check_tag()
Haibo Huang0d3810f2018-08-31 20:44:25 -070066
Haibo Huang39aaab62019-01-25 12:23:03 -080067 def get_current_version(self):
68 """Returns the latest version name recorded in METADATA."""
69 return self.metadata.third_party.version
70
71 def get_latest_version(self):
72 """Returns the latest version name in upstream."""
73 return self.new_version
Haibo Huang0d3810f2018-08-31 20:44:25 -070074
75 def _check_tag(self):
76 tags = git_utils.list_remote_tags(self.proj_path,
77 self.upstream_remote_name)
Haibo Huang39aaab62019-01-25 12:23:03 -080078 current_ver = self.get_current_version()
Haibo Huang0d3810f2018-08-31 20:44:25 -070079 self.new_version = updater_utils.get_latest_version(
80 current_ver, tags)
Haibo Huang0d3810f2018-08-31 20:44:25 -070081 print('Current version: {}. Latest version: {}'.format(
82 current_ver, self.new_version), end='')
Haibo Huang0d3810f2018-08-31 20:44:25 -070083
84 def _check_head(self):
Haibo Huang24950e72018-06-29 14:53:39 -070085 commits = git_utils.get_commits_ahead(
86 self.proj_path, self.upstream_remote_name + '/master',
87 self.android_remote_name + '/master')
88
89 if not commits:
Haibo Huang39aaab62019-01-25 12:23:03 -080090 self.new_version = self.get_current_version()
91 return
Haibo Huang24950e72018-06-29 14:53:39 -070092
Haibo Huang0d3810f2018-08-31 20:44:25 -070093 self.new_version = commits[0]
94
Haibo Huang24950e72018-06-29 14:53:39 -070095 commit_time = git_utils.get_commit_time(self.proj_path, commits[-1])
96 time_behind = datetime.datetime.now() - commit_time
97 print('{} commits ({} days) behind.'.format(
98 len(commits), time_behind.days), end='')
Haibo Huang24950e72018-06-29 14:53:39 -070099
100 def _write_metadata(self, path):
101 updated_metadata = metadata_pb2.MetaData()
102 updated_metadata.CopyFrom(self.metadata)
Haibo Huang0d3810f2018-08-31 20:44:25 -0700103 updated_metadata.third_party.version = self.new_version
Haibo Huang24950e72018-06-29 14:53:39 -0700104 fileutils.write_metadata(path, updated_metadata)
105
106 def update(self):
107 """Updates the package.
108
109 Has to call check() before this function.
110 """
Haibo Huang24950e72018-06-29 14:53:39 -0700111 upstream_branch = self.upstream_remote_name + '/master'
112
Haibo Huang39aaab62019-01-25 12:23:03 -0800113 print("Running `git merge {merge_branch}`..."
Haibo Huang66479dd2019-02-02 23:38:54 -0800114 .format(merge_branch=self.new_version))
115 git_utils.merge(self.proj_path, self.new_version)
Haibo Huangc3c0cd42019-01-29 15:24:45 -0800116 self._write_metadata(self.proj_path)
117 git_utils.add_file(self.proj_path, 'METADATA')