diff --git a/.config/dictionaries/project.dic b/.config/dictionaries/project.dic
index 105394ea5..924f707a2 100644
--- a/.config/dictionaries/project.dic
+++ b/.config/dictionaries/project.dic
@@ -1,18 +1,25 @@
aarch
buildkit
camelcase
+codegen
colordiff
cowsay
cytopia
devenv
dind
dockerhub
+doublecircle
Earthfile
Earthfiles
errchkjson
extldflags
+fira
+fmtchk
+fmtfix
fontawesome
fontconfig
+fontname
+forcelabels
genpkey
ginkgolinter
gitops
@@ -29,11 +36,14 @@ GOMODCACHE
gopls
gosec
graphviz
+idents
jorm
jormungandr
Kroki
kubeconfig
ldflags
+libgcc
+lintfix
markdownlint
mattn
mdlint
@@ -41,45 +51,41 @@ mkdocs
modcache
mozallowfullscreen
multirepo
+nextest
nilnil
nixos
nixpkgs
onsi
+penwidth
pkeyopt
pkgs
projectcatalyst
pubout
pymdownx
PYTHONDONTWRITEBYTECODE
+rankdir
rivo
runewidth
+rustdoc
+rustdocflags
+rustflags
+rustfmt
sqlfluff
subproject
subprojects
superfences
templating
+testcov
+testdocs
testpackage
+testunit
Timoni
transpiling
UDCs
uniseg
voteplan
+wasi
webkitallowfullscreen
WORKDIR
xerrors
zstd
-idents
-rustflags
-rustdoc
-rustdocflags
-rustfmt
-codegen
-libgcc
-lintfix
-testunit
-nextest
-testcov
-testdocs
-fmtchk
-fmtfix
-wasi
\ No newline at end of file
diff --git a/docs/src/appendix/examples/diagrams/invasion_plan.dot b/docs/src/appendix/examples/diagrams/invasion_plan.dot
new file mode 100644
index 000000000..9b0d27b85
--- /dev/null
+++ b/docs/src/appendix/examples/diagrams/invasion_plan.dot
@@ -0,0 +1,6 @@
+digraph G {
+ rankdir=LR
+ Earth [peripheries=2]
+ Mars
+ Earth -> Mars
+}
diff --git a/docs/src/appendix/examples/graphviz-diagrams.md b/docs/src/appendix/examples/graphviz-diagrams.md
new file mode 100644
index 000000000..dc2756af4
--- /dev/null
+++ b/docs/src/appendix/examples/graphviz-diagrams.md
@@ -0,0 +1,178 @@
+---
+icon: material/draw
+---
+
+# Graphviz Diagrams
+
+## Graphviz SVG's
+
+=== "Trees"
+
+
+
+
+ ```dot
+ graph G {
+ size="1.8"
+ node [shape=circle, fontname="fira code", fontsize=28, penwidth=3]
+ edge [penwidth=3]
+ "-" -- {"x", "+"}
+ "x" -- 3 [weight=2]
+ "x" -- 5
+ "+" -- 2
+ "+" -- 4 [weight=2]
+ }
+ ```
+
+ Tree 1: Tree of Arithmetic Expressions
+
+ ```dot
+ graph G {
+ size="3"
+ forcelabels=true
+ node [shape=circle, fontname="fira code", fontsize=24, penwidth=3];
+ edge [penwidth=3]
+ 5 -- {4, 32} [color=red]
+ 31, 32 [label="3"]
+ 21, 22, 23 [label="2"]
+ 11, 12, 13, 14, 15 [label="1"]
+ 01, 02, 03, 04, 05, 06, 07, 08 [label="0"]
+ 4 -- 31 [color=blue, weight=2]
+ 4 -- 22 [color=blue]
+ 31 -- 21 [color=red, weight=3]
+ 31 -- 12 [color=red]
+ 32 -- 23 [color=blue]
+ 32 -- 15 [color=blue, weight=2]
+ 21 -- 11 [color=blue, weight=3]
+ 21 -- 02 [color=blue]
+ 11 -- 01 [color=red]
+ 12 -- 03 [color=blue]
+ 22 -- 13 [color=red]
+ 22 -- 05 [color=red, weight=2]
+ 13 -- 04 [color=blue]
+ 23 -- {14, 07} [color=red]
+ 14 -- 06 [color=blue]
+ 15 -- 08 [color=red]
+ 07, 08 [shape=doublecircle]
+ }
+ ```
+
+ Tree 2: Game Tree (of Nim)
+
+
+
+=== "Graphs"
+
+
+
+ ```dot
+ graph G {
+ size="2";
+ bgcolor=none;
+ node [shape=circle, fontsize=30, style=bold];
+ edge [style=bold, fontsize=30]
+ 4 -- 0
+ 4 -- 0
+ 4 -- 1
+ 0 -- 2
+ 0 -- 2
+ 0 -- 2
+ 2 -- 2
+ 0 -- 3
+ 1 -- 2
+ 1 -- 3
+ 1 -- 1
+ }
+ ```
+
+ An Unweighted
Undirected
Multi-graph (with loops)
+
+ ```dot
+ digraph G {
+ size="8"
+ node [shape=circle, fontsize=38]
+ edge [arrowhead=none]
+ subgraph cluster0 {
+ 0 -> 1
+ 2, 0, 3, 8, 11, 10 [color=blue, style=bold]
+ 0 -> 2 [color=blue, style=bold]
+ 0 -> 3 [color=blue, style=bold]
+ 2 -> 3
+ 8 -> 9
+ 2 -> 9
+ 8 -> 3 [color=blue, style=bold]
+ 0 -> 4 -> 10
+ 10 -> 11 [color=blue, style=bold]
+ 8 -> 11 [color=blue, style=bold]
+ subgraph cluster00 {
+ 1, 5, 6 [color=red, style=bold]
+ 1 -> 5 [color=red, style=bold]
+ 1 -> 6 [color=red, style=bold]
+ 5 -> 6 [color=red, style=bold]
+ label="cycle"
+ fontcolor=red
+ fontsize=38
+ {rank = same; 5; 6;}
+ }
+ 6 -> 7
+ 2 -> 8
+ 3 -> 9
+ label = "Related Component";
+ fontsize=38
+ {rank = same; 2; 3;}
+ {rank = same; 8; 9;}
+ }
+
+ subgraph cluster1 {
+ 15 -> 16 -> 17
+ 16 -> 18 -> 19
+ label="Related Component"
+ fontsize=38
+ }
+
+ subgraph cluster2 {
+ 20 -> 21 -> 22
+ 20 -> 23
+ 21 -> 23
+ 23 -> 24
+ label="Related Component"
+ fontsize=38
+ }
+ }
+ ```
+
+
+ Graph G Undirected Unweighted Unrelated
+
+
+## Graphviz inside Admonitions
+
+???- note "graphviz in UnExpanded Block"
+
+ ```dot
+ {{ include_file('src/appendix/examples/diagrams/invasion_plan.dot', indent=4) }}
+ ```
+
+???+ note "graphviz in Expanded Block"
+
+ ```dot
+ {{ include_file('src/appendix/examples/diagrams/invasion_plan.dot', indent=4) }}
+ ```
+
+## Graphviz PNG's (lower quality than SVGs)
+
+=== "Graphviz Render"
+
+ ```graphviz dot attack_plan.png
+ {{ include_file('src/appendix/examples/diagrams/invasion_plan.dot', indent=4) }}
+ ```
+
+=== "Example of Code Syntax"
+
+ **SYNTAX (WATCHOUT) :** NO SPACES BETWEEN ` ``` ` and `graphviz`
+
+ ~~~
+ ``` graphviz dot attack_plan.png
+ {{ include_file('src/appendix/examples/diagrams/invasion_plan.dot', indent=4) }}
+ ```
+ ~~~
diff --git a/docs/src/appendix/examples/kroki-diagrams.md b/docs/src/appendix/examples/kroki-diagrams.md
index 1d70704d9..1ef658793 100644
--- a/docs/src/appendix/examples/kroki-diagrams.md
+++ b/docs/src/appendix/examples/kroki-diagrams.md
@@ -4,6 +4,11 @@ icon: material/drawing-box
# Kroki Diagrams
+**Kroki has proven unreliable in CI** therefore we no longer recommend its use.
+It will be removed as soon as the last existing diagrams have a local renderer.
+For diagrams that do not have a local renderer we will need to export them manually and
+embed both the source and rendered image file inside the docs themselves.
+
## Kroki Mermaid
@@ -11,24 +16,37 @@ icon: material/drawing-box
* No Links
* Stand alone SVG
+* Fails with 504 as at 8 March 2024
+
+
+
+~~~md
```kroki-mermaid theme=forest
-flowchart LR
- A[Start] --> B{Error?};
- B -->|Yes| C[Hmm...];
- C --> D[Debug];
- D --> B;
- B ---->|No| E[Yay!];
+ flowchart LR
+ A[Start] -> B{Error?};
+ B ->|Yes| C[Hmm...];
+ C -> D[Debug];
+ D -> B;
+ B ->|No| E[Yay!];
```
+~~~
+
## Other types
+* Fails with 500 as at 8 March 2024
+
+
+~~~md
```kroki-blockdiag no-transparency=false size=1000x400
-blockdiag {
- blockdiag -> generates -> "block-diagrams";
- blockdiag -> is -> "very easy!!";
-
- blockdiag [color = "greenyellow"];
- "block-diagrams" [color = "pink"];
- "very easy!!" [color = "orange"];
-}
+ blockdiag {
+ blockdiag -> generates -> "block-diagrams";
+ blockdiag -> is -> "very easy!!";
+
+ blockdiag [color = "greenyellow"];
+ "block-diagrams" [color = "pink"];
+ "very easy!!" [color = "orange"];
+ }
```
+~~~
+
diff --git a/docs/src/reference/workflows.md b/docs/src/reference/workflows.md
index 83d331819..c025ff602 100644
--- a/docs/src/reference/workflows.md
+++ b/docs/src/reference/workflows.md
@@ -97,10 +97,16 @@ It then uses the custom `push` GitHub Action to re-tag the image and push it to
| Name | Type | Description | Required | Default |
| ---------------- | ------ | ---------------------------------------------------------------------------------- | -------- | ----------------------------------------------- |
| aws_ecr_registry | string | The AWS ECR registry that will be used to publish images | No | `""` |
-| default_branch | string | The default branch of the repository. | No | `${{ github.event.repository.default_branch }}` |
+| default_branch | string | The default branch of the repository. | No | `master` |
| tags | string | A line separated list of additional tags that will be applied to published images. | No | `""` |
| target | string | The target used to mark check builds | No | `publish` |
+
+
## Release
The release workflow is responsible for performing logic related to the `release` target.
diff --git a/earthly/docs/common/javascript/massilia-graphviz.js b/earthly/docs/common/javascript/massilia-graphviz.js
new file mode 100644
index 000000000..be8c4e27a
--- /dev/null
+++ b/earthly/docs/common/javascript/massilia-graphviz.js
@@ -0,0 +1,80 @@
+/* License: GNU GPLv3+, Rodrigo Schwencke (Copyleft) */
+/* src:
+ https://github.com/rod2ik/cdn/blob/main/mkdocs/javascripts/massiliaGraphviz.js
+*/
+
+/* cspell: words Schwencke */
+
+window.addEventListener('load', function() {
+ // console.log("massilia-graphviz PAGE LOADED");
+
+ var span = document.querySelector("[class='graphviz-light-dark']:first-of-type");
+ if (span !== null) { // at least one graphviz diagram in the page
+ var dataLibraryDefault = span.getAttribute("data-library-default");
+ var dataDefault = span.getAttribute("data-default");
+ var dataLight = span.getAttribute("data-light");
+ if ((dataLight == '#0')) {
+ dataLight="#000000";
+ }
+ var dataDark = span.getAttribute("data-dark");
+ tag_default();
+ update_theme();
+ } // else no graphviz diagram
+
+ function tag_default() {
+ // console.log("TAG DEFAULTS");
+ if (dataDefault == dataLibraryDefault) { // if 'color' option has not been set in 'mkdocs.yml'
+ document.querySelectorAll("svg.graphviz *[stroke*='"+dataDefault+"' i]")
+ .forEach( el => {
+ el.classList.add("stroke-default");
+ });
+ document.querySelectorAll("svg.graphviz *[fill*='"+dataDefault+"' i]")
+ .forEach( el => {
+ el.classList.add("fill-default");
+ });
+ }
+ }
+
+ function update_theme() {
+ // console.log("UPDATE THEME...");
+ let theme = document.querySelector("body").getAttribute("data-md-color-scheme");
+ if (dataDefault == dataLibraryDefault) { // if 'color' option has not been set in 'mkdocs.yml'
+ document.querySelectorAll("svg.graphviz *[class*='stroke-default']")
+ .forEach( el => {
+ if (theme == "default") {
+ el.style.setProperty("stroke", ''+dataLight,"important");
+ } else {
+ el.style.setProperty("stroke", dataDark,"important");
+ }
+ });
+
+ document.querySelectorAll("svg.graphviz *[class*='fill-default']")
+ .forEach( el => {
+ if (theme == "default") {
+ el.style.setProperty("fill", ''+dataLight,"important");
+ } else {
+ el.style.setProperty("fill", dataDark,"important");
+ }
+ });
+ }
+ // other_function_to_update();
+ }
+
+ const mutationCallback = (mutationsList) => {
+ for (const mutation of mutationsList) {
+ if (
+ mutation.type !== "attributes" &&
+ mutation.attributeName !== "data-md-color-scheme"
+ ) {
+ return
+ }
+ update_theme();
+ }
+ };
+
+ const observer = new MutationObserver(mutationCallback);
+
+ let themeChange = document.querySelector("body");
+ observer.observe(themeChange, { attributes: true });
+
+ })
\ No newline at end of file
diff --git a/earthly/docs/common/macros/include.py b/earthly/docs/common/macros/include.py
index 7a97a73fd..4a9ca0b1b 100644
--- a/earthly/docs/common/macros/include.py
+++ b/earthly/docs/common/macros/include.py
@@ -1,5 +1,6 @@
import os
import textwrap
+import re
def inc_file(env, filename, start_line=0, end_line=None, indent=None):
"""
@@ -7,6 +8,7 @@ def inc_file(env, filename, start_line=0, end_line=None, indent=None):
(start counting from 0)
The path is relative to the top directory of the documentation
project.
+ indent = number of spaces to indent every line but the first.
"""
try:
@@ -16,10 +18,15 @@ def inc_file(env, filename, start_line=0, end_line=None, indent=None):
lines = f.readlines()
line_range = lines[start_line:end_line]
text = "".join(line_range)
+ # print(text)
if indent is None:
indent = ""
else:
indent = " " * indent
- return textwrap.indent(text, indent)
+ text = textwrap.indent(text, indent)
+ text = text[len(indent):] # First line should not be indented at all.
+ text = re.sub(r'\n$', '', text, count=1)
+ # print(text)
+ return text
except Exception as exc:
return f"{filename} error: {exc}"
diff --git a/earthly/docs/common/std-theme.yml b/earthly/docs/common/std-theme.yml
index cdad995cc..913b0052e 100644
--- a/earthly/docs/common/std-theme.yml
+++ b/earthly/docs/common/std-theme.yml
@@ -1,6 +1,7 @@
# cspell: words Diagramsnet, pymdownx, linenums, inlinehilite, superfences,
# cspell: words tasklist, betterem, materialx, twemoji, smartsymbols,
# cspell: words kroki, excalidraw, glightbox, cips, pygments, arithmatex, fontawesome
+# cspell: words massillia
site_author: The Project Catalyst Team
copyright: (c) 2023 Input Output Global Ltd.
@@ -53,10 +54,10 @@ plugins:
- macros:
module_name: macros
# - diagrams - Plugin is installed, but produces corrupted output
- - kroki:
- ServerURL: https://kroki.io
- EnableDiagramsnet: true
- HttpMethod: POST
+ #- kroki: - Plugin works, but kroki.io is unreliable and results in broken CI
+ # ServerURL: https://kroki.io
+ # EnableDiagramsnet: true
+ # HttpMethod: POST
- d2
- glightbox
@@ -71,6 +72,7 @@ markdown_extensions:
- tables
- toc:
permalink: true
+ - mkdocs_graphviz
# Python Markdown Extensions
- pymdownx.arithmatex:
@@ -114,4 +116,6 @@ extra:
find what they're searching for. With your consent, you're helping us to
make our documentation better.
+extra_javascript:
+ - javascript/massillia-graphviz.js
\ No newline at end of file
diff --git a/earthly/docs/poetry.lock b/earthly/docs/poetry.lock
index 087699a8e..93ff9ef00 100644
--- a/earthly/docs/poetry.lock
+++ b/earthly/docs/poetry.lock
@@ -743,6 +743,20 @@ files = [
{file = "mkdocs_glightbox-0.3.7-py3-none-any.whl", hash = "sha256:9659631a9829d93d8fb0ce3a20a10261c258605ba4dc87a3b7b5d847b93a276d"},
]
+[[package]]
+name = "mkdocs-graphviz"
+version = "1.5.3"
+description = "Render Graphviz graphs in Mkdocs, as inline SVGs and PNGs, natively & dynamically compatible with Mkdocs Light & Dark Themes, directly from your Markdown"
+optional = false
+python-versions = "*"
+files = [
+ {file = "mkdocs_graphviz-1.5.3-py3-none-any.whl", hash = "sha256:fb2159cf49c02604104a4077f4b92ddc543cd054102dc78cb1c347dd1a847ddc"},
+ {file = "mkdocs_graphviz-1.5.3.tar.gz", hash = "sha256:913fbd77a0b4f2683b6d4f244f1f7d4e421866f9a7b70057900700909052709c"},
+]
+
+[package.dependencies]
+Markdown = ">=2.3.1"
+
[[package]]
name = "mkdocs-kroki-plugin"
version = "0.6.1"
@@ -785,13 +799,13 @@ test = ["mkdocs-include-markdown-plugin", "mkdocs-macros-test", "mkdocs-material
[[package]]
name = "mkdocs-material"
-version = "9.5.11"
+version = "9.5.13"
description = "Documentation that simply works"
optional = false
python-versions = ">=3.8"
files = [
- {file = "mkdocs_material-9.5.11-py3-none-any.whl", hash = "sha256:788ee0f3e036dca2dc20298d65e480297d348a44c9d7b2ee05c5262983e66072"},
- {file = "mkdocs_material-9.5.11.tar.gz", hash = "sha256:7af7f8af0dea16175558f3fb9245d26c83a17199baa5f157755e63d7437bf971"},
+ {file = "mkdocs_material-9.5.13-py3-none-any.whl", hash = "sha256:5cbe17fee4e3b4980c8420a04cc762d8dc052ef1e10532abd4fce88e5ea9ce6a"},
+ {file = "mkdocs_material-9.5.13.tar.gz", hash = "sha256:d8e4caae576312a88fd2609b81cf43d233cdbe36860d67a68702b018b425bd87"},
]
[package.dependencies]
@@ -1107,13 +1121,13 @@ files = [
[[package]]
name = "pydantic"
-version = "2.6.2"
+version = "2.6.3"
description = "Data validation using Python type hints"
optional = false
python-versions = ">=3.8"
files = [
- {file = "pydantic-2.6.2-py3-none-any.whl", hash = "sha256:37a5432e54b12fecaa1049c5195f3d860a10e01bdfd24f1840ef14bd0d3aeab3"},
- {file = "pydantic-2.6.2.tar.gz", hash = "sha256:a09be1c3d28f3abe37f8a78af58284b236a92ce520105ddc91a6d29ea1176ba7"},
+ {file = "pydantic-2.6.3-py3-none-any.whl", hash = "sha256:72c6034df47f46ccdf81869fddb81aade68056003900a8724a4f160700016a2a"},
+ {file = "pydantic-2.6.3.tar.gz", hash = "sha256:e07805c4c7f5c6826e33a1d4c9d47950d7eaf34868e2690f8594d2e30241f11f"},
]
[package.dependencies]
@@ -1232,13 +1246,13 @@ windows-terminal = ["colorama (>=0.4.6)"]
[[package]]
name = "pymdown-extensions"
-version = "10.7"
+version = "10.7.1"
description = "Extension pack for Python Markdown."
optional = false
python-versions = ">=3.8"
files = [
- {file = "pymdown_extensions-10.7-py3-none-any.whl", hash = "sha256:6ca215bc57bc12bf32b414887a68b810637d039124ed9b2e5bd3325cbb2c050c"},
- {file = "pymdown_extensions-10.7.tar.gz", hash = "sha256:c0d64d5cf62566f59e6b2b690a4095c931107c250a8c8e1351c1de5f6b036deb"},
+ {file = "pymdown_extensions-10.7.1-py3-none-any.whl", hash = "sha256:f5cc7000d7ff0d1ce9395d216017fa4df3dde800afb1fb72d1c7d3fd35e710f4"},
+ {file = "pymdown_extensions-10.7.1.tar.gz", hash = "sha256:c70e146bdd83c744ffc766b4671999796aba18842b268510a329f7f64700d584"},
]
[package.dependencies]
@@ -1250,13 +1264,13 @@ extra = ["pygments (>=2.12)"]
[[package]]
name = "python-dateutil"
-version = "2.8.2"
+version = "2.9.0.post0"
description = "Extensions to the standard Python datetime module"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
files = [
- {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"},
- {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
+ {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"},
+ {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"},
]
[package.dependencies]
@@ -1675,4 +1689,4 @@ files = [
[metadata]
lock-version = "2.0"
python-versions = "^3.12"
-content-hash = "08eb42642cad818a66ddb651db40a3a80f9a26a693b0f066e055042122472f04"
+content-hash = "82c0c1911819d1de33e0014b628b5d15c4f7bfe3c2f608ecb317d4fe0e06b5e4"
diff --git a/earthly/docs/pyproject.toml b/earthly/docs/pyproject.toml
index 63c1df608..285cb50d2 100644
--- a/earthly/docs/pyproject.toml
+++ b/earthly/docs/pyproject.toml
@@ -46,6 +46,9 @@ mkdocs-awesome-pages-plugin = "^2.9.2"
# https://github.com/landmaj/mkdocs-d2-plugin
mkdocs-d2-plugin = "^1.1.0"
+# https://gitlab.com/rod2ik/mkdocs-graphviz
+mkdocs-graphviz = "^1.5.3"
+
### DO NOT ENABLE THESE BAD PLUGINS.
### DOCUMENTED HERE FOR INFORMATIONAL PURPOSES.
# https://github.com/zoni/mkdocs-diagrams