Gentoo-Overlay

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

 - All namespaces now declare $AUTHORITY

 [Packaging]
 - Update LICENSE (Year, Indent, Address)
 - Move author/release tests to xt/
 - Update repository.url
 - Set x_authority

1.0.0 2011-08-02T10:24:40Z
 [Features]
 - Have a new iteration interface for easy overlay walking. ( Partially Existed in code but was undocumented )
 - Can now iterate by 'ebuilds'.

 [Internals]
 - Restyled a lot of the internals because the 'has' form I was using was ugly and buggy.

 [Meta]
 - resource URI's moved to https:// only.

 [Modules::New]
 - Gentoo::Overlay::Ebuild # A representaition of an individual ebuild.

MANIFEST  view on Meta::CPAN

.mailmap
.perltidyrc
.travis.yml
Changes
LICENSE
MANIFEST
META.json
META.yml
Makefile.PL
README
corpus/overlay_0/keepdir
corpus/overlay_1/keepdir
corpus/overlay_1/profiles/keepdir
corpus/overlay_2/fake-category/keepdir
corpus/overlay_2/metadata/keepdir
corpus/overlay_2/profiles/repo_name
corpus/overlay_3/fake-category-2/keepdir
corpus/overlay_3/fake-category/keepdir
corpus/overlay_3/metadata/keepdir
corpus/overlay_3/profiles/categories
corpus/overlay_3/profiles/repo_name
corpus/overlay_4/fake-category-2/keepdir
corpus/overlay_4/fake-category/keepdir
corpus/overlay_4/metadata/keepdir
corpus/overlay_4/profiles/categories
corpus/overlay_4/profiles/repo_name
corpus/overlay_5/fake-category-2/fake-package/fake-package-1.0.0.ebuild
corpus/overlay_5/fake-category-2/keepdir
corpus/overlay_5/fake-category/keepdir
corpus/overlay_5/metadata/keepdir
corpus/overlay_5/profiles/categories
corpus/overlay_5/profiles/repo_name
dist.ini
dist.ini.meta
examples/portage.pl
lib/Gentoo/Overlay.pm
lib/Gentoo/Overlay/Category.pm
lib/Gentoo/Overlay/Ebuild.pm
lib/Gentoo/Overlay/Exceptions.pm
lib/Gentoo/Overlay/Package.pm
lib/Gentoo/Overlay/Types.pm
maint/perlcritic.rc.gen.pl

corpus/overlay_2/profiles/repo_name  view on Meta::CPAN

overlay_2

corpus/overlay_3/profiles/repo_name  view on Meta::CPAN

overlay_3

corpus/overlay_4/profiles/repo_name  view on Meta::CPAN

overlay_3

corpus/overlay_5/profiles/repo_name  view on Meta::CPAN

overlay_3

examples/portage.pl  view on Meta::CPAN

#!/usr/bin/perl

use strict;
use warnings;

use Gentoo::Overlay;

my $overlay = Gentoo::Overlay->new( path => '/usr/portage' );

my %categories = $overlay->categories;

for my $category ( sort keys %categories ) {
  print $categories{$category}->pretty_name, "\n";

  my %packages = $categories{$category}->packages;

  for my $package ( sort keys %packages ) {
    print "   " . $packages{$package}->pretty_name . "\n";
  }
}

lib/Gentoo/Overlay.pm  view on Meta::CPAN




sub _build_name {
  my ($self) = shift;
  my $f = $self->default_path( repo_name => );
  if ( not $f->exists or $f->is_dir ) {
    exception(
      ident   => 'no repo_name',
      message => <<'EOF',
No repo_name file for overlay at: %{overlay_path}s
 Expects:%{expected_path}s
EOF
      payload => {
        overlay_path  => $self->path->stringify,
        expected_path => $f->stringify,
      },
    );
  }
  return [ $f->lines_raw( { chomp => 1 } ) ]->[0];

}



lib/Gentoo/Overlay.pm  view on Meta::CPAN




sub _build__profile_dir {
  my ($self) = shift;
  my $pd = $self->default_path( profiles => );
  if ( not $pd->exists or not $pd->is_dir ) {
    exception(
      ident   => 'no profile directory',
      message => <<'EOF',
No profile directory for overlay at: %{overlay_path}s
  Expects:%{expected_path}s
EOF
      payload => {
        overlay_path  => $self->path->stringify,
        expected_path => $pd->stringify,
      },
    );
  }
  return $pd->absolute;
}




lib/Gentoo/Overlay.pm  view on Meta::CPAN




sub _build__categories {
  my ($self) = @_;
  my $cf = $self->default_path('catfile');
  if ( not $cf->exists or $cf->is_dir ) {
    warning(
      ident   => 'no category file',
      message => <<'EOF',
No category file for overlay %{name}s, expected: %{category_file}s.
 Falling back to scanning
EOF
      payload => {
        name          => $self->name,
        category_file => $cf->stringify,
      },
    );
    goto $self->can('_build___categories_scan');
  }
  goto $self->can('_build___categories_file');

lib/Gentoo/Overlay.pm  view on Meta::CPAN





sub _build___categories_file {
  my ($self) = shift;
  my %out;
  for my $cat ( $self->default_path('catfile')->lines_raw( { chomp => 1 } ) ) {
    my $category = Gentoo::Overlay::Category->new(
      name    => $cat,
      overlay => $self,
    );
    if ( !$category->exists ) {
      exception(
        ident   => 'missing category',
        message => <<'EOF',
category %{category_name}s is not an existing directory (%{expected_path}s) for overlay %{overlay_name}s
EOF
        payload => {
          category_name => $category->name,
          expected_path => $category->path->stringify,
          overlay_name  => $self->name,
        },
      );
      next;
    }
    $out{$cat} = $category;
  }
  return \%out;
}


lib/Gentoo/Overlay.pm  view on Meta::CPAN


sub _build___categories_scan {
  my ($self) = shift;
  my %out;
  my $it = $self->path->absolute->iterator();
  while ( my $entry = $it->() ) {
    my $cat = $entry->basename;
    next if Gentoo::Overlay::Category->is_blacklisted($cat);

    my $category = Gentoo::Overlay::Category->new(
      overlay => $self,
      name    => $cat,
    );
    next unless $category->exists();
    $out{$cat} = $category;
  }
  return \%out;

}


lib/Gentoo/Overlay.pm  view on Meta::CPAN

=head1 NAME

Gentoo::Overlay - Tools for working with Gentoo Overlays

=head1 VERSION

version 2.001002

=head1 SYNOPSIS

  my $overlay = Gentoo::Overlay->new( path => '/usr/portage' );

  my $name       = $overlay->name();
  my %categories = $overlay->categories();

  print "Overlay $name 's categories:\n";
  for( sort keys %categories ){
    printf "%30s : %s", $_, $categories{$_};
  }

  # Overlay gentoo 's categories:
  #  .....
  #  dev-lang      : /usr/portage/dev-lang
  #  .....

There will be more features eventually, this is just a first release.

=head1 METHODS

=head2 default_path

Useful function to easily wrap the class-wide method with a per-object sugar.

    $overlay->default_path('profiles');
    ->
    ::Overlay->_default_paths->{'profiles'}->($overlay);
    ->
    $overlay->path->subdir('profiles')


    $overlay->default_path('category','foo');
    ->
    ::Overlay->_default_path('category')->( $overlay, 'foo' );
    ->
    $overlay->path->subdir('foo')

    $overlay->default_path('repo_name');
    ->
    ::Overlay->_default_path('repo_name')->( $overlay );
    ->
    $overlay->_profile_dir->file('repo_name')

They're class wide functions, but they need individual instances to work.

=head2 iterate

  $overlay->iterate( $what, sub {
      my ( $context_information ) = shift;

  } );

The iterate method provides a handy way to do walking across the whole tree stopping at each of a given type.

=over 4

=item * C<$what = 'categories'>

  $overlay->iterate( categories => sub {
      my ( $self, $c ) = shift;
      # $c->{category_name}  # String
      # $c->{category}       # Category Object
      # $c->{num_categories} # How many categories are there to iterate
      # $c->{last_category}  # Index ID of the last category.
      # $c->{category_num}   # Index ID of the current category.
  } );

=item * C<$what = 'packages'>

  $overlay->iterate( packages => sub {
      my ( $self, $c ) = shift;
      # $c->{category_name}  # String
      # $c->{category}       # Category Object
      # $c->{num_categories} # How many categories are there to iterate
      # $c->{last_category}  # Index ID of the last category.
      # $c->{category_num}   # Index ID of the current category.
      #
      # $c->{package_name}   # String
      # See ::Category for the rest of the fields provided by the package Iterator.
      # Very similar though.
  } );

=item * C<$what = 'ebuilds'>

  $overlay->iterate( ebuilds => sub {
      my ( $self, $c ) = shift;
      # $c->{category_name}  # String
      # $c->{category}       # Category Object
      # $c->{num_categories} # How many categories are there to iterate
      # $c->{last_category}  # Index ID of the last category.
      # $c->{category_num}   # Index ID of the current category.
      #
      # $c->{package_name}   # String
      # See ::Category for the rest of the fields provided by the package Iterator.
      # Very similar though.

lib/Gentoo/Overlay.pm  view on Meta::CPAN

L<< C<RepositoryName>|Gentoo::Overlay::Types/Gentoo__Overlay_RepositoryName >>

L</_build_name>

=head1 ATTRIBUTE ACCESSORS

=head2 category_names

Returns a list of the names of all the categories.

    my @list = sort $overlay->category_names();

L</_categories>

=head2 categories

Returns a hash of L<< C<Category>|Gentoo::Overlay::Category >> objects.

    my %hash = $overlay->categories;
    print $hash{dev-perl}->pretty_name; # dev-perl/::gentoo

L</_categories>

=head2 get_category

Returns a Category Object for a given category name

    my $cat = $overlay->get_category('dev-perl');

L</_categories>

=head1 PRIVATE ATTRIBUTES

=head2 _profile_dir

Path to the profile sub-directory.

    isa => Dir, ro, lazy_build

lib/Gentoo/Overlay.pm  view on Meta::CPAN

L<Gentoo::Overlay::Types/Gentoo__Overlay_Category>

L<< C<MooseX::Types::Moose>|MooseX::Types::Moose >>

=head1 PRIVATE ATTRIBUTE ACCESSORS

=head2 _has_category

Returns if a named category exists

    $overlay->_has_category("dev-perl");

L</_categories>

=head1 PRIVATE CLASS ATTRIBUTES

=head2 _default_paths

Class-wide list of path generators.

    isa => HashRef[ CodeRef ], ro, lazy_build

L</_build__default_paths>

=head1 PRIVATE METHODS

=head2 _build_name

Extracts the repository name out of the file 'C<repo_name>'
in C<$OVERLAY/profiles/repo_name>

    $overlay->_build_name

L</name>

=head2 _build__profile_dir

Verifies the existence of the profile directory, and returns the path to it.

    $overlay->_build__profile_dir

L</_profile_dir>

=head2 _build__categories

Generates the Category Hash-Table, either by reading the categories index ( new, preferred )
or by traversing the directory ( old, discouraged )

    $category->_build_categories;

L</_categories>

L</_build___categories_scan>

L</_build___categories_file>

=head2 _build___categories_file

Builds the category map using the 'categories' file found in the overlays profile directory.

    $overlay->_build___categories_file

=head2 _build___categories_scan

Builds the category map the hard way by scanning the directory and then skipping things
that are files and/or blacklisted.

    $overlay->_build___categories_scan

=head2 _iterate_ebuilds

  $object->_iterate_ebuilds( ignored_value => sub {  } );

Handles dispatch call for

  $object->iterate( ebuilds => sub { } );

=head2 _iterate_categories

lib/Gentoo/Overlay/Category.pm  view on Meta::CPAN










has name => ( isa => Gentoo__Overlay_CategoryName, required, ro );
has overlay => ( isa => Gentoo__Overlay_Overlay, required, ro, coerce );
has path => ( lazy, ro,
  isa     => Path,
  default => sub {
    my ($self) = shift;
    return $self->overlay->default_path( category => $self->name );
  },
);








lib/Gentoo/Overlay/Category.pm  view on Meta::CPAN









sub pretty_name {
  my $self = shift;
  return $self->name . '/::' . $self->overlay->name;
}









lib/Gentoo/Overlay/Category.pm  view on Meta::CPAN

=head1 VERSION

version 2.001002

=head1 SYNOPSIS

Still limited functionality, more to come.

    my $category = ::Overlay::Category->new(
        name => 'dev-perl',
        overlay => '/usr/portage' ,
    );

    my $category = ::Overlay::Category->new(
        name => 'dev-perl',
        overlay => $overlay_object ,
    );

    $category->exists()  # is the category there, is it a directory?

    $category->pretty_name()  #  dev-perl/::gentoo

    $category->path()  # /usr/portage/dev-perl

    ::Overlay::Category->is_blacklisted('..') # is '..' a blacklisted category

lib/Gentoo/Overlay/Category.pm  view on Meta::CPAN

    ::Category->is_blacklisted('metadata') # true

=head2 pretty_name

A pretty form of the name.

    $category->pretty_name  # dev-perl/::gentoo

=head2 iterate

  $overlay->iterate( $what, sub {
      my ( $context_information ) = shift;

  } );

The iterate method provides a handy way to do walking across the whole tree stopping at each of a given type.

=over 4

=item * C<$what = 'packages'>

  $overlay->iterate( packages => sub {
      my ( $self, $c ) = shift;
      # $c->{package_name}  # String
      # $c->{package}       # Package Object
      # $c->{num_packages}  # How many packages are there to iterate
      # $c->{last_package}  # Index ID of the last package.
      # $c->{package_num}   # Index ID of the current package.
  } );

=item * C<$what = 'ebuilds'>

  $overlay->iterate( ebuilds => sub {
      my ( $self, $c ) = shift;
      # $c->{package_name}  # String
      # $c->{package}       # Package Object
      # $c->{num_packages}  # How many packages are there to iterate
      # $c->{last_package}  # Index ID of the last package.
      # $c->{package_num}   # Index ID of the current package.

      # $c->{ebuild_name}   # String
      # See ::Ebuild for the rest of the fields provided by the ebuild Iterator.
      # Very similar though.

lib/Gentoo/Overlay/Category.pm  view on Meta::CPAN

=head1 ATTRIBUTES

=head2 name

The classes short name

    isa => Gentoo__Overlay_CategoryName, required, ro

L<< C<CategoryName>|Gentoo::Overlay::Types/Gentoo__Overlay_CategoryName >>

=head2 overlay

The overlay it is in.

    isa => Gentoo__Overlay_Overlay, required, coerce

L<Gentoo::Overlay::Types/Gentoo__Overlay_Overlay>

=head2 path

The full path to the category

    isa => Dir, lazy, ro

lib/Gentoo/Overlay/Ebuild.pm  view on Meta::CPAN







has name => ( isa => Gentoo__Overlay_EbuildName, required, ro );
has package => (
  isa => Gentoo__Overlay_Package,
  required, ro,
  handles => [qw( overlay category )],
);

has path => (
  isa => File,
  ro,
  lazy,
  default => sub {
    my ($self) = shift;
    return $self->overlay->default_path( 'ebuild', $self->category->name, $self->package->name, $self->name );
  },
);








lib/Gentoo/Overlay/Ebuild.pm  view on Meta::CPAN






sub pretty_name {
  my $self     = shift;
  my $filename = $self->name;
  ## no critic (RegularExpressions)
  $filename =~ s/\.ebuild$//;
  return q{=} . $self->category->name . q{/} . $filename . q{::} . $self->overlay->name;
}

no Moo;
1;

__END__

=pod

=encoding UTF-8

lib/Gentoo/Overlay/Ebuild.pm  view on Meta::CPAN

  isa => Gentoo__Overlay_EbuildName, required, ro

L<< C<EbuildName>|Gentoo::Overlay::Types/Gentoo__Overlay_EbuildName >>

=head2 package

The package object this ebuild is within.

  isa => Gentoo__Overlay_EbuildName, required, ro

  accessors => overlay category

L<< C<Package>|Gentoo::Overlay::Types/Gentoo__Overlay_Package >>

L</overlay>

L</category>

=head2 path

The full path to the ebuild.

    isa => File, lazy, ro

L<MooseX::Types::Path::Tiny/File>

=head1 ATTRIBUTE ACCESSORS

=head2 overlay

  $ebuild->overlay -> Gentoo::Overlay::Package->overlay

L<Gentoo::Overlay::Package/overlay>

L</package>

=head2 category

  $ebuild->category -> Gentoo::Overlay::Package->category

L<Gentoo::Overlay::Package/category>

L</package>

lib/Gentoo/Overlay/Package.pm  view on Meta::CPAN










has name => ( isa => Gentoo__Overlay_PackageName, required, ro, );
has category => ( isa => Gentoo__Overlay_Category, required, ro, handles => [qw( overlay )], );
has path => (
  isa => Path,
  ro,
  lazy,
  default => sub {
    my ($self) = shift;
    return $self->overlay->default_path( 'package', $self->category->name, $self->name );
  },
);








lib/Gentoo/Overlay/Package.pm  view on Meta::CPAN









sub pretty_name {
  my $self = shift;
  return $self->category->name . q{/} . $self->name . q{::} . $self->overlay->name;
}









lib/Gentoo/Overlay/Package.pm  view on Meta::CPAN

    ::Package->is_blacklisted('..') # true

=head2 pretty_name

A pretty form of the name

    $package->pretty_name # dev-perl/Moose::gentoo

=head2 iterate

  $overlay->iterate( $what, sub {
      my ( $context_information ) = shift;

  } );

The iterate method provides a handy way to do walking across the whole tree stopping at each of a given type.

=over 4

=item * C<$what = 'ebuilds'>

  $overlay->iterate( ebuilds => sub {
      my ( $self, $c ) = shift;
      # $c->{ebuild_name}  # String
      # $c->{ebuild}       # Ebuild Object
      # $c->{num_ebuilds}  # How many ebuild are there to iterate
      # $c->{last_ebuild}  # Index ID of the last ebuild.
      # $c->{ebuild_num}   # Index ID of the current ebuild.
  } );

=back

lib/Gentoo/Overlay/Package.pm  view on Meta::CPAN

    isa => Gentoo__Overlay_PackageName, required, ro

L<< C<PackageName>|Gentoo::Overlay::Types/Gentoo__Overlay_PackageName >>

=head2 category

The category object that this package is in.

    isa => Gentoo__Overlay_Category, required, ro

    accessors => overlay

L<< C<Category>|Gentoo::Overlay::Types/Gentoo__Overlay_Category >>

L</overlay>

=head2 path

The full path to the package.

    isa => Dir, lazy, ro

L<MooseX::Types::Path::Tiny/Dir>

=head1 ATTRIBUTE ACCESSORS

=head2 overlay

    $package->overlay -> Gentoo::Overlay::Category->overlay

L<Gentoo::Overlay::Category/overlay>

L</category>

=head2 ebuild_names

    for( $package->ebuild_names ){
        print $_;
    }

L</_ebuilds>

t/basic.t  view on Meta::CPAN

  else {
    fail( "FORCED FAIL:" . $reason . ': Ident is \'' . $ident . '\'' );
  }
  if ($needs_diag) {
    diag($exception);
  }
}

need_fail_ident(
  exception {
    my $overlay = Gentoo::Overlay->new();
  },
  'Objects need a path',
  'path parameter required'
);

is(
  exception {
    my $overlay = Gentoo::Overlay->new( path => "$base/overlay_0" );
  },
  undef,
  "Providing path => Success"
);

need_fail_ident(
  exception {
    Gentoo::Overlay->new( path => "$base/overlay_0" )->_profile_dir;
  },
  'Need a profile dir',
  'no profile directory',
);

is(
  exception {
    Gentoo::Overlay->new( path => "$base/overlay_1" )->_profile_dir;
  },
  undef,
  'Having a profile dir => Success'
);

need_fail_ident(
  exception {
    Gentoo::Overlay->new( path => "$base/overlay_1" )->name;
  },
  'Need a repo_name file',
  'no repo_name',
);

is(
  exception {
    Gentoo::Overlay->new( path => "$base/overlay_2" )->name;
  },
  undef,
  'Having a repo_name file => Success'
);

is( Gentoo::Overlay->new( path => "$base/overlay_2" )->name, 'overlay_2', '->name is right' );
my $stderr;
my %cats;
is(
  exception {
    $stderr = stderr_from {
      %cats = Gentoo::Overlay->new( path => "$base/overlay_2" )->categories;
    };
  },
  undef,
  'call to categories lives'
);
like( $stderr, qr/No category file/, 'categories without indices warn' );
is_deeply( [ sort keys %cats ], [ sort qw( fake-category) ], 'Good discovered categories' );
{
  local $Gentoo::Overlay::Exceptions::WARNINGS_ARE = qw( fatal );

  need_fail_ident(
    exception {
      %cats = Gentoo::Overlay->new( path => "$base/overlay_2" )->categories;
    },
    'call to categories without a categories file fatals when asked to',
    'no category file',
  );

}
need_fail_ident(
  exception {
    %cats = Gentoo::Overlay->new( path => "$base/overlay_3" )->categories;
  },
  'call to categories w/ missing category dies',
  'missing category',
);

is(
  exception {
    $stderr = '';
    $stderr = stderr_from {
      %cats = Gentoo::Overlay->new( path => "$base/overlay_4" )->categories;
    };

  },
  undef,
  'Proper category tree doesn\'t die'
);
is( $stderr, '', 'No output was made to stderr' );
is_deeply( [ sort keys %cats ], [ sort qw( fake-category fake-category-2) ], 'Good discovered categories' );

done_testing;

t/ebuild.t  view on Meta::CPAN

use FindBin;

my $base = "$FindBin::Bin/../corpus";

use Gentoo::Overlay;

my $its = 0;

my $ebuild = {};

Gentoo::Overlay->new( path => "$base/overlay_5" )->iterate(
  'ebuilds' => sub {
    my ( $self, $config ) = @_;
    $its++;
    $ebuild = $config;
  }
);
is( $its, 1, 'Iterator iterates once' );

is( $ebuild->{category_name}, 'fake-category-2',           'simple category name' );
is( $ebuild->{package_name},  'fake-package',              'simple package name' );

t/iterate.t  view on Meta::CPAN


use Test::More 0.96;
use FindBin;

my $base = "$FindBin::Bin/../corpus";

use Gentoo::Overlay;

my $its = 0;

Gentoo::Overlay->new( path => "$base/overlay_4" )->iterate(
  'categories' => sub {
    my ( $self, $config ) = @_;
    $its++;
  }
);

is( $its, 2, 'Iterator iterates twice' );

my $pits = 0;

Gentoo::Overlay->new( path => "$base/overlay_4" )->iterate(
  'packages' => sub {
    my ( $self, $config ) = @_;
    $pits++;
  }
);

is( $pits, 0, 'Iterator iterates none ( no packages yet )' );

done_testing;



( run in 0.834 second using v1.01-cache-2.11-cpan-49f99fa48dc )