Jaypore CI

> Jaypore CI: Minimal, Offline, Local CI system.
Log | Files | Refs | README | LICENSE

commit 16a6b16c87c23ab738efdd7afaa1f1feaa927db2
parent 55ed51fe84e8ebe33997738afadd1c74530804e4
Author: Arjoonn Sharma <arjoonn@midpathsoftware.com>
Date:   Sat,  7 Mar 2026 22:41:55 +0530

x

Diffstat:
M.jci/run.sh | 11+++++++++++
Ascripts/render_examples.sh | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 112 insertions(+), 0 deletions(-)

diff --git a/.jci/run.sh b/.jci/run.sh @@ -128,6 +128,17 @@ echo "--- Step 1: Updating code with latest VERSION ---" run_step "Sync Version" "scripts/sync_version.sh" scripts/sync_version.sh echo "" +# --------------------------------------------------------------------------- +# Step 1b: Render examples into README.md, then regenerate the TOC index +# --------------------------------------------------------------------------- +echo "--- Step 1b: Rendering examples section into README.md ---" +run_step "Render Examples" "scripts/render_examples.sh" scripts/render_examples.sh +echo "" + +echo "--- Step 1c: Regenerating README index ---" +run_step "README Index" "scripts/generate_readme_index.sh" scripts/generate_readme_index.sh +echo "" + # Step 2: Build Docker image (sequential — other steps depend on it) # --------------------------------------------------------------------------- echo "--- Step 2: Building Docker image via scripts/build_image.sh ---" diff --git a/scripts/render_examples.sh b/scripts/render_examples.sh @@ -0,0 +1,101 @@ +#!/usr/bin/env bash +set -euo pipefail + +README_FILE="${1:-README.md}" + +if [[ ! -f "${README_FILE}" ]]; then + echo "README file not found: ${README_FILE}" >&2 + exit 1 +fi + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" +EXAMPLES_DIR="${REPO_ROOT}/examples" + +python3 - "$README_FILE" "$EXAMPLES_DIR" <<'PY' +import sys +import os +from pathlib import Path + +readme_path = Path(sys.argv[1]) +examples_dir = Path(sys.argv[2]) + +# --------------------------------------------------------------------------- +# Build a tree-style listing for a given directory (mirrors `tree .` output). +# Hidden files/dirs (dot-prefixed) are included since .jci is relevant. +# --------------------------------------------------------------------------- +def build_tree(root: Path) -> str: + lines = ["."] + + def walk(directory: Path, prefix: str): + entries = sorted( + directory.iterdir(), + key=lambda p: (p.is_file(), p.name), + ) + for idx, entry in enumerate(entries): + connector = "└── " if idx == len(entries) - 1 else "├── " + lines.append(f"{prefix}{connector}{entry.name}") + if entry.is_dir(): + extension = " " if idx == len(entries) - 1 else "│ " + walk(entry, prefix + extension) + + walk(root, "") + return "\n".join(lines) + + +# --------------------------------------------------------------------------- +# Collect examples +# --------------------------------------------------------------------------- +examples = sorted( + [d for d in examples_dir.iterdir() if d.is_dir()], + key=lambda d: d.name, +) + +section_lines = ["## Examples", ""] + +for example in examples: + # Header: derive a readable title from the folder name + name = example.name + # Strip leading digits+dash prefix (e.g. "00-", "13-") for the title + parts = name.split("-", 1) + title = parts[1].replace("-", " ").title() if len(parts) == 2 and parts[0].isdigit() else name + section_lines.append(f"### {title}") + section_lines.append("") + + run_sh = example / ".jci" / "run.sh" + + # Single fenced block with tree output + run.sh contents + section_lines.append("```") + section_lines.append("$ tree .") + section_lines.append(build_tree(example)) + + if run_sh.exists(): + section_lines.append("") + section_lines.append("") + section_lines.append("$ cat .jci/run.sh") + section_lines.append(run_sh.read_text(encoding="utf-8").rstrip()) + + section_lines.append("```") + section_lines.append("") + +# --------------------------------------------------------------------------- +# Replace the ## Examples section (everything from that heading to EOF) +# --------------------------------------------------------------------------- +text = readme_path.read_text(encoding="utf-8") +lines = text.splitlines() + +examples_heading_idx = next( + (i for i, l in enumerate(lines) if l.strip() == "## Examples"), + None, +) +if examples_heading_idx is None: + raise SystemExit("Could not find '## Examples' heading in README") + +new_lines = lines[:examples_heading_idx] + section_lines +new_text = "\n".join(new_lines) +if not new_text.endswith("\n"): + new_text += "\n" + +readme_path.write_text(new_text, encoding="utf-8") +print(f"Rendered {len(examples)} examples into {readme_path}") +PY