aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile9
-rwxr-xr-xlisten169
2 files changed, 178 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..de09631
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,9 @@
+PREFIX = /usr/local
+
+all:
+
+install:
+ mkdir -p ${PREFIX}/bin
+ cp -f listen ${PREFIX}/bin
+ chmod 755 ${PREFIX}/bin/listen
+
diff --git a/listen b/listen
new file mode 100755
index 0000000..d8ae232
--- /dev/null
+++ b/listen
@@ -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();
+