aboutsummaryrefslogtreecommitdiff
path: root/llvm_tools
diff options
context:
space:
mode:
authorSalud Lemus <saludlemus@google.com>2019-06-24 15:27:34 -0700
committerSalud Lemus <saludlemus@google.com>2019-07-02 22:48:15 +0000
commit6befccfc2baa5042a9a2438b2012df2fa7f788b8 (patch)
treea6c6108d9b0bfac70a8ba96489fbfc134cfdeeda /llvm_tools
parent900dbc92800d8fc927905db29cb302461054cf97 (diff)
downloadtoolchain-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-xllvm_tools/get_google3_llvm_version.py134
-rwxr-xr-xllvm_tools/get_llvm_hash.py190
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()