Skip to content

Instantly share code, notes, and snippets.

@MarcSkovMadsen
Created November 16, 2019 16:21
Show Gist options
  • Save MarcSkovMadsen/75b1f4924f1d8261c8276917e5aa34bf to your computer and use it in GitHub Desktop.
Save MarcSkovMadsen/75b1f4924f1d8261c8276917e5aa34bf to your computer and use it in GitHub Desktop.
"""This module contains functionality to run a command with autoreload.
The command will autoreload everytime a file in the folder or it's subfolders are updated
Use this as for example
```bash
python autoreload panel serve *.py
```
To run [panel](https://panel.pyviz.org/) with autoreload.
"""
import os
import sys
import subprocess
import time
from typing import Generator
def watch_file(name: str) -> bool:
"""Whether or not to watch the file
Arguments:
name {str} -- The name of the file. For example 'main.py'
Returns:
bool -- True if the file should be watched. Otherwise Falses
"""
return not name.startswith(".")
def modified_times_of_files_to_watch(path: str = ".") -> Generator[float, None, None]:
"""The modified times of the files to Watch
Keyword Arguments:
path {str} -- The path (default: {"."})
Yields:
Generator[float, None, None] -- [description]
"""
for root, _, files in os.walk(path):
for file in filter(watch_file, files):
yield os.path.getmtime(os.path.join(root, file))
def print_stdout(process: subprocess.Popen):
"""Prints to standard out
Arguments:
process_ {subprocess.Popen} -- The process
"""
stdout = process.stdout
if stdout is not None:
print(stdout)
def main(command: str):
"""The command will autoreload everytime a file in the folder or it's subfolders are updated
Use this as for example
```bash
python autoreload panel serve *.py
```
To run [panel](https://panel.pyviz.org/) with autoreload.
Arguments:
command {str} -- [description]
"""
# The path to watch
path = "."
# How often we check the filesystem for changes (in seconds)
wait = 1
# The process to autoreload
process = subprocess.Popen(command, shell=False)
# The current maximum file modified time under the watched directory
last_mtime = max(modified_times_of_files_to_watch(path))
while True:
max_mtime = max(modified_times_of_files_to_watch(path))
print_stdout(process)
if max_mtime > last_mtime:
last_mtime = max_mtime
print("Killing Proces.")
process.kill()
process.wait()
print("Retarting Process.")
process = subprocess.Popen(command, shell=False)
time.sleep(wait)
if __name__ == "__main__":
# We concatenate all of the arguments together, and treat that as the command to run
COMMAND = " ".join(sys.argv[1:])
main(COMMAND)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment