App-af

 view release on metacpan or  search on metacpan

bin/af  view on Meta::CPAN

#!perl

use strict;
use warnings;
use 5.014;
#use lib::findbin '../lib'; # dev-only
use App::af;
use File::chdir;

# PODNAME: af
# ABSTRACT: Command line tool for alienfile
# VERSION


package App::af::download 0.18 {
  use Moose;
  use namespace::autoclean;
  use MooseX::Types::Path::Tiny qw( AbsPath );
  use Path::Tiny qw( path );

  with 'App::af';
  with 'App::af::role::alienfile';


  has local => (
    is       => 'ro',
    isa      => AbsPath,
    traits   => ['App::af::opt'],
    short    => 'l',
    coerce   => 1,
    opt_type => 's',
    default  => '.',
  );

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

    unless(-d $self->local)
    {
      say STDERR "no such directory: @{[ $self->local ]}";
      return 2;
    }

    local $ENV{ALIEN_INSTALL_TYPE} = 'share';
    my $build = $self->build;
    $build->load_requires('configure');
    $build->load_requires('share');
    eval { $build->download };
    warn $@ if $@;

    unless(defined $build->install_prop->{download} &&
           length $build->install_prop->{download})
    {
      say STDERR "Recipe did not seem to download a file or directory";
      return 2;
    }

    my $download = path($build->install_prop->{download});

    if(-f $download)
    {
      my $to = $self->local->child($download->basename);
      $download->copy($to) || die "unable to copy $download => $to $!";
      say "Wrote archive to $to";
    }
    elsif(-d $download)
    {
      require File::Copy::Recursive;
      my $to = $self->local->child($download->basename);
      File::Copy::Recursive::dircopy("$download", "$to") || die "unable to copy $download => $to $!";
      say "Wrote directory to $to";
    }
    else
    {
      say STDERR "Recipe did not seem to download a file or directory";
      return 2;
    }

    0;
  }

  __PACKAGE__->meta->make_immutable;
}

package App::af::probe 0.18 {
  use Moose;
  use namespace::autoclean;
  use MooseX::Types::Path::Tiny qw( AbsPath );
  use File::Temp qw( tempdir );

  with 'App::af';
  with 'App::af::role::alienfile';
  with 'App::af::role::libandblib';


  has root => (
    is       => 'ro',
    isa      => AbsPath,
    traits   => ['App::af::opt'],
    opt_type => 's',
    coerce   => 1,
    lazy     => 1,
    default  => sub {
      shift->_tmp->child('root');
    },
  );

  has _tmp => (
    is      => 'ro',
    isa     => AbsPath,
    lazy    => 1,
    default => sub {
      my $dir = Path::Tiny->new(tempdir( CLEANUP => 1));
      $dir->child($_)->mkpath for qw( root stage prefix );
      $dir;
    },
  );

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

    my $build = $self->build( root => $self->root->stringify );

    $build->set_stage($self->_tmp->child('stage')->stringify);
    $build->set_prefix($self->_tmp->child('prefix')->stringify);
    $build->load_requires('configure');
    my $type = $build->install_type;

    say "install type: $type";

    0;
  }
}

package App::af::install 0.18 {
  use Moose;
  use namespace::autoclean;
  use File::Temp qw( tempdir );
  use MooseX::Types::Path::Tiny qw( AbsPath );
  use YAML qw( Dump );
  use Path::Tiny qw( path );

  with 'App::af';
  with 'App::af::role::alienfile';
  with 'App::af::role::libandblib';


  has stage => (
    is       => 'ro',
    isa      => AbsPath,
    traits   => ['App::af::opt'],
    coerce   => 1,
    lazy     => 1,
    opt_type => 's',
    default  => sub {
      tempdir( CLEANUP => 1);
    },
  );

  has prefix => (
    is     => 'rw',
    isa    => AbsPath,
    traits => ['App::af::opt'],
    opt_type => 's',
    coerce => 1,
  );

  has type => (
    is       => 'ro',
    isa      => 'Str',
    traits   => ['App::af::opt'],
    opt_type => 's',
  );

  has dry_run => (
    is     => 'ro',
    isa    => 'Int',
    traits => ['App::af::opt'],
  );

  has root => (
    is       => 'ro',
    isa      => AbsPath,
    traits   => ['App::af::opt'],
    opt_type => 's',
    coerce   => 1,
    lazy     => 1,
    default  => sub {
      tempdir( CLEANUP => 1);
    },
  );

  has before => (
    is       => 'ro',
    isa      => 'ArrayRef[Str]',
    traits   => ['App::af::opt'],
    opt_type => 's{2}',

bin/af  view on Meta::CPAN

    }


    if($self->dry_run && ! defined $self->prefix)
    {
      $self->prefix(tempdir( CLEANUP => 1 ));
    }

    unless(defined $self->prefix)
    {
      say STDERR "You must specify a prefix with --prefix or use --dry-run";
      return 2;
    }

    if(-d $self->prefix->child('_alien'))
    {
      my $test = $self->prefix->child('_alien/test');
      eval { $test->touch };
      if($@)
      {
        say STDERR "prefix is not writable.  You may need to use su or sudo";
        return 2;
      }
      $test->remove;
    }

    $build->set_stage($self->stage->stringify);
    $build->set_prefix($self->prefix->stringify);
    $build->load_requires('configure');
    $build->load_requires($build->install_type);
    $build->download;
    $build->build;

    unless($self->dry_run)
    {
      require File::Copy::Recursive;

      if(-d $self->prefix)
      {
        # this is slightly dangerous.
        foreach my $child ($self->prefix->children)
        {
          say "rm -rf $child";
          $_->remove_tree({ safe => 0 }) for $self->prefix->children;
        }
      }

      File::Copy::Recursive::dircopy($self->stage, $self->prefix) || die "unable to copy @{[ $self->stage ]} => @{[ $self->prefix ]} $!";
      say "copied staged install into @{[ $self->prefix ]}";
    };

    print Dump($build->runtime_prop);

    0;
  }
  __PACKAGE__->meta->make_immutable;
}

package App::af::requires 0.18 {
  use Moose;
  use namespace::autoclean;
  use YAML qw( Dump );


  with 'App::af';
  with 'App::af::role::alienfile';
  with 'App::af::role::phase';

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

    $self->check_phase;

    my $build = $self->build;

    if($self->phase eq 'all')
    {
      print Dump({
        map { $_ => $build->requires($_) } qw( configure any share system )
      });
    }
    else
    {
      print Dump($build->requires($self->phase));
    }

    0;
  }

  __PACKAGE__->meta->make_immutable;
}

package App::af::missing 0.18 {
  use Moose;
  use namespace::autoclean;
  use Capture::Tiny qw( capture );

  with 'App::af';
  with 'App::af::role::alienfile';
  with 'App::af::role::phase';


  has plugin => (
    is     => 'ro',
    isa    => 'Int',
    traits => ['App::af::opt'],
  );

  has precompile => (
    is     => 'ro',
    isa    => 'Int',
    traits => ['App::af::opt'],
  );

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

    $self->check_phase;

    if($self->plugin)
    {
      require Alien::Build;
      require Test2::Mock;

      my %need;

      my $mock = Test2::Mock->new(class => 'Alien::Build::Meta');
      $mock->around('apply_plugin' => sub {
        my($orig, $self, @args) = @_;
        local @INC = @INC;
        push @INC, sub {
          my(undef, $filename) = @_;
          my $mod = $filename;
          $mod =~ s{/}{::}g;
          $mod =~ s{\.pm$}{};
          $need{$mod}++;
        };
        eval { $orig->($self, @args) };
      });
      my(undef, undef, $build) = capture { $self->build };
      print "$_\n" for sort keys %need;
      return 0;
    }

    if($self->precompile)
    {
      my %need;

      foreach my $line ($self->file->lines)
      {
        chomp $line;
        if($line =~ /^\s*use\s+([A-Za-z_0-9]+(::[A-Za-z_0-9]+)*)/)
        {
          my $mod = $1;
          eval qq{ use $mod () };
          if($@) { $need{$mod}++ };
        }
      }
      print "$_\n" for sort keys %need;
      exit 0;
    }

    my(undef,undef, $build) = capture { $self->build };

    my @reqs;
    my %need;

    if($self->phase eq 'all')
    {
      $build->load_requires('configure');
      capture { $build->probe };
      @reqs = map { $build->requires($_) } qw( configure any share system );
      @reqs = (
        $build->requires('configure'),
        $build->requires($build->install_type),
      );
    }
    else
    {
      @reqs = ( $build->requires($self->phase) );
    }

    foreach my $reqs (@reqs)
    {
      foreach my $module (sort keys %$reqs)
      {
        my $version = $reqs->{$module};
        eval {
          my $pm = $module . '.pm';
          $pm =~ s/::/\//g;
          require $pm;
          !$version || $module->VERSION($version);
        };
        $need{$module} = 1 if $@
      }
    }

    say $_ for sort keys %need;

    0;
  }

  __PACKAGE__->meta->make_immutable;
}

