File Coverage

lib/PortageXS/Core.pm
Criterion Covered Total %
statement 11 13 84.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 16 18 88.8


line stmt bran cond sub pod time code
1 5     5   2784 use strict;
  5         9  
  5         156  
2 5     5   22 use warnings;
  5         8  
  5         194  
3              
4             package PortageXS::Core;
5             BEGIN {
6 5     5   169 $PortageXS::Core::AUTHORITY = 'cpan:KENTNL';
7             }
8             {
9             $PortageXS::Core::VERSION = '0.3.1';
10             }
11              
12             # ABSTRACT: Core behaviour role for C
13             #
14             # -----------------------------------------------------------------------------
15             #
16             # PortageXS::Core
17             #
18             # author : Christian Hartmann
19             # license : GPL-2
20             # header : $Header: /srv/cvsroot/portagexs/trunk/lib/PortageXS/Core.pm,v 1.19 2008/12/01 19:53:27 ian Exp $
21             #
22             # -----------------------------------------------------------------------------
23             #
24             # This program is free software; you can redistribute it and/or modify it under
25             # the terms of the GNU General Public License as published by the Free Software
26             # Foundation; either version 2 of the License, or (at your option) any later
27             # version.
28             #
29             # -----------------------------------------------------------------------------
30              
31 5     5   23 use Path::Tiny qw(path);
  5         9  
  5         226  
32 5     5   8238 use Shell::EnvImporter;
  0            
  0            
