[26785] users/pipping/merge.rb
source_changes at macosforge.org
source_changes at macosforge.org
Sat Jul 7 08:27:07 PDT 2007
Revision: 26785
http://trac.macosforge.org/projects/macports/changeset/26785
Author: pipping at macports.org
Date: 2007-07-07 08:27:05 -0700 (Sat, 07 Jul 2007)
Log Message:
-----------
r40
add/clean up comments
r41
if-to-case transition
make full use of pathname library
r42
replace symlink-creation with call to copy_entry, remove :preserve as it doesn't work with broken symlinks
r43
minor changes (reformatting)
r44
add comments that describe helper functions briefly
allow --exclude to be passed glob-style arguments
r45
get rid of unneccessary regex
r46
make check_singlearch into a function
Modified Paths:
--------------
users/pipping/merge.rb
Modified: users/pipping/merge.rb
===================================================================
--- users/pipping/merge.rb 2007-07-07 11:09:55 UTC (rev 26784)
+++ users/pipping/merge.rb 2007-07-07 15:27:05 UTC (rev 26785)
@@ -41,8 +41,8 @@
self[:verbose] = false
self[:exclude] = Set.new << '.svn' << 'CVS'
- self[:output] = File.join( Dir.pwd, 'out' )
- self[:input] = Dir.pwd
+ self[:output] = Pathname.pwd + 'out'
+ self[:input] = Pathname.pwd
opts = OptionParser.new {|opts|
opts.banner = "Usage: #$0 [options] <arch> <arch> [<arch> ...]"
@@ -51,14 +51,14 @@
'-i', '--input DIRECTORY',
'specify input directory'
) {|input|
- self[:input] = File.expand_path( input ) || Dir.pwd
+ self[:input] = Pathname.new( input ).expand_path || Pathname.pwd
}
opts.on(
'-o', '--output DIRECTORY',
'specify output directory'
- ) {|out|
- self[:output] = File.expand_path( out ) || Dir.pwd
+ ) {|output|
+ self[:output] = Pathname.new( output ).expand_path || Pathname.pwd
}
opts.on(
@@ -110,244 +110,184 @@
ARGS = ARGV.collect {|arg| arg.chomp( '/' )}.uniq
def true_for_all? ( path, args, first_too, &block )
+# checks if a predicate is true for all (but the first) architecture
result = true
iter_over = first_too ? ARGS : ARGS[1..-1]
iter_over.each {|arch|
- result = false unless yield( File.join( args[:input], arch, path ), arch )
+ result = false unless yield( args[:input] + arch + path, arch )
}
return result
end
def copy ( origin, target, args )
- if !File.exist?( target ) or args[:force]
- FileUtils.cp(
- origin,
- target,
+# copies files
+ unless target.exist? and !args[:force]
+ FileUtils.cp( origin, target,
:noop => args[:dry_run],
- :preserve => true,
:verbose => args[:verbose]
)
end
end
+def check_singlearch( my_path, args, regex )
+# checks if a file has the correct type and architecture across all trees
+ type_matches = true_for_all?( my_path, args, true ) {|filepath, arch|
+ filecall_out = %x{#{ FILE } -b "#{ filepath }"}.chomp
+ filecall_out =~ regex
+ }
+ arch_matches = true_for_all?( my_path, args, true ) {|filepath, arch|
+ lipocall_out = %x{lipo -info "#{ filepath }"}.chomp
+ lipocall_out =~ %r{is architecture: #{ arch }$}
+ }
+ raise 'type or architecture mismatch' unless type_matches and arch_matches
+end
+
def lipo ( filepath, architectures, args )
+# glues single-architecture files together using lipo(1)
lipoargs = Array.new
architectures.each {|arch|
- lipoargs << sprintf(
- '-arch %s %s',
- arch, File.join(
- args[:input], arch, filepath
- )
- )
+ lipoargs << sprintf( '-arch %s %s', arch, args[:input] + arch + filepath )
}
- lipotarget = File.join( args[:output], filepath )
- lipocmd = sprintf(
- 'lipo %s -create -o %s',
- lipoargs.join( ' ' ),
- lipotarget
- )
- if !File.exist?( lipotarget ) or args[:force]
+ lipotarget = args[:output] + filepath
+ lipocmd = sprintf( 'lipo %s -create -o %s', lipoargs.join( ' ' ), lipotarget )
+ unless lipotarget.exist? and !args[:force]
puts lipocmd if args[:verbose]
system lipocmd unless args[:dry_run]
end
end
-ORIGINAL_DIR = Dir.pwd
+ORIGINAL_DIR = Pathname.pwd
processed = Set.new
# make sure we're given a valid root directory
-unless File.directory?( arguments[:input] )
- raise sprintf(
- 'invalid input directory: %s',
- arguments[:input]
- )
+unless arguments[:input].directory?
+ raise sprintf( 'invalid input directory: %s', arguments[:input] )
end
# make sure the requested architectures have corresponding subdirectories
# in the the given input directory
unless true_for_all?( '.', arguments, true) {|filepath, arch|
- File.directory? filepath
+ filepath.directory?
}
raise 'architecture missing from input directory'
end
ARGS.each {|architecture|
- FileUtils.cd(
- File.join( arguments[:input], architecture )
- )
- Find.find( '.' ) {|path|
+ FileUtils.cd arguments[:input] + architecture
+ Pathname.new( '.' ).find {|path|
arguments[:exclude].each {|exclude_me|
- Find.prune if File.basename( path ) == exclude_me
+ Find.prune if path.basename.fnmatch? exclude_me
}
- unless processed.include? path
- my_dir = File.dirname( File.join( arguments[:output], path ) )
- # TODO: maybe mkdir should only be called *after* we've decided what
- # needs to be done with the file
- unless File.exist? my_dir
- FileUtils.mkdir_p(
- my_dir,
- :noop => arguments[:dry_run],
- :verbose => arguments[:verbose]
- )
+ Find.prune if processed.include? path
+
+ first_path = arguments[:input] + ARGS[0] + path
+ unless true_for_all?( path, arguments, false ) {|filepath, arch|
+ begin
+ filepath.ftype == first_path.ftype
+ # file does not exist
+ rescue Errno::ENOENT
+ false
end
- first_path = File.join( arguments[:input], ARGS[0], path )
- if true_for_all?( path, arguments, true ) {|filepath, arch|
- !FileTest.symlink? filepath
+ }
+ printf "DEBUG: skipping %s\n", path
+ Find.prune
+ end
+
+ case first_path.ftype
+ # handle file type: directory
+ when 'directory'
+ my_dir = arguments[:output] + path
+ my_dir.mkpath unless arguments[:dry_run]
+ # handle file type: symlinks
+ when 'link'
+ link_target = first_path.readlink
+ if true_for_all?( path, arguments, false ) {|filepath, arch|
+ my_symlink = arguments[:input] + arch + path
+ my_symlink.readlink == link_target
}
- if true_for_all?( path, arguments, true ) {|filepath, arch|
- File.exist? filepath
+ link_output = arguments[:output] + path
+ unless link_output.symlink? or link_output.exist?
+ FileUtils.copy_entry(
+ first_path,
+ link_output
+ )
+ end
+ else
+ # DEBUG: link targets differ
+ end
+ when 'file'
+ if true_for_all?( path, arguments, false ) {|filepath, arch|
+ FileUtils.identical?( filepath, first_path )
+ }
+ copy( first_path, arguments[:output] + path, arguments )
+ Find.prune
+ end
+
+ case path.extname
+ # handle file type: header files
+ when '.h', '.hpp'
+ unless ( arguments[:output] + path ).exist? and !arguments[:force]
+ open( arguments[:output] + path, 'w' ) {|file|
+ ARGS.each {|arch|
+ file.printf '#ifdef __%s__\n', arch
+ file.puts open( arguments[:input] + arch + path, 'r' ).read
+ file.puts '#endif'
+ }
+ }
+ end
+ # handle file type: pkg-config files
+ when '.pc'
+ ARGS.each {|arch|
+ copy_target = arguments[:output] + path.dirname + arch + path.basename
+ copy_target.dirname.mkpath unless arguments[:dry_run]
+ copy( arguments[:input] + arch + path, copy_target, arguments )
}
- if true_for_all?( path, arguments, true ) {|filepath, arch|
- !File.directory? filepath
+ # handle file type: other files
+ else
+ file_output = %x{ #{ FILE } -b "#{ first_path }" }.chomp
+ case file_output
+ # handle file type: ar archives
+ when %r{^current ar archive}
+ check_singlearch( path, arguments, %r{^current ar archive} )
+ lipo( path, ARGS, arguments )
+ # handle file type: mach-o files
+ when %r{^Mach-O}
+ check_singlearch( path, arguments, %r{^Mach-O} )
+ links = Hash.new
+ ARGS.each {|my_arch|
+ links[my_arch] = %x{
+ #{
+ my_arch[-2..-1] == '64' ? 'otool64' : 'otool'
+ } -arch #{ my_arch } -LX #{
+ arguments[:input] + my_arch + path
+ }
+ }.split( "\n" ).collect {|dep_line|
+ dep_line.lstrip.gsub(
+ %r{ \(compatibility version \d+(\.\d+)*, current version \d+(\.\d+)*\)}, ''
+ )
+ }.reject {|dep|
+ dep[0..7] == '/usr/lib'
+ }.to_set
}
- if true_for_all?( path, arguments, false ) {|filepath, arch|
- FileUtils.identical?( filepath, first_path )
- }
- copy( first_path, File.join( arguments[:output], path ), arguments )
- else
- case File.basename path
- when %r{\.h$}, %r{\.hpp$}
- if arguments[:force] or !File.exists?(
- File.join( arguments[:output], path )
+ ARGS.each {|my_arch|
+ unless links[my_arch] == links[ARGS[0]]
+ missing_in = links[my_arch]-links[ARGS[0]]
+ missing_out = links[ARGS[0]]-links[my_arch]
+ if missing_in.any? or missing_out.any?
+ raise sprintf(
+ 'difference in linking encountered: file %s',
+ path
)
- open( File.join( arguments[:output], path ), 'w' ) {|file|
- ARGS.each {|arch|
- file.printf '#ifdef __%s__\n', arch
- file.puts open(
- File.join( arguments[:input], arch, path ), 'r'
- ).read
- file.puts '#endif'
- }
- }
- end
- when %r{\.pc$}
- ARGS.each {|arch|
- copy_target = File.join(
- arguments[:output],
- File.dirname( path ),
- arch,
- File.basename( path )
- )
- unless File.exists? File.dirname( copy_target )
- FileUtils.mkdir_p(
- File.dirname( copy_target ),
- :verbose => arguments[:verbose],
- :noop => arguments[:dry_run]
- )
- end
- copy(
- File.join( arguments[:input], arch, path ),
- copy_target,
- arguments
- )
- }
- else
- file_output = %x{ #{ FILE } -b "#{ first_path }" }.chomp
- case file_output
- when %r{^current ar archive}
- if true_for_all?( path, arguments, false ) {|filepath, arch|
- filecall_out = %x{#{ FILE } -b "#{ filepath }"}.chomp
- filecall_out =~ %r{^current ar archive}
- }
- if true_for_all?( path, arguments, true ) {|filepath, arch|
- lipocall_out = %x{lipo -info "#{ filepath }"}.chomp
- lipocall_out =~ %r{is architecture: #{ arch }$}
- }
- lipo( path, ARGS, arguments )
- else
- raise sprintf(
- 'universal binary or wrong architecture: %s',
- path
- )
- end
- else
- # some files are archives, some are not
- end
- when %r{^Mach-O}
- if true_for_all?( path, arguments, false ) {|filepath, arch|
- filecall_out = %x{#{ FILE } -b "#{ filepath }"}.chomp
- filecall_out =~ %r{^Mach-O}
- }
- if true_for_all?( path, arguments, true ) {|filepath, arch|
- lipocall_out = %x{lipo -info "#{ filepath }"}.chomp
- lipocall_out =~ %r{is architecture: #{arch}$}
- }
- links = Hash.new
- ARGS.each {|my_arch|
- links[my_arch] = %x{
- #{
- my_arch =~ %r{64$} ? 'otool64' : 'otool'
- } -arch #{ my_arch } -LX #{
- File.join( arguments[:input], my_arch, path )
- }
- }.split( "\n" ).collect {|dep_line|
- dep_line.lstrip.gsub(
- %r{ \(compatibility version \d+(\.\d+)*, current version \d+(\.\d+)*\)}, ''
- )
- }.reject {|dep|
- dep =~ %r{^\/usr\/lib\/}
- }.to_set
- }
- ARGS.each {|my_arch|
- unless links[my_arch] == links[ARGS[0]]
- missing_in = links[my_arch]-links[ARGS[0]]
- missing_out = links[ARGS[0]]-links[my_arch]
- if missing_in.any? or missing_out.any?
- raise sprintf(
- 'difference in linking encountered: file %s',
- path
- )
- end
- end
- }
- lipo( path, ARGS, arguments )
- else
- raise sprintf(
- 'universal binary or wrong architecture: %s',
- path
- )
- end
- else
- # some files are mach-o, some are not
- end
- else
- # unable to determine file type
- end
end
end
- end
+ }
+ lipo( path, ARGS, arguments )
else
- # a file is not present in all trees.
+ # DEBUG: unable to determine file type
end
- elsif true_for_all?( path, arguments, true ) {|filepath, arch|
- FileTest.symlink? filepath
- }
- link_target = Pathname.new( first_path ).readlink
- if true_for_all?( path, arguments, false ) {|filepath, arch|
- my_link_target = Pathname.new(
- File.join( arguments[:input], arch, path )
- ).readlink
- my_link_target == link_target
- }
- link_output = File.join( arguments[:output], path )
- if !File.exists? link_output or arguments[:force]
- FileUtils.symlink(
- link_target,
- link_output,
- :force => arguments[:force],
- :verbose => arguments[:verbose],
- :noop => arguments [:dry_run]
- )
- end
- else
- # link targets differ
- end
- else
- # dealing with a mix of at least one symlink and items that are not
- # symlinks
end
- processed << path
end
+ processed << path
}
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macports-changes/attachments/20070707/0058acf5/attachment.html
More information about the macports-changes
mailing list