1
0
mirror of git://f0xx.org/android_cast synced 2026-07-29 05:37:52 +03:00

last changes in rendering pipeline

This commit is contained in:
Anton Afanasyeu
2026-05-23 12:52:19 +02:00
parent aa05e8e39c
commit a698803d19
21 changed files with 167 additions and 219 deletions

View File

@@ -92,4 +92,4 @@ Activities bind via AIDL (`ICastSenderService` / `ICastReceiverService`) for sta
We use a **green `master`** plus integration branch **`next`**: features merge to `next` first; releases merge `next``master` and are tagged there; production hotfixes branch from `master` and sync back into `next`. We use a **green `master`** plus integration branch **`next`**: features merge to `next` first; releases merge `next``master` and are tagged there; production hotfixes branch from `master` and sync back into `next`.
- Narrative: [docs/GIT_FLOW.md](docs/GIT_FLOW.md) - Narrative: [docs/GIT_FLOW.md](docs/GIT_FLOW.md)
- PDF: [docs/GIT_FLOW.pdf](docs/GIT_FLOW.pdf) — `pip install -r docs/_pdf_build/requirements-pdf.txt` + `rsvg-convert`, then `python3 docs/_pdf_build/build_git_flow_pdf.py` (SVG sources alongside for vector view) - PDF: [docs/GIT_FLOW.pdf](docs/GIT_FLOW.pdf) — `pip install -r docs/_pdf_build/requirements-pdf.txt`, then `python3 docs/_pdf_build/build_git_flow_pdf.py`

View File

@@ -1,15 +1,15 @@
# Android Cast — Git flow (green `master`) # Android Cast — Git flow (green `master`)
This document defines how we develop, integrate, release, and hotfix. **Cursor agents and humans follow the same rules.**
| Field | Value | | Field | Value |
|-------|-------| |-------|-------|
| **Version** | 1.1 | | Version | 1.3 |
| **Published** | 2026-05-21 | | Published | 2026-05-23 |
| **Author(s)** | Anton Afanaasyeu | | Author(s) | Anton Afanaasyeu |
| **Markdown source** | `docs/GIT_FLOW.md` | | Markdown source | `docs/GIT_FLOW.md` |
| **PDF** | `docs/GIT_FLOW.pdf``python3 docs/_pdf_build/build_git_flow_pdf.py` | | PDF | `docs/GIT_FLOW.pdf` |
| **Diagrams (vector)** | `docs/_pdf_build/git_flow_diagram_*.svg` — open in Okular for crisp zoom | | Diagram sources | `docs/_pdf_build/git_flow_diagram_*.mmd` (render via `build_git_flow_pdf.py`) |
This document defines how we develop, integrate, release, and hotfix. **Cursor agents and humans follow the same rules.**
--- ---

File diff suppressed because one or more lines are too long

View File

