Generated: Sun Apr 15 11:46:03 2012 from dirdate-old2.pl 2011/11/12 15.7 KB.
#!/usr/bin/perl -w #< dirdate.pl - show the latest file dates... # 12/11/2011 - Option --norepo, to EXCLUDE all repo folders. # 11/09/2011 - Add option --invert, to invert the time sort, and show earliest (oldest) file # 16/07/2011 - Add .suo and .ncb to the def msvc excludes (and .o for gcc Qt compiles) # 06/06/2011 - Like in Ubuntu, added by-day -d option # 15/03/2011 - copied from Ubuntu bin, but fixed -? exit use strict; use warnings; use File::stat; use File::Basename; # split path ($n,$d,$e) = fileparse($file, qr/\.[^.]*/); use Time::gmtime; my $perl_dir = 'C:\GTools\perl'; unshift(@INC, $perl_dir); require 'lib_utils.pl' or die "Unable to load 'lib_utils.pl ...\n"; # log file stuff my ($LF); my $pgmname = $0; if ($pgmname =~ /(\\|\/)/) { my @tmpsp = split(/(\\|\/)/,$pgmname); $pgmname = $tmpsp[-1]; } my $outfile = $perl_dir."\\temp.$pgmname.txt"; open_log($outfile); # user variables my $load_log = 0; my $no_repo = 0; my $my_version = "Version 0.0.5 2011-09-11"; #my $my_version = "Version 0.0.4 2011-06-06"; my $os = $^O; my @excluded_exts = (); # qw( .Po .o ); my @excluded_files = (); my @def_msvc_excludes = qw( .obj .dep .dll .res .lib .exe .ilk .pdb .manifest .exp .idb .user .vcproj .dsp .sln .dsw .suo .ncb .old .bak .o ); my @def_msvc_files = qw( Buildlog.htm ); # options my $invert_date = 0; # show earliest - reverse order my $per_day = 0; # show as DAY groups # program variables my $in_folder = ''; my @g_all_files = (); my $last_time = 0; my $last_file = ''; my $earliest_time = time(); my $earliest_file = ''; my $tail_count = 0; my $repo_cnt = 0; my $repo_last = ''; my $repo_time = 0; my $oldest_repo = ''; my $oldest_time = time(); my @warnings = (); my $verbosity = 0; my $got_big_X = 0; sub VERB1() { return ($verbosity >= 1); } sub VERB2() { return ($verbosity >= 2); } sub VERB5() { return ($verbosity >= 5); } sub VERB9() { return ($verbosity >= 9); } # debug my $dbg_01 = 0; sub process_directory($); sub show_warnings($) { my ($val) = @_; if (@warnings) { prt( "\nGot ".scalar @warnings." WARNINGS...\n" ); foreach my $itm (@warnings) { prt("$itm\n"); } prt("\n"); } else { ### prt( "\nNo warnings issued.\n\n" ); } } sub pgm_exit($$) { my ($val,$msg) = @_; if (length($msg)) { $msg .= "\n" if (!($msg =~ /\n$/)); prt($msg); } show_warnings($val); close_log($outfile,$load_log); exit($val); } sub prtw($) { my ($msg) = shift; prt($msg); $msg =~ s/\n$//; push(@warnings,$msg); } sub get_YYYYMMDD_hhmmss_UTC($) { my ($t) = shift; my $tm = gmtime($t); my $m = sprintf( "%04d/%02d/%02d %02d:%02d:%02d", $tm->year() + 1900, $tm->mon() + 1, $tm->mday(), $tm->hour(), $tm->min(), $tm->sec() ); return $m; } # #sub get_YYYYMMDD($) { # my ($t) = shift; # my @f = (localtime($t))[0..5]; # my $m = sprintf("%04d/%02d/%02d", # $f[5] + 1900, $f[4] + 1, $f[3]); # return $m; #} sub mycmp2 { # by 2nd component - time in this case return 1 if (${$a}[1] > ${$b}[1]); return -1 if (${$a}[1] < ${$b}[1]); return 0; } sub mycmp2_invert { # by 2nd component - time in this case return -1 if (${$a}[1] > ${$b}[1]); return 1 if (${$a}[1] < ${$b}[1]); return 0; } sub has_repo_folder($) { my $f = shift; return 1 if ($f =~ /(\\|\/)CVS(\\|\/)/); return 2 if ($f =~ /(\\|\/)\.svn(\\|\/)/); return 3 if ($f =~ /(\\|\/)\.git(\\|\/)/); return 0; } sub has_excluded_ext($) { my $file = shift; my ($n,$d,$e) = fileparse($file, qr/\.[^.]*/); my ($ext); foreach $ext (@excluded_exts) { return 1 if ($e eq $ext); } return 0; } sub is_excluded_file($) { my $file = shift; my ($n,$d) = fileparse($file); my ($fil); foreach $fil (@excluded_files) { return 1 if ($n eq $fil); return 1 if ($n =~ /^$fil$/i); } return 0; } sub is_temp_file($) { my $file = shift; my ($n,$d) = fileparse($file); return 0 if ($n =~ /^template/i); return 1 if ($n =~ /^temp/i); return 0; } sub process_directory($) { my ($dir) = @_; my @dirs = (); if ( opendir( DIR, $dir ) ) { my @files = readdir(DIR); closedir(DIR); $dir .= '/' if !($dir =~ /(\\|\/)$/); my ($file,$ff,$sb,$ir); foreach $file (@files) { next if (($file eq '.')||($file eq '..')); $ff = $dir.$file; if (-f $ff) { next if (has_excluded_ext($file)); next if (is_excluded_file($file)); next if ($got_big_X && is_temp_file($file)); if ($sb = stat($ff)) { $ir = has_repo_folder($ff); next if ($ir && $no_repo); push(@g_all_files, [$ff, $sb->mtime, $sb->size, $ir, 0]); if ($sb->mtime > $last_time) { $last_time = $sb->mtime; $last_file = $ff; } if ($sb->mtime < $earliest_time) { $earliest_time = $sb->mtime; $earliest_file = $ff; } if ($ir > 0) { $repo_cnt++; if ($sb->mtime > $repo_time) { $repo_last = $ff; $repo_time = $sb->mtime; } if ($sb->mtime < $oldest_time) { $oldest_time = $sb->mtime; $oldest_repo = $ff; } } } else { prtw("WARNING: Unable to 'stat' [$ff]\n"); } } elsif (-d $ff) { push(@dirs,$ff); } } } foreach $dir (@dirs) { process_directory($dir); } } # ($tail_count > 0) && $per_day sub show_on_day_basis($) { my $ra = shift; # \@arr my $cnt = scalar @{$ra}; my ($i,$ff,$tm,$ctm,$val,$key,$num,$min,$len); my ($total,$j,$cnum,$num2); my %perday = (); for ($i = 0; $i < $cnt; $i++) { $ff = ${$ra}[$i][0]; $tm = ${$ra}[$i][1]; $ctm = get_YYYYMMDD($tm); if (!defined $perday{$ctm}) { $perday{$ctm} = []; } $val = $perday{$ctm}; push(@{$val}, [ $ff, $tm ]); } my @arr = sort keys(%perday); $num = 0; $min = 0; $total = 0; foreach $key (@arr) { $num++; last if ($num > $tail_count); $val = $perday{$key}; $cnt = scalar @{$val}; $total += $cnt; $ff = ${$val}[0][0]; $tm = ${$val}[0][1]; $len = length($ff); $min = $len if ($len > $min); if (VERB9()) { #$num = scalar @{$val}; for ($j = 0; $j < $cnt; $j++) { $ff = ${$val}[$j][0]; $tm = ${$val}[$j][1]; $len = length($ff); $min = $len if ($len > $min); } } } $num = scalar @arr; prt("List of $total files, spread over $num days...\n"); if (VERB9()) { $num = 0; foreach $key (@arr) { last if ($num > $tail_count); $num++; $val = $perday{$key}; $cnt = scalar @{$val}; $num2 = 0; for ($j = 0; $j < $cnt; $j++) { $num2++; $ff = ${$val}[$j][0]; $tm = ${$val}[$j][1]; if ($j == 0) { $ctm = get_YYYYMMDD($tm); prt("Count of $cnt for day $ctm\n"); } $ctm = get_YYYYMMDD_hhmmss_UTC($tm); # for display $cnum = sprintf("%4d",$num2); $ff .= ' ' while (length($ff) < $min); prt("$cnum: $ff $ctm\n"); } } $num = scalar @arr; prt("\nRepeated list of $total files, spread over $num days... showing only first...\n"); } $num = 0; foreach $key (@arr) { $num++; last if ($num > $tail_count); $val = $perday{$key}; $cnt = scalar @{$val}; $ff = ${$val}[0][0]; $tm = ${$val}[0][1]; # for display $ff .= ' ' while (length($ff) < $min); $cnt = ' '.$cnt while (length($cnt) < 6); $cnum = sprintf("%4d",$num); prt("$num: $ff ".get_YYYYMMDD_hhmmss_UTC($tm)." $cnt\n"); } } sub show_last() { my @arr = (); if ($invert_date) { @arr = sort mycmp2_invert @g_all_files; } else { @arr = sort mycmp2 @g_all_files; } my $cnt = scalar @arr; my ($i,$ff,$tm,$num,$min,$len,$msg,$cnum,$ok); $min = 0; $ok = 0; if ($invert_date) { if ($cnt && length($earliest_file) && ($earliest_time < time())) { $len = length($earliest_file); $min = $len if ($len > $min); $ok = 1; } if (length($oldest_repo) && ($oldest_time > 0) && ($oldest_repo ne $earliest_file) ) { $len = length($oldest_repo); $min = $len if ($len > $min); } } else { if ($cnt && length($last_file) && ($last_time > 0)) { $len = length($last_file); $min = $len if ($len > $min); $ok = 1; } if (length($repo_last) && ($repo_time > 0) && ($repo_last ne $last_file) ) { $len = length($repo_last); $min = $len if ($len > $min); } } if ($ok) { if ($invert_date) { $msg = $earliest_file; $msg .= ' ' while (length($msg) < $min); prt("Oldest : $msg ".get_YYYYMMDD_hhmmss_UTC($earliest_time).", of $cnt files.\n"); if ( length($oldest_repo) && ($oldest_time < time()) && ($oldest_repo ne $earliest_file) ) { $msg = $oldest_repo; $msg .= ' ' while (length($msg) < $min); prt("Repo Old : $msg ".get_YYYYMMDD_hhmmss_UTC($oldest_time).", of $repo_cnt repo files.\n"); } } else { $msg = $last_file; $msg .= ' ' while (length($msg) < $min); prt("Latest : $msg ".get_YYYYMMDD_hhmmss_UTC($last_time).", of $cnt files.\n"); if ( length($repo_last) && ($repo_time > 0) && ($repo_last ne $last_file) ) { $msg = $repo_last; $msg .= ' ' while (length($msg) < $min); prt("Repo Last: $msg ".get_YYYYMMDD_hhmmss_UTC($repo_time).", of $repo_cnt repo files.\n"); } } if ($tail_count > 0) { if ($per_day) { show_on_day_basis(\@arr); } else { $num = $cnt; $min = 0; for ($i = 0; $i < $cnt; $i++) { if ($num <= $tail_count) { $ff = $arr[$i][0]; $len = length($ff); $min = $len if ($len > $min); } $num--; } $num = $cnt; for ($i = 0; $i < $cnt; $i++) { if ($num <= $tail_count) { $ff = $arr[$i][0]; $tm = $arr[$i][1]; $ff .= ' ' while (length($ff) < $min); $cnum = sprintf("%4d",$num); prt("$cnum: $ff ".get_YYYYMMDD_hhmmss_UTC($tm)."\n"); } $num--; } } } pgm_exit(0,""); } else { prt("No files found in [$in_folder]!\n"); } } # ### MAIN ### parse_args(@ARGV); prt("Processing in folder [$in_folder]\n"); process_directory($in_folder); show_last(); pgm_exit(0,""); # ### end ### sub give_help() { prt("$0 $my_version, in OS $os\n"); prt("Usage: [options] input-directory\n"); prt("Options:\n"); prt(" --help (-h or -?) = This help, and exit 0\n"); prt(" --invert (-i) = Invert sort and show OLDEST file.\n"); prt(" --load (-l) = Load log at end.\n"); prt(" --tail <cnt> (-t) = Show <cnt> of the latest files.\n"); prt(" --xclude <ext> (-x) = Exclude files with this extension. Can be a ':' sep list.\n"); if ($os =~ /MSWin/i) { prt(" A special -X will exclude most files built.\n"); } prt(" --day (-d) = Show tail using the 'day' as the criteria.\n"); prt(" --norepo (-n) = Exclude ALL repo folders. (.git/.svn/CVS)\n"); prt("The default is to ONLY show the latest file found.\n"); prt("And the latest in any 'repo' folder found.\n"); } sub need_arg { my ($arg,@av) = @_; if (!@av) { prt("ERROR: Argument [$arg] must be followed by another argument!\n"); pmg_exit(1,""); } } sub parse_args { my @av = @_; my $cnt = scalar @av; prt("Parsing $cnt aruments...\n") if ($dbg_01); my ($sarg,@arr); my $cmd = ''; while (@av) { my $arg = $av[0]; $cmd .= "$arg "; if ($arg =~ /^-/) { $sarg = substr($arg,1); $sarg = substr($sarg,1) while ($sarg =~ /^-/); if (($sarg eq '?')||($sarg =~ /^h/i)) { give_help(); exit(0); } elsif ($sarg =~ /^i/) { $invert_date = 1; prt("Invert date - show oldest last.\n"); } elsif ($sarg =~ /^d/) { $per_day = 1; prt("Set the show tail on a per day basis.\n"); } elsif ($sarg =~ /^l/) { $load_log = 1; prt("Set to load log at end.\n"); } elsif ($sarg =~ /^t/) { need_arg(@av); shift @av; $sarg = $av[0]; $cmd .= "$sarg "; if ($sarg =~ /^\d+$/) { $tail_count = $sarg; prt("set tail count to [$tail_count]\n"); # if ($dbg_01); } else { prt("ERROR: Argument [$arg] MUST be followed by a numeric count!\n"); exit(1); } } elsif ($sarg =~ /^v/) { if ($sarg =~ /^v(\d+)$/) { $verbosity = $1; } else { while ($sarg =~ /^v/) { $verbosity++; $sarg = substr($sarg,1); } } prt("Set verbosity to [$verbosity]\n"); } elsif ($sarg =~ /^x/) { need_arg(@av); shift @av; $sarg = $av[0]; $cmd .= "$sarg "; @arr = split(':',$sarg); foreach $sarg (@arr) { $sarg = '.'.$sarg if ( !($sarg =~ /^\./) ); push(@excluded_exts,$sarg); prt("Excluding extension [$sarg].\n"); } } elsif ($sarg =~ /^X/) { $got_big_X = 1; prt("$arg excludes ["); foreach $sarg (@def_msvc_excludes) { push(@excluded_exts,$sarg); prt("$sarg"); } prt("]\n"); prt("$arg and files ["); foreach $sarg (@def_msvc_files) { push(@excluded_files,$sarg); prt("$sarg"); } prt("]\n"); } elsif ($sarg =~ /^n/) { $no_repo = 1; prt("Exclude all repo folders. (.git/.svn/CVS)\n"); } else { prt("ERROR: Unknown argument [$arg]! Aborting...\n"); pgm_exit(1,""); } } else { prt("set input folder to [$arg]\n") if ($dbg_01); $in_folder = $arg; } shift @av; } if (length($in_folder) == 0) { prt("ERROR: No input folder found in command...[$cmd]!\n"); pgm_exit(1,""); } } # eof