[Lldb-commits] [lldb] r336158 - Re-sort the lldb.xcodeproj project file and commit the script

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Mon Jul 2 17:43:57 PDT 2018


Added: lldb/trunk/scripts/sort-pbxproj.rb
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/sort-pbxproj.rb?rev=336158&view=auto
==============================================================================
--- lldb/trunk/scripts/sort-pbxproj.rb (added)
+++ lldb/trunk/scripts/sort-pbxproj.rb Mon Jul  2 17:43:57 2018
@@ -0,0 +1,241 @@
+#! /usr/bin/ruby
+#
+
+# A script to impose order on the Xcode project file, to make merging
+# across branches were many additional files are present, easier.
+
+
+
+
+## Sort the BuildFile and FileReference sections of an Xcode project file,
+## putting Apple/github-local files at the front to avoid merge conflicts.
+#
+## Run this in a directory with a project.pbxproj file.  The sorted version
+## is printed on standard output.
+#
+
+
+# Files with these words in the names will be sorted into a separate section;
+# they are only present in some repositories and so having them intermixed 
+# can lead to merge failures.
+segregated_filenames = ["Swift", "repl", "RPC"]
+
+if !File.exists?("project.pbxproj")
+    STDERR.puts "ERROR: project.pbxproj does not exist."
+    exit(1)
+end
+
+def read_pbxproj(fn)
+    beginning  = Array.new   # All lines before "PBXBuildFile section"
+    files      = Array.new   # PBXBuildFile section lines -- sort these
+    middle     = Array.new   # All lines between PBXBuildFile and PBXFileReference sections
+    refs       = Array.new   # PBXFileReference section lines -- sort these
+    ending     = Array.new   # All lines after PBXFileReference section
+
+    all_lines = File.readlines fn
+
+    state = 1 # "begin"
+    all_lines.each do |l|
+        l.chomp
+        if state == 1 && l =~ /Begin PBXBuildFile section/
+            beginning.push(l)
+            state = 2
+            next
+        end
+        if state == 2 && l =~ /End PBXBuildFile section/
+            middle.push(l)
+            state = 3
+            next
+        end
+        if state == 3 && l =~ /Begin PBXFileReference section/
+            middle.push(l)
+            state = 4
+            next
+        end
+        if state == 4 && l =~ /End PBXFileReference section/
+            ending.push(l)
+            state = 5
+            next
+        end
+
+        if state == 1
+            beginning.push(l)
+        elsif state == 2
+            files.push(l)
+        elsif state == 3
+            middle.push(l)
+        elsif state == 4
+            refs.push(l)
+        else
+            ending.push(l)
+        end
+    end
+
+    return beginning, files, middle, refs, ending
+end
+
+beginning, files, middle, refs, ending = read_pbxproj("project.pbxproj")
+
+
+### If we're given a "canonical" project.pbxproj file, get the uuid and fileref ids for
+### every source file in this project.pbxproj and the canonical one, and fix any of
+### the identifiers that don't match in the project file we're updating.
+### this comes up when people add the file independently on different branches and it
+### gets different identifiers.
+
+if ARGV.size() > 0
+    canonical_pbxproj = nil
+    if ARGV.size == 2 && ARGV[0] == "--canonical"
+        canonical_pbxproj = ARGV[1]
+    elsif ARGV.size == 1 && ARGV[0] =~ /--canonical=(.+)/
+        canonical_pbxproj = $1
+    end
+
+    if File.exists?(canonical_pbxproj)
+        ignore1, canon_files, ignore2, ignore3, ignore4 = read_pbxproj(canonical_pbxproj)
+        canon_files_by_filename = Hash.new { |k, v| k[v] = Array.new }
+
+        canon_files.each do |l|
+            # 2669421A1A6DC2AC0063BE93 /* MICmdCmdTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266941941A6DC2AC0063BE93 /* MICmdCmdTarget.cpp */; };
+
+            if l =~ /^\s+([A-F0-9]{24})\s+\/\*\s+(.*?)\sin.*?\*\/.*?fileRef = ([A-F0-9]{24})\s.*$/
+                uuid = $1
+                filename = $2
+                fileref = $3
+                canon_files_by_filename[filename].push({ :uuid => uuid, :fileref => fileref })
+            end
+        end
+
+        this_project_files = Hash.new { |k, v| k[v] = Array.new }
+
+        files.each do |l|
+            # 2669421A1A6DC2AC0063BE93 /* MICmdCmdTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266941941A6DC2AC0063BE93 /* MICmdCmdTarget.cpp */; };
+
+            if l =~ /^\s+([A-F0-9]{24})\s+\/\*\s+(.*?)\sin.*?\*\/.*?fileRef = ([A-F0-9]{24})\s.*$/
+                uuid = $1
+                filename = $2
+                fileref = $3
+                this_project_files[filename].push({ :uuid => uuid, :fileref => fileref })
+            end
+        end
+
+        this_project_files.keys.each do |fn|
+            next if !canon_files_by_filename.has_key?(fn)
+            next if this_project_files[fn].size() > 1 || canon_files_by_filename[fn].size() > 1
+            this_ent = this_project_files[fn][0]
+            canon_ent = canon_files_by_filename[fn][0]
+            if this_ent[:uuid] != canon_ent[:uuid]
+                STDERR.puts "#{fn} has uuid #{this_ent[:uuid]} in this project file, #{canon_ent[:uuid]} in the canonical"
+                [ beginning, files, middle, refs, ending ].each do |arr|
+                    arr.each { |l| l.gsub!(this_ent[:uuid], canon_ent[:uuid]) }
+                end
+            end
+            if this_ent[:fileref] != canon_ent[:fileref]
+                STDERR.puts "#{fn} has fileref #{this_ent[:fileref]} in this project file, #{canon_ent[:fileref]} in the canonical"
+                [ beginning, files, middle, refs, ending ].each do |arr|
+                    arr.each { |l| l.gsub!(this_ent[:fileref], canon_ent[:fileref]) }
+                end
+            end
+
+        end
+    end
+end
+
+
+
+######### Sort FILES by the filename, putting swift etc in front
+
+# key is filename
+# value is array of text lines for that filename in the FILES text
+# (libraries like libz.dylib seem to occur multiple times, probably
+# once each for different targets).
+
+files_by_filename = Hash.new { |k, v| k[v] = Array.new }
+
+files.each do |l|
+    # 2669421A1A6DC2AC0063BE93 /* MICmdCmdTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266941941A6DC2AC0063BE93 /* MICmdCmdTarget.cpp */; };
+
+    if l =~ /^\s+([A-F0-9]{24})\s+\/\*\s+(.*?)\sin.*?\*\/.*?fileRef = ([A-F0-9]{24})\s.*$/
+        uuid = $1
+        filename = $2
+        fileref = $3
+        files_by_filename[filename].push(l)
+    end
+
+end
+
+# clear the FILES array
+
+files = Array.new
+
+# add the lines in sorted order.  First swift/etc, then everything else.
+
+segregated_filenames.each do |keyword|
+    filenames = files_by_filename.keys
+    filenames.select {|l| l.include?(keyword) }.sort.each do |fn|
+        # re-add all the lines for the filename FN to our FILES array that we'll
+        # be outputting.
+        files_by_filename[fn].sort.each do |l|
+            files.push(l)
+        end
+        files_by_filename.delete(fn)
+    end
+end
+
+# All segregated filenames have been added to the FILES output array.
+# Now add all the other lines, sorted by filename.
+
+files_by_filename.keys.sort.each do |fn|
+    files_by_filename[fn].sort.each do |l|
+        files.push(l)
+    end
+end
+
+######### Sort REFS by the filename, putting swift etc in front
+
+refs_by_filename = Hash.new { |k, v| k[v] = Array.new }
+refs.each do |l|
+    # 2611FF12142D83060017FEA3 /* SBValue.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBValue.i; sourceTree = "<group>"; };
+
+    if l =~ /^\s+([A-F0-9]{24})\s+\/\*\s+(.*?)\s\*\/.*$/
+        uuid = $1
+        filename = $2
+        refs_by_filename[filename].push(l)
+    end
+end
+
+# clear the refs array
+
+refs = Array.new
+
+# add the lines in sorted order.  First swift/etc, then everything else.
+
+
+segregated_filenames.each do |keyword|
+    filenames = refs_by_filename.keys
+    filenames.select {|l| l.include?(keyword) }.sort.each do |fn|
+        # re-add all the lines for the filename FN to our refs array that we'll
+        # be outputting.
+        refs_by_filename[fn].sort.each do |l|
+            refs.push(l)
+        end
+        refs_by_filename.delete(fn)
+    end
+end
+
+# All segregated filenames have been added to the refs output array.
+# Now add all the other lines, sorted by filename.
+
+refs_by_filename.keys.sort.each do |fn|
+    refs_by_filename[fn].sort.each do |l|
+        refs.push(l)
+    end
+end
+
+
+
+####### output the sorted pbxproj
+
+[ beginning, files, middle, refs, ending ].each do |arr|
+    arr.each {|l| puts l}
+end

Propchange: lldb/trunk/scripts/sort-pbxproj.rb
------------------------------------------------------------------------------
    svn:executable = *




More information about the lldb-commits mailing list