--- splat.org 2003-07-31 00:50:37.000000000 +0900 +++ splat 2003-08-01 17:33:01.000000000 +0900 @@ -26,6 +26,13 @@ use File::Basename qw(dirname); use File::Find; use File::Spec::Functions qw(splitdir catfile); +use Gentoo::Ebuild; + +my $SORT = { + NAME => 1, + DATE => 1, + TIME => 1, +}; my $OPT = { 'verbose' => 0, @@ -34,6 +41,8 @@ 'colored' => 0, 'package' => undef, 'logfile' => undef, + 'sort' => 'NAME', + 'sloppy' => 0, }; my %COLORS = ( @@ -48,22 +57,6 @@ # time format my $TF = "%a %b %e %H:%M:%S %Y"; -# load installed packages -my %INSTALLED = (); -find({ 'wanted' => - sub { - return unless /\.ebuild$/; - - my $basedir = dirname($File::Find::name); - $basedir =~ s/^\/var\/db\/pkg//; - my $package = join('/',(splitdir($basedir))[1,2]); - - $INSTALLED{$package} = 1; - - }, 'no_chdir' => 1, }, - '/var/db/pkg', -); - # Main Program &parse_command_line(); @@ -74,49 +67,132 @@ # Colored output? I think not! $ENV{'ANSI_COLORS_DISABLED'} = 1 unless $OPT->{'colored'}; -my $rawlog = &fetch_portage_log($OPT->{'logfile'}); -my $parsed = &parse_portage_log($rawlog); -my $emerge = &fetch_emerge_info($parsed,$OPT->{'package'}); - -my $summary = { - 'emerges' => 0, - 'duration' => 0, - 'first' => undef, - 'last' => undef, -}; +my $rawlog = &fetch_portage_log($OPT->{'logfile'}); +my $parsed = &parse_portage_log($rawlog); +my $emerge = &fetch_emerge_info($parsed,$OPT->{'package'}); +my $result = []; +my $longest = 0; +my $slowest = 0; +my $sum_dur = 0; +foreach my $package (keys %{&fetch_emerge_info($parsed,$OPT->{'package'}) || {}}) +{ + my @times = @{$emerge->{$package}}; + while ( my ($start,$end) = splice(@times,0,2) ) + { + push @$result, { + ebuild => Gentoo::Ebuild->create($package), + start => $start, + end => $end, + }; + + $longest = ( + $longest, length($package) + )[$longest < length($package)]; + + $slowest = ( + $slowest, length( int( ( $end - $start ) / 3600 ) ) + )[$slowest < length( int( ( $end - $start ) / 3600 ) )]; + + $sum_dur += ( $end - $start ); + } +} +undef $emerge; + -my $count = keys %$emerge; +my $count = @$result; if( $count == 0 ) { die "!!! Package not found '$OPT->{'package'}'\n"; } + +# determin sort method +my $sort_code=sub{ 1 }; +unless( $OPT->{summary} ) +{ + if( $OPT->{sort} eq 'NAME' ) + { + $sort_code = sub{ + $a->{ebuild} cmp $b->{ebuild} || + $a->{start} <=> $b->{start} + }; + } + elsif( $OPT->{sort} eq 'DATE' ) + { + $sort_code = sub{ + $a->{start} <=> $b->{start} + }; + } + else + { + $sort_code = sub{ + $a->{end}-$a->{start} <=> $b->{end}-$b->{start} || + $a->{ebuild} cmp $b->{ebuild} || + $a->{start} <=> $b->{start} + }; + } +} + + # foreach package that was matched -foreach my $package (sort keys %$emerge) +my $prev_package = Gentoo::Ebuild->new; +foreach my $info (sort $sort_code @$result) { + my ($package,$start,$end) = @{$info}{qw(ebuild start end)}; + # print out the package name - unless( $OPT->{'summary'} ) + if( !$OPT->{'summary'} ) { - print colored( " * $package\n", &pkgcolor($package) ); - print "\n"; + if( $OPT->{sloppy} ) + { + print colored( + sprintf( "%-${longest}s", $package ), + &pkgcolor($package) + ); + print " "; + } + else + { + if( $package ne $prev_package ) + { + print colored( " * $package\n", &pkgcolor($package) ); + print "\n"; + } + } } # print out the build information for each one - my @times = @{$emerge->{$package}}; - while ( my ($start,$end) = splice(@times,0,2) ) - { - my $duration = ($end-$start); + my $duration = ($end-$start); - if( $duration < 0 ) + if( $duration < 0 ) + { + $duration = 0; + if( $OPT->{'verbose'} ) { - $duration = 0; - if( $OPT->{'verbose'} ) - { - warn "*** Invalid timestamp for $package\n"; - } + warn "*** Invalid timestamp for $package\n"; } + } - unless( $OPT->{'summary'} ) + unless( $OPT->{'summary'} ) + { + if( $OPT->{sloppy} ) + { + print colored( + sprintf( + "%${slowest}d:%02d:%02d(%s)\n", + $duration / 3600, + $duration / 60 % 60, + $duration % 60, + scalar localtime $start, + ), + $duration>($sum_dur/@$result)*4 + ? 'red' + : $duration<($sum_dur/@$result)/4 + ? 'green' + : 'yellow' + ); + } + else { # standard output print "\tEmerged at: ", @@ -129,42 +205,14 @@ $COLORS{'duration'} ), "\n"; } - - # summary information - $summary->{'emerges'}++; - $summary->{'duration'} += $duration; - - if( !defined($summary->{'first'}) || - $start < $summary->{'first'}->{'start'} ) - { - $summary->{'first'} = { - 'name' => $package, - 'start' => $start, - 'end' => $end, - }; - } - - if( !defined($summary->{'last'}) || - $end > $summary->{'last'}->{'end'} ) - { - $summary->{'last'} = { - 'name' => $package, - 'start' => $start, - 'end' => $end, - }; - } - # end summary info - - unless( $OPT->{'summary'} ) - { - print "\n" if @times; - } } - unless( $OPT->{'summary'} ) + if( !$OPT->{'summary'} && !$OPT->{'sloppy'} ) { print "\n"; } + + $prev_package = $package; } # output the summary @@ -174,8 +222,8 @@ print "\n"; my $of = "\t%-14s %s\n"; - my $emerges = $summary->{'emerges'}; - my $duration = $summary->{'duration'}; + my $emerges = @$result; + my $duration = $sum_dur; my $average = int($duration/$emerges); printf( $of, "Total Builds:", @@ -192,9 +240,10 @@ print "\n"; - my $first = $summary->{'first'}; + my ($first,$last) = (sort { $a->{start} <=> $b->{start} } @$result)[0,-1]; + printf( $of, "First Build:", - colored( $first->{'name'}, &pkgcolor($first->{'name'}) ) + colored( "$first->{'ebuild'}", &pkgcolor($first->{'ebuild'}) ) ); printf( $of, "", "(" . colored( strftime($TF,localtime($first->{'start'})), @@ -203,11 +252,10 @@ print "\n"; - if( $summary->{'emerges'} > 1 ) + if( $emerges > 1 ) { - my $last = $summary->{'last'}; printf( $of, "Last Build:", - colored( $last->{'name'}, &pkgcolor($last->{'name'}) ) + colored( "$last->{'ebuild'}", &pkgcolor($last->{'ebuild'}) ) ); printf( $of, "", "(" . colored( strftime($TF,localtime($last->{'end'})), @@ -226,7 +274,7 @@ { my $package = shift; - return exists $INSTALLED{$package} + return $package->installed ? $COLORS{'pkg_install'} : $COLORS{'pkg_normal'}; } @@ -247,10 +295,15 @@ 'help|h|?' => \$OPT->{'gethelp'}, 'package|p=s'=> \$OPT->{'package'}, 'logfile|l=s'=> \$OPT->{'logfile'}, + 'sort|o=s' => \$OPT->{'sort'}, + 'sloppy!' => \$OPT->{'sloppy'}, + 'y!' => \$OPT->{'sloppy'}, ) or pod2usage(2); pod2usage(1) if $OPT->{'gethelp'}; + pod2usage(1) unless exists $SORT->{$OPT->{'sort'}}; + if( !defined($OPT->{'package'}) && !defined($ARGV[0]) ) { pod2usage(1); @@ -482,12 +535,17 @@ splat [options] [--package] package Options: - --help -? -h brief help message - --verbose -v print extra warnings during parsing - --summary -s print a summary line instead of full info - --logfile -l use specified logfile as emerge log - --colored -c output with colors - --package -p a package name to match. can be a partial package + --help -? -h brief help message + --verbose -v print extra warnings during parsing + --sloppy -y display in sloppy mode(one package in a line) + --summary -s print a summary line instead of full info + --logfile -l use specified logfile as emerge log + --colored -c output with colors + --sort -o sort output + --sort=NAME sort by package name(default) + --sort=DATE sort by date emerged at + --sort=TIME sort by build time + --package -p a package name to match. can be a partial package name (ie 'evo'), in which case it will match any package that starts with 'evo'. you can also include the category (ie 'net-www/evo')