Add script to update LLVM binutils symlinks

Test: update-binutils.py
Bug: 133170927
Change-Id: Ia295011623d4dbcd1d7dbc518f876ac19d07d87c
diff --git a/update-binutils.py b/update-binutils.py
new file mode 100755
index 0000000..7efc9c8
--- /dev/null
+++ b/update-binutils.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# pylint: disable=not-callable, relative-import
+
+""" Update symlinks for binutils """
+
+import argparse
+import inspect
+import os
+import subprocess
+import sys
+import utils
+
+class ArgParser(argparse.ArgumentParser):
+    def __init__(self):
+        super(ArgParser, self).__init__(
+            description=inspect.getdoc(sys.modules[__name__]))
+
+        self.add_argument(
+            'version', metavar='VERSION',
+            help='Version of binutil prebuilt updating to (e.g. r123456a).')
+
+        self.add_argument(
+            '-b', '--bug', type=int,
+            help='Bug to reference in commit message.')
+
+        self.add_argument(
+            '--use-current-branch', action='store_true',
+            help='Do not repo start a new branch for the update.')
+
+
+def update_binutils_symlink(host, prebuilt_dir, version):
+    binutils = [
+        'llvm-addr2line',
+        'llvm-ar',
+        'llvm-as',
+        'llvm-cov',
+        'llvm-dis',
+        'llvm-link',
+        'llvm-modextract',
+        'llvm-nm',
+        'llvm-objcopy',
+        'llvm-objdump',
+        'llvm-profdata',
+        'llvm-ranlib',
+        'llvm-readelf',
+        'llvm-readobj',
+        'llvm-size',
+        'llvm-strings',
+        'llvm-strip',
+        'llvm-symbolizer',
+    ]
+
+    for b in binutils:
+        symlink_path = os.path.join(prebuilt_dir, 'llvm-binutils-stable', b)
+        util_rela_path = os.path.join('..', 'clang-' + version, 'bin', b)
+        if os.path.exists(symlink_path):
+            os.remove(symlink_path)
+        os.symlink(util_rela_path, symlink_path)
+
+
+def do_commit(prebuilt_dir, use_cbr, version, bug_id):
+    if not use_cbr:
+        subprocess.call(['repo', 'abandon', 'update-binutils-' + version, prebuilt_dir])
+        subprocess.check_call(['repo', 'start', 'update-binutils-' + version, prebuilt_dir])
+
+    subprocess.check_call(['git', 'add', '.'], cwd=prebuilt_dir)
+
+    message_lines = []
+    message_lines.append('Update LLVM binutils to {}.'.format(version))
+    message_lines.append('')
+    message_lines.append('Test: N/A')
+    if bug_id is not None:
+        message_lines.append('Bug: http://b/{}'.format(bug_id))
+    message = '\n'.join(message_lines)
+    subprocess.check_call(['git', 'commit', '-m', message], cwd=prebuilt_dir)
+
+
+def main():
+    args = ArgParser().parse_args()
+    bug_id = args.bug
+    use_cbr = args.use_current_branch
+    version = args.version
+
+    hosts = ['darwin-x86', 'linux-x86']
+
+    for host in hosts:
+        prebuilt_dir = utils.android_path('prebuilts/clang/host', host)
+        update_binutils_symlink(host, prebuilt_dir, version)
+        do_commit(prebuilt_dir, use_cbr, version, bug_id)
+
+    return 0
+
+
+if __name__ == '__main__':
+    main()