@@ -1,16 +1,16 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Build docs/GIT_FLOW.pdf from structured content and Mermaid diagrams. """Build docs/GIT_FLOW.pdf from structured content and Mermaid diagrams.
Pipeline: Mermaid (.mmd) → SVG → high-DPI PNG (rsvg-convert) → PDF with correct aspect ratio. Diagrams: Mermaid CLI renders PNG via headless Chromium (text + layout correct).
Vector sources: docs/_pdf_build/git_flow_diagram_*.svg (open in Okular for crisp zoom). Do NOT pipe Mermaid SVG through rsvg-convert — Mermaid uses foreignObject HTML labels
that librsvg drops (boxes only, no text).
Requires: reportlab, npx (@mermaid-js/mermaid-cli), rsvg-convert (librsvg). Requires: reportlab, npx (@mermaid-js/mermaid-cli), Chromium (puppeteer bundled).
Regenerate: python3 docs/_pdf_build/build_git_flow_pdf.py Regenerate: python3 docs/_pdf_build/build_git_flow_pdf.py
""" """
from __future__ import annotations from __future__ import annotations
import shutil
import subprocess import subprocess
import sys import sys
from pathlib import Path from pathlib import Path
@@ -33,40 +33,47 @@ from reportlab.platypus import (
ROOT = Path(__file__).resolve().parents[2] ROOT = Path(__file__).resolve().parents[2]
BUILD = Path(__file__).resolve().parent BUILD = Path(__file__).resolve().parent
CONFIG = BUILD / "mermaid-config.json"
OUT_PDF = ROOT / "docs" / "GIT_FLOW.pdf" OUT_PDF = ROOT / "docs" / "GIT_FLOW.pdf"
# (mmd, svg, png, caption, mermaid w/h px, max width cm in PDF) # (mmd, png, caption, mermaid width px, height px, scale, max width cm in PDF)
DIAGRAMS = [ DIAGRAMS = [
("git_flow_diagram_branches.mmd", "git_flow_diagram_branches.svg", "git_flow_diagram_branches.png", ("git_flow_diagram_branches.mmd", "git_flow_diagram_branches.png",
"Branch model (green master)", 1600, 720, 15.5), "Branch model (green master)", 1800, 900, 2, 15.5),
("git_flow_diagram_feature.mmd", "git_flow_diagram_feature.svg", "git_flow_diagram_feature.png", ("git_flow_diagram_feature.mmd", "git_flow_diagram_feature.png",
"Daily development", 1100, 1300, 14.0), "Daily development", 2400, 2000, 2, 14.0),
("git_flow_diagram_release.mmd", "git_flow_diagram_release.svg", "git_flow_diagram_release.png", ("git_flow_diagram_release.mmd", "git_flow_diagram_release.png",
"Release: next → master", 1100, 1300, 14.0), "Release: next → master", 2400, 2000, 2, 14.0),
("git_flow_diagram_hotfix.mmd", "git_flow_diagram_hotfix.svg", "git_flow_diagram_hotfix.png", ("git_flow_diagram_hotfix.mmd", "git_flow_diagram_hotfix.png",
"Hotfix decision and flow", 1200, 1000, 14.5), "Hotfix decision and flow", 1300, 1100, 2, 14.5),
] ]
MAX_DIAGRAM_HEIGHT_CM = 16.5 MAX_DIAGRAM_HEIGHT_CM = 16.5
RSVG_DPI = 200
DOC_VERSION = "1.1" DOC_VERSION = "1.3"
DOC_DATE = "2026-05-21" DOC_DATE = "2026-05-23"
DOC_AUTHOR = "Anton Afanaasyeu" DOC_AUTHOR = "Anton Afanaasyeu"
DOC_SOURCE = "docs/GIT_FLOW.md" DOC_SOURCE = "docs/GIT_FLOW.md"
def render_mermaid() -> None: def render_mermaid() -> None:
for mmd, svg_name, _, _, w_px, h_px, _ in DIAGRAMS: if not CONFIG.exists():
raise FileNotFoundError(CONFIG)
for mmd, png_name, _, w_px, h_px, scale, _ in DIAGRAMS:
src = BUILD / mmd src = BUILD / mmd
dst = BUILD / svg_name dst = BUILD / png_name
if not src.exists(): if not src.exists():
raise FileNotFoundError(src) raise FileNotFoundError(src)
subprocess.run( subprocess.run(
[ [
"npx", "--yes", "@mermaid-js/mermaid-cli@11.4.0", "npx", "--yes", "@mermaid-js/mermaid-cli@11.4.0",
"-i", str(src), "-o", str(dst), "-i", str(src),
"-b", "white", "-w", str(w_px), "-H", str(h_px), "-o", str(dst),
"-c", str(CONFIG),
"-b", "white",
"-w", str(w_px),
"-H", str(h_px),
"-s", str(scale),
], ],
cwd=str(ROOT), cwd=str(ROOT),
check=True, check=True,
@@ -74,24 +81,7 @@ def render_mermaid() -> None:
) )
def svg_to_png(svg_path: Path, png_path: Path) -> None:
if not shutil.which("rsvg-convert"):
raise RuntimeError("rsvg-convert not found (install librsvg / gnome-base/rsvg)")
subprocess.run(
[
"rsvg-convert",
"-d", str(RSVG_DPI),
"-p", str(RSVG_DPI),
"-o", str(png_path),
str(svg_path),
],
check=True,
timeout=60,
)
def diagram_size_cm(png_path: Path, max_width_cm: float) -> tuple[float, float]: def diagram_size_cm(png_path: Path, max_width_cm: float) -> tuple[float, float]:
"""Width/height in cm preserving aspect ratio, capped by page frame."""
w_px, h_px = ImageReader(str(png_path)).getSize() w_px, h_px = ImageReader(str(png_path)).getSize()
max_w = max_width_cm * cm max_w = max_width_cm * cm
max_h = MAX_DIAGRAM_HEIGHT_CM * cm max_h = MAX_DIAGRAM_HEIGHT_CM * cm
@@ -159,17 +149,15 @@ def build_pdf() -> None:
["Published", DOC_DATE], ["Published", DOC_DATE],
["Author(s)", DOC_AUTHOR], ["Author(s)", DOC_AUTHOR],
["Markdown source", DOC_SOURCE], ["Markdown source", DOC_SOURCE],
["Diagrams (PDF)", f"Mermaid → SVG → PNG @ {RSVG_DPI} DPI"], ["Diagrams", "Mermaid CLI → PNG (Chromium); proportional embed in PDF"],
["Diagrams (vector)", "docs/_pdf_build/git_flow_diagram_*.svg"],
], ],
[4.0 * cm, 12.5 * cm], [4.0 * cm, 12.5 * cm],
) )
story.append(Spacer(1, 0.25 * cm)) story.append(Spacer(1, 0.25 * cm))
story.append( story.append(
p( p(
"PDF diagrams are high-resolution raster with correct aspect ratio (not stretched). " "Diagrams are rendered by headless Chromium (not rsvg/SVG rasterize) so labels stay visible. "
"For infinite zoom, open the SVG files in Okular or a browser. " "Regenerate after editing docs/_pdf_build/git_flow_diagram_*.mmd.",
"Okular: View → Zoom for PDF; SVG opens as native vector.",
small, small,
), ),
) )
@@ -202,7 +190,7 @@ def build_pdf() -> None:
[3 * cm, 8.5 * cm, 4 * cm], [3 * cm, 8.5 * cm, 4 * cm],
) )
story.append(Spacer(1, 0.3 * cm)) story.append(Spacer(1, 0.3 * cm))
add_diagram(story, DIAGRAMS[0][2], DIAGRAMS[0][3], h2, DIAGRAMS[0][6]) add_diagram(story, DIAGRAMS[0][1], DIAGRAMS[0][2], h2, DIAGRAMS[0][6])
story.append(PageBreak()) story.append(PageBreak())
story.append(p("3. Daily development", h1)) story.append(p("3. Daily development", h1))
@@ -230,7 +218,7 @@ def build_pdf() -> None:
body, body,
), ),
) )
add_diagram(story, DIAGRAMS[1][2], DIAGRAMS[1][3], h2, DIAGRAMS[1][6]) add_diagram(story, DIAGRAMS[1][1], DIAGRAMS[1][2], h2, DIAGRAMS[1][6])
story.append(PageBreak()) story.append(PageBreak())
story.append(p("4. Release (next → master)", h1)) story.append(p("4. Release (next → master)", h1))
@@ -243,7 +231,7 @@ def build_pdf() -> None:
"Continue feature branches from updated next", "Continue feature branches from updated next",
]: ]:
story.append(p(f"{line}", bullet)) story.append(p(f"{line}", bullet))
add_diagram(story, DIAGRAMS[2][2], DIAGRAMS[2][3], h2, DIAGRAMS[2][6]) add_diagram(story, DIAGRAMS[2][1], DIAGRAMS[2][2], h2, DIAGRAMS[2][6])
story.append(PageBreak()) story.append(PageBreak())
story.append(p("5. Hotfixes — recommended strategy", h1)) story.append(p("5. Hotfixes — recommended strategy", h1))
@@ -271,7 +259,7 @@ def build_pdf() -> None:
body, body,
), ),
) )
add_diagram(story, DIAGRAMS[3][2], DIAGRAMS[3][3], h2, DIAGRAMS[3][6]) add_diagram(story, DIAGRAMS[3][1], DIAGRAMS[3][2], h2, DIAGRAMS[3][6])
story.append(p("5.1 Sync cheat sheet", h2)) story.append(p("5.1 Sync cheat sheet", h2))
add_table( add_table(
@@ -304,9 +292,8 @@ def build_pdf() -> None:
story.append( story.append(
p( p(
"<b>Force-push on next:</b> keep disabled by default. Allow only when you intentionally " "<b>Force-push on next:</b> keep disabled by default. Allow only when you intentionally "
"rewrite integration history (e.g. squash fixups before release) — never on master. " "rewrite integration history — never on master. Prefer fixing on topic branches before "
"Prefer merge/rebase on topic branches instead. If you force-push next, coordinate with " "merging to next.",
"anyone else using the repo and re-sync their clones.",
body, body,
), ),
) )
@@ -322,10 +309,7 @@ def build_pdf() -> None:
story.append(p(f"{line}", bullet)) story.append(p(f"{line}", bullet))
story.append(Spacer(1, 0.4 * cm)) story.append(Spacer(1, 0.4 * cm))
story.append( story.append(
p( p("Regenerate: python3 docs/_pdf_build/build_git_flow_pdf.py", small),
"Regenerate: python3 docs/_pdf_build/build_git_flow_pdf.py",
small,
),
) )
doc = SimpleDocTemplate( doc = SimpleDocTemplate(
@@ -343,17 +327,12 @@ def build_pdf() -> None:
def main() -> int: def main() -> int:
try: try:
render_mermaid() render_mermaid()
for _mmd, svg_name, png_name, *_ in DIAGRAMS:
svg_to_png(BUILD / svg_name, BUILD / png_name)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
print("Diagram render failed:", e, file=sys.stderr) print("Mermaid render failed:", e, file=sys.stderr)
return 1 return 1
except FileNotFoundError as e: except FileNotFoundError as e:
print(e, file=sys.stderr) print(e, file=sys.stderr)
return 1 return 1
except RuntimeError as e:
print(e, file=sys.stderr)
return 1
build_pdf() build_pdf()
return 0 return 0

View File

@@ -1,10 +1,5 @@
%% Branch model — render PNG via mermaid-cli (Chromium). Do not rasterize SVG with rsvg.
flowchart TB flowchart TB
subgraph legend[" "]
direction LR
L1[Long-lived]
L2[Short-lived]
end
M["master\n(always green, tagged releases)"] M["master\n(always green, tagged releases)"]
N["next\n(integration / release candidate)"] N["next\n(integration / release candidate)"]
F["feature/* fix/*\n(fork next)"] F["feature/* fix/*\n(fork next)"]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 71 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 16 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -11,4 +11,4 @@ sequenceDiagram
Dev->>CI: run tests Dev->>CI: run tests
CI-->>Dev: pass CI-->>Dev: pass
Dev->>Next: merge topic branch Dev->>Next: merge topic branch
Note over Next: server may delete merged branch on origin Note over Next: delete branch on merge<br/>(origin server setting)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 70 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 27 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 114 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 149 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 149 KiB

View File

@@ -5,7 +5,7 @@ sequenceDiagram
participant CI as Tests / CI participant CI as Tests / CI
participant Tag as tag vX.Y.Z participant Tag as tag vX.Y.Z
Note over Next: feature complete, QA ok Note over Next: feature complete,<br/>QA ok
Next->>CI: full test suite Next->>CI: full test suite
CI-->>Next: green CI-->>Next: green
Next->>Master: merge next to master Next->>Master: merge next to master
@@ -13,4 +13,4 @@ sequenceDiagram
CI-->>Master: green CI-->>Master: green
Master->>Tag: annotated tag on master Master->>Tag: annotated tag on master
Master->>Next: merge master into next (sync) Master->>Next: merge master into next (sync)
Note over Next: continue features from synced next Note over Next: continue features<br/>from synced next

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 88 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 28 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -0,0 +1,17 @@
{
"theme": "neutral",
"flowchart": {
"htmlLabels": true,
"curve": "basis"
},
"sequence": {
"diagramMarginX": 120,
"diagramMarginY": 28,
"actorMargin": 90,
"noteMargin": 24,
"messageMargin": 48,
"boxMargin": 14,
"mirrorActors": false,
"useMaxWidth": false
}
}

View File

@@ -1,3 +1,4 @@
reportlab>=4.0 reportlab>=4.0
# PDF diagrams: Mermaid CLI (npx) + rsvg-convert (system package librsvg). # Diagrams: npx @mermaid-js/mermaid-cli (uses bundled Chromium).
# Do NOT use rsvg-convert on Mermaid SVG — HTML labels are dropped.