Danny van Dyk wrote: [Wed Jul 12 2006, 09:16:30AM EDT] > There are 505 ebuilds which are missing use flags in IUSE that they use > in other places.
I once wrote a script (attached) to update IUSE automatically. To use it, simply: $ cd games-emulation/xmess $ fixiuse It reports what it changed, and give you a resulting repoman commit line which you can cut-and-paste. Aron
#!/usr/bin/ruby -w # # fixiuse: update IUSE based on apparent usage in ebuild(s) # PORTDIR = %x{portageq envvar PORTDIR}.strip ARCHLIST = IO.read(PORTDIR + '/profiles/arch.list').split(/\s+/) $added = [] $removed = [] class Regexp def +(rxp) Regexp.new(self.to_s + rxp.to_s) end end class Efile attr_reader :inherits FLAG = /['"]?!?(\w[-\w+.]*)['"]?/ # regex to match a USE-flag and put it in $1 def initialize(filename) @filename = filename @old_iuse = nil @new_iuse = nil @inherits = [] if File.exists?(@filename) @e = IO.read(@filename) else @e = IO.read(PORTDIR + "/eclass/" + @filename + ".eclass") end end def inherits?(name) name == @filename.sub(/\.eclass$/, '') or @inherits.index(name) end def write # Short-circuit if there's nothing to do return if @new_iuse == @old_iuse # Remove the existing IUSE and remember the location iuse_location = @e.index(/^IUSE=/) @e.gsub!(/\bIUSE=(?:$|(['"]).*?\1)/m, "") # Insert at remembered location or just after KEYWORDS if iuse_location.nil? iuse_location = @e.index(/^KEYWORDS.*\n/) || @e.index(/\n\n/) iuse_location += $&.length @e.insert(iuse_location, "\n") end @e.insert(iuse_location, %Q(IUSE="[EMAIL PROTECTED] ' '}")) # Rewrite file File.open(@filename, "w") { |ios| ios.puts @e } # Announce what we did a = @new_iuse - @old_iuse r = @old_iuse - @new_iuse puts "##### [EMAIL PROTECTED]" if a.size != 0 puts "+++++ Added #{a.join ' '}" puts "+" * 70 a.each do |x| system("fgrep", "--color=always", "-C2", x, @filename) puts '--' end end if r.size != 0 puts "----- Removed #{r.join ' '}" puts "-" * 70 (r + ['$IUSE', '${IUSE}']).each do |x| system("fgrep", "--color=always", "-C2", x, @filename) puts '--' end end puts # Add to the global accumulators $added |= a $removed |= r end def scan # Collect the USE variables from inherited eclasses inherited_iuse = [] @e.scan(/^inherit\s.*/).each do |line| line.sub(/#.*/, "").split.each do |name| next if self.inherits?(name) @inherits << name eclass = Efile.new(name) inherited_iuse << eclass.scan @inherits << eclass.inherits end end # Collect the content of the old IUSE if @e =~ %r{^IUSE=.(.*?)['"]}m @old_iuse = $1.split.sort else @old_iuse = [] end # Strip false matches to create e_nc (no comments) e_nc = @e.gsub(/#.*/, "") e_nc.gsub!(/\b(?:echo|einfo|ewarn|eerror|ebegin|die)\b.*/, "") e_nc.gsub!(/^DESCRIPTION=(["']).*?\1[^\n]*/m, "") # Find candidates for IUSE @new_iuse = e_nc.scan(/\b(?:use_enable|use_with|use[qv]?)\s+/ + FLAG).flatten e_nc.scan(/(?:\bSRC_URI|\b[RP]?DEPEND)=.(.*?)["']/m).flatten.each do |dep| @new_iuse += dep.scan(FLAG + /(?=\?)/).flatten end @new_iuse << 'boundschecking' if e_nc =~ /\bwant_boundschecking\b/ @new_iuse << 'nopie' if e_nc =~ /\bwant_pie\b/ @new_iuse << 'nossp' if e_nc =~ /\bwant_ssp\b/ # Special treatment for ebuilds that inherit particular eclasses if self.inherits? 'confutils' @new_iuse += e_nc.scan(%r{\b (?: confutils_use_conflict | confutils_use_depend_all | confutils_use_depend_any ) }x + ('(?:\s+' + FLAG.to_s + ')+')).flatten @new_iuse += e_nc.scan(%r{\b (?: enable_extension_enable | enable_extension_disable | enable_extension_enableonly | enable_extension_without | enable_with | enable_withonly ) \s+}x + FLAG).flatten end if self.inherits? 'mozconfig' @new_iuse += e_nc.scan(/\bmozconfig_use_(?:enable|with|extension)\s+/ + FLAG).flatten end if self.inherits? 'x11' @new_iuse += e_nc.scan(/\buse_build\s+/ + FLAG).flatten end # Special treatment for some ebuilds... case @filename when /^wine-/ @new_iuse += e_nc.scan(/\bconfig_cache\s+/ + FLAG).flatten when /^qt-\d/ @new_iuse += e_nc.scan(/\bqt_use\s+/ + FLAG).flatten when /^ezm3-\d/ @new_iuse += e_nc.scan(/\bseduse\s+/ + FLAG).flatten when /^xmess-\d/ @new_iuse += e_nc.scan(/\btoggle_feature2?\s+/ + FLAG).flatten @new_iuse += e_nc.scan(/\btoggle_feature2\s+\S+\s+/ + FLAG).flatten end # Clean up @new_iuse -= [ 'the' ] # common false matches @new_iuse -= ARCHLIST @new_iuse.reject! { |x| x =~ /^kernel_|^elibc_|^linguas_|^video_cards_|^input_devices_/ } (@old_iuse - @new_iuse).each do |u| # don't remove items from IUSE that are in an inherited eclass, because # really it's broken either way @new_iuse << u if inherited_iuse.index(u) end # don't add or remove build or bootstrap; just ignore them @new_iuse -= %w(build bootstrap) @new_iuse += (@old_iuse & %w(build bootstrap)) # Final result @new_iuse = @new_iuse.uniq.sort end end ebuilds = ARGV ebuilds += Dir['*.ebuild'] if ebuilds.empty? ebuilds.each do |ebuild| ef = Efile.new(ebuild) ef.scan ef.write end system("cvs diff #{ebuilds.join ' '}") exit if $? == 0 common = $added & $removed $added -= common $removed -= common rc_string = "repoman commit -m 'sync IUSE" unless $added.empty? and $removed.empty? rc_string += " (" rc_string += $added.map {|x| '+' + x}.join(' ') rc_string += " " unless $added.empty? or $removed.empty? rc_string += $removed.map {|x| '-' + x}.join(' ') rc_string += ")" end rc_string += "'" puts rc_string