[llvm] r368667 - gn build: Give cmake sync script an opt-in --write flag

Nico Weber via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 13 04:32:46 PDT 2019


Author: nico
Date: Tue Aug 13 04:32:45 2019
New Revision: 368667

URL: http://llvm.org/viewvc/llvm-project?rev=368667&view=rev
Log:
gn build: Give cmake sync script an opt-in --write flag

Differential Revision: https://reviews.llvm.org/D66101

Modified:
    llvm/trunk/utils/gn/build/sync_source_lists_from_cmake.py

Modified: llvm/trunk/utils/gn/build/sync_source_lists_from_cmake.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/gn/build/sync_source_lists_from_cmake.py?rev=368667&r1=368666&r2=368667&view=diff
==============================================================================
--- llvm/trunk/utils/gn/build/sync_source_lists_from_cmake.py (original)
+++ llvm/trunk/utils/gn/build/sync_source_lists_from_cmake.py Tue Aug 13 04:32:45 2019
@@ -8,6 +8,10 @@ file, and prints the difference if not.
 
 Also checks that each CMakeLists.txt file below unittests/ folders that define
 binaries have corresponding BUILD.gn files.
+
+If --write is passed, tries to write modified .gn files and adds one git
+commit for each cmake commit this merges. If an error is reported, the state
+of HEAD is unspecified; run `git reset --hard origin/master` if this happens.
 """
 
 from __future__ import print_function
@@ -19,10 +23,38 @@ import subprocess
 import sys
 
 
-def sync_source_lists():
+def patch_gn_file(gn_file, add, remove):
+    with open(gn_file) as f:
+      gn_contents = f.read()
+
+    srcs_tok = 'sources = ['
+    tokloc = gn_contents.find(srcs_tok)
+
+    if tokloc == -1: raise ValueError(gn_file + ': Failed to find source list')
+    if gn_contents.find(srcs_tok, tokloc + 1) != -1:
+        raise ValueError(gn_file + ': Multiple source lists')
+    if gn_file.find('# NOSORT', 0, tokloc) != -1:
+        raise ValueError(gn_file + ': Found # NOSORT, needs manual merge')
+
+    tokloc += len(srcs_tok)
+    for a in add:
+        gn_contents = (gn_contents[:tokloc] + ('"%s",' % a) +
+                       gn_contents[tokloc:])
+    for r in remove:
+        gn_contents = gn_contents.replace('"%s",' % r, '')
+    with open(gn_file, 'w') as f:
+      f.write(gn_contents)
+
+    # Run `gn format`.
+    gn = os.path.join(os.path.dirname(__file__), '..', 'gn.py')
+    subprocess.check_call([sys.executable, gn, 'format', '-q', gn_file])
+
+
+def sync_source_lists(write):
     # Use shell=True on Windows in case git is a bat file.
+    git_want_shell = os.name == 'nt'
     gn_files = subprocess.check_output(['git', 'ls-files', '*BUILD.gn'],
-                                       shell=os.name == 'nt').splitlines()
+                                       shell=git_want_shell).splitlines()
 
     # Matches e.g. |   "foo.cpp",|, captures |foo| in group 1.
     gn_cpp_re = re.compile(r'^\s*"([^"]+\.(?:cpp|c|h|S))",$', re.MULTILINE)
@@ -35,13 +67,13 @@ def sync_source_lists():
     def find_gitrev(touched_line, in_file):
         return subprocess.check_output(
             ['git', 'log', '--format=%h', '-1', '-S' + touched_line, in_file],
-            shell=os.name == 'nt').rstrip()
+            shell=git_want_shell).rstrip()
     def svnrev_from_gitrev(gitrev):
         git_llvm = os.path.join(
             os.path.dirname(__file__), '..', '..', 'git-svn', 'git-llvm')
         return int(subprocess.check_output(
             [sys.executable, git_llvm, 'svn-lookup', gitrev],
-            shell=os.name == 'nt').rstrip().lstrip('r'))
+            ).rstrip().lstrip('r'))
 
     # Collect changes to gn files, grouped by revision.
     for gn_file in gn_files:
@@ -71,19 +103,29 @@ def sync_source_lists():
         by_rev(sorted(gn_cpp - cmake_cpp), 'remove')
 
     # Output necessary changes grouped by revision.
-    for svnrev in sorted(changes_by_rev.keys()):
+    for svnrev in sorted(changes_by_rev):
         print('gn build: Merge r{0} -- https://reviews.llvm.org/rL{0}'
             .format(svnrev))
         for gn_file, data in sorted(changes_by_rev[svnrev].items()):
-            print('  ' + gn_file)
-            add = data.get('add')
-            if add:
-                print('    add:\n' + '\n'.join('    "%s",' % a for a in add))
-            remove = data.get('remove')
-            if remove:
-                print('    remove:\n    ' + '\n    '.join(remove))
+            add = data.get('add', [])
+            remove = data.get('remove', [])
+            if write:
+                patch_gn_file(gn_file, add, remove)
+                subprocess.check_call(['git', 'add', gn_file],
+                                      shell=git_want_shell)
+            else:
+                print('  ' + gn_file)
+                if add:
+                    print('   add:\n' + '\n'.join('    "%s",' % a for a in add))
+                if remove:
+                    print('   remove:\n    ' + '\n    '.join(remove))
+                print()
+        if write:
+            subprocess.check_call(
+                ['git', 'commit', '-m', 'gn build: Merge r%d' % svnrev],
+                shell=git_want_shell)
+        else:
             print()
-        print()
 
     return bool(changes_by_rev)
 
@@ -110,7 +152,7 @@ def sync_unittests():
 
 
 def main():
-    src = sync_source_lists()
+    src = sync_source_lists(len(sys.argv) > 1 and sys.argv[1] == '--write')
     tests = sync_unittests()
     if src or tests:
         sys.exit(1)




More information about the llvm-commits mailing list