summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Schlosser <christoph@linux.com>2025-09-19 19:21:11 +0200
committerChristoph Schlosser <christoph@linux.com>2025-09-19 19:21:11 +0200
commita3324b7e71ec48daab81981e7d85967a590d4f79 (patch)
treedef4a8d901d9a56047a0e63f5f3d93803c93ee87
parentbd403e6ab18d5cc7818e86d43c3ca0b15c5e53a1 (diff)
downloadgit2hugo-a3324b7e71ec48daab81981e7d85967a590d4f79.tar.gz
g2h: Add utility script
Also move the sources into the more conventional src/g2h dir
-rw-r--r--README.md14
-rwxr-xr-xg2h36
-rw-r--r--src/g2h/__init__.py (renamed from g2h/__init__.py)0
-rw-r--r--src/g2h/cli.py (renamed from g2h/cli.py)12
-rw-r--r--src/g2h/commit_page.py (renamed from g2h/commit_page.py)0
-rw-r--r--src/g2h/file.py (renamed from g2h/file.py)0
-rw-r--r--src/g2h/file_page.py (renamed from g2h/file_page.py)0
-rw-r--r--src/g2h/git.py (renamed from g2h/git.py)0
-rw-r--r--src/g2h/log_page.py (renamed from g2h/log_page.py)0
-rw-r--r--src/g2h/overview_page.py (renamed from g2h/overview_page.py)0
-rw-r--r--src/g2h/page.py (renamed from g2h/page.py)2
-rw-r--r--src/g2h/page_factory.py (renamed from g2h/page_factory.py)0
-rw-r--r--src/g2h/tree.py (renamed from g2h/tree.py)0
-rw-r--r--src/g2h/tree_page.py (renamed from g2h/tree_page.py)0
-rw-r--r--tests/base_page_test.py2
-rw-r--r--tests/commit_page_test.py2
-rw-r--r--tests/file_page_test.py2
-rw-r--r--tests/file_test.py2
-rw-r--r--tests/log_page_test.py2
-rw-r--r--tests/overview_page_test.py2
-rw-r--r--tests/tree_page_test.py2
-rw-r--r--tests/tree_test.py2
22 files changed, 60 insertions, 20 deletions
diff --git a/README.md b/README.md
index b22dc83..48767e8 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,6 @@
# g2h - Generate Hugo style markdown pages from your git repository history
This program allows you to generate markdown files to have a static web based interface for navigating git repositores.
-Something like [cgit](https://git.zx2c4.com/cgit/) for static websites, like [stagit](https://codemadness.org/stagit.html), but emitting Markdown for use in [Hugo](https://gohugo.io)[^1].
## Goals
@@ -14,7 +13,7 @@ Something like [cgit](https://git.zx2c4.com/cgit/) for static websites, like [st
- Provide codesearch.
- Replacement for Git forges.
-- Replace cgit.
+- Replace `cgit`.
- Work for large projects, as they may be found in a company (like) setting.
- Implement any work that should be taken care of by Hugo, e.g. combining multiple projects onto a single page, feeds and custom styling.
@@ -23,9 +22,9 @@ Something like [cgit](https://git.zx2c4.com/cgit/) for static websites, like [st
Let's assume your git project is in `~/development/project` and the sources for your static site are in `~/web/page`.
Then you would run this command:
```bash
-g2h --repo ~/development/project --out ~/web/page --title "My awesome project" --static-subdir project --content-subdir git/project
+g2h --repo ~/development/project --out ~/web/page --name "My awesome project" --content-subdir git/project
```
-The markdown files for Hugo will be placed in `~/web/page/content/git/project` and static files, like tarballs for each commit and individual file hashes, into `~/web/page/static/project`.
+The markdown files for Hugo will be placed in `~/web/page/content/git/project`.
For a full list of options, their defaults and how they're changing the behavior of the program run `g2h --help`.
## Features
@@ -62,9 +61,14 @@ For a full list of options, their defaults and how they're changing the behavior
- [ ] Add button to download raw file.
- [x] Nav bar for navigating the pages mentioned above.
- [ ] Link to special readme, if a readme can be found, rendering markdown.
-- [ ] Wrapper script that takes care of `venv` setup.
+- [x] Wrapper script that takes care of `venv` setup.
- [ ] Limit to certain branch(es).
- [ ] Limit commit range.
- [ ] Parallelize generating output.
+## Similar projects
+
+- [cgit](https://git.zx2c4.com/cgit/) does everything `g2h` does and more, but not as static websites.
+- [stagit](https://codemadness.org/stagit.html) generates HTML instead of emitting Markdown for a consistent style in [Hugo](https://gohugo.io)[^1].
+
[^1]: I'm using Hugo but any static site generator with a similar layout should work.
diff --git a/g2h b/g2h
new file mode 100755
index 0000000..9f54652
--- /dev/null
+++ b/g2h
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+
+SCRIPT_DIR=$(dirname $(readlink -f $0))
+VENV_DIR="${SCRIPT_DIR}/.venv/"
+ACTIVATE_SCRIPT="${SCRIPT_DIR}/.venv/bin/activate"
+
+if [ ! -f "${ACTIVATE_SCRIPT}" ]; then
+ echo "Virtual environment not found. Creating..."
+ python3 -m venv "${VENV_DIR}"
+ if [ $? -ne 0 ]; then
+ echo "Failed to create virtual environment."
+ exit 1
+ fi
+ echo "Virtual environment created at ${VENV_DIR}."
+
+ source "${ACTIVATE_SCRIPT}"
+ if [ $? -ne 0 ]; then
+ echo "Failed to activate virtual environment."
+ exit 1
+ fi
+
+ pip install -r "${SCRIPT_DIR}/requirements.txt"
+ if [ $? -ne 0 ]; then
+ echo "Failed to install project dependencies."
+ exit 1
+ fi
+ echo "Project dependencies installed."
+else
+ source "${ACTIVATE_SCRIPT}"
+ if [ $? -ne 0 ]; then
+ echo "Failed to activate virtual environment."
+ exit 1
+ fi
+fi
+
+python3 -m src.g2h.cli "$@"
diff --git a/g2h/__init__.py b/src/g2h/__init__.py
index e69de29..e69de29 100644
--- a/g2h/__init__.py
+++ b/src/g2h/__init__.py
diff --git a/g2h/cli.py b/src/g2h/cli.py
index 3f60b82..9eb869c 100644
--- a/g2h/cli.py
+++ b/src/g2h/cli.py
@@ -9,8 +9,8 @@ def parse_args():
prog='g2h',
description='Convert a git repository into markdown files Hugo can understand.')
# TODO: Defaults for these two values should be $PWD.
- parser.add_argument('repo_path', help='Path to the root of git repository')
- parser.add_argument('out_dir', help='Path to where the generated files should be stored')
+ parser.add_argument('--repo', help='Path to the root of git repository', default=os.getcwd())
+ parser.add_argument('--out', help='Path to where the generated files should be stored', default=os.getcwd())
parser.add_argument('--name', help='Name of the project. Default: directory name of repo')
parser.add_argument('--content-subdir', help='Subdir(s) where the page will be served from. Default: None', default='')
@@ -18,16 +18,16 @@ def parse_args():
def main():
args = parse_args()
- git = Git(args.repo_path)
+ git = Git(args.repo)
branches = sorted(git.get_branches(), key=lambda b: b.commit.committed_date, reverse=True)
commits = git.get_commits()
head = git.get_head()
- # TODO: Fix this for repo_path=(.|~)
- project_name = args.name if args.name is not None else os.path.basename(args.repo_path)
+ # TODO: Fix this for repo=(.|~)
+ project_name = args.name if args.name is not None else os.path.basename(args.repo)
tags = sorted(git.get_tags(), key=lambda t: t.commit.committed_date, reverse=True)
- factory = PageFactory(args.out_dir, project_name, args.content_subdir)
+ factory = PageFactory(args.out, project_name, args.content_subdir)
factory.new_overview(branches, tags, head).render()
factory.new_log(commits, branches, tags, head).render()
for commit in commits:
diff --git a/g2h/commit_page.py b/src/g2h/commit_page.py
index 84374e6..84374e6 100644
--- a/g2h/commit_page.py
+++ b/src/g2h/commit_page.py
diff --git a/g2h/file.py b/src/g2h/file.py
index e07f251..e07f251 100644
--- a/g2h/file.py
+++ b/src/g2h/file.py
diff --git a/g2h/file_page.py b/src/g2h/file_page.py
index a558254..a558254 100644
--- a/g2h/file_page.py
+++ b/src/g2h/file_page.py
diff --git a/g2h/git.py b/src/g2h/git.py
index 283135c..283135c 100644
--- a/g2h/git.py
+++ b/src/g2h/git.py
diff --git a/g2h/log_page.py b/src/g2h/log_page.py
index b8df839..b8df839 100644
--- a/g2h/log_page.py
+++ b/src/g2h/log_page.py
diff --git a/g2h/overview_page.py b/src/g2h/overview_page.py
index 145a8d7..145a8d7 100644
--- a/g2h/overview_page.py
+++ b/src/g2h/overview_page.py
diff --git a/g2h/page.py b/src/g2h/page.py
index b829a88..afe6ac2 100644
--- a/g2h/page.py
+++ b/src/g2h/page.py
@@ -6,7 +6,7 @@ class Page:
self.out_file_path = os.path.join(out_dir, out_file)
self.name = name
self.content_subdir = content_subdir
- template_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'templates'))
+ template_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'templates'))
self.template = Environment(loader=FileSystemLoader(template_dir)).get_template(template_file)
def context(self):
diff --git a/g2h/page_factory.py b/src/g2h/page_factory.py
index 4a46f14..4a46f14 100644
--- a/g2h/page_factory.py
+++ b/src/g2h/page_factory.py
diff --git a/g2h/tree.py b/src/g2h/tree.py
index bd8116c..bd8116c 100644
--- a/g2h/tree.py
+++ b/src/g2h/tree.py
diff --git a/g2h/tree_page.py b/src/g2h/tree_page.py
index df65a33..df65a33 100644
--- a/g2h/tree_page.py
+++ b/src/g2h/tree_page.py
diff --git a/tests/base_page_test.py b/tests/base_page_test.py
index c68e435..eb1409c 100644
--- a/tests/base_page_test.py
+++ b/tests/base_page_test.py
@@ -1,4 +1,4 @@
-from g2h.page import Page
+from src.g2h.page import Page
from jinja2.exceptions import TemplateNotFound
import pytest
diff --git a/tests/commit_page_test.py b/tests/commit_page_test.py
index 2078ed3..0d7a225 100644
--- a/tests/commit_page_test.py
+++ b/tests/commit_page_test.py
@@ -1,4 +1,4 @@
-from g2h.commit_page import CommitPage, redact_email
+from src.g2h.commit_page import CommitPage, redact_email
from unittest.mock import MagicMock
def test_init():
diff --git a/tests/file_page_test.py b/tests/file_page_test.py
index 097f5a1..5bd2f6d 100644
--- a/tests/file_page_test.py
+++ b/tests/file_page_test.py
@@ -1,6 +1,6 @@
from unittest.mock import MagicMock
-from g2h.file_page import FilePage, bytes_to_content
+from src.g2h.file_page import FilePage, bytes_to_content
def test_init():
commit = MagicMock()
diff --git a/tests/file_test.py b/tests/file_test.py
index d1b40bd..92b888c 100644
--- a/tests/file_test.py
+++ b/tests/file_test.py
@@ -3,7 +3,7 @@ import pytest
from unittest.mock import MagicMock, Mock
-from g2h.file import generate_breadcrumbs, sanitize_file_name, tree_join
+from src.g2h.file import generate_breadcrumbs, sanitize_file_name, tree_join
def test_sanitize_not_necessary():
assert(sanitize_file_name('foo', None) == 'foo')
diff --git a/tests/log_page_test.py b/tests/log_page_test.py
index da00fd0..353de8a 100644
--- a/tests/log_page_test.py
+++ b/tests/log_page_test.py
@@ -1,4 +1,4 @@
-from g2h.log_page import LogPage
+from src.g2h.log_page import LogPage
from unittest.mock import MagicMock
def test_init():
diff --git a/tests/overview_page_test.py b/tests/overview_page_test.py
index d2b3f82..2e7b32c 100644
--- a/tests/overview_page_test.py
+++ b/tests/overview_page_test.py
@@ -1,6 +1,6 @@
from unittest.mock import Mock
-from g2h.overview_page import OverviewPage
+from src.g2h.overview_page import OverviewPage
def test_init():
commit = Mock()
diff --git a/tests/tree_page_test.py b/tests/tree_page_test.py
index 57084d1..53738c6 100644
--- a/tests/tree_page_test.py
+++ b/tests/tree_page_test.py
@@ -2,7 +2,7 @@ import os
from pytest import fail
from unittest.mock import MagicMock
-from g2h.tree_page import TreePage
+from src.g2h.tree_page import TreePage
def test_init():
repo = MagicMock()
diff --git a/tests/tree_test.py b/tests/tree_test.py
index 7ec0f0e..8883106 100644
--- a/tests/tree_test.py
+++ b/tests/tree_test.py
@@ -1,6 +1,6 @@
from unittest.mock import Mock
-from g2h.tree import safe_join
+from src.g2h.tree import safe_join
def test_safe_join_empty():
tree = Mock()