Source code for license_updater.main.client

__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2022-2023, Vanessa Sochat"
__license__ = "MPL 2.0"

import os
import re

from rich.console import Console
from rich.markdown import Markdown

import license_updater.defaults as defaults
import license_updater.utils as utils

from .script import ScriptFile
from .updater import UpdaterFinder


[docs]class LicenseUpdater: """ Create a License Updater """ def __init__(self, quiet=False, code_theme="vim", **kwargs): self._updaters = {} self.quiet = quiet self.code_theme = code_theme self.c = Console() # Keep a summary of updates self.summary = {} # If using for a GitHub action, a global flag that indicates changes self.has_changes = False @property def updaters(self): """ Get a list of updaters available """ if not self._updaters: # All updaters can be provided with the GitHub token self.finder = UpdaterFinder() self._updaters = {} for name, updaterClass in self.finder.items(): # Instantiate an updater for the path, provide settings self._updaters[name] = updaterClass() return self._updaters
[docs] def iter_paths(self, paths): """ Helper function to flexibly handle parsing paths. """ # Ensure we start from a list if not isinstance(paths, list): paths = [paths] final = set() # Run each updater on each path for path in paths: if path == ".": path = os.getcwd() if os.path.exists(path) and os.path.isfile(path): final.add(path) continue for filename in utils.recursive_find(path, defaults.supported_filetypes): final.add(filename) return list(final)
[docs] def detect(self, paths, details=True, updaters=None, ignore_patterns=None): """ Look for changes in files according to updaters """ ignore_patterns = ignore_patterns or [] if ignore_patterns: ignore_patterns = "(%s)" % "|".join(ignore_patterns) scripts = {} # Reset out summary self.summary = {} for path in self.iter_paths(paths): # Ignore patterns that match a user provided pattern! if ignore_patterns and re.search(ignore_patterns, path): continue # Load into script script = ScriptFile(path) showed_script = False # Todo convert this into an iter function (shared between detect and update) for _, updater in self.updaters.items(): # Skip updaters per request of the user if updaters and updater.slug not in updaters: continue # Don't print anything if no match if not updater.matches(path): continue # The count reflects the last run if updater.detect(script): if not showed_script: self.c.print(f"⭐️ [yellow]{path}[/yellow]") showed_script = True self.c.print(f"[red]✖️ {updater.title} Updater: {updater.count} updates[/red]") self.has_changes = True else: if not showed_script: self.c.print(f"⭐️ [yellow]{path}[/yellow]") showed_script = True self.c.print(f"[green]✔ {updater.title}: No updates[/green]") # If we want to show summary details: if details and script.has_changes: self.collect_summary(script) scripts[path] = script if details: self.show_summary() return scripts
[docs] def show_summary(self): """ Show summary of changes """ if not self.summary: md = Markdown("""\n# No changes\n""", code_theme=self.code_theme) self.c.print(md) return # Sort by counts self.summary = {k: v for k, v in sorted(self.summary.items(), key=lambda item: item[1])} md = Markdown("""\n# Summary of changes\n""", code_theme=self.code_theme) self.c.print(md) total = 0 for diff, count in self.summary.items(): md = Markdown( f"""\n```diff\n{diff}\n```\n- count: {count}\n""", code_theme=self.code_theme ) self.c.print(md) total += count # Show total count! md = Markdown(f"""## Total count: {total}\n""", code_theme=self.code_theme) self.c.print(md)
[docs] def collect_summary(self, script): """ Collect a summary of the changes """ summary = script.diff(self.code_theme, return_result=True) if not summary: return if summary not in self.summary: self.summary[summary] = 0 self.summary[summary] += 1
[docs] def update(self, paths, details=True, updaters=None, ignore_patterns=None): """ Update files. """ updates = self.detect( paths, details=details, updaters=updaters, ignore_patterns=ignore_patterns ) for path, script in updates.items(): if script.has_changes: self.c.print(f"[purple]❇ Writing updated {path}[/purple]") script.write(path)
def __repr__(self): return str(self) def __str__(self): return "[license-updater]"