diff options
author | Salud Lemus <saludlemus@google.com> | 2019-07-29 13:43:50 -0700 |
---|---|---|
committer | Salud Lemus <saludlemus@google.com> | 2019-08-01 22:44:42 +0000 |
commit | 1394e94e88b54b10afe0dbaad656de8cd21f3431 (patch) | |
tree | 3671dd10cf3db5a30a5d49b8d42f6c997ce3de6a /llvm_tools | |
parent | 8231d4fd7797571fd5c04c9c37c0411995e99061 (diff) | |
download | toolchain-utils-1394e94e88b54b10afe0dbaad656de8cd21f3431.tar.gz |
LLVM tools: Gets the latest git hash from ToT of LLVM
BUG=None
TEST='./get_llvm_hash_unittest.py' passes
Change-Id: I6c5a58b82811f2d3abe8d377651f0036fa1bc491
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/toolchain-utils/+/1724419
Reviewed-by: George Burgess <gbiv@chromium.org>
Reviewed-by: Manoj Gupta <manojgupta@chromium.org>
Tested-by: Salud Lemus <saludlemus@google.com>
Diffstat (limited to 'llvm_tools')
-rwxr-xr-x | llvm_tools/get_llvm_hash.py | 129 | ||||
-rwxr-xr-x | llvm_tools/get_llvm_hash_unittest.py | 36 |
2 files changed, 128 insertions, 37 deletions
diff --git a/llvm_tools/get_llvm_hash.py b/llvm_tools/get_llvm_hash.py index 07ea2009..2b37bd16 100755 --- a/llvm_tools/get_llvm_hash.py +++ b/llvm_tools/get_llvm_hash.py @@ -4,7 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Returns the latest llvm version's hash.""" +"""Returns the latest LLVM version's hash.""" from __future__ import print_function @@ -19,8 +19,37 @@ from cros_utils import command_executer from get_google3_llvm_version import LLVMVersion +def is_svn_option(svn_option): + """Validates whether the argument (string) is a git hash option. + + The argument is used to find the git hash of LLVM. + + Args: + svn_option: The option passed in as a command line argument. + + Raises: + ValueError: Invalid svn option provided. + """ + + if svn_option.lower() in ('google3', 'tot'): + return svn_option.lower() + + try: + svn_version = int(svn_option) + + return svn_version + + # Unable to convert argument to an int, so the option is invalid. + # + # Ex: 'one'. + except ValueError: + pass + + raise ValueError('Invalid LLVM git hash option provided: %s' % svn_option) + + class LLVMHash(object): - """Provides two methods to retrieve a llvm hash.""" + """Provides three methods to retrieve a LLVM hash.""" def __init__(self, log_level='none'): self._ce = command_executer.GetCommandExecuter(log_level=log_level) @@ -38,31 +67,31 @@ class LLVMHash(object): shutil.rmtree(temp_dir) def _CloneLLVMRepo(self, temp_dir): - """Clones the llvm repo.""" + """Clones the LLVM repo.""" clone_cmd = 'git clone %s %s' % (quote(self._llvm_url), quote(temp_dir)) ret, _, err = self._ce.RunCommandWOutput(clone_cmd, print_to_console=False) - if ret: # failed to create repo + if ret: # Failed to create repo. raise ValueError('Failed to clone the llvm repo: %s' % err) def _ParseCommitMessages(self, subdir, hash_vals, llvm_version): - """Parses the hashes that match the llvm version. + """Parses the hashes that match the LLVM version. Args: subdir: The directory where the git history resides. - hash_vals: All the hashes that match the llvm version. + hash_vals: All the hashes that match the LLVM version. llvm_version: The version to compare to in the commit message. Returns: - The hash that matches the llvm version. + The hash that matches the LLVM version. Raises: Exception: Failed to parse a commit message. """ - # create regex + # Create regex. llvm_svn_pattern = re.compile(r'llvm-svn: ([0-9]+)') # For each hash, grab the last "llvm-svn:" line @@ -70,43 +99,43 @@ class LLVMHash(object): # the llvm version we are looking for and return # that hash only if they match. for cur_commit in hash_vals.splitlines(): - cur_hash = cur_commit.split()[0] # get hash + cur_hash = cur_commit.split()[0] # Get hash. - # cmd to output the commit body + # Cmd to output the commit body. find_llvm_cmd = 'git -C %s log --format=%%B -n 1 %s' % \ (quote(subdir), cur_hash) ret, out, err = self._ce.RunCommandWOutput( find_llvm_cmd, print_to_console=False) - if ret: # failed to parse the commit message + if ret: # Failed to parse the commit message. raise ValueError('Failed to parse commit message: %s' % err) - # find all "llvm-svn:" instances + # Find all "llvm-svn:" instances. llvm_versions = llvm_svn_pattern.findall(out) - # check the last llvm version against the llvm version we are looking for + # Check the last llvm version against the llvm version we are looking for. if llvm_versions and int(llvm_versions[-1]) == llvm_version: return cur_hash - # failed to find the commit hash + # Failed to find the commit hash. raise ValueError('Could not find commit hash.') def GetGitHashForVersion(self, llvm_git_dir, llvm_version): - """Finds the commit hash(es) of the llvm version in the git log history. + """Finds the commit hash(es) of the LLVM version in the git log history. Args: llvm_git_dir: The LLVM git directory. llvm_version: The version to search for in the git log history. Returns: - A string of the hash corresponding to the llvm version. + A string of the hash corresponding to the LLVM version. Raises: Exception: The hash was not found in the git log history. """ - # base directory to search the git log history + # Base directory to search the git log history. subdir = os.path.join(llvm_git_dir, 'llvm') hash_cmd = """git -C %s log --oneline --no-abbrev --grep \"llvm-svn: %d\" @@ -115,75 +144,101 @@ class LLVMHash(object): ret, hash_vals, err = self._ce.RunCommandWOutput( hash_cmd, print_to_console=False) - if ret: # failed to find hash + if ret: # Failed to find hash. raise ValueError('Hash not found: %s' % err) return self._ParseCommitMessages(subdir, hash_vals, llvm_version) def GetLLVMHash(self, llvm_version): - """Retrieves the llvm hash corresponding to the llvm version passed in. + """Retrieves the LLVM hash corresponding to the LLVM version passed in. Args: - llvm_version: The llvm version to use as a delimiter. + llvm_version: The LLVM version to use as a delimiter. Returns: - The hash as a string that corresponds to the llvm version. + The hash as a string that corresponds to the LLVM version. """ try: - # create a temporary directory for the LLVM repo + # Create a temporary directory for the LLVM repo. llvm_git_dir = self._CreateTempDirectory() - # clone the "llvm-project" repo + # Clone the "llvm-project" repo. self._CloneLLVMRepo(llvm_git_dir) - # find the hash + # Find the git hash. hash_value = self.GetGitHashForVersion(llvm_git_dir, llvm_version) finally: - # delete temporary directory + # Delete temporary directory. self._DeleteTempDirectory(llvm_git_dir) return hash_value def GetGoogle3LLVMHash(self): - """Retrieves the google3 llvm hash.""" + """Retrieves the google3 LLVM hash.""" google3_llvm = LLVMVersion(self._ce.GetLogLevel()) google3_llvm_version = google3_llvm.GetGoogle3LLVMVersion() return self.GetLLVMHash(google3_llvm_version) + def GetTopOfTrunkGitHash(self): + """Gets the latest git hash from top of trunk of LLVM.""" + + llvm_url = 'https://github.com/llvm/llvm-project' + + path_to_master_branch = 'refs/heads/master' + + llvm_tot_git_hash_cmd = 'git ls-remote %s %s' % ( + quote(llvm_url), quote(path_to_master_branch)) + + # Get the latest git hash of the master branch of LLVM. + ret, llvm_tot_git_hash, err = self._ce.RunCommandWOutput( + llvm_tot_git_hash_cmd, print_to_console=False) + + if ret: # Failed to get the latest git hash of the master branch of LLVM. + raise ValueError('Failed to get the latest git hash from the top of ' + 'trunk of LLVM: %s' % err) + + return llvm_tot_git_hash.rstrip().split()[0] + def main(): - """Prints the google3 llvm version. + """Prints the git hash of LLVM. Parses the command line for the optional command line arguments. """ - # create parser and add optional command-line arguments - parser = argparse.ArgumentParser(description='Finds the llvm hash.') + # Create parser and add optional command-line arguments. + parser = argparse.ArgumentParser(description='Finds the LLVM hash.') parser.add_argument( '--log_level', default='none', choices=['none', 'quiet', 'average', 'verbose'], help='the level for the logs (default: %(default)s)') - parser.add_argument('--llvm_version', type=int, - help='the llvm version to use as the delimiter ' \ - '(default: uses the google3 llvm version)') + parser.add_argument( + '--llvm_version', + type=is_svn_option, + required=True, + help='which git hash of LLVM to find ' + '{google3, ToT, <svn_version>}') - # parse command-line arguments + # Parse command-line arguments. args_output = parser.parse_args() - cur_log_level = args_output.log_level # get log level - cur_llvm_version = args_output.llvm_version # get llvm version + cur_log_level = args_output.log_level + cur_llvm_version = args_output.llvm_version new_llvm_hash = LLVMHash(log_level=cur_log_level) - if cur_llvm_version: # passed in a specific llvm version + if isinstance(cur_llvm_version, int): + # Find the git hash of the specific LLVM version. print(new_llvm_hash.GetLLVMHash(cur_llvm_version)) - else: # find the google3 llvm hash + elif cur_llvm_version == 'google3': print(new_llvm_hash.GetGoogle3LLVMHash()) + else: # Find the top of trunk git hash of LLVM. + print(new_llvm_hash.GetTopOfTrunkGitHash()) if __name__ == '__main__': diff --git a/llvm_tools/get_llvm_hash_unittest.py b/llvm_tools/get_llvm_hash_unittest.py index 97dd1278..dc23b290 100755 --- a/llvm_tools/get_llvm_hash_unittest.py +++ b/llvm_tools/get_llvm_hash_unittest.py @@ -356,6 +356,42 @@ class TestGetLLVMHash(unittest.TestCase): mock_get_llvm_hash.assert_called_once_with(1000) mock_google3_llvm_version.assert_called_once() + @mock.patch.object(command_executer.CommandExecuter, 'RunCommandWOutput') + def testFailedToGetHashFromTopOfTrunk(self, mock_run_cmd): + # Simulate the behavior of 'RunCommandWOutput()' when failed to get the + # latest git hash from top of tree of LLVM. + # + # Returns shell error code, stdout, stderr. + mock_run_cmd.return_value = (1, None, 'Could not get git hash from HEAD.') + + TestLLVMHash = LLVMHash() + + # Verify the exception is raised when failed to get the git hash of HEAD + # from LLVM. + with self.assertRaises(ValueError) as err: + TestLLVMHash.GetTopOfTrunkGitHash() + + self.assertEqual( + err.exception.message, + 'Failed to get the latest git hash from the top of trunk ' + 'of LLVM: Could not get git hash from HEAD.') + + mock_run_cmd.assert_called_once() + + @mock.patch.object(command_executer.CommandExecuter, 'RunCommandWOutput') + def testSuccessfullyGetGitHashFromToTOfLLVM(self, mock_run_cmd): + # Simulate the behavior of 'RunCommandWOutput()' when successfully retrieved + # the git hash from top of tree of LLVM. + # + # Returns shell error code, stdout, stderr. + mock_run_cmd.return_value = (0, 'a123testhash1 path/to/master\n', 0) + + TestLLVMHash = LLVMHash() + + self.assertEqual(TestLLVMHash.GetTopOfTrunkGitHash(), 'a123testhash1') + + mock_run_cmd.assert_called_once() + if __name__ == '__main__': unittest.main() |