package App::af::prop 0.18 {
  use Moose;
  use namespace::autoclean;


  with 'App::af';

  has class => (
    is       => 'ro',
    isa      => 'Str',
    traits   => ['App::af::opt'],
    short    => 'c',
    opt_type => 's',
  );

  has $_ => (
    is       => 'ro',
    isa      => 'Int',
    traits   => ['App::af::opt'],
  ) for qw( static cflags libs modversion bin_dir );

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

    unless($self->class)
    {
      say STDERR "You must specify a class.\n";
      return 2;
    }

    my $class = $self->class =~ /::/ ? $self->class : 'Alien::' . $self->class;

    {
      my $pm = $class . '.pm';
      $pm =~ s/::/\//g;
      require $pm;
    }
    unless($class->can('runtime_prop'))
    {
      say STDERR "$class was not installed with Alien::Build";
      return 2;
    }

    my $prop = $class->runtime_prop;

    unless($prop)
    {
      say STDERR "$class was not installed with Alien::Build";
      return 2;
    }

    my $found = 0;

    if($self->cflags)
    {
      if($self->static)
      {
        say $class->cflags_static;
      }
      else
      {
        say $class->cflags;
      }
      $found = 1;
    }

    if($self->libs)
    {
      if($self->static)
      {
        say $class->libs_static;
      }
      else
      {
        say $class->libs;
      }
      $found = 1;
    }

    if($self->bin_dir)
    {
      say $_ for $class->bin_dir;
      $found = 1;
    }

    if($self->modversion)
    {
      say $class->version // 'undef';
      $found = 1;
    }

    unless($found)
    {
      require YAML;
      print YAML::Dump($prop);
    }

    0;
  }
  __PACKAGE__->meta->make_immutable;
}

package App::af::list 0.18 {
  use Moose;
  use namespace::autoclean;
  use Path::Tiny qw( path );
  use Text::Table;


  with 'App::af';

  has long => (
    is       => 'ro',
    isa      => 'Int',
    traits   => ['App::af::opt'],
    short    => 'l',
  );

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

    my $table;
    $table = Text::Table->new('name', 'install type', 'alien version', 'package version')
      if $self->long;

    foreach my $inc (map { path($_)->absolute } @INC)
    {
      my $dist_root = $inc->child('auto/share/dist');
      next unless -d $dist_root;

      foreach my $dist_dir ($dist_root->children)
      {
        next unless -f $dist_dir->child('_alien/alien.json');
        my $dist = $dist_dir->basename;
        my $class = $dist;
        $class =~ s/-/::/g;

        unless($table)
        {
          say $class;
          next;
        }

        eval {
          my $pm = $class . '.pm';
          $pm =~ s/::/\//g;
          require $pm;
        };
        if($@)
        {
          $table->add($class, '---', '---');
        }
        else
        {
          my $install_type = eval { $class->install_type } // '---';
          my $perl_version = eval { $class->VERSION } // '---';
          my $pkg_version   = eval { $class->version } // '---';
          $table->add($class, $install_type, $perl_version, $pkg_version);
        }
      }

    }

    print $table if defined $table;



( run in 0.590 second using v1.01-cache-2.11-cpan-d8267643d1d )