f421e218452d v1.0.0

Change how --dynamic works

This is a backwards-incompatible change.  I'm sorry.  Hey, it wasn't 1.0.0 yet.

Previously --dynamic made peat look for the listing command on standard in.
This was consistent in the sense that it was always looking for "the input
files" on standard in, but in practice it was a giant pain in the ass because it
required you to quote shell commands in two separate ways (one for the listing
command, the other for the action command).

Now you can quote both commands in the same way and avoid going insane.
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Sat, 29 Aug 2015 16:17:52 +0000
parents d1b458495f4f
children c4f5cf1bfffd
branches/tags v1.0.0
files README.markdown peat

Changes

--- a/README.markdown	Sat Nov 24 14:44:12 2012 -0500
+++ b/README.markdown	Sat Aug 29 16:17:52 2015 +0000
@@ -57,26 +57,15 @@
 newly created files without having to restart it) you can use the `--dynamic`
 option.
 
-Instead of piping in the list of files to watch, you'll pipe in a *command* that
-`peat` will run to generate the list before every check.  For example:
+Instead of piping in the list of files to watch, you'll specify a *command* that
+`peat` will run to generate the list before every check (as well as the actual
+command to run, of course).  For example:
 
     $ ffind ".markdown$"
     ./foo.markdown
     ./bar/baz.markdown
 
-    $ echo 'ffind ".markdown$"'
-    ffind ".markdown$"
-
-    $ echo 'ffind ".markdown$"' | peat --dynamic 'echo "A file changed!"'
-
-If your command contains quotes you'll need to make sure they get passed
-into peat properly.  For example, the following will **not** work:
-
-    $ echo "find . -name '*.markdown'" | peat --dynamic ...
-
-The problem is that the shell will expand the `*` in the double-quoted string
-before it ever gets to `peat`.  Google around and learn about shell quoting if
-you don't understand.  This can be tricky.  You've been warned.
+    $ peat --dynamic 'ffind ".markdown$"' 'echo "A file changed!"'
 
 ### Full Usage
 
@@ -94,17 +83,11 @@
         find . -name '*.py' | peat 'rm *.pyc'
         find . -name '*.py' -print0 | peat -0 'rm *.pyc'
 
-    If --dynamic is given, a command to generate the list should be piped in
-    on standard input instead.  It will be used to generate the list of files
-    to check before each run.
+    If --dynamic is used, the given command will be run each time to generate the
+    list of files to check:
 
-    This command must be quoted properly, and this can be tricky.  Make sure
-    you know what you're doing.
-
-    For example:
-
-        echo find . | peat --dynamic './test.sh'
-        echo find . -name '*.py' | peat --dynamic 'rm *.pyc'
+        peat --dynamic 'find .' './test.sh'
+        peat --dynamic 'find . -name '\''*.py'\''' 'rm *.pyc'
 
 
     Options:
@@ -112,18 +95,18 @@
       -i N, --interval=N    interval between checks in milliseconds
       -I, --smart-interval  determine the interval based on number of files
                             watched (default)
-      -d, --dynamic         take a command on standard input to generate the list
-                            of files to watch
+      -d COMMAND, --dynamic=COMMAND
+                            run COMMAND before each run to generate the list of
+                            files to check
       -D, --no-dynamic      take a list of files to watch on standard in (default)
       -c, --clear           clear screen before runs (default)
       -C, --no-clear        don't clear screen before runs
       -v, --verbose         show extra logging output (default)
       -q, --quiet           don't show extra logging output
-      -w, --whitespace      assume paths on stdin are separated by whitespace
-                            (default)
-      -n, --newlines        assume paths on stdin are separated by newlines
-      -s, --spaces          assume paths on stdin are separated by spaces
-      -0, --zero            assume paths on stdin are separated by null bytes
+      -w, --whitespace      assume paths are separated by whitespace (default)
+      -n, --newlines        assume paths are separated by newlines
+      -s, --spaces          assume paths are separated by spaces
+      -0, --zero            assume paths are separated by null bytes
 
 License
 -------
