1# Copyright 2020 The Pigweed Authors 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4# use this file except in compliance with the License. You may obtain a copy of 5# the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations under 13# the License. 14"""Spinner!""" 15 16import contextlib 17import os 18import sys 19import threading 20import time 21 22PW_ENVSETUP_DISABLE_SPINNER = os.environ.get('PW_ENVSETUP_DISABLE_SPINNER') 23 24 25class Spinner(object): # pylint: disable=useless-object-inheritance 26 """Spinner!""" 27 def __init__(self): 28 self._done = None 29 self._thread = None 30 31 def __del__(self): 32 self._done = True 33 34 def _spin(self): 35 i = 0 36 chars = '|/-\\' 37 while not self._done: 38 sys.stdout.write('[{}]'.format(chars[i])) 39 sys.stdout.flush() 40 time.sleep(0.1) 41 sys.stdout.write('\b\b\b') 42 i = (i + 1) % len(chars) 43 44 def start(self): 45 if PW_ENVSETUP_DISABLE_SPINNER: 46 return 47 48 self._done = False 49 self._thread = threading.Thread(target=self._spin) 50 self._thread.start() 51 52 def stop(self): 53 if PW_ENVSETUP_DISABLE_SPINNER: 54 return 55 56 assert self._thread 57 self._done = True 58 self._thread.join() 59 self._thread = None 60 61 @contextlib.contextmanager 62 def __call__(self): 63 try: 64 self.start() 65 yield self 66 finally: 67 self.stop() 68 69 @contextlib.contextmanager 70 def pause(self): 71 try: 72 self.stop() 73 yield self 74 finally: 75 self.start() 76