Alien-Base-ModuleBuild

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

    [version 1.16]

     my $rule = $amb->alien_download_rule;

    This will return one of warn, digest, encrypt, digest_or_encrypt or
    digest_and_encrypt. This is based on the ALIEN_DOWNLOAD_RULE
    environment variable.

GUIDE TO DOCUMENTATION

    The documentation for Module::Build is broken up into sections:

    General Usage (Module::Build)

      This is the landing document for Alien::Base::ModuleBuild's parent
      class. It describes basic usage and background information. Its main
      purpose is to assist the user who wants to learn how to invoke and
      control Module::Build scripts at the command line.

      It also lists the extra documentation for its use. Users and authors
      of Alien:: modules should familiarize themselves with these

README  view on Meta::CPAN

      other Alien::Build documentation.

ENVIRONMENT

    ALIEN_ARCH

      Set to a true value to install to an arch-specific directory.

    ALIEN_DOWNLOAD_RULE

      This controls security options for fetching alienized packages over
      the internet. The legal values are:

      warn

	Warn if the package is either unencrypted or lacks a digest. This
	is currently the default, but will change in the near future.

      digest

	Fetch will not happen unless there is a digest for the alienized

README  view on Meta::CPAN

      digest_or_encrypt

	Fetch will only happen if the alienized package has a cryptographic
	signature digest, or if an encrypted protocol like https is used,
	or if the package is bundled with the Alien. This will be the
	default in the near future.

      digest_and_encrypt

	Fetch will only happen if the alienized package has a cryptographic
	signature digest, and is fetched via a secure protocol (like
	https). Bundled packages are also considered fetch via a secure
	protocol, but will still require a digest.

    ALIEN_FORCE

      Skips checking for an installed version and forces reinstalling the
      Alien target.

    ALIEN_INSTALL_NETWORK

      If true (the default if not defined), then network installs will be

lib/Alien/Base/ModuleBuild.pm  view on Meta::CPAN

[version 1.16]

 my $rule = $amb->alien_download_rule;

This will return one of C<warn>, C<digest>, C<encrypt>, C<digest_or_encrypt>
or C<digest_and_encrypt>.  This is based on the C<ALIEN_DOWNLOAD_RULE>
environment variable.

=head1 GUIDE TO DOCUMENTATION

The documentation for C<Module::Build> is broken up into sections:

=over

=item General Usage (L<Module::Build>)

This is the landing document for L<Alien::Base::ModuleBuild>'s parent class.
It describes basic usage and background information.
Its main purpose is to assist the user who wants to learn how to invoke
and control C<Module::Build> scripts at the command line.

lib/Alien/Base/ModuleBuild.pm  view on Meta::CPAN

=head1 ENVIRONMENT

=over 4

=item B<ALIEN_ARCH>

Set to a true value to install to an arch-specific directory.

=item B<ALIEN_DOWNLOAD_RULE>

This controls security options for fetching alienized packages over the internet.
The legal values are:

=over 4

=item C<warn>

Warn if the package is either unencrypted or lacks a digest.  This is currently
the default, but will change in the near future.

=item C<digest>

lib/Alien/Base/ModuleBuild.pm  view on Meta::CPAN


=item C<digest_or_encrypt>

Fetch will only happen if the alienized package has a cryptographic signature digest,
or if an encrypted protocol like C<https> is used, or if the package is bundled with
the L<Alien>.  This will be the default in the near future.

=item C<digest_and_encrypt>

Fetch will only happen if the alienized package has a cryptographic signature digest,
and is fetched via a secure protocol (like C<https>).  Bundled packages are also
considered fetch via a secure protocol, but will still require a digest.

=back

=item B<ALIEN_FORCE>

Skips checking for an installed version and forces reinstalling the Alien target.

=item B<ALIEN_INSTALL_NETWORK>

If true (the default if not defined), then network installs will be allowed.

lib/Alien/Base/ModuleBuild/Repository.pm  view on Meta::CPAN

