Skip to content

Commit

Permalink
Merge branch 'release/1.3.3'
Browse files Browse the repository at this point in the history
  • Loading branch information
emcrisostomo committed May 29, 2014
2 parents f0c2e68 + 64def03 commit dbbd2de
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 24 deletions.
18 changes: 18 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
ChangeLog
*********

2014-05-29 Enrico M. Crisostomo <[email protected]>

release: stable minor release 1.3.3:

* ChangeLog: Update.
* Makefile.am: Add fswatch-run to the script installation list.
* README.md:
- Add link to the release page (Issue 22).
- Add section about compatibility issues with v. 0.x.
- Add information about fswatch-run in README.
* configure.ac: Bump v. 1.3.3.
* fswatch.7: Update man page.
* fswatch.cpp: Add -o/--one-per-batch option to print a single message
with the number of change events in the current batch.
* fswatch-run: Add shell script to mimic the behaviour of earlier
fswatch versions and launch the specified command when change events
are received.

2014-04-27 Enrico M. Crisostomo <[email protected]>

release: stable major release 1.3.2:
Expand Down
2 changes: 2 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@ man_MANS = fswatch.7
EXTRA_DIST = $(man_MANS)
dist_doc_DATA = README.bsd README.freebsd README.gnu-build-system README.md
dist_doc_DATA += README.osx

dist_bin_SCRIPTS = scripts/fswatch-run
9 changes: 8 additions & 1 deletion NEWS
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
NEWS
****

New in 1.0.0:
New in 1.3.3:

* Add -o/--one-per-batch option to print a single message with the number of
change events in the current batch.
* Add fswatch-run shell script to mimic the behaviour of earlier fswatch
versions and launch the specified command when change events are received.

New in 1.3.2:

