#!/usr/bin/env ruby # Copyright (C) 2006-2007 Diego Pettenò # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with autoepatch; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # Handling of parameters require_gem 'getopt' require 'getopt/std' require 'pathname' require 'set' class Profile @@profiles = Hash.new @@profiles_dir = Pathname.new(`portageq portdir`.strip) + "profiles" attr_reader :name def Profile.profiles_dir @@profiles_dir end def Profile.get(name) dir = profiles_dir + name return @@profiles[dir.realpath] ? @@profiles[dir.realpath] : Profile.new(name) end def initialize(name) @dir = @@profiles_dir + name @name = name @@profiles[@dir.realpath] = self @parent = Profile.get(name + "/" + (@dir + "parent").read.gsub(/#.*$/, '').strip) if (@dir + "parent").exist? end def usemask return @usemask if @usemask # if there's a parent, inherit its useflags @usemask = @parent ? @parent.usemask.dup : Set.new return @usemask unless (@dir + "use.mask").exist? (@dir + "use.mask").each_line do |l| l.sub!(/#.*/, '') l.strip! next if l.empty? if l[0,1] == "-" @usemask.delete(l[1..-1]) else @usemask << l end end return @usemask end end opts = Getopt::Std.getopts("hvs:l:") if opts["h"] puts "Usage: useflags-report -h" puts " or: useflags-report [-v] [-l limit]" puts " or: useflags-report [-v] -s useflag [-l limit]" puts puts "Options:" puts " -h\t Shows this help output." puts " -v\t Be verbose, show the masking/unmasking status for all useflags." puts " \t By default only the flags masked/unmasked in more than half the" puts " \t profiles are shown." puts " -s\t Show the status of a single flag masking/unmasking." puts " -l\t Change the verbosity limit from half the profiles to a given limit." puts end useflags = Set.new File.new(Profile::profiles_dir + "use.desc").each_line do |l| flag = l.sub(/#.*/, '').sub(/ - .*/, '').strip useflags << flag if flag != "" end File.new(Profile::profiles_dir + "use.local.desc").each_line do |l| flag = l.sub(/#.*/, '').sub(/ - .*/, '').sub(/.*:/, '').strip useflags << flag if flag != "" end profiles = Set.new File.new(Profile::profiles_dir + "profiles.desc").each_line do |l| l.sub!(/#.*/, '') l.strip! next if l == "" profiles << Profile.get(l.split[1]) end puts "Tracking #{profiles.size} main profiles\n" baseprofile = Profile.get("base") verboselevel = opts["l"] ? opts["l"].to_i : profiles.size/2 unless opts["s"] useflags.each do |use| count = 0 profiles.each do |profile| count = count+1 if profile.usemask.include?(use) end if baseprofile.usemask.include?(use) if opts["v"] or count < verboselevel puts "- useflag '#{use}' masked on base profile, unmasked in #{profiles.size-count} profiles." end else if opts["v"] or count > verboselevel puts "- useflag '#{use}' masked in #{count} profiles.\n" if count > 0 end end end else count = 0 profiles_masked = Set.new profiles_unmasked = Set.new profiles.each do |profile| if profile.usemask.include?(opts["s"]) count = count+1 profiles_masked << profile else profiles_unmasked << profile end end if baseprofile.usemask.include?(opts["s"]) if opts["v"] or count < verboselevel puts "Useflag #{opts["s"]} is masked on these profiles:" profiles_masked.to_a.each { |profile| puts " - #{profile.name}" } end else if opts["v"] or count > verboselevel puts "Useflag #{opts["s"]} is unmasked on these profiles:" profiles_unmasked.to_a.each { |profile| puts " - #{profile.name}" } end end end