[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