pw_watch: Fix watchdog version and ignore project dirs

Pins the watchdog version to preserve functionality on MacOS, and
adds  the commonly ignored directories that fall under the
PW_PROJECT_ROOT, in addition to PW_ROOT. This makes life easier for
downstream projects, which likely want to ignore the same directories.

Change-Id: I624b47c3ecce27a00c76e0c9fcf95fde4c4041ff
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/38180
Commit-Queue: Max Koopman <koopman@google.com>
Reviewed-by: Wyatt Hepler <hepler@google.com>
Reviewed-by: Keir Mierle <keir@google.com>
Reviewed-by: Jennifer Silva <jennifersilva@google.com>
diff --git a/pw_watch/py/pw_watch/watch.py b/pw_watch/py/pw_watch/watch.py
index 770b2c8..159e88c 100755
--- a/pw_watch/py/pw_watch/watch.py
+++ b/pw_watch/py/pw_watch/watch.py
@@ -487,26 +487,30 @@
     """Find commonly excluded directories, and return them as a [Path]"""
     exclude_list: List[Path] = []
 
+    typical_ignored_directories: List[str] = [
+        '.environment',  # Legacy bootstrap-created CIPD and Python venv.
+        '.presubmit',  # Presubmit-created CIPD and Python venv.
+        '.git',  # Pigweed's git repo.
+        '.mypy_cache',  # Python static analyzer.
+        '.cargo',  # Rust package manager.
+        'environment',  # Bootstrap-created CIPD and Python venv.
+        'out',  # Typical build directory.
+    ]
+
     # Preset exclude list for Pigweed's upstream directories.
     pw_root_dir = Path(os.environ['PW_ROOT'])
-    exclude_list.extend([
-        pw_root_dir / ignored_directory for ignored_directory in [
-            '.environment',  # Bootstrap-created CIPD and Python venv.
-            '.presubmit',  # Presubmit-created CIPD and Python venv.
-            '.git',  # Pigweed's git repo.
-            '.mypy_cache',  # Python static analyzer.
-            '.cargo',  # Rust package manager.
-            'out',  # Typical build directory.
-        ]
-    ])
+    exclude_list.extend(pw_root_dir / ignored_directory
+                        for ignored_directory in typical_ignored_directories)
 
     # Preset exclude for common downstream project structures.
     #
-    # By convention, Pigweed projects use "out" as a build directory, so if
-    # watch is invoked outside the Pigweed root, also ignore the local out
-    # directory.
-    if Path.cwd() != pw_root_dir:
-        exclude_list.append(Path('out'))
+    # If watch is invoked outside of the Pigweed root, exclude common
+    # directories.
+    pw_project_root_dir = Path(os.environ['PW_PROJECT_ROOT'])
+    if pw_project_root_dir != pw_root_dir:
+        exclude_list.extend(
+            pw_project_root_dir / ignored_directory
+            for ignored_directory in typical_ignored_directories)
 
     # Check for and warn about legacy directories.
     legacy_directories = [
diff --git a/pw_watch/py/setup.py b/pw_watch/py/setup.py
index 086747d..82f4c17 100644
--- a/pw_watch/py/setup.py
+++ b/pw_watch/py/setup.py
@@ -26,6 +26,11 @@
     zip_safe=False,
     install_requires=[
         'pw_cli',
-        'watchdog',
+        # Fixes the watchdog version to 0.10.3, released 2020-06-25
+        # as versions later than this ignore the 'recursive' argument
+        # on MacOS. This was causing us to trigger on any file within
+        # the source tree, even those that should have been ignored.
+        # See https://github.com/gorakhargosh/watchdog/issues/771.
+        'watchdog==0.10.3',
     ],
 )