From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Date: Fri, 28 Mar 2008 23:28:52 +0300 From: Alexey Tourbin To: ALT Linux Team development discussions Message-ID: <20080328202852.GD31135@solemn.turbinal> Mail-Followup-To: ALT Linux Team development discussions References: <20080324190536.GA19045@dad.imath.kiev.ua> <20080324191827.GZ31135@solemn.turbinal> <20080324193448.GA20516@dad.imath.kiev.ua> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="5SR535opHDmk1Ddx" Content-Disposition: inline In-Reply-To: <20080324193448.GA20516@dad.imath.kiev.ua> Subject: Re: [devel] repocop 0.07 changes X-BeenThere: devel@lists.altlinux.org X-Mailman-Version: 2.1.10b3 Precedence: list Reply-To: ALT Linux Team development discussions List-Id: ALT Linux Team development discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 28 Mar 2008 20:28:53 -0000 Archived-At: List-Archive: List-Post: --5SR535opHDmk1Ddx Content-Type: multipart/mixed; boundary="sNTM2e4Famet7VLS" Content-Disposition: inline --sNTM2e4Famet7VLS Content-Type: text/plain; charset=koi8-r Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Mon, Mar 24, 2008 at 09:34:48PM +0200, Igor Vlasenko wrote: > > =F1 =C4=CC=D1 =DC=D4=CF=C7=CF =D7 =D3=D7=CF=C5 =D7=D2=C5=CD=D1 =D7 =D0= =C1=CB=C5=D4=C5 qa-robot =D3=C4=C5=CC=C1=CC cmdcache(1). > > =EE=CF =CE=C9=CB=C1=CB=CF=CA =C9=CE=D7=C1=CC=C9=C4=C1=C3=C9=C9 =CB=C5= =DB=C1 =D4=C1=CD =CE=C5=D4, =D4=C1=CB =DE=D4=CF =DC=D4=CF =CD=CF=D6=CE=CF = =C9=D3=D0=CF=CC=D8=DA=CF=D7=C1=D4=D8 > > =D4=CF=CC=D8=CB=CF =C4=CC=D1 =CF=DE=C5=CE=D8 =D3=D4=C1=C2=C9=CC=D8=CE= =CF =D2=C1=C2=CF=D4=C1=C0=DD=C9=C8 =CB=CF=CD=C1=CE=C4 -- =CE=C1=D0=D2=C9=CD= =C5=D2, =C4=CC=D1 file(1) > > =D7 =D3=CF=DE=C5=D4=C1=CE=C9=C9 c nm(1). >=20 > =EB=D3=D4=C1=D4=C9, =CB=D5=D3=CB=C9 qa-robot =C9 =D7 =D3=CF=D3=D4=C1=D7 = =C6=C5=C4=CF=D2=D9 =D7=C8=CF=C4=D1=D4, =D7 =D0=C1=CB=C5=D4=C5 > rpmdevtools. =ED=C5=CE=D1 =CB=C1=CB =D2=C1=DA qa-robot =C9 =D7=C4=CF=C8= =CE=CF=D7=C9=CC. =E8=CF=D4=C5=CC=CF=D3=D8=20 > =DE=C5=C7=CF-=D4=CF =DC=D4=C1=CB=CF=C7=CF, =CE=CF =DE=D4=CF=C2=D9 =CC=C5= =C7=DE=C5 =C4=CF=C2=C1=D7=CC=D1=D4=D8 =D4=C5=D3=D4=D9. =F3=C9=C5 =D0=D2=C1=CB=D4=C9=DE=C5=D3=CB=C9 =CF=D4=D2=C1=C4=CE=CF, =CE=CF = =CE=C5 =CF=DE=C5=CE=D8. =EE=C1 =D3=C1=CD=CF=CD =C4=C5=CC=C5 topic =DC=D4=CF =CB=CF=CC=CC=C5=CB=D4=CF=D2=D9 vs =CD=C5=CD=CF=C9=DA=C1=C3=C9=D1.= =F1 =D3=DE=C9=D4=C1=C0, =DE=D4=CF =CD=C5=CD=CF=C9=DA=C1=C3=C9=D1 =C4=CC=D1 =C2=C1=DA=CF=D7=D9=C8/=D3=D4=C1=C2=C9=CC=D8=CE=D9=C8/=CE=C9=DA=CB=CF=D5=D2= =CF=D7=CE=C5=D7=D9=C8 =C4=C1=CE=CE=D9=C8 =D0=CF=C4=C8=CF=C4=C9=D4 =CC=D5=DE= =DB=C5, =DE=C5=CD =CB=CF=CC=CC=C5=CB=D4=CF=D2=D9. =EB=CF=CC=CC=C5=CB=D4=CF=D2=D9 -- =DC=D4=CF =C9=DA=C2=D9=D4=CF=DE=CE=C1=D1 = =C2=C9=DA=CE=C5=D3-=CC=CF=C7=C9=CB=C1, =C1 =CD=C5=CD=CF=C9=DA=C1=C3=C9=D1 = =CD=CF=D6=C5=D4 =C2=D9=D4=D8 =D0=CF=CC=CE=CF=D3=D4=D8=C0 =D0=D2=CF=DA=D2=C1=DE=CE=CF=CA. =F1 =D7 =D3=D7=CF=C5 =D7=D2=C5=CD=D1 =D4=CF=D6=C5 =CE=C1=D0=C9=D3=C1=CC =D0= =D2=C9=C7=CF=D2=CF=DB=CE=C0 =D0=C5=D2=CC=CF=D7=D9=C8 =CD=CF=C4=CC=D5=C5=CA = =C4=CC=D1 =DC=D4=CF=C7=CF =C4=C5=CC=C1, =CE=CF =CF=CE=C9 =D4=C1=CB =CE=C9=C7=C4=C5 =C9 =CE=C5 =C2=D9=CC=C9 =CF=D0= =D5=C2=CC=C9=CB=CF=D7=C1=CE=D9, =D0=CF=C5=CC=C9=CB=D5 =D1 =D3=DE=C5=CC, =DE= =D4=CF =CE=C1 =DB=C5=CC=CC=C5 =C9 =D4=C1=CB =D0=CF=CC=D5=DE=C1=C5=D4=D3=D1 =C4=CF=D3=D4=C1=D4=CF=DE=CE=CF= =C4=A3=DB=C5=D7=CF =C9 =D3=C5=D2=C4=C9=CE=CF. =E4=C1=CC=C5=C5 =D0=D2=C9=CC=CF=D6=C5=CE=CF =CE=C5=D3=CB=CF=CC=D8=CB=CF =C6= =C1=CA=CC=CF=D7 =C7=C4=C5-=D4=CF =CB=CF=CE=C3=C1 2005--=CE=C1=DE=C1=CC=C1 2= 006 =C7=CF=C4=C1: qa::cache - =D3=D5=D0=C5=D2=DC=C6=C6=C5=CB=D4=C9=D7=CE=D9=CA =CB=C5=DB =CE= =C1 =CF=D3=CE=CF=D7=C5 BerkeleyDB =C9 Compress::LZO; qa::memoize -- =CD=C5=CD=CF=C9=DA=C1=C3=C9=D1 =CF=C2=D2=C1=C2=CF=D4=CB=C9 = =C6=C1=CA=CC=CF=D7; qa::rpmsoname -- =D4=CF =DE=D4=CF =C4=C5=CC=C1=C5=D4 rpmsoname(1). =F7 =D0=D2=C9=CE=C3=C9=D0=C5 =C5=D3=D4=D8 =C5=DD=A3 =D7=D3=D1=CB=C9=CA =CB= =CF=C4 =D4=C1 =DC=D4=D5 =D4=C5=CD=D5, =CE=CF =D3=CB=CF=D2=C5=C5 =CE=C5=C4= =CF=C4=C5=CC=C1=CE=CE=D9=CA. =ED=CF=C5 =CD=CE=C5=CE=C9=C5 =D0=D2=CF=D3=D4=CF=C5 -- =CD=C5=CD=CF=C9=DA=C1= =C3=C9=D1, =CB=CF=C7=C4=C1 =CF=CE=C1 =D7=CF=DA=CD=CF=D6=CE=C1, =CC=D5=DE=DB= =C5 =D3=D0=C5=C3=C9=C1=CC=D8=CE=CF=CA =C2=C9=DA=CE=C5=D3-=CC=CF=C7=C9=CB=C9. =F7=D3=A3 =C7=C4=C5-=D4=CF =C8=D2= =C1=CE=C9=D4=D3=D1, =C9 =CB=C1=CB=C1=D1 =D2=C1=DA=CE=C9=C3=C1, =C7=C4=C5 = =C8=D2=C1=CE=C9=D4=D8. =E1 =C5=D3=CC=C9 =D7=DA=C7=D1=C4 =CE=C1 =D7=C5=DD=C9 =D5=D0=D2=CF=DD=C1=C5= =D4=D3=D1, =D4=CF =D2=C1=DA=CE=C9=C3=C1 =D4=C1=CB=C1=D1, =DE=D4=CF =CD=CE= =C5 =D0=D2=CF=DD=C5 =CF=C2 =DC=D4=CF=CD =C4=D5=CD=C1=D4=D8. =E1 =DC=D4=CF =CD=CF=D6=C5=D4 =D3=D4=CF=C9=D4=D8 =CE= =C5 =CD=C5=CE=D8=DB=C5 =C4=D7=C1=C4=C3=C1=D4=C9 =C4=CF=CC=CC=C1=D2=CF=D7!! --sNTM2e4Famet7VLS Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="cache.pm" package qa::cache; use strict; use BerkeleyDB; our $topdir = "$ENV{HOME}/.qa-cache"; my $topdir_fd; my $dbenv; sub init_dbenv () { use Fcntl qw(:flock O_DIRECTORY); -d $topdir or mkdir $topdir; sysopen $topdir_fd, $topdir, O_DIRECTORY or die "$topdir: $!"; if (flock $topdir_fd, LOCK_EX | LOCK_NB) { $dbenv = BerkeleyDB::Env->new(-Home => $topdir, -Verbose => 1, -ErrFile => *STDERR, -Flags => DB_CREATE | DB_INIT_CDB | DB_INIT_MPOOL) or die $BerkeleyDB::Error; # TODO: drop all locks flock $topdir_fd, LOCK_SH; } else { flock $topdir_fd, LOCK_SH; $dbenv = BerkeleyDB::Env->new(-Home => $topdir, -Verbose => 1, -ErrFile => *STDERR, -Flags => DB_JOINENV) or die $BerkeleyDB::Error; } } my %blessed; my $pagesize; sub TIEHASH ($$) { my ($class, $id) = @_; return $blessed{$id} if $blessed{$id}; init_dbenv() unless $dbenv; my $dir = "$topdir/$id"; -d $dir or mkdir $dir; my $db = BerkeleyDB::Hash->new(-Filename => "$id/cache.db", -Env => $dbenv, -Flags => DB_CREATE) or die $BerkeleyDB::Error; $pagesize ||= $db->db_stat->{hash_pagesize}; my $self = bless [ $dir, $db ] => $class; $blessed{$id} = $self; use Scalar::Util qw(weaken); weaken $blessed{$id}; return $self; } use Storable qw(freeze thaw); use Compress::LZO qw(compress decompress); use Digest::SHA1 qw(sha1); use constant { V_STO => 2**1, # STO is Special Theory of Relativity V_LZO => 2**2, # LZO is real-time compressor }; my $today = int($^T / 3600 / 24); sub STORE ($$$) { my ($self, $k, $v) = @_; $k = freeze($k) if ref $k; $k = sha1($k); my $vflags = 0; if (ref $v) { $v = freeze($v); $vflags |= V_STO; } if (length($v) > 768) { $v = compress($v); $vflags |= V_LZO; } my ($dir, $db) = @$self; if (length($v) > $pagesize / 2) { my ($subdir, $file) = unpack "H2H*", $k; $subdir = "$dir/$subdir"; $file = "$subdir/$file"; -d $subdir or mkdir $subdir; open my $fh, ">", "$file.$$" or die $!; syswrite $fh, pack("S", $vflags); syswrite $fh, $v; close $fh; rename "$file.$$", $file; } else { # SSS: mtime, atime, vflags $db->db_put($k, pack("SSS", $today, 0, $vflags) . $v); } } sub FETCH ($$) { my ($self, $k) = @_; $k = freeze($k) if ref $k; $k = sha1($k); my ($dir, $db) = @$self; my ($vflags, $v); if ($db->db_get($k, $v) == 0) { (my $m, my $a, $vflags) = unpack "SSS", $v; substr $v, 0, 6, ""; $db->db_put($k, pack("SSS", $m, $today, $vflags) . $v) if $a != $today; # XXX not atomic } else { my ($subdir, $file) = unpack "H2H*", $k; $subdir = "$dir/$subdir"; $file = "$subdir/$file"; open my $fh, "<", $file or return; local $/; $v = <$fh>; $vflags = unpack "S", $v; substr $v, 0, 2, ""; } $v = decompress($v) if $vflags & V_LZO; $v = thaw($v) if $vflags & V_STO; return $v; } sub EXISTS ($$) { my ($self, $k) = @_; $k = freeze($k) if ref($k); $k = sha1($k); my ($dir, $db) = @$self; return 1 if $db->db_get($k, my $v) == 0; my ($subdir, $file) = unpack "H2H*", $k; $subdir = "$dir/$subdir"; $file = "$subdir/$file"; return -f $file; } sub DELETE ($$) { my ($self, $k) = @_; $k = freeze($k) if ref($k); $k = sha1($k); my ($dir, $db) = @$self; $db->db_del($k); my ($subdir, $file) = unpack "H2H*", $k; $subdir = "$dir/$subdir"; $file = "$subdir/$file"; unlink $file; } # BerkeleyDB cleans up at the END, so do I my $global_destruction; # execute the END when interrupted by a signal -- # it is VERY important to release all locks and shut down gracefully use sigtrap qw(die normal-signals); our $expire = 33; sub DESTROY ($) { return if $global_destruction; my $self = shift; my ($dir, $db) = @$self; my $cur = $db->_db_write_cursor() or return; if ($db->db_get("cleanup", my $cleanup) != 0) { $db->db_put("cleanup", $today); return; } elsif ($cleanup == $today) { return; } while ($cur->c_get(my $k, my $v, DB_NEXT) == 0) { next if $k eq "cleanup"; my ($m, $a, $vflags) = unpack "SSS", $v; next if $a + 33 > $today; next if $m + 33 > $today; $cur->c_del(); } my $wanted = sub { stat or return; -f _ and -M _ > $expire and -A _ > $expire and unlink; -d _ and rmdir; }; require File::Find; File::Find::finddepth($wanted, $dir); } END { undef $dbenv; while (my ($id, $self) = each %blessed) { next unless $self; $self->DESTROY(); undef @$self; } $global_destruction = 1; } 1; --sNTM2e4Famet7VLS Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="memoize.pm" package qa::memoize; use strict; our $NOCACHE ||= $ENV{QA_NOCACHE}; use qa::cache; use File::stat qw(stat); sub memoize_st1 ($) { return if $NOCACHE; my $id = shift; my $pkg = caller; my $sym = $pkg . '::' . $id; no strict 'refs'; my $code = *{$sym}{CODE}; my $cache; no warnings 'redefine'; *$sym = sub ($) { goto $code if $NOCACHE; my $f = shift; $cache ||= qa::cache->TIEHASH($id); my $st0 = stat($f) or die "$id: $f: $!"; my @ism0 = ($st0->ino, $st0->size, $st0->mtime); my $v = $cache->FETCH("@ism0"); return $v if defined $v; $v = $code->($f); my $st1 = stat($f) or die "$id: $f: $!"; my @ism1 = ($st1->ino, $st1->size, $st1->mtime); die "$id: $f: file has changed" unless "@ism0" eq "@ism1"; $cache->STORE("@ism0", $v) if defined $v; return $v; } } require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw(memoize_st1); 1; --sNTM2e4Famet7VLS Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="rpmsoname.pm" package qa::rpmsoname; use strict; use RPM::Header; sub rpmsoname ($) { my $fname = shift; my $rpm = RPM::Header->new($fname) or die "$fname: $RPM::err"; my %filenames = do { my $i = 0; map { $_, $i++ } @{$rpm->filenames||[]} }; my $rpm_realpath = sub ($) { my $i = shift; while (my $link = $$rpm{FILELINKTOS}[$i]) { my $dir = $$rpm{DIRNAMES}[$$rpm{DIRINDEXES}[$i]]; use File::Spec; local $_ = File::Spec->rel2abs($link, $dir); 1 while s#/[^/]+/[.][.]/#/#; # XXX if (exists $filenames{$_}) { $i = $filenames{$_}; } else { my $basename = $$rpm{BASENAMES}[$i]; warn "$fname: outer link $dir$basename -> $_\n"; return; } } return $i; }; my @prov = grep { /^lib[^(\/)\s]+[.]so\b[^(\/)\s]*$/ } @{$$rpm{PROVIDES}}; my @ret; for my $soname (@prov) { my @i = map { $$_[0] } grep { $$_[1] eq $soname } do { my $i = 0; map {[ $i++, $_ ]} @{$$rpm{BASENAMES}}; }; my @j = map { $rpm_realpath->($_) } @i; @j = do { my %j = map { $_, 1 } @j; keys %j }; if (@j == 0) { warn "$fname: no file for $soname\n"; next; } if (@j > 1) { warn "$fname: $soname maps to a few files\n"; } my $i = $j[0]; push @ret, [ $soname, $$rpm{DIRNAMES}[$$rpm{DIRINDEXES}[$i]] . $$rpm{BASENAMES}[$i] ]; } return \@ret; } use qa::memoize qw(memoize_st1); memoize_st1("rpmsoname"); require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw(rpmsoname); 1; --sNTM2e4Famet7VLS-- --5SR535opHDmk1Ddx Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEARECAAYFAkftVQQACgkQfBKgtDjnu0bmnwCgr3yvjPu9xa2QpoB73T0U3L9R wi8An3AIvf0YT5Q9W0weF1sZSKY1daXX =FRom -----END PGP SIGNATURE----- --5SR535opHDmk1Ddx--