summary refs log tree commit diff stats
path: root/ganarchy
diff options
context:
space:
mode:
authorSoniEx2 <endermoneymod@gmail.com>2020-07-26 19:11:44 -0300
committerSoniEx2 <endermoneymod@gmail.com>2020-07-26 19:11:44 -0300
commitc80a738c806697369d77b522b1f2524eec9e2c11 (patch)
tree22db98bea4231d6958074a9e98501ff00cc74356 /ganarchy
parentbdf5cb78b9d7daf702e0e05660580ab311473fdc (diff)
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.
Diffstat (limited to 'ganarchy')
-rw-r--r--ganarchy/cli/run_targets.py140
-rw-r--r--ganarchy/core.py18
-rw-r--r--ganarchy/templating/environment.py4
3 files changed, 139 insertions, 23 deletions
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']