* fswatch has been merged with fsw (https://github.com/emcrisostomo/fsw).
64 changes: 63 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,51 @@ how to install the C++ toolchain and the C++ runtime.
No other software packages or dependencies are required to configure and
install `fswatch` but the aforementioned APIs used by the file system monitors.

Compability Issues with fswatch v. 0.x
--------------------------------------

The previous major version of `fswatch` (v. 0.x) allowed users to run a command
whenever a set of changes was detected with the following syntax:

$ fswatch path program

Starting with `fswatch` v. 1.x this behaviour is no longer supported. The
rationale behind this decision includes:

* The old version only allows watching one path.
* The command to execute was passed as last argument, alongside the path to
watch, making it difficult to extend the program functionality to add
multiple path support
* The old version forks and executes `/bin/bash`, which is neither portable,
nor guaranteed to succeed, nor desirable by users of other shells.
* No information about the change events is passed to the forked process.

To solve the aforementioned issues and keep `fswatch` consistent with common
UNIX practices, the behaviour has changed and `fswatch` now prints event
records to the standard output that users can process further by piping the
output of `fswatch` to other programs.

To fully support the old use, the `-o/--one-per-batch` option was added in
v. 1.3.3. When specified, `fswatch` will only dump 1 event to standard output
which can be used to trigger another `program`:

$ fswatch -o path | xargs -n1 program

In this case, `program` will receive the number of change events as first
argument. If no argument should be passed to `program`, then the following
command could be used:

$ fswatch -o path | xargs -n1 -I{} program

Although we encourage you to embrace the new fswatch behaviour and update your
scripts, we provide a little wrapper called `fswatch-run` which is installed
alongside `fswatch` which lets you use the legacy syntax:

$ fswatch-run path program

Under the hood, `fswatch-run` simply calls `fswatch -o` piping its output to
`xargs`.

Usage
-----

Expand All @@ -125,9 +170,26 @@ Usage

The event stream is created even if any of the paths do not exist yet. If they
are created after `fswatch` is launched, change events will be properly
received. Depending on the wathcher being used, newly created paths will be
received. Depending on the watchher being used, newly created paths will be
monitored after the amount of configured latency has elapsed.

The output of `fswatch` can be piped to other program in order to process it
further:

$ fswatch -0 path | while read -d "" event \
do \
// do something with ${event}
done

To run a command when a set of change events is printed to standard output but
no event details are required, then the following command can be used:

$ fswatch -o path | xargs -n1 -I{} program

The behaviour is consistent with earlier versions of `fswatch` (v. 0.x).
Please, read the _Compability Issues with fswatch v. 0.x_ section for further
information.

For more information, refer to the `fswatch` man page.

Bug Reports
Expand Down
4 changes: 2 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
# Process this file with autoconf to produce a configure script.
#
AC_PREREQ([2.69])
AC_INIT([fswatch], [1.3.2], [[email protected]], [], [https://github.com/alandipert/fswatch])
AC_INIT([fswatch], [1.3.3], [[email protected]], [], [https://github.com/alandipert/fswatch])
AC_COPYRIGHT([2014 (C) Enrico M. Crisostomo])
AC_REVISION([$Revision: 1.3.2-1 $])
AC_REVISION([$Revision: 1.3.3-1 $])
AC_CONFIG_SRCDIR([fswatch.cpp])
AC_CONFIG_AUX_DIR([config])
AC_CONFIG_HEADERS([config.h])
Expand Down
5 changes: 4 additions & 1 deletion fswatch.7
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ hierarchies are modified.

.Sh SYNOPSIS
.Nm fswatch
.Op Fl 0EhikLnprtuvx
.Op Fl 0EhikLnoprtuvx
.Op Fl e Ar regexp
.Op Fl f Ar format-time
.Op Fl l Ar latency
Expand Down Expand Up @@ -123,6 +123,9 @@ The numeric value of the event flags are system-specific and may vary across
different versions of OS X.
As a consequence, the use of numeric values is discouraged.

.It Fl o, -one-per-batch
Print a single message with the number of change events.

.It Fl p, -poll
Use the poll-based monitor.
This monitor periodically stats the file system to detect changes on the
Expand Down
68 changes: 49 additions & 19 deletions fswatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ static bool kflag = false;
static bool lflag = false;
static bool Lflag = false;
static bool nflag = false;
static bool oflag = false;
static bool pflag = false;
static bool rflag = false;
static bool tflag = false;
Expand Down Expand Up @@ -97,6 +98,8 @@ static void usage()
cout << " -l, --latency=DOUBLE Set the latency.\n";
cout << " -L, --follow-links Follow symbolic links.\n";
cout << " -n, --numeric Print a numeric event mask.\n";
cout << " -o, --one-per-batch Print a single message with the number of change events.\n";
cout << " in the current batch.\n";
cout << " -p, --poll Use the poll monitor.\n";
cout << " -r, --recursive Recurse subdirectories.\n";
cout << " -t, --timestamp Print the event timestamp.\n";
Expand All @@ -108,7 +111,7 @@ static void usage()
cout << endl;
#else
string option_string = "[";
option_string += "01"
option_string += "01";
# ifdef HAVE_REGCOMP
option_string += "eE";
# endif
Expand All @@ -119,7 +122,7 @@ static void usage()
# ifdef HAVE_SYS_EVENT_H
option_string += "k";
# endif
option_string += "lLnprtuvx";
option_string += "lLnoprtuvx";
option_string += "]";

cout << PACKAGE_STRING << "\n\n";
Expand All @@ -128,7 +131,7 @@ static void usage()
cout << "\n";
cout << "Usage:\n";
cout << " -0 Use the ASCII NUL character (0) as line separator.\n";
cout << " -1 Exit fsw after the first set of events is received.\n"
cout << " -1 Exit fsw after the first set of events is received.\n";
cout << " -e Exclude paths matching REGEX.\n";
cout << " -E Use exended regular expressions.\n";
cout << " -f Print the event time stamp with the specified format.\n";
Expand All @@ -140,6 +143,8 @@ static void usage()
cout << " -l Set the latency.\n";
cout << " -L Follow symbolic links.\n";
cout << " -n Print a numeric event masks.\n";
cout << " -o Print a single message with the number of change events in the current\n";
cout << " batch.\n";
cout << " -p Use the poll monitor.\n";
cout << " -r Recurse subdirectories.\n";
cout << " -t Print the event timestamp.\n";
Expand Down Expand Up @@ -316,35 +321,55 @@ static void print_event_flags(const vector<event_flag> &flags)
}
}

static void process_events(const vector<event> &events)
static void end_event_record()
{
for (const event &evt : events)
if (_0flag)
{
vector<event_flag> flags = evt.get_flags();
cout << '\0';
cout.flush();
}
else
{
cout << endl;
}
}

static void write_one_batch_event(const vector<event> &events)
{
cout << events.size();
end_event_record();
}

static void write_events(const vector<event> &events)
{
for (const event &evt : events)
{
if (tflag) print_event_timestamp(evt.get_time());

cout << evt.get_path();

if (xflag) print_event_flags(flags);

if (_0flag)
if (xflag)
{
cout << '\0';
cout.flush();
}
else
{
cout << endl;
print_event_flags(evt.get_flags());
}

end_event_record();
}

if (_1flag)
{
::exit(FSW_EXIT_OK);
}
}

static void process_events(const vector<event> &events)
{
if (oflag)
write_one_batch_event(events);
else
write_events(events);
}

static void start_monitor(int argc, char ** argv, int optind)
{
// parsing paths
Expand Down Expand Up @@ -398,7 +423,7 @@ static void parse_opts(int argc, char ** argv)
int ch;
ostringstream short_options;

short_options << "01f:hkl:Lnprtuvx";
short_options << "01f:hkl:Lnoprtuvx";
#ifdef HAVE_REGCOMP
short_options << "e:Ei";
#endif
Expand Down Expand Up @@ -426,6 +451,7 @@ static void parse_opts(int argc, char ** argv)
{ "latency", required_argument, nullptr, 'l'},
{ "follow-links", no_argument, nullptr, 'L'},
{ "numeric", no_argument, nullptr, 'n'},
{ "one-per-batch", no_argument, nullptr, 'o'},
{ "poll", no_argument, nullptr, 'p'},
{ "recursive", no_argument, nullptr, 'r'},
{ "timestamp", no_argument, nullptr, 't'},
Expand Down Expand Up @@ -456,7 +482,7 @@ static void parse_opts(int argc, char ** argv)
case '1':
_1flag = true;
break;

#ifdef HAVE_REGCOMP
case 'e':
exclude_regex.push_back(optarg);
Expand Down Expand Up @@ -508,6 +534,10 @@ static void parse_opts(int argc, char ** argv)
xflag = true;
break;

case 'o':
oflag = true;
break;

case 'p':
pflag = true;
break;
Expand Down Expand Up @@ -556,7 +586,7 @@ int main(int argc, char ** argv)
cerr << "-k and -p are mutually exclusive." << endl;
::exit(FSW_EXIT_OPT);
}

// configure and start the monitor
try
{
Expand Down
13 changes: 13 additions & 0 deletions scripts/fswatch-run
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/sh

[ $# -eq 2 ] || {
echo "Illegal number of arguments."
exit 1
}

command -v xargs >/dev/null 2>&1 || {
echo >&2 "xargs is required. Aborting."
exit 2
}

fswatch -o "$1" | xargs -n1 -I{} "$2"

0 comments on commit dbbd2de

Please sign in to comment.