From 3d06f9dca156c42f40b0a8630c9e0b0461e0bbe4 Mon Sep 17 00:00:00 2001 From: AndreaRe9 <59319678+AndreaRe9@users.noreply.github.com> Date: Thu, 2 Sep 2021 13:03:27 +0200 Subject: [PATCH 1/4] Removed argh from watchmedo. Replaced with argparser --- src/watchdog/watchmedo.py | 545 ++++++++++++++++++++------------------ 1 file changed, 283 insertions(+), 262 deletions(-) diff --git a/src/watchdog/watchmedo.py b/src/watchdog/watchmedo.py index 2977a918..b2ec8560 100755 --- a/src/watchdog/watchmedo.py +++ b/src/watchdog/watchmedo.py @@ -31,16 +31,53 @@ import logging from io import StringIO -from argh import arg, aliases, ArghParser, expects_obj +from argparse import ArgumentParser from watchdog.version import VERSION_STRING from watchdog.utils import WatchdogShutdown, load_class - logging.basicConfig(level=logging.INFO) CONFIG_KEY_TRICKS = 'tricks' CONFIG_KEY_PYTHON_PATH = 'python-path' +epilog = """Copyright 2011 Yesudeep Mangalapilly . +Copyright 2012 Google, Inc & contributors. + +Licensed under the terms of the Apache license, version 2.0. Please see +LICENSE in the source code for more information.""" + +cli = ArgumentParser(epilog=epilog) +cli.add_argument('--version', + action='version', + version='%(prog)s ' + VERSION_STRING) +subparsers = cli.add_subparsers(dest="command") + +def argument(*name_or_flags, **kwargs): + """Convenience function to properly format arguments to pass to the + command decorator. + """ + return (list(name_or_flags), kwargs) + + +def command(args=[], parent=subparsers): + """Decorator to define a new command in a sanity-preserving way. + The function will be stored in the ``func`` variable when the parser + parses arguments so that it can be called directly like so:: + args = cli.parse_args() + args.func(args) + Usage example:: + @command([argument("-d", help="Enable debug mode", action="store_true")]) + def command(args): + print(args) + Then on the command line:: + $ python cli.py command -d + """ + def decorator(func): + parser = parent.add_parser(func.__name__, description=func.__doc__) + for arg in args: + parser.add_argument(*arg[0], **arg[1]) + parser.set_defaults(func=func) + return decorator def path_split(pathname_spec, separator=os.pathsep): """ @@ -138,44 +175,42 @@ def schedule_tricks(observer, tricks, pathname, recursive): trick_pathname = getattr(handler, 'source_directory', None) or pathname observer.schedule(handler, trick_pathname, recursive) - -@aliases('tricks') -@arg('files', - nargs='*', - help='perform tricks from given file') -@arg('--python-path', - default='.', - help='paths separated by %s to add to the python path' % os.pathsep) -@arg('--interval', - '--timeout', - dest='timeout', - default=1.0, - help='use this as the polling interval/blocking timeout (in seconds)') -@arg('--recursive', - default=True, - help='recursively monitor paths') -@arg('--debug-force-polling', - default=False, - help='[debug] forces polling') -@arg('--debug-force-kqueue', - default=False, - help='[debug] forces BSD kqueue(2)') -@arg('--debug-force-winapi', - default=False, - help='[debug] forces Windows API') -@arg('--debug-force-winapi-async', - default=False, - help='[debug] forces Windows API + I/O completion') -@arg('--debug-force-fsevents', - default=False, - help='[debug] forces Mac OS X FSEvents') -@arg('--debug-force-inotify', - default=False, - help='[debug] forces Linux inotify(7)') -@expects_obj +@command([argument('files', + nargs='*', + help='perform tricks from given file'), + argument('--python-path', + default='.', + help='paths separated by %s to add to the python path' % os.pathsep), + argument('--interval', + '--timeout', + dest='timeout', + default=1.0, + type=float, + help='use this as the polling interval/blocking timeout (in seconds)'), + argument('--recursive', + default=True, + help='recursively monitor paths'), + argument('--debug-force-polling', + default=False, + help='[debug] forces polling'), + argument('--debug-force-kqueue', + default=False, + help='[debug] forces BSD kqueue(2)'), + argument('--debug-force-winapi', + default=False, + help='[debug] forces Windows API'), + argument('--debug-force-winapi-async', + default=False, + help='[debug] forces Windows API + I/O completion'), + argument('--debug-force-fsevents', + default=False, + help='[debug] forces Mac OS X FSEvents'), + argument('--debug-force-inotify', + default=False, + help='[debug] forces Linux inotify(7)')]) def tricks_from(args): """ - Subcommand to execute tricks from a tricks configuration file. + command to execute tricks from a tricks configuration file. :param args: Command line argument options. @@ -236,27 +271,26 @@ def tricks_from(args): o.join() -@aliases('generate-tricks-yaml') -@arg('trick_paths', - nargs='*', - help='Dotted paths for all the tricks you want to generate') -@arg('--python-path', - default='.', - help='paths separated by %s to add to the python path' % os.pathsep) -@arg('--append-to-file', - default=None, - help='appends the generated tricks YAML to a file; \ -if not specified, prints to standard output') -@arg('-a', - '--append-only', - dest='append_only', - default=False, - help='if --append-to-file is not specified, produces output for \ -appending instead of a complete tricks yaml file.') -@expects_obj +#@aliases('generate-tricks-yaml') +@command([argument('trick_paths', + nargs='*', + help='Dotted paths for all the tricks you want to generate'), + argument('--python-path', + default='.', + help='paths separated by %s to add to the python path' % os.pathsep), + argument('--append-to-file', + default=None, + help='appends the generated tricks YAML to a file; \ + if not specified, prints to standard output'), + argument('-a', + '--append-only', + dest='append_only', + default=False, + help='if --append-to-file is not specified, produces output for \ + appending instead of a complete tricks yaml file.')]) def tricks_generate_yaml(args): """ - Subcommand to generate Yaml configuration for tricks named on the command + command to generate Yaml configuration for tricks named on the command line. :param args: @@ -286,63 +320,64 @@ def tricks_generate_yaml(args): with open(args.append_to_file, 'ab') as output: output.write(content) - -@arg('directories', - nargs='*', - default='.', - help='directories to watch.') -@arg('-p', - '--pattern', - '--patterns', - dest='patterns', - default='*', - help='matches event paths with these patterns (separated by ;).') -@arg('-i', - '--ignore-pattern', - '--ignore-patterns', - dest='ignore_patterns', - default='', - help='ignores event paths with these patterns (separated by ;).') -@arg('-D', - '--ignore-directories', - dest='ignore_directories', - default=False, - help='ignores events for directories') -@arg('-R', - '--recursive', - dest='recursive', - default=False, - help='monitors the directories recursively') -@arg('--interval', - '--timeout', - dest='timeout', - default=1.0, - help='use this as the polling interval/blocking timeout') -@arg('--trace', - default=False, - help='dumps complete dispatching trace') -@arg('--debug-force-polling', - default=False, - help='[debug] forces polling') -@arg('--debug-force-kqueue', - default=False, - help='[debug] forces BSD kqueue(2)') -@arg('--debug-force-winapi', - default=False, - help='[debug] forces Windows API') -@arg('--debug-force-winapi-async', - default=False, - help='[debug] forces Windows API + I/O completion') -@arg('--debug-force-fsevents', - default=False, - help='[debug] forces Mac OS X FSEvents') -@arg('--debug-force-inotify', - default=False, - help='[debug] forces Linux inotify(7)') -@expects_obj +@command([argument('directories', + nargs='*', + default='.', + help='directories to watch. (default: \'.\')'), + argument('-p', + '--pattern', + '--patterns', + dest='patterns', + default='*', + help='matches event paths with these patterns (separated by ;).'), + argument('-i', + '--ignore-pattern', + '--ignore-patterns', + dest='ignore_patterns', + default='', + help='ignores event paths with these patterns (separated by ;).'), + argument('-D', + '--ignore-directories', + dest='ignore_directories', + default=False, + action='store_true', + help='ignores events for directories'), + argument('-R', + '--recursive', + dest='recursive', + default=False, + action='store_true', + help='monitors the directories recursively'), + argument('--interval', + '--timeout', + dest='timeout', + default=1.0, + type=float, + help='use this as the polling interval/blocking timeout'), + argument('--trace', + default=False, + help='dumps complete dispatching trace'), + argument('--debug-force-polling', + default=False, + help='[debug] forces polling'), + argument('--debug-force-kqueue', + default=False, + help='[debug] forces BSD kqueue(2)'), + argument('--debug-force-winapi', + default=False, + help='[debug] forces Windows API'), + argument('--debug-force-winapi-async', + default=False, + help='[debug] forces Windows API + I/O completion'), + argument('--debug-force-fsevents', + default=False, + help='[debug] forces Mac OS X FSEvents'), + argument('--debug-force-inotify', + default=False, + help='[debug] forces Linux inotify(7)')]) def log(args): """ - Subcommand to log file system events to the console. + command to log file system events to the console. :param args: Command line argument options. @@ -379,78 +414,79 @@ def log(args): observer = Observer(timeout=args.timeout) observe_with(observer, handler, args.directories, args.recursive) - -@arg('directories', - nargs='*', - default='.', - help='directories to watch') -@arg('-c', - '--command', - dest='command', - default=None, - help='''shell command executed in response to matching events. -These interpolation variables are available to your command string:: - - ${watch_src_path} - event source path; - ${watch_dest_path} - event destination path (for moved events); - ${watch_event_type} - event type; - ${watch_object} - ``file`` or ``directory`` - -Note:: - Please ensure you do not use double quotes (") to quote - your command string. That will force your shell to - interpolate before the command is processed by this - subcommand. - -Example option usage:: - - --command='echo "${watch_src_path}"' -''') -@arg('-p', - '--pattern', - '--patterns', - dest='patterns', - default='*', - help='matches event paths with these patterns (separated by ;).') -@arg('-i', - '--ignore-pattern', - '--ignore-patterns', - dest='ignore_patterns', - default='', - help='ignores event paths with these patterns (separated by ;).') -@arg('-D', - '--ignore-directories', - dest='ignore_directories', - default=False, - help='ignores events for directories') -@arg('-R', - '--recursive', - dest='recursive', - default=False, - help='monitors the directories recursively') -@arg('--interval', - '--timeout', - dest='timeout', - default=1.0, - help='use this as the polling interval/blocking timeout') -@arg('-w', '--wait', - dest='wait_for_process', - action='store_true', - default=False, - help="wait for process to finish to avoid multiple simultaneous instances") -@arg('-W', '--drop', - dest='drop_during_process', - action='store_true', - default=False, - help="Ignore events that occur while command is still being executed " - "to avoid multiple simultaneous instances") -@arg('--debug-force-polling', - default=False, - help='[debug] forces polling') -@expects_obj +@command([argument('directories', + nargs='*', + default='.', + help='directories to watch'), + argument('-c', + '--command', + dest='command', + default=None, + help='''shell command executed in response to matching events. + These interpolation variables are available to your command string:: + + ${watch_src_path} - event source path; + ${watch_dest_path} - event destination path (for moved events); + ${watch_event_type} - event type; + ${watch_object} - ``file`` or ``directory`` + + Note:: + Please ensure you do not use double quotes (") to quote + your command string. That will force your shell to + interpolate before the command is processed by this + command. + + Example option usage:: + + --command='echo "${watch_src_path}"' + '''), + argument('-p', + '--pattern', + '--patterns', + dest='patterns', + default='*', + help='matches event paths with these patterns (separated by ;).'), + argument('-i', + '--ignore-pattern', + '--ignore-patterns', + dest='ignore_patterns', + default='', + help='ignores event paths with these patterns (separated by ;).'), + argument('-D', + '--ignore-directories', + dest='ignore_directories', + default=False, + action='store_true', + help='ignores events for directories'), + argument('-R', + '--recursive', + dest='recursive', + default=False, + action='store_true', + help='monitors the directories recursively'), + argument('--interval', + '--timeout', + dest='timeout', + default=1.0, + type=float, + help='use this as the polling interval/blocking timeout'), + argument('-w', '--wait', + dest='wait_for_process', + action='store_true', + default=False, + help="wait for process to finish to avoid multiple simultaneous instances"), + argument('-W', '--drop', + dest='drop_during_process', + action='store_true', + default=False, + help="Ignore events that occur while command is still being executed " + "to avoid multiple simultaneous instances"), + argument('--debug-force-polling', + default=False, + help='[debug] forces polling')]) def shell_command(args): """ - Subcommand to execute shell commands in response to file system events. + command to execute shell commands in response to file system events. :param args: Command line argument options. @@ -476,68 +512,68 @@ def shell_command(args): observer = Observer(timeout=args.timeout) observe_with(observer, handler, args.directories, args.recursive) - -@arg('command', - help='''Long-running command to run in a subprocess. -''') -@arg('command_args', - metavar='arg', - nargs='*', - help='''Command arguments. - -Note: Use -- before the command arguments, otherwise watchmedo will -try to interpret them. -''') -@arg('-d', - '--directory', - dest='directories', - metavar='directory', - action='append', - help='Directory to watch. Use another -d or --directory option ' - 'for each directory.') -@arg('-p', - '--pattern', - '--patterns', - dest='patterns', - default='*', - help='matches event paths with these patterns (separated by ;).') -@arg('-i', - '--ignore-pattern', - '--ignore-patterns', - dest='ignore_patterns', - default='', - help='ignores event paths with these patterns (separated by ;).') -@arg('-D', - '--ignore-directories', - dest='ignore_directories', - default=False, - help='ignores events for directories') -@arg('-R', - '--recursive', - dest='recursive', - default=False, - help='monitors the directories recursively') -@arg('--interval', - '--timeout', - dest='timeout', - default=1.0, - help='use this as the polling interval/blocking timeout') -@arg('--signal', - dest='signal', - default='SIGINT', - help='stop the subprocess with this signal (default SIGINT)') -@arg('--debug-force-polling', - default=False, - help='[debug] forces polling') -@arg('--kill-after', - dest='kill_after', - default=10.0, - help='when stopping, kill the subprocess after the specified timeout ' - '(default 10)') -@expects_obj +@command([argument('command', + help='''Long-running command to run in a subprocess.'''), + argument('command_args', + metavar='arg', + nargs='*', + help='''Command arguments. + + Note: Use -- before the command arguments, otherwise watchmedo will + try to interpret them. + '''), + argument('-d', + '--directory', + dest='directories', + metavar='directory', + action='append', + help='Directory to watch. Use another -d or --directory option ' + 'for each directory.'), + argument('-p', + '--pattern', + '--patterns', + dest='patterns', + default='*', + help='matches event paths with these patterns (separated by ;).'), + argument('-i', + '--ignore-pattern', + '--ignore-patterns', + dest='ignore_patterns', + default='', + help='ignores event paths with these patterns (separated by ;).'), + argument('-D', + '--ignore-directories', + dest='ignore_directories', + default=False, + action='store_true', + help='ignores events for directories'), + argument('-R', + '--recursive', + dest='recursive', + default=False, + action='store_true', + help='monitors the directories recursively'), + argument('--interval', + '--timeout', + dest='timeout', + default=1.0, + type=float, + help='use this as the polling interval/blocking timeout'), + argument('--signal', + dest='signal', + default='SIGINT', + help='stop the subprocess with this signal (default SIGINT)'), + argument('--debug-force-polling', + default=False, + help='[debug] forces polling'), + argument('--kill-after', + dest='kill_after', + default=10.0, + help='when stopping, kill the subprocess after the specified timeout ' + '(default 10)')]) def auto_restart(args): """ - Subcommand to start a long-running subprocess and restart it + command to start a long-running subprocess and restart it on matched events. :param args: @@ -593,28 +629,13 @@ def handler_termination_signal(_signum, _frame): finally: handler.stop() - -epilog = """Copyright 2011 Yesudeep Mangalapilly . -Copyright 2012 Google, Inc & contributors. - -Licensed under the terms of the Apache license, version 2.0. Please see -LICENSE in the source code for more information.""" - -parser = ArghParser(epilog=epilog) -parser.add_commands([tricks_from, - tricks_generate_yaml, - log, - shell_command, - auto_restart]) -parser.add_argument('--version', - action='version', - version='%(prog)s ' + VERSION_STRING) - - def main(): """Entry-point function.""" - parser.dispatch() - + args = cli.parse_args() + if args.command is None: + cli.print_help() + else: + args.func(args) if __name__ == '__main__': main() From c3940e388ec7c9e30db2b1d7374f6c689fca1264 Mon Sep 17 00:00:00 2001 From: AndreaRe9 <59319678+AndreaRe9@users.noreply.github.com> Date: Sun, 5 Sep 2021 09:15:02 +0200 Subject: [PATCH 2/4] Fixing styling issues --- src/watchdog/watchmedo.py | 466 +++++++++++++++++++------------------- 1 file changed, 234 insertions(+), 232 deletions(-) diff --git a/src/watchdog/watchmedo.py b/src/watchdog/watchmedo.py index b2ec8560..8046ae0b 100755 --- a/src/watchdog/watchmedo.py +++ b/src/watchdog/watchmedo.py @@ -48,36 +48,32 @@ cli = ArgumentParser(epilog=epilog) cli.add_argument('--version', - action='version', - version='%(prog)s ' + VERSION_STRING) + action='version', + version='%(prog)s ' + VERSION_STRING) subparsers = cli.add_subparsers(dest="command") + def argument(*name_or_flags, **kwargs): - """Convenience function to properly format arguments to pass to the - command decorator. - """ - return (list(name_or_flags), kwargs) + """Convenience function to properly format arguments to pass to the + command decorator. + """ + return (list(name_or_flags), kwargs) def command(args=[], parent=subparsers): - """Decorator to define a new command in a sanity-preserving way. - The function will be stored in the ``func`` variable when the parser - parses arguments so that it can be called directly like so:: - args = cli.parse_args() - args.func(args) - Usage example:: - @command([argument("-d", help="Enable debug mode", action="store_true")]) - def command(args): - print(args) - Then on the command line:: - $ python cli.py command -d - """ - def decorator(func): - parser = parent.add_parser(func.__name__, description=func.__doc__) - for arg in args: - parser.add_argument(*arg[0], **arg[1]) - parser.set_defaults(func=func) - return decorator + """Decorator to define a new command in a sanity-preserving way. + The function will be stored in the ``func`` variable when the parser + parses arguments so that it can be called directly like so:: + args = cli.parse_args() + args.func(args) + """ + def decorator(func): + parser = parent.add_parser(func.__name__, description=func.__doc__) + for arg in args: + parser.add_argument(*arg[0], **arg[1]) + parser.set_defaults(func=func) + return decorator + def path_split(pathname_spec, separator=os.pathsep): """ @@ -175,39 +171,40 @@ def schedule_tricks(observer, tricks, pathname, recursive): trick_pathname = getattr(handler, 'source_directory', None) or pathname observer.schedule(handler, trick_pathname, recursive) + @command([argument('files', - nargs='*', - help='perform tricks from given file'), - argument('--python-path', - default='.', - help='paths separated by %s to add to the python path' % os.pathsep), - argument('--interval', - '--timeout', - dest='timeout', - default=1.0, - type=float, - help='use this as the polling interval/blocking timeout (in seconds)'), - argument('--recursive', - default=True, - help='recursively monitor paths'), - argument('--debug-force-polling', - default=False, - help='[debug] forces polling'), - argument('--debug-force-kqueue', - default=False, - help='[debug] forces BSD kqueue(2)'), - argument('--debug-force-winapi', - default=False, - help='[debug] forces Windows API'), - argument('--debug-force-winapi-async', - default=False, - help='[debug] forces Windows API + I/O completion'), - argument('--debug-force-fsevents', - default=False, - help='[debug] forces Mac OS X FSEvents'), - argument('--debug-force-inotify', - default=False, - help='[debug] forces Linux inotify(7)')]) + nargs='*', + help='perform tricks from given file'), + argument('--python-path', + default='.', + help='paths separated by %s to add to the python path' % os.pathsep), + argument('--interval', + '--timeout', + dest='timeout', + default=1.0, + type=float, + help='use this as the polling interval/blocking timeout (in seconds)'), + argument('--recursive', + default=True, + help='recursively monitor paths'), + argument('--debug-force-polling', + default=False, + help='[debug] forces polling'), + argument('--debug-force-kqueue', + default=False, + help='[debug] forces BSD kqueue(2)'), + argument('--debug-force-winapi', + default=False, + help='[debug] forces Windows API'), + argument('--debug-force-winapi-async', + default=False, + help='[debug] forces Windows API + I/O completion'), + argument('--debug-force-fsevents', + default=False, + help='[debug] forces Mac OS X FSEvents'), + argument('--debug-force-inotify', + default=False, + help='[debug] forces Linux inotify(7)')]) def tricks_from(args): """ command to execute tricks from a tricks configuration file. @@ -271,22 +268,22 @@ def tricks_from(args): o.join() -#@aliases('generate-tricks-yaml') +# @aliases('generate-tricks-yaml') @command([argument('trick_paths', - nargs='*', - help='Dotted paths for all the tricks you want to generate'), - argument('--python-path', - default='.', - help='paths separated by %s to add to the python path' % os.pathsep), - argument('--append-to-file', - default=None, - help='appends the generated tricks YAML to a file; \ + nargs='*', + help='Dotted paths for all the tricks you want to generate'), + argument('--python-path', + default='.', + help='paths separated by %s to add to the python path' % os.pathsep), + argument('--append-to-file', + default=None, + help='appends the generated tricks YAML to a file; \ if not specified, prints to standard output'), - argument('-a', - '--append-only', - dest='append_only', - default=False, - help='if --append-to-file is not specified, produces output for \ + argument('-a', + '--append-only', + dest='append_only', + default=False, + help='if --append-to-file is not specified, produces output for \ appending instead of a complete tricks yaml file.')]) def tricks_generate_yaml(args): """ @@ -320,61 +317,62 @@ def tricks_generate_yaml(args): with open(args.append_to_file, 'ab') as output: output.write(content) + @command([argument('directories', - nargs='*', - default='.', - help='directories to watch. (default: \'.\')'), - argument('-p', - '--pattern', - '--patterns', - dest='patterns', - default='*', - help='matches event paths with these patterns (separated by ;).'), - argument('-i', - '--ignore-pattern', - '--ignore-patterns', - dest='ignore_patterns', - default='', - help='ignores event paths with these patterns (separated by ;).'), - argument('-D', - '--ignore-directories', - dest='ignore_directories', - default=False, - action='store_true', - help='ignores events for directories'), - argument('-R', - '--recursive', - dest='recursive', - default=False, - action='store_true', - help='monitors the directories recursively'), - argument('--interval', - '--timeout', - dest='timeout', - default=1.0, - type=float, - help='use this as the polling interval/blocking timeout'), - argument('--trace', - default=False, - help='dumps complete dispatching trace'), - argument('--debug-force-polling', - default=False, - help='[debug] forces polling'), - argument('--debug-force-kqueue', - default=False, - help='[debug] forces BSD kqueue(2)'), - argument('--debug-force-winapi', - default=False, - help='[debug] forces Windows API'), - argument('--debug-force-winapi-async', - default=False, - help='[debug] forces Windows API + I/O completion'), - argument('--debug-force-fsevents', - default=False, - help='[debug] forces Mac OS X FSEvents'), - argument('--debug-force-inotify', - default=False, - help='[debug] forces Linux inotify(7)')]) + nargs='*', + default='.', + help='directories to watch. (default: \'.\')'), + argument('-p', + '--pattern', + '--patterns', + dest='patterns', + default='*', + help='matches event paths with these patterns (separated by ;).'), + argument('-i', + '--ignore-pattern', + '--ignore-patterns', + dest='ignore_patterns', + default='', + help='ignores event paths with these patterns (separated by ;).'), + argument('-D', + '--ignore-directories', + dest='ignore_directories', + default=False, + action='store_true', + help='ignores events for directories'), + argument('-R', + '--recursive', + dest='recursive', + default=False, + action='store_true', + help='monitors the directories recursively'), + argument('--interval', + '--timeout', + dest='timeout', + default=1.0, + type=float, + help='use this as the polling interval/blocking timeout'), + argument('--trace', + default=False, + help='dumps complete dispatching trace'), + argument('--debug-force-polling', + default=False, + help='[debug] forces polling'), + argument('--debug-force-kqueue', + default=False, + help='[debug] forces BSD kqueue(2)'), + argument('--debug-force-winapi', + default=False, + help='[debug] forces Windows API'), + argument('--debug-force-winapi-async', + default=False, + help='[debug] forces Windows API + I/O completion'), + argument('--debug-force-fsevents', + default=False, + help='[debug] forces Mac OS X FSEvents'), + argument('--debug-force-inotify', + default=False, + help='[debug] forces Linux inotify(7)')]) def log(args): """ command to log file system events to the console. @@ -414,15 +412,16 @@ def log(args): observer = Observer(timeout=args.timeout) observe_with(observer, handler, args.directories, args.recursive) + @command([argument('directories', - nargs='*', - default='.', - help='directories to watch'), - argument('-c', - '--command', - dest='command', - default=None, - help='''shell command executed in response to matching events. + nargs='*', + default='.', + help='directories to watch'), + argument('-c', + '--command', + dest='command', + default=None, + help='''shell command executed in response to matching events. These interpolation variables are available to your command string:: ${watch_src_path} - event source path; @@ -440,50 +439,50 @@ def log(args): --command='echo "${watch_src_path}"' '''), - argument('-p', - '--pattern', - '--patterns', - dest='patterns', - default='*', - help='matches event paths with these patterns (separated by ;).'), - argument('-i', - '--ignore-pattern', - '--ignore-patterns', - dest='ignore_patterns', - default='', - help='ignores event paths with these patterns (separated by ;).'), - argument('-D', - '--ignore-directories', - dest='ignore_directories', - default=False, - action='store_true', - help='ignores events for directories'), - argument('-R', - '--recursive', - dest='recursive', - default=False, - action='store_true', - help='monitors the directories recursively'), - argument('--interval', - '--timeout', - dest='timeout', - default=1.0, - type=float, - help='use this as the polling interval/blocking timeout'), - argument('-w', '--wait', - dest='wait_for_process', - action='store_true', - default=False, - help="wait for process to finish to avoid multiple simultaneous instances"), - argument('-W', '--drop', - dest='drop_during_process', - action='store_true', - default=False, - help="Ignore events that occur while command is still being executed " - "to avoid multiple simultaneous instances"), - argument('--debug-force-polling', - default=False, - help='[debug] forces polling')]) + argument('-p', + '--pattern', + '--patterns', + dest='patterns', + default='*', + help='matches event paths with these patterns (separated by ;).'), + argument('-i', + '--ignore-pattern', + '--ignore-patterns', + dest='ignore_patterns', + default='', + help='ignores event paths with these patterns (separated by ;).'), + argument('-D', + '--ignore-directories', + dest='ignore_directories', + default=False, + action='store_true', + help='ignores events for directories'), + argument('-R', + '--recursive', + dest='recursive', + default=False, + action='store_true', + help='monitors the directories recursively'), + argument('--interval', + '--timeout', + dest='timeout', + default=1.0, + type=float, + help='use this as the polling interval/blocking timeout'), + argument('-w', '--wait', + dest='wait_for_process', + action='store_true', + default=False, + help="wait for process to finish to avoid multiple simultaneous instances"), + argument('-W', '--drop', + dest='drop_during_process', + action='store_true', + default=False, + help="Ignore events that occur while command is still being executed " + "to avoid multiple simultaneous instances"), + argument('--debug-force-polling', + default=False, + help='[debug] forces polling')]) def shell_command(args): """ command to execute shell commands in response to file system events. @@ -512,65 +511,66 @@ def shell_command(args): observer = Observer(timeout=args.timeout) observe_with(observer, handler, args.directories, args.recursive) + @command([argument('command', - help='''Long-running command to run in a subprocess.'''), - argument('command_args', - metavar='arg', - nargs='*', - help='''Command arguments. + help='''Long-running command to run in a subprocess.'''), + argument('command_args', + metavar='arg', + nargs='*', + help='''Command arguments. Note: Use -- before the command arguments, otherwise watchmedo will try to interpret them. '''), - argument('-d', - '--directory', - dest='directories', - metavar='directory', - action='append', - help='Directory to watch. Use another -d or --directory option ' - 'for each directory.'), - argument('-p', - '--pattern', - '--patterns', - dest='patterns', - default='*', - help='matches event paths with these patterns (separated by ;).'), - argument('-i', - '--ignore-pattern', - '--ignore-patterns', - dest='ignore_patterns', - default='', - help='ignores event paths with these patterns (separated by ;).'), - argument('-D', - '--ignore-directories', - dest='ignore_directories', - default=False, - action='store_true', - help='ignores events for directories'), - argument('-R', - '--recursive', - dest='recursive', - default=False, - action='store_true', - help='monitors the directories recursively'), - argument('--interval', - '--timeout', - dest='timeout', - default=1.0, - type=float, - help='use this as the polling interval/blocking timeout'), - argument('--signal', - dest='signal', - default='SIGINT', - help='stop the subprocess with this signal (default SIGINT)'), - argument('--debug-force-polling', - default=False, - help='[debug] forces polling'), - argument('--kill-after', - dest='kill_after', - default=10.0, - help='when stopping, kill the subprocess after the specified timeout ' - '(default 10)')]) + argument('-d', + '--directory', + dest='directories', + metavar='directory', + action='append', + help='Directory to watch. Use another -d or --directory option ' + 'for each directory.'), + argument('-p', + '--pattern', + '--patterns', + dest='patterns', + default='*', + help='matches event paths with these patterns (separated by ;).'), + argument('-i', + '--ignore-pattern', + '--ignore-patterns', + dest='ignore_patterns', + default='', + help='ignores event paths with these patterns (separated by ;).'), + argument('-D', + '--ignore-directories', + dest='ignore_directories', + default=False, + action='store_true', + help='ignores events for directories'), + argument('-R', + '--recursive', + dest='recursive', + default=False, + action='store_true', + help='monitors the directories recursively'), + argument('--interval', + '--timeout', + dest='timeout', + default=1.0, + type=float, + help='use this as the polling interval/blocking timeout'), + argument('--signal', + dest='signal', + default='SIGINT', + help='stop the subprocess with this signal (default SIGINT)'), + argument('--debug-force-polling', + default=False, + help='[debug] forces polling'), + argument('--kill-after', + dest='kill_after', + default=10.0, + help='when stopping, kill the subprocess after the specified timeout ' + '(default 10)')]) def auto_restart(args): """ command to start a long-running subprocess and restart it @@ -629,13 +629,15 @@ def handler_termination_signal(_signum, _frame): finally: handler.stop() + def main(): """Entry-point function.""" args = cli.parse_args() if args.command is None: - cli.print_help() + cli.print_help() else: - args.func(args) + args.func(args) + if __name__ == '__main__': main() From cef5b908ff3f5bbe62d2ad072ed35de3e1ebb889 Mon Sep 17 00:00:00 2001 From: AndreaRe9 <59319678+AndreaRe9@users.noreply.github.com> Date: Sun, 12 Sep 2021 14:39:46 +0200 Subject: [PATCH 3/4] Removed references to argh --- README.rst | 3 --- docs/source/global.rst.inc | 1 - docs/source/installation.rst | 2 -- setup.py | 2 +- 4 files changed, 1 insertion(+), 7 deletions(-) diff --git a/README.rst b/README.rst index 9593a3a1..a7fc0d3d 100755 --- a/README.rst +++ b/README.rst @@ -238,8 +238,6 @@ Dependencies 1. Python 3.6 or above. 2. XCode_ (only on macOS when installing from sources) 3. PyYAML_ (only for ``watchmedo``) -4. argh_ (only for ``watchmedo``) - Licensing --------- @@ -283,7 +281,6 @@ to do: .. _changelog: https://github.com/gorakhargosh/watchdog/blob/master/changelog.rst .. _homebrew: https://brew.sh/ -.. _argh: https://pypi.python.org/pypi/argh .. _PyYAML: https://www.pyyaml.org/ .. _XCode: https://developer.apple.com/technologies/tools/xcode.html .. _LibYAML: https://pyyaml.org/wiki/LibYAML diff --git a/docs/source/global.rst.inc b/docs/source/global.rst.inc index b9bff830..ade2b9e3 100644 --- a/docs/source/global.rst.inc +++ b/docs/source/global.rst.inc @@ -18,7 +18,6 @@ .. _GetQueuedCompletionStatus: https://docs.microsoft.com/windows/win32/api/ioapiset/nf-ioapiset-getqueuedcompletionstatus .. _CreateIoCompletionPort: https://docs.microsoft.com/windows/win32/api/ioapiset/nf-ioapiset-createiocompletionport -.. _argh: https://pypi.python.org/pypi/argh .. _coverage: https://coverage.readthedocs.io/en/latest/ .. _file.monitor: https://github.com/pke/file.monitor .. _fsmonitor: https://github.com/shaurz/fsmonitor diff --git a/docs/source/installation.rst b/docs/source/installation.rst index 12dc41ec..ecc34ace 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -65,8 +65,6 @@ using the ``watchmedo`` utility. +=====================+=============+=============+=============+=============+ | PyYAML_ | Yes | Yes | Yes | Yes | +---------------------+-------------+-------------+-------------+-------------+ -| argh_ | Yes | Yes | Yes | Yes | -+---------------------+-------------+-------------+-------------+-------------+ Installing Dependencies ~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/setup.py b/setup.py index cf408d06..072dfc8d 100644 --- a/setup.py +++ b/setup.py @@ -78,7 +78,7 @@ ] extras_require = { - 'watchmedo': ['PyYAML>=3.10', 'argh>=0.24.1'], + 'watchmedo': ['PyYAML>=3.10'], } with open('README.rst', encoding='utf-8') as f: From 75208d5e6d2043851c66ff456606dc3c0c086cd7 Mon Sep 17 00:00:00 2001 From: AndreaRe9 <59319678+AndreaRe9@users.noreply.github.com> Date: Sun, 26 Sep 2021 09:40:16 +0200 Subject: [PATCH 4/4] Added missing aliases for commands tricks and generate-tricks-yaml --- src/watchdog/watchmedo.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/watchdog/watchmedo.py b/src/watchdog/watchmedo.py index 8046ae0b..e43248a1 100755 --- a/src/watchdog/watchmedo.py +++ b/src/watchdog/watchmedo.py @@ -60,7 +60,7 @@ def argument(*name_or_flags, **kwargs): return (list(name_or_flags), kwargs) -def command(args=[], parent=subparsers): +def command(args=[], parent=subparsers, cmd_aliases=[]): """Decorator to define a new command in a sanity-preserving way. The function will be stored in the ``func`` variable when the parser parses arguments so that it can be called directly like so:: @@ -68,7 +68,7 @@ def command(args=[], parent=subparsers): args.func(args) """ def decorator(func): - parser = parent.add_parser(func.__name__, description=func.__doc__) + parser = parent.add_parser(func.__name__, description=func.__doc__, aliases=cmd_aliases) for arg in args: parser.add_argument(*arg[0], **arg[1]) parser.set_defaults(func=func) @@ -204,7 +204,7 @@ def schedule_tricks(observer, tricks, pathname, recursive): help='[debug] forces Mac OS X FSEvents'), argument('--debug-force-inotify', default=False, - help='[debug] forces Linux inotify(7)')]) + help='[debug] forces Linux inotify(7)')], cmd_aliases=['tricks']) def tricks_from(args): """ command to execute tricks from a tricks configuration file. @@ -268,7 +268,6 @@ def tricks_from(args): o.join() -# @aliases('generate-tricks-yaml') @command([argument('trick_paths', nargs='*', help='Dotted paths for all the tricks you want to generate'), @@ -284,7 +283,7 @@ def tricks_from(args): dest='append_only', default=False, help='if --append-to-file is not specified, produces output for \ - appending instead of a complete tricks yaml file.')]) + appending instead of a complete tricks yaml file.')], cmd_aliases=['generate-tricks-yaml']) def tricks_generate_yaml(args): """ command to generate Yaml configuration for tricks named on the command