33             use Role::Tiny;
34              
35              
36             # Description:
37             # Returnvalue is ARCH set in the system-profile.
38             # Wrapper for old getArch()-version. Use getPortageMakeParam() instead.
39             #
40             # Example:
41             # $arch=$pxs->getArch();
42             sub getArch {
43             my $self = shift;
44             return $self->getPortageMakeParam('ARCH');
45             }
46              
47             # Description:
48             # Returns the profile tree as array
49             # "depth first, left to right, with duplicate parent paths being sourced
50             # for every time they are encountered"
51             sub getProfileTree {
52             my $self = shift;
53             my $curPath = shift;
54             my @path;
55              
56             my $parent = path("$curPath/parent");
57             if ( -e $parent ) {
58             foreach my $line ($parent->lines({ chomp => 1 })) {
59             push @path, $self->getProfileTree("$curPath/$line");
60             }
61             }
62             push @path, $curPath;
63             return @path;
64             }
65              
66             # Description:
67             # Helper for getPortageMakeParam()
68             sub getPortageMakeParamHelper {
69             my $self = shift;
70             my $curPath = shift;
71             my @files = ();
72              
73             foreach my $profile ( $self->getProfileTree($curPath) ) {
74             push(@files,"$profile/make.defaults") if (-e "$profile/make.defaults");
75             }
76             return @files;
77             }
78              
79             # Description:
80             # Returnvalue is $PARAM set in the system-profile.
81             #
82             # Example:
83             # $arch=$pxs->getPortageMakeParam();
84             sub getPortageMakeParam {
85             my $self = shift;
86             my $param = shift;
87             my @files = ();
88             my @etcfiles = ( $self->{'MAKE_GLOBALS_PATH'}, $self->{'MAKE_CONF_PATH'}) ;
89             my $v = '';
90             my $parent = '';
91             my $curPath;
92              
93             if(!-e $self->{'MAKE_PROFILE_PATH'}) {
94             $self->print_err('Profile not set!');
95             exit(0);
96             }
97             else {
98             $curPath=$self->getProfilePath();
99             }
100              
101             @files=$self->getPortageMakeParamHelper($curPath);
102             push(@files,@etcfiles);
103              
104             foreach (@files) {
105             my $importer = Shell::EnvImporter->new( shell => "bash",
106             file => $_,
107             auto_run => 1,
108             auto_import => 1
109             );
110              
111             $importer->shellobj->envcmd('set');
112             $importer->run();
113              
114             if ($ENV{$param}) {
115             $v=$ENV{$param};
116             $v=~s/\\t/ /g;
117             $v=~s/\t/ /g;
118             $v=~s/^\$'(.*)'$/$1/m;
119             $v=~s/^'(.*)'$/$1/m;
120             $v=~s/\\n/ /g;
121             $v=~s/\\|\'|\\'|\$//gmxs;
122             $v=~s/^\s//;
123             $v=~s/\s$//;
124             $v=~s/\s{2,}/ /g;
125             }
126              
127             $importer->restore_env();
128             }
129              
130             # - Defaults >
131             if ($param eq 'PORTDIR' && !$v) {
132             $v= $self->{PREFIX}->child('usr/portage');
133             }
134              
135             return $v;
136             }
137              
138             # Description:
139             # Returnvalue is PORTDIR from make.conf or make.globals (make.conf overrules make.globals).
140             # This function initializes itself at the first time it is called and reuses $self->{'PORTDIR'}
141             # as a return value from then on.
142             #
143             # Provides:
144             # $self->{'PORTDIR'}
145             #
146             # Parameters:
147             # $forcereload is optional and forces a reload of the make.conf and make.globals files.
148             #
149             # Example:
150             # $portdir=$pxs->getPortdir([$forcereload]);
151             sub getPortdir {
152             die "please use pxs->portdir";
153             }
154              
155             # Description:
156             # Returnvalue is PORTDIR_OVERLAY from make.conf or make.globals (make.conf overrules make.globals).
157             #
158             # Parameters:
159             # $forcereload is optional and forces a reload of the make.conf and make.globals files.
160             #
161             # Example:
162             # @portdir_overlay=$pxs->getPortdirOverlay();
163             sub getPortdirOverlay {
164             my $self = shift;
165             my $forcereload = shift;
166              
167             return split(/ /, $self->config->getParam('PORTDIR_OVERLAY', 'lastseen'));
168             }
169              
170             # Description:
171             # Returnvalue is the content of the given file.
172             # $filecontent=$pxs->getFileContents($file);
173             sub getFileContents {
174             die 'getFileContents(foo) is deprecated, use Path::Tiny; path(foo)->slurp';
175             }
176              
177             # Description:
178             # Returns an array containing all packages that match $searchString
179             # @packages=$pxs->searchInstalledPackage($searchString);
180             sub searchInstalledPackage {
181             my $self = shift;
182             my $searchString = shift; if (! $searchString) { $searchString=''; }
183             my @matches = ();
184             my $s_cat = '';
185             my $s_pak = '';
186             my $m_cat = 0;
187              
188             # - escape special chars >
189             $searchString =~ s/\+/\\\+/g;
190              
191             # - split >
192             if ($searchString=~m/\//) {
193             ($s_cat,$s_pak)=split(/\//,$searchString);
194             }
195             else {
196             $s_pak=$searchString;
197             }
198              
199             $s_cat=~s/\*//g;
200             $s_pak=~s/\*//g;
201              
202             # - read categories >
203             my $dhc = path($self->{'PKG_DB_DIR'})->iterator;
204             if (defined $dhc) {
205             while (defined(my $tc = $dhc->())) {
206             $m_cat=0;
207             if ($s_cat ne '') {
208             if ($tc->basename=~m/$s_cat/i) {
209             $m_cat=1;
210             }
211             else {
212             next;
213             }
214             }
215              
216             # - not excluded and $_ is a dir?
217             if (! $self->{'EXCLUDE_DIRS'}{$tc->basename} && -d $tc) {
218             my $dhp = $tc->iterator;
219             while (defined(my $tp = $dhp->())) {
220             # - check if packagename matches
221             # (faster if we already check it now) >
222             if ($tp->basename =~m/$s_pak/i || $s_pak eq '') {
223             # - not excluded and $_ is a dir?
224             if (! $self->{'EXCLUDE_DIRS'}{$tp->basename} && -d $tp) {
225             if (($s_cat ne '') && ($m_cat)) {
226             push(@matches,$tc->basename.'/'.$tp->basename);
227             }
228             elsif ($s_cat eq '') {
229             push(@matches,$tc->basename.'/'.$tp->basename);
230             }
231             }
232             }
233             }
234             undef $dhp;
235             }
236             }
237             }
238             undef $dhc;
239              
240             return (sort @matches);
241             }
242              
243             sub _foreach_category {
244             my ( $self, $repo , $callback ) = @_;
245             return () unless -d $repo;
246             for my $category ($self->getCategories($repo)) {
247             my $path = $repo . '/' . $category;
248             if ( not -e $path ){
249             die "Category $path expected, but does not exist";
250             }
251             if ( not -d $path ){
252             die "Category $path exists, but is not a dir";
253             }
254             if ( not -r $path ){
255             warn "Category $path exists, but not readable, skipping";
256             next;
257             }
258             local $_ = {
259             category => $category,
260             path => $path
261             };
262             my $result = $callback->();
263             return if defined $result and $result eq 'BAIL';
264             }
265             }
266             sub _foreach_package {
267             my ( $self, $repo, $category, $callback ) = @_;
268             return () unless -d $repo;
269             my $category_path = $repo . '/' . $category;
270             return () unless -d $category_path;
271             return () unless -r $category_path;
272             my $dhc = path( $category_path )->iterator;
273             while(defined(my $tp = $dhc->()) ){
274             next if $self->{'EXCLUDE_DIRS'}{$tp->basename};
275             local $_ = {
276             category => $category,
277             package => $tp->basename,
278             path => $tp
279             };
280             my $result = $callback->();
281             return if defined $result and $result eq 'BAIL';
282             }
283             }
284              
285             sub _searchPackage_like {
286             my ( $self, $searchString, $repo ) = @_ ;
287             return () unless -d $repo;
288             $searchString =~ s/\+/\\\+/g;
289             my @matches;
290             # - read categories >
291             $self->_foreach_category( $repo => sub {
292             $self->_foreach_package( $repo => $_->{category} => sub {
293             return unless $_->{package} =~ m/$searchString/i;
294             return unless -d $_->{path};
295             push @matches, $_->{category} . '/' . $_->{package};
296             });
297             });
298             return (sort @matches);
299             }
300              
301             sub _searchPackage_exact {
302             my ( $self, $searchString, $repo ) = @_ ;
303             return () unless -d $repo;
304             my @matches;
305             # - read categories >
306             $self->_foreach_category( $repo => sub {
307             $self->_foreach_package( $repo => $_->{category} => sub {
308             return unless $_->{package} eq $searchString;
309             return unless -d $_->{path};
310             push @matches, $_->{category} . '/' . $_->{package};
311             });
312             });
313             return (sort @matches);
314             }
315              
316             # Description:
317             # Search for packages in given repository.
318             # @packages=$pxs->searchPackage($searchString [,$mode, $repo] );
319             #
320             # Parameters:
321             # searchString: string to search for
322             # mode: like || exact
323             # repo: repository to search in
324             #
325             # Examples:
326             # @packages=$pxs->searchPackage('perl');
327             # @packages=$pxs->searchPackage('perl','exact');
328             # @packages=$pxs->searchPackage('perl','like','/usr/portage');
329             # @packages=$pxs->searchPackage('git','exact','/usr/local/portage');
330             sub searchPackage {
331             my $self = shift;
332             my $searchString = shift;
333             my $mode = shift;
334             my $repo = shift;
335             my @matches = ();
336              
337             if (!$mode) { $mode='like'; }
338             $repo=$self->portdir if (!$repo);
339             if (!-d $repo) { return (); }
340              
341             if ($mode eq 'like') {
342             return $self->_searchPackage_like($searchString, $repo );
343             }
344             if ($mode eq 'exact') {
345             return $self->_searchPackage_exact($searchString, $repo );
346             }
347             die "Unknown search mode $mode";
348             }
349              
350             # Description:
351             # Returns the value of $param. Expects filecontents in $file.
352             # $valueOfKey=$pxs->getParamFromFile($filecontents,$key,{firstseen,lastseen});
353             # e.g.
354             # $valueOfKey=$pxs->getParamFromFile($pxs->getFileContents("/path/to.ebuild"),"IUSE","firstseen");
355             sub getParamFromFile {
356             my $self = shift;
357             my $file = shift;
358             my $param = shift;
359             my $mode = shift; # ("firstseen","lastseen") - default is "lastseen"
360             my $c = 0;
361             my $d = 0;
362             my @lines = ();
363             my $value = ''; # value of $param
364              
365             # - split file in lines >
366             @lines = split(/\n/,$file);
367              
368             for($c=0;$c<=$#lines;$c++) {
369             next if $lines[$c]=~m/^#/;
370              
371             # - remove comments >
372             $lines[$c]=~s/#(.*)//g;
373              
374             # - remove leading whitespaces and tabs >
375             $lines[$c]=~s/^[ \t]+//;
376              
377             if ($lines[$c]=~/^$param="(.*)"/) {
378             # single-line with quotationmarks >
379             $value=$1;
380              
381             last if ($mode eq 'firstseen');
382             }
383             elsif ($lines[$c]=~/^$param="(.*)/) {
384             # multi-line with quotationmarks >
385             $value=$1.' ';
386             for($d=$c+1;$d<=$#lines;$d++) {
387             # - look for quotationmark >
388             if ($lines[$d]=~/(.*)"?/) {
389             # - found quotationmark; append contents and leave loop >
390             $value.=$1;
391             last;
392             }
393             else {
394             # - no quotationmark found; append line contents to $value >
395             $value.=$lines[$d].' ';
396             }
397             }
398              
399             last if ($mode eq 'firstseen');
400             }
401             elsif ($lines[$c]=~/^$param=(.*)/) {
402             # - single-line without quotationmarks >
403             $value=$1;
404              
405             last if ($mode eq 'firstseen');
406             }
407             }
408              
409             # - clean up value >
410             $value=~s/^[ \t]+//; # remove leading whitespaces and tabs
411             $value=~s/[ \t]+$//; # remove trailing whitespaces and tabs
412             $value=~s/\t/ /g; # replace tabs with whitespaces
413             $value=~s/ {2,}/ /g; # replace 1+ whitespaces with 1 whitespace
414              
415             return $value;
416             }
417              
418             # Description:
419             # Returns useflag settings of the given (installed) package.
420             # @useflags=$pxs->getUseSettingsOfInstalledPackage("dev-perl/perl-5.8.8-r3");
421             sub getUseSettingsOfInstalledPackage {
422             my $self = shift;
423             my $package = shift;
424             my $tmp_filecontents = '';
425             my @package_IUSE = ();
426             my @package_USE = ();
427             my @USEs = ();
428             my $hasuse = '';
429              
430             my $IUSE_PATH = path($self->{PKG_DB_DIR} )->child($package, 'IUSE');
431             my $USE_PATH = path($self->{PKG_DB_DIR} )->child($package, 'USE' );
432              
433             if (-e $IUSE_PATH ) {
434             $tmp_filecontents = $IUSE_PATH->slurp;
435             }
436             $tmp_filecontents =~s/\n//g;
437             @package_IUSE = split(/ /,$tmp_filecontents);
438             if (-e $USE_PATH ) {
439             $tmp_filecontents = $USE_PATH->slurp;
440             }
441             $tmp_filecontents =~s/\n//g;
442             @package_USE = split(/ /,$tmp_filecontents);
443              
444             foreach my $thisIUSE (@package_IUSE) {
445             next if ($thisIUSE eq '');
446             $hasuse = '-';
447             foreach my $thisUSE (@package_USE) {
448             if ($thisIUSE eq $thisUSE) {
449             $hasuse='';
450             last;
451             }
452             }
453             push(@USEs,$hasuse.$thisIUSE);
454             }
455              
456             return @USEs;
457             }
458              
459             # Description:
460             # @listOfEbuilds=$pxs->getAvailableEbuilds(category/packagename,[$repo]);
461             sub getAvailableEbuilds {
462             my $self = shift;
463             my $catPackage = shift;
464             my $repo = shift;
465             my @packagelist = ();
466              
467             $repo=$self->portdir if (!$repo);
468             if (!-d $repo) { return (); }
469              
470             my $repo_path = path($repo);
471             my $category = $repo_path->child( $catPackage );
472              
473             if (-e $category) {
474             # - get list of ebuilds >
475             my $dh = $category->iterator();
476             while (defined(my $ebuild = $dh->())) {
477             if ($ebuild->basename =~ m/(.+)\.ebuild$/) {
478             push(@packagelist,$ebuild);
479             }
480             }
481             }
482              
483             return @packagelist;
484             }
485              
486             # Description:
487             # @listOfEbuildVersions=$pxs->getAvailableEbuildVersions(category/packagename,[$repo]);
488             sub getAvailableEbuildVersions {
489             my $self = shift;
490             my $catPackage = shift;
491             my $repo = shift;
492             my @packagelist;
493              
494             @packagelist = map { $self->getEbuildVersion($_) } $self->getAvailableEbuilds($catPackage,$repo);
495              
496             return @packagelist;
497             }
498              
499             # Description:
500             # $bestVersion=$pxs->getBestEbuildVersion(category/packagename,[$repo]);
501             sub getBestEbuildVersion {
502             my $self = shift;
503             my $catPackage = shift;
504             my $repo = shift;
505              
506             my @versions = map { PortageXS::Version->new($_) } $self->getAvailableEbuildVersions($catPackage,$repo);
507             my @best_version = sort { $a <=> $b } (@versions);
508             return $best_version[-1];
509             }
510              
511             # Description:
512             # @listOfArches=$pxs->getAvailableArches();
513             sub getAvailableArches {
514             my $self = shift;
515             return $self->portdir->child('profiles','arch.list')->lines({ chomp => 1 });
516             }
517              
518             # Description:
519             # Reads from /etc/portagexs/categories/$listname.list and returns all entries as an array.
520             # @listOfCategories=$pxs->getPortageXScategorylist($listname);
521             sub getPortageXScategorylist {
522             my $self = shift;
523             my $category = shift;
524             my $etcpath = path($self->{'PORTAGEXS_ETC_DIR'});
525             return $etcpath->child('categories',$category . '.list')->lines({ chomp => 1 });
526             }
527              
528             # Description:
529             # Returns all available packages from the given category.
530             # @listOfPackages=$pxs->getPackagesFromCategory($category,[$repo]);
531             # E.g.:
532             # @listOfPackages=$pxs->getPackagesFromCategory("dev-perl","/usr/portage");
533             sub getPackagesFromCategory {
534             my $self = shift;
535             my $category = shift;
536             my $repo = shift;
537             my @packages = ();
538              
539             return () if !$category;
540             $repo= $self->portdir if (!$repo);
541              
542             my $repo_path = path($repo);
543             my $category_path = $repo_path->child( $category );
544              
545             if (-d $category_path ) {
546             my $dhp = $category_path->iterator;
547             while (defined( my $tp = $dhp->())) {
548             # - not excluded and $_ is a dir?
549             if (! $self->{'EXCLUDE_DIRS'}{$tp->basename} && -d $tp) {
550             push(@packages,$tp);
551             }
552             }
553             undef $dhp;
554             }
555              
556             return @packages;
557             }
558              
559             # Description:
560             # Returns package(s) where $file belongs to.
561             # (Actually this is an array and not a scalar due to a portage design bug.)
562             # @listOfPackages=$pxs->fileBelongsToPackage("/path/to/file");
563             sub fileBelongsToPackage {
564             my $self = shift;
565             my $file = shift;
566              
567             my @matches = ();
568              
569             # - read categories >
570             my $dhc = path( $self->{'PKG_DB_DIR'} )->iterator;
571             if (defined $dhc) {
572             while (defined(my $tc = $dhc->())) {
573             # - not excluded and $_ is a dir?
574             if (! $self->{EXCLUDE_DIRS}{$tc->basename} && -d $tc) {
575             my $dhp = $tc->iterator;
576             while (defined(my $tp = $dhp->())) {
577             my $contents = $tp->child('CONTENTS');
578             next unless -f $contents;
579             my $fh = $contents->openr;
580             while (<$fh>) {
581             if ($_=~m/$file/) {
582             push(@matches,$tc->basename.'/'.$tp->basename);
583             last;
584             }
585             }
586             close $fh;
587             }
588             }
589             }
590             }
591              
592             return @matches;
593             }
594              
595             # Description:
596             # Returns all files provided by $category/$package.
597             # @listOfFiles=$pxs->getFilesOfInstalledPackage("$category/$package");
598             sub getFilesOfInstalledPackage {
599             my $self = shift;
600             my $package = shift;
601             my @files = ();
602              
603             # - find installed versions & loop >
604             foreach my $pkg ($self->searchInstalledPackage($package)) {
605             my $pkg = ( ref $pkg ? $pkg : do {
606             path($self->{PKG_DB_DIR})->child($pkg);
607             });
608             foreach my $file_line ( $pkg->child('CONTENTS')->lines({ chomp => 1 } )) {
609             push(@files,(split(/ /,$file_line))[1]);
610             }
611             }
612              
613             return @files;
614             }
615              
616             # Description:
617             # Returns version of an ebuild.
618             # $version=$pxs->getEbuildVersion("foo-1.23-r1.ebuild");
619             sub getEbuildVersion {
620             my $self = shift;
621             my $version = shift;
622             $version =~ s/\.ebuild$//;
623             $version =~ s/^([a-zA-Z0-9\-_\/\+]*)-([0-9\.]+[a-zA-Z]?)/$2/;
624              
625             return $version;
626             }
627              
628             # Description:
629             # Returns name of an ebuild (w/o version).
630             # $version=$pxs->getEbuildName("foo-1.23-r1.ebuild");
631             sub getEbuildName {
632             my $self = shift;
633             my $version = shift;
634             my $name = $version;
635              
636             $version =~ s/^([a-zA-Z0-9\-_\/\+]*)-([0-9\.]+[a-zA-Z]?)/$2/;
637              
638             return substr($name,0,length($name)-length($version)-1);
639             }
640              
641             # Description:
642             # Returns the repo_name of the given repo.
643             # $repo_name=$pxs->getReponame($repo);
644             # Example:
645             # $repo_name=$pxs->getRepomane("/usr/portage");
646             sub getReponame {
647             my $self = shift;
648             my $repo = shift;
649             my $repo_name = '';
650              
651             my $repofile = path($repo)->child('profiles','repo_name' );
652             if (-f $repofile ) {
653             $repo_name = $repofile->slurp();
654             chomp($repo_name);
655             return $repo_name;
656             }
657              
658             return '';
659             }
660              
661             # Description:
662             # Returns an array of URLs of the given mirror.
663             # @mirrorURLs=$pxs->resolveMirror($mirror);
664             # Example:
665             # @mirrorURLs=$pxs->resolveMirror('cpan');
666             sub resolveMirror {
667             my $self = shift;
668             my $mirror = shift;
669             my $mirrorlist = $self->portdir->child('profiles/thirdpartymirrors');
670              
671             foreach my $q_mirror ($mirrorlist->lines({ chomp => 1 })) {
672             my @p=split(/\t/,$q_mirror);
673             if ($mirror eq $p[0]) {
674             return split(/ /,$p[2]);
675             }
676             }
677              
678             return;
679             }
680              
681             # Description:
682             # Returns list of valid categories (from $repo/profiles/categories)
683             # @categories=$pxs->getCategories($repo);
684             # Example:
685             # @categories=$pxs->getCategories('/usr/portage');
686             sub getCategories {
687             my $self = shift;
688             my $repo = shift;
689              
690             my $categoryfile = path($repo)->child('profiles/categories');
691             if (-e $categoryfile) {
692             return $categoryfile->lines({ chomp => 1 });
693             }
694             my %not_a_category = (
695             'packages','distfiles','profiles','eclass','licenses','metadata','scripts'
696             );
697              
698             my @categories;
699             my $it = path($repo)->iterator;
700             while(defined(my $tc = $it->()) ){
701             next if $self->{'EXCLUDE_DIRS'}{$tc->basename};
702             next if exists $not_a_category{$tc->basename};
703             next if not -d $tc;
704             push @categories, $tc->basename;
705             }
706             return (@categories);
707             }
708              
709             # Description:
710             # Returns path to profile.
711             # $path=$pxs->getProfilePath();
712             sub getProfilePath {
713             my $self = shift;
714              
715             my $profile_path = path($self->{'MAKE_PROFILE_PATH'});
716             my $etcdir = path($self->{'ETC_DIR'});
717             my $rl_target = readlink($profile_path);
718              
719             if (-e $etcdir->child($rl_target)) {
720             return $etcdir->child($rl_target)
721             }
722             elsif (-e $rl_target ) {
723             return $rl_target;
724             }
725              
726             return;
727             }
728              
729             # Description:
730             # Returns all packages that are in the world file.
731             # @packages=$pxs->getPackagesFromWorld();
732             sub getPackagesFromWorld {
733             my $self = shift;
734              
735             if (-e $self->{'PATH_TO_WORLDFILE'}) {
736             return path($self->{'PATH_TO_WORLDFILE'})->lines({ chomp => 1 });
737             }
738              
739             return ();
740             }
741              
742             # Description:
743             # Records package in world file.
744             # $pxs->recordPackageInWorld($package);
745             sub recordPackageInWorld {
746             my $self = shift;
747             my $package = shift;
748             my %world = ();
749              
750             # - get packages already recorded in world >
751             foreach ($self->getPackagesFromWorld()) {
752             $world{$_}=1;
753             }
754              
755             # - add $package >
756             $world{$package}=1;
757              
758             # - write world file >
759             my $fh = path($self->{'PATH_TO_WORLDFILE'})->openw;
760             foreach (keys %world) {
761             print $fh $_,"\n";
762             }
763             close $fh;
764              
765             return 1;
766             }
767              
768             # Description:
769             # Removes package from world file.
770             # $pxs->removePackageFromWorld($package);
771             sub removePackageFromWorld {
772             my $self = shift;
773             my $package = shift;
774             my %world = ();
775              
776             # - get packages already recorded in world >
777             foreach ($self->getPackagesFromWorld()) {
778             $world{$_}=1;
779             }
780              
781             # - remove $package >
782             $world{$package}=0;
783              
784             # - write world file >
785             my $fh = path($self->{'PATH_TO_WORLDFILE'})->openw;
786             foreach (keys %world) {
787             print $fh $_,"\n" if ($world{$_});
788             }
789             close $fh;
790              
791             return 1;
792             }
793              
794             # Description:
795             # Returns path to profile.
796             # $pxs->resetCaches();
797             sub resetCaches {
798             my $self = shift;
799              
800             # - Console >
801              
802             # - System - getHomedir >
803             $self->{'CACHE'}{'System'}{'getHomedir'}{'homedir'}=undef;
804              
805             # - Useflags - getUsedescs >
806             foreach my $k1 (keys %{$self->{'CACHE'}{'Useflags'}{'getUsedescs'}}) {
807             $self->{'CACHE'}{'Useflags'}{'getUsedescs'}{$k1}{'use.desc'}{'initialized'}=undef;
808             foreach my $k2 (keys %{$self->{'CACHE'}{'Useflags'}{'getUsedescs'}{$k1}{'use.desc'}{'use'}}) {
809             $self->{'CACHE'}{'Useflags'}{'getUsedescs'}{$k1}{'use.desc'}{'use'}{$k2}=undef;
810             }
811             $self->{'CACHE'}{'Useflags'}{'getUsedescs'}{$k1}{'use.desc'}{'use'}=undef;
812             $self->{'CACHE'}{'Useflags'}{'getUsedescs'}{$k1}{'use.local.desc'}=undef;
813             }
814              
815             # - Useflags - getUsemasksFromProfile >
816             $self->{'CACHE'}{'Useflags'}{'getUsemasksFromProfile'}{'useflags'}=undef;
817              
818             return 1;
819             }
820              
821             # Description:
822             # Search packages by maintainer. Returns an array of packages.
823             # @packages=$pxs->searchPackageByMaintainer($searchString,[$repo]);
824             # Example:
825             # @packages=$pxs->searchPackageByMaintainer('ian@gentoo.org');
826             # @packages=$pxs->searchPackageByMaintainer('ian@gentoo.org','/usr/local/portage/');
827             sub searchPackageByMaintainer {
828             my $self = shift;
829             my $searchString = shift;
830             my $repo = shift;
831             my $dhc;
832             my $dhp;
833             my $tc;
834             my $tp;
835             my @matches = ();
836             my @fields = ();
837              
838             #if (!$mode) { $mode='like'; }
839             $repo=$self->portdir if (!$repo);
840             if (!-d $repo) { return (); }
841              
842             # - read categories >
843             foreach my $pkg ($self->searchPackage('','like',$repo)) {
844             my $metaxml = path($repo)->child($pkg, 'metadata.xml');
845             if (-e $metaxml ) {
846             my $buffer= $metaxml->slurp();
847             if ($buffer =~ m/$searchString(.*)?<\/email>/i) {
848             push(@matches,$pkg);
849             }
850             elsif ($buffer =~ m/$searchString(.*)?<\/name>/i) {
851             push(@matches,$pkg);
852             }
853             }
854             }
855              
856             return (sort @matches);
857             }
858              
859             # Description:
860             # Search packages by herd. Returns an array of packages.
861             # @packages=$pxs->searchPackageByHerd($searchString,[$repo]);
862             # Example:
863             # @packages=$pxs->searchPackageByHerd('perl');
864             # @packages=$pxs->searchPackageByHerd('perl','/usr/local/portage/');
865             sub searchPackageByHerd {
866             my $self = shift;
867             my $searchString = shift;
868             my $repo = shift;
869             my $dhc;
870             my $dhp;
871             my $tc;
872             my $tp;
873             my @matches = ();
874             my @fields = ();
875              
876             #if (!$mode) { $mode='like'; }
877             $repo=$self->portdir if (!$repo);
878             if (!-d $repo) { return (); }
879              
880             # - read categories >
881             foreach my $pkg ($self->searchPackage('','like',$repo)) {
882             my $metaxml = path($repo)->child($pkg, 'metadata.xml');
883             if (-e $metaxml ) {
884             my $buffer= $metaxml->slurp();
885             if ($buffer =~ m/$searchString(.*)?<\/herd>/i) {
886             push(@matches,$metaxml->parent);
887             }
888             }
889             }
890              
891             return (sort @matches);
892             }
893              
894             1;
895              
896             __END__