--- a/peat	Sat Nov 24 14:44:12 2012 -0500
+++ b/peat	Sat Aug 29 16:17:52 2015 +0000
@@ -23,11 +23,9 @@
 clear = True
 get_paths = lambda: set()
 verbose = True
-dynamic = False
-paths_command = None
+dynamic = None
 
-USAGE = """\
-usage: %prog [options] COMMAND
+USAGE = r"""usage: %prog [options] COMMAND
 
 COMMAND should be given as a single argument using a shell string.
 
@@ -39,17 +37,11 @@
     find . -name '*.py' | peat 'rm *.pyc'
     find . -name '*.py' -print0 | peat -0 'rm *.pyc'
 
-If --dynamic is given, a command to generate the list should be piped in
-on standard input instead.  It will be used to generate the list of files
-to check before each run.
+If --dynamic is used, the given command will be run each time to generate the
+list of files to check:
 
-This command must be quoted properly, and this can be tricky.  Make sure
-you know what you're doing.
-
-For example:
-
-    echo find . | peat --dynamic './test.sh'
-    echo find . -name '*.py' | peat --dynamic 'rm *.pyc'
+    peat --dynamic 'find .' './test.sh'
+    peat --dynamic 'find . -name '\''*.py'\''' 'rm *.pyc'
 """
 
 
@@ -90,36 +82,40 @@
     p.add_option('-I', '--smart-interval', dest='interval',
                  action='store_const', const=None,
                  help='determine the interval based on number of files watched (default)')
-    p.add_option('-d', '--dynamic', default=False,
-                 action='store_true',
-                 help='take a command on standard input to generate the list of files to watch')
+
+    p.add_option('-d', '--dynamic', default=None,
+                 help='run COMMAND before each run to generate the list of files to check',
+                 metavar='COMMAND')
     p.add_option('-D', '--no-dynamic', dest='dynamic',
-                 action='store_false',
+                 action='store_const', const=None,
                  help='take a list of files to watch on standard in (default)')
+
     p.add_option('-c', '--clear', default=True,
                  action='store_true', dest='clear',
                  help='clear screen before runs (default)')
     p.add_option('-C', '--no-clear',
                  action='store_false', dest='clear',
                  help="don't clear screen before runs")
+
     p.add_option('-v', '--verbose', default=True,
                  action='store_true', dest='verbose',
                  help='show extra logging output (default)')
     p.add_option('-q', '--quiet',
                  action='store_false', dest='verbose',
                  help="don't show extra logging output")
+
     p.add_option('-w', '--whitespace', default=None,
                  action='store_const', dest='sep', const=None,
-                 help="assume paths on stdin are separated by whitespace (default)")
+                 help="assume paths are separated by whitespace (default)")
     p.add_option('-n', '--newlines',
                  action='store_const', dest='sep', const='\n',
-                 help="assume paths on stdin are separated by newlines")
+                 help="assume paths are separated by newlines")
     p.add_option('-s', '--spaces',
                  action='store_const', dest='sep', const=' ',
-                 help="assume paths on stdin are separated by spaces")
+                 help="assume paths are separated by spaces")
     p.add_option('-0', '--zero',
                  action='store_const', dest='sep', const='\0',
-                 help="assume paths on stdin are separated by null bytes")
+                 help="assume paths are separated by null bytes")
 
     return p
 
@@ -127,7 +123,7 @@
 def _main():
     if dynamic:
         log("Running the following command to generate watch list:")
-        log('  ' + paths_command)
+        log('  ' + dynamic)
         log('')
 
     log("Watching the following paths:")
@@ -178,7 +174,7 @@
     return paths
 
 def main():
-    global interval, command, clear, get_paths, verbose, dynamic, paths_command
+    global interval, command, clear, get_paths, verbose, dynamic
 
     (options, args) = build_option_parser().parse_args()
 
@@ -192,13 +188,8 @@
     dynamic = options.dynamic
 
     if dynamic:
-        paths_command = sys.stdin.read().rstrip()
-
-        if not paths_command:
-            die("no command to generate watch list was given on standard input")
-
         def _get_paths():
-            data = subprocess.check_output(paths_command, shell=True)
+            data = subprocess.check_output(dynamic, shell=True)
             return _parse_paths(sep, data)
 
         get_paths = _get_paths