diff --git a/docs/_static/css/theme.css b/docs/_static/css/theme.css index 368e93f..d8b8495 100644 --- a/docs/_static/css/theme.css +++ b/docs/_static/css/theme.css @@ -17,6 +17,19 @@ html[data-theme="dark"] { max-width: 100%; } +html[data-theme=dark] .bd-content div.cell_output .text_html, +html[data-theme=dark] .bd-content div.cell_output img { + background: unset !important; + color: unset !important; +} + +div.cell_output table { + color: unset !important; +} + +div.cell_output tbody tr:nth-child(odd) { + background-color: unset !important; +} /* sphinx-design */ .sd-tab-content { border-top: solid 1px var(--pst-color-border); diff --git a/docs/index.md b/docs/index.md index 1e31620..63f8422 100644 --- a/docs/index.md +++ b/docs/index.md @@ -7,5 +7,5 @@ ```{toctree} :maxdepth: 2 graph -logs +work ``` diff --git a/docs/logs.ipynb b/docs/logs.ipynb deleted file mode 100644 index 6879d3f..0000000 --- a/docs/logs.ipynb +++ /dev/null @@ -1,239 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "4c81215c-7cdf-4145-b29f-2da5bbe11486", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "# work logs" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6f8e1570-478c-4ab3-9902-ff3832b88800", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "import json\n", - "from pathlib import Path\n", - "\n", - "import jinja2\n", - "from IPython.display import HTML, Markdown, display\n", - "from nbconvert.filters import ansi2html" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f34a0361-32db-4fb7-9d3a-068e911b00d5", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "LOGS = sorted(\n", - " (Path.cwd() / \"../work/build/logs/\").resolve().glob(\"*.json\"),\n", - " key=lambda x: x.stat().st_mtime,\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "676e76d1-1f75-4f0d-bbdd-217c8e0a229d", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "HTML(\n", - " \"\"\"\n", - "\n", - "\"\"\"\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "74089506-8627-4c3b-afa1-dfddd34ee629", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "TMPL = jinja2.Template(\n", - " \"\"\"\n", - "

{{ log.stem }}

\n", - "\n", - " \n", - " \n", - " {% for h in headers %}{% endfor %}\n", - " {% for f in fields %}{% endfor %}\n", - " {% for d in details %}{% endfor %}\n", - " \n", - " \n", - " \n", - " {% for t in tasks %}\n", - " \n", - " {% for h in headers %}\n", - " \n", - " {% endfor %}\n", - " {% for f in fields %}\n", - " {% endfor %}\n", - " {% for d in details %}{% endfor %}\n", - " \n", - " {% endfor %}\n", - " \n", - "
{{ h }}{{ f }}{{ d }}
\n", - " {% if h == \"name\" %}\n", - " {{ t[h].replace(\"shave:\", \"\") }}\n", - " {% else %}\n", - " {{ t[h] }}\n", - " {% endif %}\n", - " \n", - " {% if f == \"elapsed\" and t[f] %}\n", - " {{ (t[f]) | round(1) }} s\n", - " {% else %}\n", - " {{ t[f] or \"\" }}\n", - " {% endif %}\n", - " \n", - " {% if t[d] %}\n", - "
\n", - " {{ t[d] | count }} lines\n", - "
{{ ansi2html(\"\".join(t[d])) }}
\n", - "
\n", - " {% endif %}\n", - "
\n", - "\"\"\"\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "aa0c4339-1992-48cb-99c5-9837d00cc938", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "HEADERS = [\"result\", \"name\"]\n", - "FIELDS = [\"elapsed\"]\n", - "DETAILS = [\"out\", \"err\"]\n", - "CONTEXT = dict(headers=HEADERS, fields=FIELDS, details=DETAILS, ansi2html=ansi2html)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9515d74a-c5b7-4cfc-9172-cad89c39f669", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "for log in LOGS:\n", - " try:\n", - " tasks = [\n", - " t\n", - " for t in json.loads(log.read_text(encoding=\"utf-8\"))[\"tasks\"]\n", - " if t[\"elapsed\"]\n", - " ]\n", - " except:\n", - " continue\n", - " display(HTML(TMPL.render(log=log, tasks=tasks, **CONTEXT)))\n", - "else:\n", - " display(Markdown(\"> No work logs were created\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "57db93ba-aa38-4498-861c-5a3340ceb9fe", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.6" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/work.ipynb b/docs/work.ipynb new file mode 100644 index 0000000..de006cb --- /dev/null +++ b/docs/work.ipynb @@ -0,0 +1,407 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "id": "8d00fa48-db19-4f3b-9f41-6946f7c3e41a", + "metadata": {}, + "source": [ + "# work\n", + "\n", + "This site was built with the following [configuration](#configuration), and may have generated some [logs](#logs)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a1af23f2-46ee-4cf2-ad1a-943785533bce", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [ + "remove-cell" + ] + }, + "outputs": [], + "source": [ + "import json\n", + "import subprocess\n", + "from pathlib import Path\n", + "\n", + "import importnb\n", + "import jinja2\n", + "from IPython.display import HTML, display\n", + "from nbconvert.filters import ansi2html, markdown2html\n", + "\n", + "with importnb.Notebook():\n", + " from jupyak.tasks import load_tasks\n", + " from jupyak.tasks._yak import Repo, Yak" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "676e76d1-1f75-4f0d-bbdd-217c8e0a229d", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [ + "remove-input" + ] + }, + "outputs": [], + "source": [ + "HTML(\n", + " \"\"\"\n", + "\n", + "\"\"\"\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e25d6b1a-4be5-4577-af1c-e0624f3601de", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [ + "remove-cell" + ] + }, + "outputs": [], + "source": [ + "load_tasks()\n", + "yak = Yak(conf_dir=str(Path.cwd().parent))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c1592b77-9ea7-4584-90f6-4993f0aa3515", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [ + "remove-cell" + ] + }, + "outputs": [], + "source": [ + "def ref_link(url: str, repo: Repo, attrs=\"\", loop=None):\n", + " ref = last = url.split(\"#\")[0].split(\"?\")[0].split(\"/\")[-1]\n", + " if \"/pull/\" in url:\n", + " last = f\"#{last}\"\n", + " ref = f\"pr-{ref}\"\n", + " try:\n", + " commit, log = (\n", + " subprocess.check_output(\n", + " [\"git\", \"log\", \"-1\", \"--pretty=%H: %B\", ref],\n", + " cwd=str(repo.work_path),\n", + " encoding=\"utf-8\",\n", + " )\n", + " .splitlines()[0]\n", + " .split(\":\", 1)\n", + " )\n", + " except Exception as err:\n", + " print(err)\n", + " log = \"...\"\n", + " commit = \"\"\n", + " cols = f\"\"\"\n", + " \n", + " {last}\n", + " \n", + " \n", + " {commit[:7]}\n", + " \n", + " \n", + " {log}\n", + " \n", + " \"\"\"\n", + "\n", + " if loop and loop.length > 1:\n", + " if not loop.index0:\n", + " cols += \"\"\n", + " else:\n", + " cols = \"\" + cols\n", + " return cols" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d9671048-269e-4cd4-a9cf-7f80ae3d835c", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [ + "remove-cell" + ] + }, + "outputs": [], + "source": [ + "YAK_TMPL = jinja2.Template(\n", + " \"\"\"\n", + "

{{ yak.pr.title }}

\n", + "\n", + "{{ md2h(yak.pr.description) }}\n", + "\n", + "

repos

\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " {% for i in range(2) %}\n", + " \n", + " \n", + " \n", + " {% endfor %}\n", + " \n", + " \n", + " \n", + " {% for name, r in yak.repos.items() -%}{%- set gh = r.github -%}\n", + " \n", + " {% set attrs = \"\" %}\n", + " {% if (gh.merge_with | length) > 1 %}\n", + " {% set attrs = 'rowspan=\"' ~ (gh.merge_with | length) ~ '\"' %}\n", + " {% endif %}\n", + " \n", + " {{ ref(gh.baseline, r, attrs=attrs) -}}\n", + " {% for m in gh.merge_with %}\n", + " {{ ref(m, r, loop=loop) }}\n", + " {%- endfor -%}\n", + " \n", + " {% endfor %}\n", + " \n", + "
repobaselinemerged with...
branch/refcommitlog
\n", + " {{r.name}}\n", + "
\n", + "\"\"\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "884bdf38-4e6f-428c-b791-eeef651e73ba", + "metadata": {}, + "source": [ + "## configuration" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6a4e3848-2d60-4d69-8141-269314435517", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [ + "remove-input" + ] + }, + "outputs": [], + "source": [ + "HTML(YAK_TMPL.render(yak=yak, ref=ref_link, md2h=markdown2html))" + ] + }, + { + "cell_type": "markdown", + "id": "07b20709-c22a-4122-ae2a-e45a2f3a1cb8", + "metadata": {}, + "source": [ + "## logs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f34a0361-32db-4fb7-9d3a-068e911b00d5", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [ + "remove-cell" + ] + }, + "outputs": [], + "source": [ + "LOGS = sorted(\n", + " (Path.cwd() / \"../work/build/logs/\").resolve().glob(\"*.json\"),\n", + " key=lambda x: x.stat().st_mtime,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "74089506-8627-4c3b-afa1-dfddd34ee629", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [ + "remove-cell" + ] + }, + "outputs": [], + "source": [ + "TMPL = jinja2.Template(\n", + " \"\"\"\n", + "

{{ log.stem }}

\n", + "\n", + " \n", + " \n", + " {% for h in headers %}{% endfor %}\n", + " {% for f in fields %}{% endfor %}\n", + " {% for d in details %}{% endfor %}\n", + " \n", + " \n", + " \n", + " {% for t in tasks %}\n", + " \n", + " {% for h in headers %}\n", + " \n", + " {% endfor %}\n", + " {% for f in fields %}\n", + " {% endfor %}\n", + " {% for d in details %}{% endfor %}\n", + " \n", + " {% endfor %}\n", + " \n", + "
{{ h }}{{ f }}{{ d }}
\n", + " {% if h == \"name\" %}\n", + " {{ t[h].replace(\"shave:\", \"\") }}\n", + " {% else %}\n", + " {{ t[h] }}\n", + " {% endif %}\n", + " \n", + " {% if f == \"elapsed\" and t[f] %}\n", + " {{ (t[f]) | round(1) }} s\n", + " {% else %}\n", + " {{ t[f] or \"\" }}\n", + " {% endif %}\n", + " \n", + " {% if t[d] %}\n", + "
\n", + " {{ t[d] | count }} lines\n", + "
{{ ansi2html(\"\".join(t[d])) }}
\n", + "
\n", + " {% endif %}\n", + "
\n", + "\"\"\"\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "aa0c4339-1992-48cb-99c5-9837d00cc938", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [ + "remove-cell" + ] + }, + "outputs": [], + "source": [ + "HEADERS = [\"result\", \"name\"]\n", + "FIELDS = [\"elapsed\"]\n", + "DETAILS = [\"out\", \"err\"]\n", + "CONTEXT = dict(headers=HEADERS, fields=FIELDS, details=DETAILS, ansi2html=ansi2html)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9515d74a-c5b7-4cfc-9172-cad89c39f669", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [ + "remove-input" + ] + }, + "outputs": [], + "source": [ + "for log in LOGS:\n", + " try:\n", + " tasks = [\n", + " t\n", + " for t in json.loads(log.read_text(encoding=\"utf-8\"))[\"tasks\"]\n", + " if t[\"elapsed\"]\n", + " ]\n", + " except:\n", + " continue\n", + " display(HTML(TMPL.render(log=log, tasks=tasks, **CONTEXT)))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "57db93ba-aa38-4498-861c-5a3340ceb9fe", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/src/jupyak/tasks/_yak.ipynb b/src/jupyak/tasks/_yak.ipynb index db3afbf..89ecb94 100644 --- a/src/jupyak/tasks/_yak.ipynb +++ b/src/jupyak/tasks/_yak.ipynb @@ -594,6 +594,7 @@ "outputs": [], "source": [ "class Yak(T.HasTraits):\n", + " conf_dir = T.Unicode().tag(sync=True)\n", " work_dir = T.Unicode().tag(sync=True)\n", " pr = InstanceDict(PullRequest)\n", " repos = T.Dict(value_trait=InstanceDict(Repo))\n", @@ -604,7 +605,7 @@ " _default_repos: dict[tuple[str, tuple[str]], TRepoFactory] = {}\n", "\n", " def __init__(self, issue: dict | None = None, **kwargs):\n", - " issue = issue or Yak.find_config()\n", + " issue = issue or Yak.find_config(conf_dir=kwargs.get(\"conf_dir\"))\n", "\n", " kwargs[\"issue\"] = deepcopy(\n", " nested_update({\"repos\": {}, \"pr\": {}, \"env\": {}, \"lite\": {}}, issue)\n", @@ -686,13 +687,15 @@ " return _ensure\n", "\n", " @classmethod\n", - " def find_config(cls):\n", + " def find_config(cls, conf_dir: str):\n", " issue_path = None\n", + " conf_path = Path(conf_dir or Path.cwd())\n", " for candidate in [os.environ.get(W.ENV_VAR_CONFIG), *W.JPYK_CONFIGS]:\n", " if not candidate:\n", " continue\n", - " if Path(candidate).exists():\n", - " issue_path = Path(candidate).resolve()\n", + " issue_path = (conf_path / candidate).resolve()\n", + " if issue_path.exists():\n", + " break\n", " if issue_path and issue_path.exists():\n", " issue_text = issue_path.read_text(encoding=\"utf-8\")\n", " suffix = issue_path.suffix\n",