【小ネタ】ぐるぐる回る表示をしたい

# きっかけ

docker compose を起動しようと

```
docker compose up -d
```

を実行するとおしゃれなぐるぐる回る表示で起動中であることを示してくれます。

どうやってこのぐるぐる表示を実現しているのか気になったので調べてみました。

# 調べた方法

ソースコードを見るのが一番エンジニアっぽいやりかたなのですが、安直に emacs の shell モードで docker コマンドを叩いてその表示を見る、ということをやってみました。

適当な docker を emacs の shell バッファから起動停止してみると、こんな表示が出てきました。

```
  C-c C-cGracefully stopping... (press Ctrl+C again to force)
[+] Stopping 0/0
 ⠋ Container xxxxx  Stopping                                      0.1s 
[+] Stopping 0/1
 ⠙ Container xxxxx  Stopping                                      0.2s 
[+] Stopping 0/1
 ⠹ Container xxxxx  Stopping                                      0.3s 
[+] Stopping 0/1
 ⠸ Container xxxxx  Stopping                                      0.4s 
[+] Stopping 0/1
 ⠼ Container xxxxx  Stopping                                      0.5s 
[+] Stopping 0/1
 ⠴ Container xxxxx  Stopping                                      0.6s 
[+] Stopping 0/1
 ⠦ Container xxxxx  Stopping                                      0.7s 
[+] Stopping 0/1
 ⠧ Container xxxxx  Stopping                                      0.8s 
[+] Stopping 0/1
 ⠇ Container xxxxx  Stopping                                      0.9s 
[+] Stopping 0/1
 ⠏ Container xxxxx  Stopping                                      1.0s 
[+] Stopping 0/1
 ⠋ Container xxxxx  Stopping                                      1.1s 
[+] Stopping 0/1
 ⠙ Container xxxxx  Stopping                                      1.2s 
[+] Stopping 0/1
 ⠹ Container xxxxx  Stopping                                      1.3s 
[+] Stopping 0/1
 ⠸ Container xxxxx  Stopping                                      1.4s 
[+] Stopping 0/1
 ⠼ Container xxxxx  Stopping                                      1.5s 
[+] Stopping 0/1
 ⠴ Container xxxxx  Stopping                                      1.6s 
[+] Stopping 0/1
 ⠦ Container xxxxx  Stopping                                      1.7s 
[+] Stopping 0/1
 ⠧ Container xxxxx  Stopping                                      1.8s 
[+] Stopping 0/1
 ⠇ Container xxxxx  Stopping                                      1.9s 
[+] Stopping 0/1
 ⠏ Container xxxxx  Stopping                                      2.0s 
[+] Stopping 0/1
 ⠋ Container xxxxx  Stopping                                      2.1s 
[+] Stopping 0/1
 ⠙ Container xxxxx  Stopping                                      2.2s 
[+] Stopping 0/1
 ⠹ Container xxxxx  Stopping                                      2.3s 
[+] Stopping 0/1
 ⠸ Container xxxxx  Stopping                                      2.4s 
[+] Stopping 1/1
 ✔ Container xxxxx  Stopped                                       2.4s 
canceled
```

というわけで、こんなのを順に表示しているようです。

```
⠋ ⠙ ⠹ ⠸ ⠼ ⠦ ⠧ ⠇ ⠏ ⠋ ⠙ ⠹ ⠸ ⠼ ⠦ ⠧ ⠇ ⠏ ⠋ ⠙
```

これは点字フォントで、点字フォントの見た目をうまく使ってぐるぐる回りに見せているらしいです。

# 実際にぐるぐる回してみる

自分でもぐるぐる回してみたいので、こんなのを作って試してみました。
実行すると、１０秒間ぐるぐるを表示します。

```python
import sys
import time
import threading

class GuruguruThread(threading.Thread):
    u'''
    タイトル付きのぐるぐる表示。
    '''
    GURUGURU = '⠋⠙⠹⠸⠼⠦⠧⠇⠏'
    def __init__(self, title, interval=0.1):
        u'''
        ぐるぐる表示スレッドのコンストラクタ。
        '''
        threading.Thread.__init__(self)
        self.title = title
        self.interval = interval
        self.stopping = False
    def stop(self):
        u'''
        ぐるぐる表示を停止する
        '''
        self.stopping = True
    def run(self):
        u'''
        interval で指定された間隔でぐるぐる表示を更新する
        '''
        while not self.stopping:
            for c in GuruguruThread.GURUGURU:
                if sys.stdout.isatty():
                    # TTY 出力の場合はぐるぐる表示する。
                    # TTY 出力でない場合はぐるぐる表示不要。
                    sys.stdout.write(
                        '\r{} {}'.format(c, self.title))
                    sys.stdout.flush()
                time.sleep(self.interval)
        sys.stdout.write(
            '\r{} {}\n'.format('✔', self.title))
        sys.stdout.flush()

g = GuruguruThread('guruguru test')
g.start()  # ぐるぐる表示スレッドを開始する
time.sleep(10)  # 10 秒間ぐるぐるを表示
g.stop()   # ぐるぐる表示を停止する
g.join()
```

# まとめ

- docker コマンドがぐるぐる表示をどうやって実現しているのか簡単に調べてみました
- 点字フォントを使ってぐるぐる回るように見せていました
- 多少の待ち時間を要するコマンドに使うとかっこよくてよさげです