From c80a738c806697369d77b522b1f2524eec9e2c11 Mon Sep 17 00:00:00 2001 From: SoniEx2 Date: Sun, 26 Jul 2020 19:11:44 -0300 Subject: Add the run-once target I need to look into async/await before trying to make a proper run target, but this should help until then. --- ganarchy/cli/run_targets.py | 140 ++++++++++++++++++++++++++++++++----- ganarchy/core.py | 18 +++-- ganarchy/templating/environment.py | 4 +- 3 files changed, 139 insertions(+), 23 deletions(-) (limited to 'ganarchy') diff --git a/ganarchy/cli/run_targets.py b/ganarchy/cli/run_targets.py index 401665e..24497b9 100644 --- a/ganarchy/cli/run_targets.py +++ b/ganarchy/cli/run_targets.py @@ -18,6 +18,7 @@ """ import os +import shutil import click @@ -28,18 +29,116 @@ from ganarchy import db from ganarchy import dirs from ganarchy.templating import environment -#@cli.main.command() -#@click.argument('out', required=True) -#def run(out): +@cli.main.command() +@click.option('--keep-stale-projects/--no-keep-stale-projects', default=True) +@click.argument('out', required=True, type=click.Path(file_okay=False, resolve_path=True)) +def run_once(out, keep_stale_projects): + """Runs GAnarchy once. + + Processes any necessary updates and updates the output directory to match. + """ # """Runs ganarchy standalone. # -# This will run ganarchy so it regularly updates the output directory given by OUT. -# Additionally, it'll also search for the following hooks in its config dirs: +# This will run ganarchy so it regularly updates the output directory given +# by OUT. Additionally, it'll also search for the following hooks in its +# config dirs: # # - post_object_update_hook - executed after an object is updated. # -# - post_update_cycle_hook - executed after all objects in an update cycle are updated.""" -# pass +# - post_update_cycle_hook - executed after all objects in an update +# cycle are updated. +# """ + # create config objects + conf = data.ConfigManager.new_default() + effective_conf = data.EffectiveSource(conf) + repos = data.RepoListManager(effective_conf) + effective_repos = data.EffectiveSource(repos) + + # create dir if it doesn't exist + os.makedirs(out, exist_ok=True) + + # load template environment + env = environment.get_env() + + # make sure the cache dir exists + os.makedirs(dirs.CACHE_HOME, exist_ok=True) + + # make sure it is a git repo + core.GIT.create() + + if True: + # reload config and repo data + effective_repos.update() + database = db.connect_database(effective_conf) + database.load_repos(effective_repos) + + instance = core.GAnarchy(database, effective_conf) + + if not instance.base_url: + click.echo("No base URL specified", err=True) + return + + instance.load_projects() + + # update and render projects + if not keep_stale_projects: + shutil.rmtree(out + "/project") + + os.makedirs(out + "/project", exist_ok=True) + + template_project = env.get_template('project.html') + for p in instance.projects: + p.load_repos() + + generate_html = [] + results = p.update() + #if not p.exists: + # ... + for (repo, count) in results: + if count is not None: + generate_html.append( + (repo.url, repo.message, count, repo.branch) + ) + else: + click.echo(repo.errormsg, err=True) + html_entries = [] + for (url, msg, count, branch) in generate_html: + history = database.list_repobranch_activity(p.commit, url, branch) + # TODO process history into SVG + # TODO move this into a separate system + # (e.g. ``if project.startswith("svg-"):``) + html_entries.append((url, msg, "", branch)) + + os.makedirs(out + "/project/" + p.commit, exist_ok=True) + + with open(out + "/project/" + p.commit + "/index.html", "w") as f: + template_project.stream( + project_title = p.title, + project_desc = p.description, + project_body = p.commit_body, + project_commit = p.commit, + repos = html_entries, + base_url = instance.base_url, + # I don't think this thing supports deprecating the above? + project = p, + ganarchy = instance + ).dump(f) + + # render the config + template = env.get_template('index.toml') + with open(out + "/index.toml", "w") as f: + template.stream(database=database).dump(f) + + # render the index + # but reload projects first to pick up sorting order + # (new projects don't get sorted until their repos get fetched for the + # first time, because that's where the metadata is stored) + # FIXME .sort_projects()? + instance.load_projects() + template = env.get_template('index.html') + with open(out + "/index.html", "w") as f: + template.stream(ganarchy=instance).dump(f) + @cli.main.command() @click.option('--dry-run/--no-dry-run', '--no-update/--update', default=False) @@ -68,7 +167,7 @@ def cron_target(dry_run, project): if project == "config": # render the config template = env.get_template('index.toml') - click.echo(template.render(database=database)) + click.echo(template.render(database=database), nl=False) return if project == "project-list": # could be done with a template but eh w/e, this is probably better @@ -92,7 +191,7 @@ def cron_target(dry_run, project): instance.load_projects() # render the index template = env.get_template('index.html') - click.echo(template.render(ganarchy=instance)) + click.echo(template.render(ganarchy=instance), nl=False) return p = core.Project(database, project) @@ -116,12 +215,17 @@ def cron_target(dry_run, project): html_entries.append((url, msg, "", branch)) template = env.get_template('project.html') - click.echo(template.render(project_title = p.title, - project_desc = p.description, - project_body = p.commit_body, - project_commit = p.commit, - repos = html_entries, - base_url = instance.base_url, - # I don't think this thing supports deprecating the above? - project = p, - ganarchy = instance)) + click.echo( + template.render( + project_title = p.title, + project_desc = p.description, + project_body = p.commit_body, + project_commit = p.commit, + repos = html_entries, + base_url = instance.base_url, + # I don't think this thing supports deprecating the above? + project = p, + ganarchy = instance + ), + nl=False + ) diff --git a/ganarchy/core.py b/ganarchy/core.py index c225735..b1025d1 100644 --- a/ganarchy/core.py +++ b/ganarchy/core.py @@ -244,8 +244,20 @@ class GAnarchy: """ def __init__(self, dbconn, config): + self.title = None + self.base_url = None + self.projects = None + self._dbconn = dbconn + self._config = config + self.load_metadata() + + def load_metadata(self): + """Loads instance metadata from config. + + If instance metadata has already been loaded, re-loads it. + """ try: - base_url = config.get_property_value( + base_url = self._config.get_property_value( ganarchy.data.DataProperty.INSTANCE_BASE_URL ) except LookupError: @@ -253,7 +265,7 @@ class GAnarchy: raise ValueError try: - title = config.get_property_value( + title = self._config.get_property_value( ganarchy.data.DataProperty.INSTANCE_TITLE ) except LookupError: @@ -261,8 +273,6 @@ class GAnarchy: self.title = title self.base_url = base_url - self.projects = None - self._dbconn = dbconn def load_projects(self): """Loads the projects into this GAnarchy instance. diff --git a/ganarchy/templating/environment.py b/ganarchy/templating/environment.py index a527053..0258f4d 100644 --- a/ganarchy/templating/environment.py +++ b/ganarchy/templating/environment.py @@ -22,7 +22,9 @@ import ganarchy.templating.toml def get_env(): env = jinja2.Environment( loader=ganarchy.templating.templates.get_template_loader(), - autoescape=False + autoescape=False, + # aka please_stop_mangling_my_templates=True + keep_trailing_newline=True ) env.filters['tomlescape'] = ganarchy.templating.toml.tomlescape env.filters['tomle'] = env.filters['tomlescape'] -- cgit 1.4.1