-
-
Save gerdr/2891292 to your computer and use it in GitHub Desktop.
ufo with dwimmy dependency generation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl6 | |
sub dirwalk($dir = '.', Mu :$d = none(<. ..>), Mu :$f = *, | |
:&dx = -> $ {}, :&fx = -> $ {}) { | |
for dir($dir, :test(*)) -> $name { | |
given "$dir/$name" { | |
when .IO.f { | |
&fx.($_) if $f.ACCEPTS($name) | |
} | |
when .IO.d { | |
dirwalk($_, :$d, :$f, :&dx, :&fx) if $d.ACCEPTS($name) | |
} | |
} | |
} | |
&dx.($dir); | |
} | |
sub mkdir-p($file, Bool :$f = False) { | |
my @parents = $file.split('/'); | |
@parents.pop if $f; | |
my $path = ''; | |
for @parents { | |
$path ~= "$_/"; | |
mkdir($path) unless $path.IO.d; | |
} | |
} | |
sub rmdir-r($path) { | |
dirwalk($path, :dx(&rmdir), :fx(&unlink)) | |
} | |
sub compile($src, $dest) { | |
use lib <blib/lib blib/lib6>; | |
my $comp := pir::compreg__Ps('perl6'); | |
my $args := nqp::list; | |
nqp::push($args, $?FILE); | |
nqp::push($args, '--target=pir'); | |
nqp::push($args, "--output=$dest"); | |
nqp::push($args, $src); | |
$comp.command_line($args, :encoding<utf8>); | |
} | |
sub parse-makefile($file) { | |
gather for $file.IO.lines { | |
next unless /'.pir:'/; | |
my ($target, @deps) = .comb(/[<![:]>\S]+/); | |
take $target => @deps; | |
} | |
} | |
sub parse-pm-file($file) { | |
gather for $file.IO.lines { | |
take ~$0 if /^\s* ['use'|'need'] \s+ (\w+ ['::' \w+]*)/; | |
} | |
} | |
sub pir-from-pm($file) { | |
'blib/' ~ $file.subst(/\.pm6?$/, '.pir'); | |
} | |
sub name-from-pm($file) { | |
$file.subst(/^lib6?\/|\.pm6?$/, '', :g).subst('/', '::', :g); | |
} | |
multi MAIN() { | |
my $last-run = 'Makefile'.IO.f ?? 'Makefile'.IO.modified !! -Inf; | |
my @modules = gather <lib lib6>.grep(*.IO.d).map({ | |
dirwalk($_, :f(/\.pm6?$/), :fx(&take)) | |
}); | |
my %targets = @modules.map(&name-from-pm) Z=> @modules.map(&pir-from-pm); | |
my %deps = parse-makefile('Makefile') if 'Makefile'.IO.f; | |
for @modules { | |
next if $last-run > .IO.modified; | |
say "ufo: parsing $_"; | |
my $name = name-from-pm($_); | |
my $target = %targets{$name}; | |
my @deps = "blib/$_", | |
parse-pm-file($_).grep(* ne $name).map({ %targets{$_} // Nil }); | |
%deps{$target} = @deps; | |
} | |
my $ufo = "$*EXECUTABLE_NAME $?FILE"; | |
given open('Makefile', :w) { | |
LEAVE .close; | |
.say( | |
"build: {%targets.values} | |
clean: | |
$ufo rmdir blib | |
realclean: clean | |
$ufo rm Makefile | |
Makefile: {@modules} | |
$ufo | |
"); | |
for @modules -> $file { | |
.say( | |
"blib/$file: $file | |
$ufo cp $file blib/$file | |
"); | |
} | |
for %deps.kv -> $target, @deps { | |
.say( | |
"$target: {@deps} | |
$ufo compile {@deps[0]} $target | |
"); | |
} | |
} | |
} | |
multi MAIN('rm', *@files) { | |
unlink($_) for @files.grep(*.IO.e); | |
} | |
multi MAIN('rmdir', *@dirs) { | |
rmdir-r($_) for @dirs.grep(*.IO.e); | |
} | |
multi MAIN('compile', $src, $dest) { | |
mkdir-p($dest, :f); | |
compile($src, $dest); | |
} | |
multi MAIN('cp', $src, $dest) { | |
mkdir-p($dest, :f); | |
$src.IO.copy($dest); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment