Acme-Parataxis

 view release on metacpan or  search on metacpan

builder/Acme/Parataxis/Builder.pm  view on Meta::CPAN

# Based on Module::Build::Tiny which is copyright (c) 2011 by Leon Timmermans, David Golden.
# Module::Build::Tiny is free software; you can redistribute it and/or modify it under
# the same terms as the Perl 5 programming language system itself.
use v5.40;
use feature 'class';
no warnings 'experimental::class';
class    #
    Acme::Parataxis::Builder {
    use CPAN::Meta;
    use ExtUtils::Install qw[pm_to_blib install];
    use ExtUtils::InstallPaths 0.002;
    use File::Basename        qw[basename dirname];
    use File::Find            ();
    use File::Path            qw[mkpath rmtree];
    use File::Spec::Functions qw[catfile catdir rel2abs abs2rel splitdir curdir];
    use JSON::PP 2            qw[encode_json decode_json];

    # Not in CORE
    use Path::Tiny qw[path];
    use ExtUtils::Helpers 0.028 qw[make_executable split_like_shell detildefy];
    #
    field $action : param //= 'build';
    field $meta : reader = CPAN::Meta->load_file('META.json');

    # Params to Build script
    field $install_base  : param //= '';
    field $installdirs   : param //= '';
    field $uninst        : param //= 0;    # Make more sense to have a ./Build uninstall command but...
    field $install_paths : param //= ExtUtils::InstallPaths->new( dist_name => $meta->name );
    field $verbose       : param //= 0;
    field $dry_run       : param //= 0;
    field $pureperl      : param //= 0;
    field $jobs          : param //= 1;
    field $destdir       : param //= '';
    field $prefix        : param //= '';
    #
    ADJUST {
        -e 'META.json' or die "No META information provided\n";
    }
    method write_file( $filename, $content ) { path($filename)->spew_raw($content) or die "Could not open $filename: $!\n" }
    method read_file ($filename)             { path($filename)->slurp_utf8         or die "Could not open $filename: $!\n" }

    method step_build() {
        for my $pl_file ( find( qr/\.PL$/, 'lib' ) ) {
            ( my $pm = $pl_file ) =~ s/\.PL$//;
            system $^X, $pl_file->stringify, $pm and die "$pl_file returned $?\n";
        }

        # C Extension Compilation - removed conditional block
        say 'Building libparataxis...';
        require Affix::Build;    # This module is used for C compilation
        require Config;
        require File::Spec;
        my $arch_dir = catdir(qw[blib arch auto Acme Parataxis]);
        mkpath( $arch_dir, $verbose );
        my $build = Affix::Build->new(
            name  => 'parataxis',
            flags => {
                cflags => join( ' ',
                    ( $Config::Config{ccflags}, '-std=c11', map { '-I' . $_ } ( File::Spec->catdir( $Config::Config{archlibexp}, 'CORE' ), 'src' ) )
                ),
                ldflags => ( $^O eq 'MSWin32' ) ?
                    ( '-L' .
                        File::Spec->catdir( $Config::Config{archlibexp}, 'CORE' ) . ' -l' .
                        ( $Config::Config{libperl} =~ s/^lib//r =~ s/\.a$//r =~ s/\.lib$//r ) .
                        ' -lws2_32' ) : ( $^O eq 'darwin' ? '-undefined dynamic_lookup' : '' )
            },
            build_dir => $arch_dir,
            clean     => 0
        );

        # Add the C source file to be compiled. It's expected to be in 'lib/Acme/'
        $build->add('lib/Acme/Parataxis.c');
        say "Compiling and linking...";
        $build->compile_and_link();
        say "Build complete.";
        my %modules = map { $_ => catfile( 'blib', $_ ) } find( qr/\.pm$/,  'lib' );
        my %docs    = map { $_ => catfile( 'blib', $_ ) } find( qr/\.pod$/, 'lib' );
        my %scripts = map { $_ => catfile( 'blib', $_ ) } find( qr/(?:)/,   'script' );
        my %sdocs   = map { $_ => delete $scripts{$_} } grep {/.pod$/} keys %scripts;
        pm_to_blib( { %modules, %docs, %sdocs }, catdir(qw[blib lib auto]) );
        #
        mkpath( catdir(qw[blib script]), $verbose );
        for my $src ( keys %scripts ) {
            my $dest    = $scripts{$src};
            my $content = path($src)->slurp_raw;
            $content =~ s{^#!.*perl.*}{#!$^X};
            path($dest)->spew_raw($content);
            make_executable($dest);
        }
        #
        my %dist_shared   = map { $_ => catfile( qw[blib lib auto share dist],   $meta->name, abs2rel( $_, 'share' ) ) } find( qr/(?:)/, 'share' );
        my %module_shared = map { $_ => catfile( qw[blib lib auto share module], abs2rel( $_, 'module-share' ) ) } find( qr/(?:)/, 'module-share' );
        pm_to_blib( { %dist_shared, %module_shared }, catdir(qw[blib lib auto]) );
        mkpath( catdir(qw[blib arch]), $verbose );
        0;
    }
    method step_clean() { rmtree( $_, $verbose ) for qw[blib temp]; 0 }

    method step_install() {
        $self->step_build() unless -d 'blib';
        install(
            [   from_to           => $install_paths->install_map,
                verbose           => $verbose,
                dry_run           => $dry_run,
                uninstall_shadows => $uninst,
                skip              => undef,
                always_copy       => 1
            ]
        );
        0;
    }
    method step_realclean () { rmtree( $_, $verbose ) for qw[blib temp Build _build_params MYMETA.yml MYMETA.json]; 0 }

    method step_test() {
        $self->step_build() unless -d 'blib';
        require TAP::Harness::Env;
        require Config;
        my @libs = map { rel2abs( catdir( 'blib', $_ ) ) } qw[arch lib];
        local $ENV{PERL5LIB} = join( $Config::Config{path_sep}, @libs, ( defined $ENV{PERL5LIB} ? $ENV{PERL5LIB} : () ) );
        my %test_args = ( ( verbosity => $verbose ), ( jobs => $jobs ), ( color => -t STDOUT ), lib => [@libs], );
        TAP::Harness::Env->create( \%test_args )->runtests( sort map { $_->stringify } find( qr/\.t$/, 't' ) )->has_errors;



( run in 2.070 seconds using v1.01-cache-2.11-cpan-140bd7fdf52 )