diff options
author | Salud Lemus <saludlemus@google.com> | 2019-06-24 15:27:34 -0700 |
---|---|---|
committer | Salud Lemus <saludlemus@google.com> | 2019-07-02 22:48:15 +0000 |
commit | 6befccfc2baa5042a9a2438b2012df2fa7f788b8 (patch) | |
tree | a6c6108d9b0bfac70a8ba96489fbfc134cfdeeda /llvm_tools | |
parent | 900dbc92800d8fc927905db29cb302461054cf97 (diff) | |
download | toolchain-utils-6befccfc2baa5042a9a2438b2012df2fa7f788b8.tar.gz |
LLVM tools: get hashes from google3
BUG=None
TEST=Ran the script and returned expected results
Change-Id: I360884c2dc4088a7875e88f2115460c5aa75ab27
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/toolchain-utils/+/1676593
Reviewed-by: George Burgess <gbiv@chromium.org>
Tested-by: Salud Lemus <saludlemus@google.com>
Diffstat (limited to 'llvm_tools')
-rwxr-xr-x | llvm_tools/get_google3_llvm_version.py | 134 | ||||
-rwxr-xr-x | llvm_tools/get_llvm_hash.py | 190 |
2 files changed, 324 insertions, 0 deletions
diff --git a/llvm_tools/get_google3_llvm_version.py b/llvm_tools/get_google3_llvm_version.py new file mode 100755 index 00000000..420ec7ea --- /dev/null +++ b/llvm_tools/get_google3_llvm_version.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- +# Copyright 2019 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Gets the latest google3 llvm version""" + +from __future__ import print_function + +from pipes import quote +import argparse +import traceback +import os + +from cros_utils import command_executer + + +class LLVMVersion(object): + """Provides a method to retrieve the latest google3 llvm version.""" + + def __init__(self, log_level="none"): + self._ce = command_executer.GetCommandExecuter(log_level=log_level) + + def _DeleteClient(self): + """Deletes a created client.""" + + # delete client + delete_cmd = 'g4 citc -d my_local_client' + ret, _, err = self._ce.RunCommandWOutput(delete_cmd, print_to_console=False) + + if ret: # failed to delete client + raise ValueError("Failed to delete client: %s" % err) + + def _CreateClient(self): + """Creates a client returns a path to the google3 directory. + + Args: + ce: A CommandExecuter object for executing commands + + Returns: + A string that is the path to the google3 directory. + + Raises: + Exception: Failed to create a client. + """ + + # number of tries to create client + num_tries = 2 + + # cmd to create client + client_cmd = 'p4 g4d -f my_local_client' + + # try to create client + for _ in range(num_tries): + ret, google3_path, err = self._ce.RunCommandWOutput( + client_cmd, print_to_console=False) + + if not ret: # created client + return google3_path + + try: # delete client and re-try + self._DeleteClient() + except ValueError: + traceback.print_exc() + + raise Exception('Failed to create a client: %s' % err) + + def GetGoogle3LLVMVersion(self): + """Gets the latest google3 llvm version. + + Creates a client to retrieve the llvm version. + The client is then deleted after the llvm version is retrieved. + + Returns: + The latest llvm version as an integer. + + Raises: + Exception: An invalid path has been provided to the cat command. + """ + + # create a client and get the path + google3_path = self._CreateClient() + + try: + # remove '\n' at the end + google3_path = google3_path.strip() + + # cmd to retrieve latest version + llvm_version_path = 'third_party/crosstool/v18/stable/' \ + 'installs/llvm/revision' + + path_to_version = os.path.join(google3_path, llvm_version_path) + cat_cmd = 'cat %s' % quote(path_to_version) + + # get latest version + ret, g3_version, err = self._ce.RunCommandWOutput( + cat_cmd, print_to_console=False) + # check return code + if ret: # failed to get latest version + raise Exception('Failed to get google3 llvm version: %s' % err) + finally: + # no longer need the client + self._DeleteClient() + + # change type to an integer + return int(g3_version.strip()) + + +def main(): + """Prints the google3 llvm version. + + Parses the command line for the optional command line + argument. + """ + + # create parser and add optional command-line argument + parser = argparse.ArgumentParser(description='Get the google3 llvm version.') + parser.add_argument( + '--log_level', + default='none', + choices=['none', 'quiet', 'average', 'verbose'], + help='the level for the logs (default: %(default)s)') + + # parse command-line arguments + args_output = parser.parse_args() + + cur_log_level = args_output.log_level # get log level + + print(LLVMVersion(log_level=cur_log_level).GetGoogle3LLVMVersion()) + + +if __name__ == '__main__': + main() diff --git a/llvm_tools/get_llvm_hash.py b/llvm_tools/get_llvm_hash.py new file mode 100755 index 00000000..98b7b749 --- /dev/null +++ b/llvm_tools/get_llvm_hash.py @@ -0,0 +1,190 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- +# Copyright 2019 The Chromium OS Authors. All rights reserved. +# 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.""" + +from __future__ import print_function + +from pipes import quote +import argparse +import os +import re +import shutil +import tempfile + +from cros_utils import command_executer +from get_google3_llvm_version import LLVMVersion + + +class LLVMHash(object): + """Provides two methods to retrieve a llvm hash.""" + + def __init__(self, log_level='none'): + self._ce = command_executer.GetCommandExecuter(log_level=log_level) + self._llvm_url = 'https://chromium.googlesource.com/external' \ + '/github.com/llvm/llvm-project' + + @staticmethod + def _CreateTempDirectory(): + """Creates a temporary directory in /tmp.""" + return tempfile.mkdtemp() + + @staticmethod + def _DeleteTempDirectory(temp_dir): + """Deletes the directory created by CreateTempDirectory().""" + shutil.rmtree(temp_dir) + + def _CloneLLVMRepo(self, temp_dir): + """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 + raise Exception('Failed to clone the llvm repo: %s' % err) + + def _ParseCommitMessages(self, subdir, hash_vals, 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. + llvm_version: The version to compare to in the commit message. + + Returns: + The hash that matches the llvm version. + + Raises: + Exception: Failed to parse a commit message. + """ + + # create regex + llvm_svn_pattern = re.compile(r'llvm-svn: ([0-9]+)') + + # For each hash, grab the last "llvm-svn:" line + # and compare the llvm version of that line against + # 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 + + # 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 + raise Exception('Failed to parse commit message: %s' % err) + + # 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 + if llvm_versions and int(llvm_versions[-1]) == llvm_version: + return cur_hash + + # failed to find the commit hash + raise Exception('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. + + 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. + + Raises: + Exception: The hash was not found in 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\" + """ % (quote(subdir), llvm_version) + + ret, hash_vals, err = self._ce.RunCommandWOutput( + hash_cmd, print_to_console=False) + + if ret: # failed to find hash + raise Exception('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. + + Args: + llvm_version: The llvm version to use as a delimiter. + + Returns: + The hash as a string that corresponds to the llvm version. + """ + + try: + # create a temporary directory for the LLVM repo + llvm_git_dir = self._CreateTempDirectory() + + # clone the "llvm-project" repo + self._CloneLLVMRepo(llvm_git_dir) + + # find the hash + hash_value = self.GetGitHashForVersion(llvm_git_dir, llvm_version) + finally: + # delete temporary directory + self._DeleteTempDirectory(llvm_git_dir) + + return hash_value + + def GetGoogle3LLVMHash(self): + """Retrieves the google3 llvm hash.""" + + google3_llvm = LLVMVersion(self._ce.GetLogLevel()) + google3_llvm_version = google3_llvm.GetGoogle3LLVMVersion() + + return self.GetLLVMHash(google3_llvm_version) + + +def main(): + """Prints the google3 llvm version. + + 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.') + 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)') + + # 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 + + new_llvm_hash = LLVMHash(log_level=cur_log_level) + + if cur_llvm_version: # passed in a specific llvm version + print(new_llvm_hash.GetLLVMHash(cur_llvm_version)) + else: # find the google3 llvm hash + print(new_llvm_hash.GetGoogle3LLVMHash()) + + +if __name__ == '__main__': + main() |