Multi Make Script
A Raku script for selecting build system by what files are present in current directory
mk [build_rule]
Checks if there is a justfile, Makefile, or package.json in that order. If no argument is given, the
build rules are extracted and presented using fzf for fuzzy selection. If an argument is present,
it will be passed to just, make, or npm respectively.
#!/usr/bin/env raku
# Build wrapper with optional fuzzy find of build rules.
#
# Will try these build commands in this order:
# - just - if justfile exists
# - make - if Makefile exists
# - npm - if package.json exists
#
# If no argument is given build rules will be extracted and selectable using fuzzy find.
#
# Dependencies:
# - just
# - make
# - npm
# - fzf
# - jq
#
# Main ------------------------------------------------------------------------
sub MAIN(*@args) {
if './justfile'.IO.f {
say "Using just (justfile)";
just_do_it(@args);
}
elsif './Makefile'.IO.f {
say "Using make (Makefile)";
make_it();
}
elsif './package.json'.IO.f {
say "Using npm (package.json)";
npm_it(@args);
}
else {
say "ERROR: No just, make, or package.json files in directory!";
exit 1;
}
}
# Just ------------------------------------------------------------------------
sub just_do_it(*@args) {
if !@args { shell "just --choose" }
else { shell "just @args[]" }
}
# Make ------------------------------------------------------------------------
sub make_it(*@args) {
if !@args {
my $rule = fzf_makefile_rule();
return unless $rule;
@args.push($rule);
}
shell "make @args[]";
}
sub fzf_makefile_rule() {
my @rules = find_makefile_rules();
my $rulelines = @rules.join("\n");
return shell("echo \$(echo '$rulelines' | fzf)", :merge).out.lines()[0];
}
sub find_makefile_rules(Str $filepath = './Makefile') {
my @rules is Array;
for './Makefile'.IO.lines -> $line {
@rules.push($0) if $line ~~ /^ (<[a..zA..Z_\-]>+) ':' /;
}
return @rules;
}
# NPM -------------------------------------------------------------------------
sub npm_it(*@args) {
if !@args {
my $cmd = fzf_npm_commands();
return unless $cmd;
@args.push($cmd);
}
shell "npm @args[]";
}
sub fzf_npm_commands() {
my @cmds = shell('jq -r \'.scripts | keys[]\' ./package.json', :merge).out.lines();
my $cmdlines = @cmds.join("\n");
return shell("echo \$(echo '$cmdlines' | fzf)", :merge).out.lines()[0];
}