pw_watch: Terminate interrupted builds
- Terminate interrupted builds immediately. This saves time since the
the watcher doesn't have to wait for the previous build to finish
before starting a new build.
- Remove some unused members of PigweedBuildWatcher.
Change-Id: I2218f711725ceb76a374c9e035a62f8c64224fdb
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/19301
Reviewed-by: Keir Mierle <keir@google.com>
Commit-Queue: Wyatt Hepler <hepler@google.com>
diff --git a/pw_watch/py/pw_watch/debounce.py b/pw_watch/py/pw_watch/debounce.py
index dd9005d..73c5e97 100644
--- a/pw_watch/py/pw_watch/debounce.py
+++ b/pw_watch/py/pw_watch/debounce.py
@@ -24,17 +24,17 @@
class DebouncedFunction(ABC):
"""Function to be run by Debouncer"""
@abstractmethod
- def run(self):
+ def run(self) -> None:
"""Run the function"""
@abstractmethod
- def cancel(self):
+ def cancel(self) -> bool:
"""Cancel an in-progress run of the function.
Must be called from different thread than run().
Returns true if run was successfully cancelled, false otherwise"""
@abstractmethod
- def on_complete(self, cancelled=False):
+ def on_complete(self, cancelled: bool = False) -> bool:
"""Called after run() finishes. If true, cancelled indicates
cancel() was invoked during the last run()"""
diff --git a/pw_watch/py/pw_watch/watch.py b/pw_watch/py/pw_watch/watch.py
index c3cd72a..c6394a0 100755
--- a/pw_watch/py/pw_watch/watch.py
+++ b/pw_watch/py/pw_watch/watch.py
@@ -103,7 +103,6 @@
self,
patterns: Sequence[str] = (),
ignore_patterns: Sequence[str] = (),
- case_sensitive: bool = False,
build_commands: Sequence[BuildCommand] = (),
ignore_dirs=Optional[List[str]],
charset: WatchCharset = _ASCII_CHARSET,
@@ -112,13 +111,13 @@
self.patterns = patterns
self.ignore_patterns = ignore_patterns
- self.case_sensitive = case_sensitive
self.build_commands = build_commands
self.ignore_dirs = ignore_dirs or []
self.ignore_dirs.extend(cmd.build_dir for cmd in self.build_commands)
- self.cooldown_finish_time = None
self.charset: WatchCharset = charset
+ self._current_build: Optional[subprocess.Popen] = None
+
self.debouncer = Debouncer(self)
# Track state of a build. These need to be members instead of locals
@@ -216,18 +215,22 @@
self.builds_succeeded = []
num_builds = len(self.build_commands)
_LOG.info('Starting build with %d directories', num_builds)
+
+ env = os.environ.copy()
+ # Force colors in Pigweed subcommands run through the watcher.
+ env['PW_USE_COLOR'] = '1'
+
for i, cmd in enumerate(self.build_commands, 1):
_LOG.info('[%d/%d] Starting build: %s', i, num_builds, cmd)
# Run the build. Put a blank before/after for visual separation.
print()
- env = os.environ.copy()
- # Force colors in Pigweed subcommands run through the watcher.
- env['PW_USE_COLOR'] = '1'
- result = subprocess.run(['ninja', '-C', *cmd.args()], env=env)
+ self._current_build = subprocess.Popen(
+ ['ninja', '-C', *cmd.args()], env=env)
+ returncode = self._current_build.wait()
print()
- build_ok = (result.returncode == 0)
+ build_ok = (returncode == 0)
if build_ok:
level = logging.INFO
tag = '(OK)'
@@ -240,10 +243,8 @@
# Implementation of DebouncedFunction.cancel()
def cancel(self):
- # TODO: Finish implementing this by supporting cancelling the currently
- # running build. This will require some subprocess shenanigans and
- # so will leave this for later.
- return False
+ self._current_build.terminate()
+ return True
# Implementation of DebouncedFunction.run()
def on_complete(self, cancelled=False):