Skip to content
This repository
tree: e815355173
Fetching contributors…

Cannot retrieve contributors at this time

file 81 lines (70 sloc) 2.613 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
use Pies;
use Panda::Common;
use File::Find;
use Shell::Command;

class Panda::Builder does Pies::Builder {
    has $.resources;

    sub die (Pies::Project $p, $d) is hidden_from_backtrace {
        X::Panda.new($p.name, 'build', $d).throw
    }

    method build-order(@module-files) {
        my @modules = map { path-to-module-name($_) }, @module-files;
        my %module-to-path = @modules Z=> @module-files;
        my %usages_of;
        for @module-files -> $module-file {
            my $fh = open($module-file.Str, :r);
            my $module = path-to-module-name($module-file);
            %usages_of{$module} = [];
            for $fh.lines() {
                if /^\s* 'use' \s+ (\w+ ['::' \w+]*)/ && $0 -> $used {
                    next if $used eq 'v6';
                    next if $used eq 'MONKEY_TYPING';

                    %usages_of{$module}.push(~$used);
                }
            }
        }
        my @order = topo-sort(@modules, %usages_of);

        return map { %module-to-path{$_} }, @order;
    }

    method build(Pies::Project $p) {
        my $workdir = $!resources.workdir($p);
        return unless "$workdir/lib".IO ~~ :d;
        indir $workdir, {
            my @files = find(dir => 'lib', name => /\.pm6?$/).list;
            my @dirs = @files.map(*.dir).uniq;
            mkpath "blib/$_" for @dirs;

            my @tobuild = self.build-order(@files);
            my $p6lib = "{cwd}/blib/lib:{cwd}/lib:{%*ENV<PERL6LIB>}";
            for @tobuild -> $file {
                $file.IO.copy: "blib/{$file.dir}/{$file.name}";
                shell "env PERL6LIB=$p6lib perl6 --target=pir "
                    ~ "--output=blib/{$file.dir}/"
                    ~ "{$file.name.subst(/\.pm6?$/, '.pir')} $file"
                    and die $p, "Failed building $file";
            }
        };
    }

    sub topo-sort(@modules, %dependencies) {
        my @order;
        my %color_of = @modules X=> 'not yet visited';
        sub dfs-visit($module) {
            %color_of{$module} = 'visited';
            for %dependencies{$module}.list -> $used {
                if (%color_of{$used} // '') eq 'not yet visited' {
                    dfs-visit($used);
                }
            }
            push @order, $module;
        }

        for @modules -> $module {
            if %color_of{$module} eq 'not yet visited' {
                dfs-visit($module);
            }
        }
        @order;
    }

    sub path-to-module-name($path) {
        $path.subst(/^'lib/'/, '').subst(/^'lib6/'/, '').subst(/\.pm6?$/, '').subst('/', '::', :g);
    }
}

# vim: ft=perl6
Something went wrong with that request. Please try again.