From f42b10351563cdcc240c3fa12e75ab2a22ce1913 Mon Sep 17 00:00:00 2001 From: Jim Shepich III Date: Tue, 3 Feb 2026 01:07:11 -0500 Subject: [PATCH] Configured to run as a Python module --- .gitignore | 3 ++- config.yaml | 7 ++++-- jimsite/__init__.py | 24 +++++-------------- jimsite/__main__.py | 15 ++++++++++++ jimsite/articles.py | 3 +++ jimsite/assets.py | 26 ++++++++++++++------- jimsite/common.py | 7 +++++- site/templates/components/blog_archive.html | 2 ++ 8 files changed, 57 insertions(+), 30 deletions(-) create mode 100644 jimsite/__main__.py diff --git a/.gitignore b/.gitignore index d9d0210..68fd4d7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ shepich resume.pdf tmp build dist -**/__pycache__ \ No newline at end of file +**/__pycache__ +custom.yaml \ No newline at end of file diff --git a/config.yaml b/config.yaml index 6a9c028..93a5532 100644 --- a/config.yaml +++ b/config.yaml @@ -17,7 +17,8 @@ sites: title: Resume base_url: http://localhost:8000 web_root: ./dist - git_repo: ssh://gitea/jim/resume.git + git_repo: + url: ssh://gitea/jim/resume.git build_cache: ./build/resume assets: - 'shepich_resume.pdf' @@ -26,7 +27,9 @@ sites: title: Dogma Jimfinium description: May it bolster the skills of all who read it. base_url: http://localhost:8000/dogma-jimfinium - git_repo: ssh://gitea/jim/dogma-jimfinium.git + git_repo: + url: ssh://gitea/jim/dogma-jimfinium.git + branch: pub build_cache: ./build/dogma-jimfinium web_root: ./dist/dogma-jimfinium assets: diff --git a/jimsite/__init__.py b/jimsite/__init__.py index f8b83e5..76f716a 100644 --- a/jimsite/__init__.py +++ b/jimsite/__init__.py @@ -1,13 +1,5 @@ import os -import re -import glob -import shutil -import subprocess -import markdown import yaml -import pydantic -from typing import Optional -from datetime import datetime, date from dotmap import DotMap import logging @@ -21,13 +13,8 @@ from .articles import ArticleMetadata, load_markdown, build_articles, build_inde from .blog import build_blog_archive, build_rss_feed - - - - - - def build_site(site: SiteConfig, templates: DotMap): + '''The pipeline for building a site defined in config.yaml.''' logger.info(f'Building site "{site.title}".') @@ -74,9 +61,11 @@ def build_site(site: SiteConfig, templates: DotMap): else: logger.debug('Addon "rss" not elected.') -def main(): + +def build(config_filepath = './config.yaml'): + '''Pipeline for building the entire website, including all sites defined in config.yaml.''' logger.info('Loading config.') - with open('./config.yaml', 'r') as config_file: + with open(config_filepath, 'r') as config_file: config = yaml.safe_load(config_file.read()) logger.info('Loading global templates.') @@ -85,6 +74,5 @@ def main(): for site in config['sites'].values(): build_site(SiteConfig(**site), templates) -if __name__ == '__main__': - main() + diff --git a/jimsite/__main__.py b/jimsite/__main__.py new file mode 100644 index 0000000..e6cf236 --- /dev/null +++ b/jimsite/__main__.py @@ -0,0 +1,15 @@ +import argparse +from jimsite import build + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + prog='Jimsite', + description='A Python-based templating engine for building static websites from Markdown documents.', + epilog='Gonna be a hot one!' + ) + + parser.add_argument('-c', '--config', type=str, default='config.yaml', help='Specifies the path to a YAML config file; defaults to config.yaml in the CWD.') + + args = parser.parse_args() + + build(config_filepath = args.config) \ No newline at end of file diff --git a/jimsite/articles.py b/jimsite/articles.py index 7a449dd..ec803b1 100644 --- a/jimsite/articles.py +++ b/jimsite/articles.py @@ -11,6 +11,7 @@ from .common import filepath_or_string, SiteConfig from .templating import format_html_template, TemplateSelections class ArticleMetadata(pydantic.BaseModel): + '''A model for the YAML frontmatter included with Markdown articles.''' title: str date: date published: bool @@ -21,6 +22,8 @@ class ArticleMetadata(pydantic.BaseModel): description: Optional[str] = None class Article(pydantic.BaseModel): + '''A model for a Markdown article, including its YAML frontmatter + metadata, as well as its path relative to the build cache root.''' path: str content: str metadata: Optional[ArticleMetadata] = None diff --git a/jimsite/assets.py b/jimsite/assets.py index c397b60..70f13dd 100644 --- a/jimsite/assets.py +++ b/jimsite/assets.py @@ -1,20 +1,30 @@ import os import glob import shutil -from .common import run, SiteConfig +from .common import run, GitRepo, SiteConfig -# TODO: Add support for origin and branch. -def pull_git_repo(repo: str, build_cache: str) -> None: +def pull_git_repo(repo: GitRepo, build_cache: str) -> None: '''Pulls/clones a repo into the build cache directory.''' + + # If a repo exists in the build cache, pull to it. if os.path.exists(f'{build_cache}/.git'): - run(f'git -C {build_cache} pull origin') + + # If a branch is specified, check out to it. + if repo.branch is not None: + run(f"git checkout {repo.branch}") + run(f"git -C {build_cache} pull {repo.remote}{' '+repo.branch if repo.branch else ''}") + + # If the build cache is empty, clone the repo into it. else: - run(f'git clone {repo} {build_cache}') + run(f"git clone {repo.url}{(' -b '+repo.branch) if repo.branch else ''} -o {repo.remote} {build_cache}") -def copy_assets(site: SiteConfig): - '''Copies the list of site assets from the build cache to the web root.''' +def copy_assets(site: SiteConfig) -> None: + '''Copies the list of site assets from the build cache to the web root. + The asset list can include globs (*). All paths are resolved relative to + the build cache root, and will be copied to an analogous location in the + web root.''' # Expand any globbed expressions. expanded_asset_list = [] @@ -28,7 +38,7 @@ def copy_assets(site: SiteConfig): # Construct the destination path analogous to the source path # but in the web root instead of the build cache. - destination = f'{site.web_root}/{a.lstrip("/")}' + destination = f'{site.web_root}/What the program does{a.lstrip("/")}' # Delete existing files. shutil.rmtree(destination, ignore_errors=True) diff --git a/jimsite/common.py b/jimsite/common.py index 4ee97fc..05752b3 100644 --- a/jimsite/common.py +++ b/jimsite/common.py @@ -25,6 +25,11 @@ class GlobalVars(pydantic.BaseModel): '''Static-valued global variables to be interpolated into any HTML templates.''' today: date = datetime.today() +class GitRepo(pydantic.BaseModel): + '''A nested model used in SiteConfig to represent a Git repo.''' + url: str + branch: Optional[str] = None + remote: Optional[str] = 'origin' class SiteConfig(pydantic.BaseModel): base_url: str @@ -33,7 +38,7 @@ class SiteConfig(pydantic.BaseModel): title: str description: Optional[str] = None published: Optional[bool] = True - git_repo: Optional[str] = None + git_repo: Optional[GitRepo] = None assets: Optional[list] = None articles: Optional[list] = None template_selections: Optional[dict] = {} diff --git a/site/templates/components/blog_archive.html b/site/templates/components/blog_archive.html index e552559..2315645 100644 --- a/site/templates/components/blog_archive.html +++ b/site/templates/components/blog_archive.html @@ -6,5 +6,7 @@

Post History

{content} +


+

Last Updated: {globalvars.today}{templates.components.rss_icon}

\ No newline at end of file