#!/usr/bin/env python3.10 # # Copyright (C) 2021 Associated Universities, Inc. Washington DC, USA. # # This file is part of NRAO Workspaces. # # Workspaces is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Workspaces is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Workspaces. If not, see <https://www.gnu.org/licenses/>. import os import re import subprocess import sys import time from watchdog.events import FileSystemEventHandler from watchdog.observers import Observer class PexHandler(FileSystemEventHandler): event_cache = {} def on_modified(self, event): print(event) if event.is_directory or event.src_path.endswith(".py~"): return seconds = int(time.time()) key = (seconds, event.src_path) # check for identical events if key in self.event_cache: return # don't handle events if they happen quickly after another event if self.event_cache.__len__() != 0: previous_entry = list(self.event_cache)[-1] elapsed_time = seconds - previous_entry[0] print(f"elapsed_time between events: {elapsed_time}") if elapsed_time < 10: print(f"Too little time between events, Skipping...") return self.event_cache[key] = True # Only build pex if changes are made to files that end in ".py" if event.src_path.endswith(".py"): pexable = re.search("/pexable/(.*?)/", event.src_path).group(1) print(f"******************** Building pex - {pexable} ********************") # run local-build-pexables.sh sp = subprocess.run( ["./bin/local-build-pexables.sh", f"{pexable}"], stdout=subprocess.PIPE, universal_newlines=True, ) print(f"{sp.stdout}") print(f"*********************** {pexable} finished ***********************") print("Modification event handled.") def build_missing_pexes(path_to_sbin, path_to_pexables): sbin_content = os.listdir(path_to_sbin) pexables = os.listdir(path_to_pexables) existing_pexes_in_sbin = set(sbin_content).intersection(set(pexables)) if len(pexables) > len(existing_pexes_in_sbin): missing_pexables = set(pexables).difference(existing_pexes_in_sbin) print( f"There {'is' if len(missing_pexables) == 1 else 'are'} " f"{len(missing_pexables)} pex{'' if len(missing_pexables) == 1 else 'es'} " f"missing from your sbin area: \n{missing_pexables}" ) for pex in missing_pexables: print(f"Building {pex}") sp = subprocess.run( ["./bin/local-build-pexables.sh", f"{pex}"], stdout=subprocess.PIPE, universal_newlines=True, ) print(f"{sp.stdout}") else: print("There are no missing pexes.") if __name__ == "__main__": path_to_sbin = "/lustre/aoc/cluster/pipeline/docker/workspaces/sbin" path_to_pexables = sys.argv[1] if len(sys.argv) > 1 else "./apps/cli/executables/pexable/" build_missing_pexes(path_to_sbin, path_to_pexables) print("Starting Pex Watcher...") event_handler = PexHandler() observer = Observer() observer.schedule(event_handler, path_to_pexables, recursive=True) observer.start() try: while True: time.sleep(1) finally: observer.stop() observer.join()