This commit is contained in:
Bryson Steck 2022-09-07 00:32:07 -06:00
commit 2936e9ab30
2 changed files with 178 additions and 0 deletions

9
Makefile Normal file
View file

@ -0,0 +1,9 @@
PREFIX = /usr/local
all:
install:
mkdir -p ${PREFIX}/bin
cp -f listen ${PREFIX}/bin
chmod 755 ${PREFIX}/bin/listen

169
listen Executable file
View file

@ -0,0 +1,169 @@
#!/usr/bin/env perl
# TODO:
# implement -s and -r flags
# implement --timeout flag in main loop
# create --help / -h flag and possibly a man page
#
# listen: a simple configurable build system
# created by Bryson Steck, @brysonsteck on GitHub
# free and open source under the GPL Version 3
#
# Usage
# listen [flags] [file(s) to watch] [command(s) to run on file changes]
#
# Flags
# -a if all of the files have changed, required if multiple files
# -o if any one of the files have changed, required if multiple files
# -s to use checksum on file change instead of when the file was modified
# -r immediately run exec command, then start listening
# --timeout=[time] change timeout time in whole seconds (DEFAULT 1 SECOND)
# GLOBALS
local $| = 1;
my $ARGC = scalar @ARGV;
my $TIMEOUT = 1;
my $START_LISTEN = 0;
my $EXEC_POSITION = $ARGC - 1;
my $EXEC_LISTEN = undef;
my $ALL_FLAG = undef;
my $ANY_FLAG = undef;
my $MULTI_FILES = undef;
my $CHECKSUM_FLAG = undef;
my $CHECKSUM_COMMAND = "sha1sum";
sub flags {
if ($ARGC == 0) {
print "listen: To what?\n";
exit 2;
}
my $current_arg = 0;
foreach $arg (@ARGV) {
if ($arg =~ m/-[aos]/) {
if ($arg =~ m/a/) {
$ALL_FLAG = "def";
}
if ($arg =~ m/o/) {
$ANY_FLAG = "def";
}
if ($arg =~ m/s/) {
$CHECKSUM_FLAG = "def";
}
} elsif ($arg =~ m/--timeout=/) {
my @timeout_split = split /\=/, $arg;
if (scalar @timeout_split == 1) {
print "timeout flag invalid\n";
exit 2;
} elsif (int($timeout_split[1]) > 0) {
$TIMEOUT = $timeout_split[1];
print "timeout is now $TIMEOUT seconds\n";
} else {
print "timeout flag invalid\n";
exit 2;
}
} else {
last;
}
$current_arg++;
}
$START_LISTEN = $current_arg;
}
sub get_exec {
if ($START_LISTEN + 1 == $ARGC) {
print "listen: Not enough arguments\n";
exit 3;
}
$EXEC_LISTEN = $ARGV[-1];
}
sub require_flags {
if ($EXEC_POSITION - $START_LISTEN != 1) {
if (!$ALL_FLAG and !$ANY_FLAG) {
print "listen: Either -a or -o must be specified with multiple files to watch\n";
exit 4;
} elsif ($ALL_FLAG and $ANY_FLAG) {
print "listen: You must specify either -a or -o for multiple files, not both\n";
exit 4;
}
$MULTI_FILES = "def";
}
}
sub check_files {
for (my $i = $START_LISTEN; $i < $EXEC_POSITION; $i++) {
if (not -e $ARGV[$i]) {
print "listen: $ARGV[$i]: No such file or directory\n";
exit 5;
}
if (not -r $ARGV[$i]) {
print "listen: $ARGV[$i]: Permission denied (warning)\n";
}
}
}
sub start {
print "This shell command will run:\n";
print " $EXEC_LISTEN\n";
if ($MULTI_FILES) {
if ($ALL_FLAG) {
print "When all the files below have been modified:\n";
for (my $i = $START_LISTEN; $i < $EXEC_POSITION; $i++) {
print " $ARGV[$i]\n";
}
} elsif ($ANY_FLAG) {
print "When any of the files below have been modified:\n";
for (my $i = $START_LISTEN; $i < $EXEC_POSITION; $i++) {
print " $ARGV[$i]\n";
}
}
} else {
print "When this file has been modified:\n";
print " $ARGV[$START_LISTEN]\n";
}
print "Starting now...\n";
my $previous_epoch = (stat($ARGV[$START_LISTEN]))[9];
my $current_epoch = (stat($ARGV[$START_LISTEN]))[9];
while (1) {
$current_epoch = (stat($ARGV[$START_LISTEN]))[9];
if ($current_epoch > $previous_epoch) {
print "--- File \"$ARGV[$START_LISTEN]\" modified. Running command... ---\n";
system $EXEC_LISTEN;
my $status = $? >> 8;
if (int($status) != 0) {
print "--- WARNING: Exit code is $status. Returned to listen... ---\n";
} else {
print "--- Returned to listen... ---\n";
}
$previous_epoch = $current_epoch;
}
sleep(1);
}
}
# ---- START OF SCRIPT ----
# start by checking flags
flags();
# get executable to run on trigger
get_exec();
# check if additional flags are needed
# because multiple files are being listened to
require_flags();
# check if file(s) exist
check_files();
# start listen
start();