sub location {
  my $self = shift;
  $self->{location} = shift if @_;
  return $self->{location};
}

sub is_network_fetch {
  die "must override in the subclass";
}

sub is_secure_fetch {
  die "must override in the subclass";
}

sub has_digest
{
  my($self) = @_;
  defined $self->{exact_filename} && $self->{exact_version} && (defined $self->{sha1} || defined $self->{sha256});
}

sub probe {
  my $self = shift;

  require Alien::Base::ModuleBuild;
  if(!Alien::Base::ModuleBuild->alien_install_network && $self->is_network_fetch) {
    die "network fetch is disabled via ALIEN_INSTALL_NETWORK";
  }

  my $rule = Alien::Base::ModuleBuild->alien_download_rule;
  if($rule eq 'warn') {

    unless($self->is_secure_fetch || $self->has_digest) {
      warn "!!! NOTICE OF FUTURE CHANGE IN BEHAVIOR !!!\n";
      warn "A future version of Alien::Base::ModuleBuild will die here by default with this exception: File fetch is insecure and has no digest.  Required by ALIEN_DOWNLOAD_RULE=digest_or_encrypt.";
      warn "!!! NOTICE OF FUTURE CHANGE IN BEHAVIOR !!!\n";
    }

  } elsif($rule eq 'digest') {

    unless($self->has_digest) {
      die "File fetch has no digest.  Required by ALIEN_DOWNLOAD_RULE=digest.";
    }

  } elsif($rule eq 'encrypt') {

    unless($self->is_secure_fetch) {
      die "File fetch is insecure.  Secure fetch required by ALIEN_DOWNLOAD_RULE=encrypt.";
    }

  } elsif($rule eq 'digest_or_encrypt') {

    unless($self->is_secure_fetch || $self->has_digest) {
      die "File fetch is insecure and has no digest.  Required by ALIEN_DOWNLOAD_RULE=digest_or_encrypt.";
    }

  } elsif($rule eq 'digest_and_encrypt') {

    unless($self->is_secure_fetch && $self->has_digest) {
      die "File fetch is insecure and has no digest.  Both are required by ALIEN_DOWNLOAD_RULE=digest_and_encrypt.";
    }

  } else {
    die 'internal error';
  }

  my $pattern = $self->{pattern};

  my @files;

lib/Alien/Base/ModuleBuild/Repository/FTP.pm  view on Meta::CPAN

use strict;
use warnings;
use parent 'Alien::Base::ModuleBuild::Repository';
use Carp;
use Net::FTP;

# ABSTRACT: HTTP repository handler
our $VERSION = '1.17'; # VERSION

sub is_network_fetch { 1 }
sub is_secure_fetch  { 0 }

sub connection {
  my $self = shift;

  return $self->{connection}
    if $self->{connection};

  # allow easy use of Net::FTP subclass
  $self->{protocol_class} ||= 'Net::FTP';

lib/Alien/Base/ModuleBuild/Repository/HTTP.pm  view on Meta::CPAN

use Alien::Base::ModuleBuild::Utils;
use parent 'Alien::Base::ModuleBuild::Repository';

# ABSTRACT: HTTP repository handler
our $VERSION = '1.17'; # VERSION

our $Has_HTML_Parser = eval { require HTML::LinkExtor; 1 };

sub is_network_fetch { 1 }

sub is_secure_fetch {
  my($self) = @_;

  (defined $self->{exact_filename} && $self->{exact_filename} =~ /^https:/) || ($self->{protocol}||'http') eq 'https';
}

sub connection {

  my $self = shift;

  return $self->{connection}

lib/Alien/Base/ModuleBuild/Repository/HTTP.pm  view on Meta::CPAN

  my $self = shift;
  my $file = shift || croak "Must specify file to download";

  my $protocol = $self->protocol;
  my $host = $self->{host};
  my $from = $self->location;

  my $uri = $self->build_uri($protocol, $host, $from, $file);
  $file = ($uri->path_segments())[-1];

  die "Attempted downgrad from https to http on URL $uri" if $self->is_secure_fetch && $uri !~ /^https:/;

  my $res = $self->connection->mirror($uri, $file);
  my ( $is_error, $content, $headers ) = $self->check_http_response( $res );
  croak "Download failed: " . $content if $is_error;

  my $disposition = $headers->{"content-disposition"};
  if ( defined($disposition) && ($disposition =~ /filename="([^"]+)"/ || $disposition =~ /filename=([^\s]+)/)) {
    my $new_filename = $1;
    rename $file, $new_filename;
    $self->{new_filename} = $new_filename;

lib/Alien/Base/ModuleBuild/Repository/HTTP.pm  view on Meta::CPAN

}

sub list_files {
  my $self = shift;

  my $protocol = $self->protocol;
  my $host = $self->host;
  my $location = $self->location;
  my $uri = $self->build_uri($protocol, $host, $location);

  die "Attempted downgrad from https to http on URL $uri" if $self->is_secure_fetch && $uri !~ /^https:/;

  my $res = $self->connection->get($uri);

  my ( $is_error, $content, undef, $base_url ) = $self->check_http_response( $res );
  if ( $is_error ) {
    carp $content;
    return ();
  }

  $self->{base_url} = $base_url;

lib/Alien/Base/ModuleBuild/Repository/Local.pm  view on Meta::CPAN

use Carp;
use File::chdir;
use File::Copy qw/copy/;
use Path::Tiny qw( path );
use parent 'Alien::Base::ModuleBuild::Repository';

# ABSTRACT: Local file repository handler
our $VERSION = '1.17'; # VERSION

sub is_network_fetch { 0 }
sub is_secure_fetch  { 1 }

sub new {
  my $class = shift;

  my $self = $class->SUPER::new(@_);

  # make location absolute
  local $CWD = $self->location;
  $self->location("$CWD");

t/alien_base_modulebuild_repository.t  view on Meta::CPAN

use Test2::V0 -no_srand => 1;
use Alien::Base::ModuleBuild::Repository;
use File::chdir;
use Path::Tiny qw( path );
use Capture::Tiny qw( capture_stderr );

my $network_fetch = 0;
my $secure_fetch = 1;
@INC = map { path($_)->absolute->stringify } @INC;

# This test will not pass with digest required.  It does not download anything
# off the internet.
$ENV{ALIEN_DOWNLOAD_RULE} = 'warn'              if defined $ENV{ALIEN_DOWNLOAD_RULE} && $ENV{ALIEN_DOWNLOAD_RULE} eq 'digest';
$ENV{ALIEN_DOWNLOAD_RULE} = 'digest_or_encrypt' if defined $ENV{ALIEN_DOWNLOAD_RULE} && $ENV{ALIEN_DOWNLOAD_RULE} eq 'digest_and_encrypt';

my $default = {
  protocol => 'test',
  host     => 'ftp.gnu.org',

t/alien_base_modulebuild_repository.t  view on Meta::CPAN

      {
        push @warnings, $message
      }
      else
      {
        warn $message;
      }
    };

    @warnings = ();
    $secure_fetch = 1;
    Alien::Base::ModuleBuild::Repository::Test->new($default)->probe;

    is
      \@warnings,
      [];

    @warnings = ();
    $secure_fetch = 0;
    Alien::Base::ModuleBuild::Repository::Test->new($default)->probe;

    is
      \@warnings,
      array {
        item match qr/^!!! NOTICE OF FUTURE CHANGE IN BEHAVIOR !!!/;
        item match qr/^A future version of Alien::Base::ModuleBuild will die here by default with this exception: File fetch is insecure and has no digest\.  Required by ALIEN_DOWNLOAD_RULE=digest_or_encrypt\./;
        item match qr/^!!! NOTICE OF FUTURE CHANGE IN BEHAVIOR !!!/;
        end;
      };

    @warnings = ();
    local $default->{sha1} = 'xxx';
    local $default->{exact_filename} = 'gsl-1.9.tar.gz.sig';
    local $default->{exact_version}  = 1.9;
    Alien::Base::ModuleBuild::Repository::Test->new($default)->probe;

t/alien_base_modulebuild_repository.t  view on Meta::CPAN


  };

  subtest 'digest' => sub {

    local $ENV{ALIEN_DOWNLOAD_RULE} = 'digest';
    is(
      Alien::Base::ModuleBuild->alien_download_rule, 'digest',
    );

    $secure_fetch = 0;

    is(
      dies { Alien::Base::ModuleBuild::Repository::Test->new($default)->probe },
      match qr/^File fetch has no digest\.  Required by ALIEN_DOWNLOAD_RULE=digest\./,
    );

    local $default->{sha1} = 'xxx';
    local $default->{exact_filename} = 'gsl-1.9.tar.gz.sig';
    local $default->{exact_version}  = 1.9;

t/alien_base_modulebuild_repository.t  view on Meta::CPAN


  };

  subtest 'encrypt' => sub {

    local $ENV{ALIEN_DOWNLOAD_RULE} = 'encrypt';
    is(
      Alien::Base::ModuleBuild->alien_download_rule, 'encrypt',
    );

    $secure_fetch = 0;

    is(
      dies { Alien::Base::ModuleBuild::Repository::Test->new($default)->probe },
      match qr/^File fetch is insecure\.  Secure fetch required by ALIEN_DOWNLOAD_RULE=encrypt\./,
    );

    $secure_fetch = 1;

    ok(
      lives { Alien::Base::ModuleBuild::Repository::Test->new($default)->probe },
    ) or diag($@);

  };

  subtest 'digest_or_encrypt' => sub {

    local $ENV{ALIEN_DOWNLOAD_RULE} = 'digest_or_encrypt';
    is(
      Alien::Base::ModuleBuild->alien_download_rule, 'digest_or_encrypt',
    );

    $secure_fetch = 0;

    is(
      dies { Alien::Base::ModuleBuild::Repository::Test->new($default)->probe },
      match qr/^File fetch is insecure and has no digest\.  Required by ALIEN_DOWNLOAD_RULE=digest_or_encrypt\./,
    );

    $secure_fetch = 1;

    ok(
      lives { Alien::Base::ModuleBuild::Repository::Test->new($default)->probe },
    ) or diag($@);

    $secure_fetch = 0;
    local $default->{sha1} = 'xxx';
    local $default->{exact_filename} = 'gsl-1.9.tar.gz.sig';
    local $default->{exact_version}  = 1.9;

    ok(
      lives { Alien::Base::ModuleBuild::Repository::Test->new($default)->probe },
    ) or diag($@);

    $secure_fetch = 1;

    ok(
      lives { Alien::Base::ModuleBuild::Repository::Test->new($default)->probe },
    ) or diag($@);

  };

  subtest 'digest_and_encrypt' => sub {

    local $ENV{ALIEN_DOWNLOAD_RULE} = 'digest_and_encrypt';
    is(
      Alien::Base::ModuleBuild->alien_download_rule, 'digest_and_encrypt',
    );

    $secure_fetch = 0;

    is(
      dies { Alien::Base::ModuleBuild::Repository::Test->new($default)->probe },
      match qr/^File fetch is insecure and has no digest\.  Both are required by ALIEN_DOWNLOAD_RULE=digest_and_encrypt\./,
    );

    $secure_fetch = 1;

    is(
      dies { Alien::Base::ModuleBuild::Repository::Test->new($default)->probe },
      match qr/^File fetch is insecure and has no digest\.  Both are required by ALIEN_DOWNLOAD_RULE=digest_and_encrypt\./,
    );

    $secure_fetch = 0;
    local $default->{sha1} = 'xxx';
    local $default->{exact_filename} = 'gsl-1.9.tar.gz.sig';
    local $default->{exact_version}  = 1.9;

    is(
      dies { Alien::Base::ModuleBuild::Repository::Test->new($default)->probe },
      match qr/^File fetch is insecure and has no digest\.  Both are required by ALIEN_DOWNLOAD_RULE=digest_and_encrypt\./,
    );

    $secure_fetch = 1;

    ok(
      lives { Alien::Base::ModuleBuild::Repository::Test->new($default)->probe },
    ) or diag($@);

  };

};

$secure_fetch = 1;

subtest 'no pattern' => sub {
  my $repo = Alien::Base::ModuleBuild::Repository::Test->new($default);

  my @filenames = $repo->list_files;

  my @files = $repo->probe();

  is( scalar @files, scalar @filenames, 'without pattern, probe returns an object for each file');
  isa_ok( $files[0], 'Alien::Base::ModuleBuild::File' );

t/alien_base_modulebuild_repository.t  view on Meta::CPAN


done_testing;

package Alien::Base::ModuleBuild::Repository::Test;

use strict;
use warnings;
use parent 'Alien::Base::ModuleBuild::Repository';

sub is_network_fetch { $network_fetch }
sub is_secure_fetch  { $secure_fetch }

sub list_files {
  my $self = shift;
  #files from GNU GSL FTP server, fetched 1/24/2012
  my @files = ( qw/
    gsl-1.0-gsl-1.1.patch.gz
    gsl-1.0.tar.gz
    gsl-1.1-gsl-1.1.1.patch.gz
    gsl-1.1.1-gsl-1.2.patch.gz
    gsl-1.1.1.tar.gz

t/alien_base_modulebuild_repository_ftp.t  view on Meta::CPAN

use Test2::V0 -no_srand => 1;
use Alien::Base::ModuleBuild::Repository::FTP;

is(
  Alien::Base::ModuleBuild::Repository::FTP->is_network_fetch,
  1
);

is(
  Alien::Base::ModuleBuild::Repository::FTP->is_secure_fetch,
  0
);

done_testing;

t/alien_base_modulebuild_repository_http.t  view on Meta::CPAN


subtest 'network fetch' => sub {

  is(
    Alien::Base::ModuleBuild::Repository::HTTP->is_network_fetch,
    1
  );

};

subtest 'secure fetch' => sub {

  is(
    Alien::Base::ModuleBuild::Repository::HTTP->new( protocol => 'http' )->is_secure_fetch,
    F(),
  );

  is(
    Alien::Base::ModuleBuild::Repository::HTTP->new( protocol => 'https' )->is_secure_fetch,
    T(),
  );

  is(
    Alien::Base::ModuleBuild::Repository::HTTP->new( protocol => 'http', exact_filename => 'https://foo' )->is_secure_fetch,
    T(),
  );

  is(
    Alien::Base::ModuleBuild::Repository::HTTP->new( protocol => 'http', exact_filename => 'http://foo' )->is_secure_fetch,
    F(),
  );

};

subtest 'verify tls' => sub {

  local $ENV{ALIEN_DOWNLOAD_RULE};
  delete $ENV{ALIEN_DOWNLOAD_RULE};

t/alien_base_modulebuild_repository_local.t  view on Meta::CPAN

use File::Basename qw/fileparse/;
use File::Temp;
use File::chdir;

is(
  Alien::Base::ModuleBuild::Repository::Local->is_network_fetch,
  0
);

is(
  Alien::Base::ModuleBuild::Repository::Local->is_secure_fetch,
  1
);

my $repo = Alien::Base::ModuleBuild::Repository::Local->new({ location => 't' });

my @files = $repo->list_files;
my $this_file = fileparse __FILE__;

ok( grep { $_ eq $this_file } @files, "found this file" );



( run in 0.658 second using v1.01-cache-2.11-cpan-39bf76dae61 )