pw_env_setup: add spinner Fixed: 160 Change-Id: I2256b1e773117ed749ad6595558d7c1e5c7241b1
diff --git a/pw_env_setup/py/pw_env_setup/env_setup.py b/pw_env_setup/py/pw_env_setup/env_setup.py index ba90542..1b9f922 100755 --- a/pw_env_setup/py/pw_env_setup/env_setup.py +++ b/pw_env_setup/py/pw_env_setup/env_setup.py
@@ -72,6 +72,7 @@ from pw_env_setup.colors import Color, enable_colors from pw_env_setup import cargo_setup from pw_env_setup import environment +from pw_env_setup import spinner from pw_env_setup import virtualenv_setup @@ -183,7 +184,9 @@ newline=False, ) - result = step() + spin = spinner.Spinner() + with spin(): + result = step() self._env.echo(result.status_str()) for message in result.messages():
diff --git a/pw_env_setup/py/pw_env_setup/spinner.py b/pw_env_setup/py/pw_env_setup/spinner.py new file mode 100644 index 0000000..fd6ea9c --- /dev/null +++ b/pw_env_setup/py/pw_env_setup/spinner.py
@@ -0,0 +1,59 @@ +# Copyright 2020 The Pigweed Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +"""Spinner!""" + +import contextlib +import sys +import threading +import time + + +class Spinner(object): # pylint: disable=useless-object-inheritance + """Spinner!""" + def __init__(self, *args, **kwargs): + super(Spinner, self).__init__(*args, **kwargs) + self._done = None + self._thread = None + + def __del__(self): + self._done = True + + def _spin(self): + i = 0 + chars = '|/-\\' + while not self._done: + sys.stdout.write('[{}]'.format(chars[i])) + sys.stdout.flush() + time.sleep(0.1) + sys.stdout.write('\b\b\b') + i = (i + 1) % len(chars) + + def start(self): + self._done = False + self._thread = threading.Thread(target=self._spin) + self._thread.start() + + def stop(self): + assert self._thread + self._done = True + self._thread.join() + self._thread = None + + @contextlib.contextmanager + def __call__(self): + try: + self.start() + yield self + finally: + self.stop()