From f78cb6d0733bff26b367727abcbb850bde94f311 Mon Sep 17 00:00:00 2001 From: realazthat Date: Thu, 5 Sep 2024 03:42:42 -0400 Subject: [PATCH] Fix up scripts, examples and README. * Use mdreftidy on the README. * Pass EXCALIDRAW_BRUTE_EXPORT_CLI_URL into docker examples. * ensure-node-version in various scripts. * Add bump-n-tag-npm.sh. * Add deploy-to-ghr.sh. * Add ensure-reqs2.sh. * Add pin-extra-reqs2.sh. * Add pin-extra-reqs2.py. * Update pin-extra-reqs.sh. * Update pin-extra-reqs.py. * Minor changes/typo fixes in various scripts. --- .github/README.md.jinja2 | 70 +++++----- .github/README.remotified.md | 64 ++++----- README.md | 70 +++++----- examples/simple-local-docker_example.sh | 1 + .../simple-remote-docker_example-noautorun.sh | 1 + examples/simple_example.sh.jinja2 | 2 +- scripts/format.sh | 22 +++ scripts/generate-examples.sh | 3 + scripts/generate.sh | 3 + scripts/pre.sh | 1 - scripts/pyproject.toml | 1 + scripts/utilities/bump-n-tag-npm.sh | 129 ++++++++++++++++++ scripts/utilities/changeguard.sh | 2 +- scripts/utilities/deploy-to-ghr.sh | 75 ++++++++++ scripts/utilities/ensure-reqs2.sh | 91 ++++++++++++ scripts/utilities/pin-extra-reqs.py | 2 +- scripts/utilities/pin-extra-reqs.sh | 1 + scripts/utilities/pin-extra-reqs2.py | 121 ++++++++++++++++ scripts/utilities/pin-extra-reqs2.sh | 104 ++++++++++++++ 19 files changed, 656 insertions(+), 107 deletions(-) mode change 100644 => 100755 examples/simple-remote-docker_example-noautorun.sh create mode 100755 scripts/utilities/bump-n-tag-npm.sh create mode 100755 scripts/utilities/deploy-to-ghr.sh create mode 100755 scripts/utilities/ensure-reqs2.sh create mode 100644 scripts/utilities/pin-extra-reqs2.py create mode 100755 scripts/utilities/pin-extra-reqs2.sh diff --git a/.github/README.md.jinja2 b/.github/README.md.jinja2 index fe32a8f..4f70c50 100644 --- a/.github/README.md.jinja2 +++ b/.github/README.md.jinja2 @@ -17,7 +17,7 @@ -![**Audience:** Developers][4] ![**Platform:** Linux][5] +![**Audience:** Developers][2] ![**Platform:** Linux][3] @@ -41,9 +41,9 @@
-![Top language][6] [![GitHub License][7]][8] [![npm - version][9]][10] +![Top language][4] [![GitHub License][5]][6] [![npm - version][7]][8] -[![Node Version][24]][25] +[![Node Version][9]][10] **Export Excalidraw diagrams to SVG or PNG using a headless browser, using the exact same export process as Excalidraw itself** @@ -56,15 +56,15 @@ exact same export process as Excalidraw itself** | | Status | Stable | Unstable | | | ----------------- | --------------------------- | ------------------------- | ------------------------- | ------------------ | -| **[Master][11]** | [![Build and Test][13]][15] | [![since tagged][16]][18] | | ![last commit][22] | -| **[Develop][12]** | [![Build and Test][14]][15] | [![since tagged][17]][19] | [![since tagged][20]][21] | ![last commit][23] | +| **[Master][11]** | [![Build and Test][12]][13] | [![since tagged][14]][15] | | ![last commit][16] | +| **[Develop][17]** | [![Build and Test][18]][13] | [![since tagged][19]][20] | [![since tagged][21]][22] | ![last commit][23] |
Demo -- ❔ What: Uses [🎭 playwright][2] to run a headless firefox browser to export - [Excalidraw][3] diagrams to svg/png files. Using a browser bypasses certain +- ❔ What: Uses [🎭 playwright][24] to run a headless firefox browser to export + [Excalidraw][25] diagrams to svg/png files. Using a browser bypasses certain bugs that happen with other projects that attempt to export by emulating the DOM (without a browser). - Why: @@ -146,7 +146,7 @@ Example: And the resulting image (svg): -Simple Excalidraw Diagram as a SVG +Simple Excalidraw Diagram as an SVG ## 💻 Command Line Options @@ -340,51 +340,49 @@ These instructions are for maintainers of the project. `git checkout develop && git merge master`. 9. Push the develop branch to GitHub: `git push origin develop`. -[1]: ./.github/logo-exported.svg -[2]: https://playwright.dev/ -[3]: https://excalidraw.com/ - -[4]: - https://img.shields.io/badge/Audience-Developers|Users-{{badge_color}}?style=plastic&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLXVzZXJzIj48cGF0aCBkPSJNMTYgMjF2LTJhNCA0IDAgMCAwLTQtNEg2YTQgNCAwIDAgMC00IDR2MiIvPjxjaXJjbGUgY3g9IjkiIGN5PSI3IiByPSI0Ii8+PHBhdGggZD0iTTIyIDIxdi0yYTQgNCAwIDAgMC0zLTMuODciLz48cGF0aCBkPSJNMTYgMy4xM2E0IDQgMCAwIDEgMCA3Ljc1Ii8+PC9zdmc+ - -[5]: +[1]: ./.github/logo-exported.svg +[2]: + https://img.shields.io/badge/Audience-Developers|Users-{{badge_color}}?style=plastic&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLXVzZXJzIj48cGF0aCBkPSJNMTYgMjF2LTJhNCA0IDAgMCAwLTQtNEg2YTQgNCAwIDAgMC00IDR2MiIvPjxjaXJjbGUgY3g9IjkiIGN5PSI3IiByPSI0Ii8+PHBhdGggZD0iTTIyIDIxdi0yYTQgNCAwIDAgMC0zLTMuODciLz48cGF0aCBkPSJNMTYgMy4xM2E0IDQgMCAwIDEgMCA3Ljc1Ii8+PC9zdmc+ +[3]: https://img.shields.io/badge/Platform-Node-{{badge_color}}?style=plastic&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLWxhcHRvcC1taW5pbWFsIj48cmVjdCB3aWR0aD0iMTgiIGhlaWdodD0iMTIiIHg9IjMiIHk9IjQiIHJ4PSIyIiByeT0iMiIvPjxsaW5lIHgxPSIyIiB4Mj0iMjIiIHkxPSIyMCIgeTI9IjIwIi8+PC9zdmc+ -[6]: +[4]: https://img.shields.io/github/languages/top/realazthat/{{project_name}}.svg?&cacheSeconds=28800&style=plastic&color={{badge_color}} -[7]: +[5]: https://img.shields.io/github/license/realazthat/{{project_name}}?style=plastic&color={{badge_color}} -[8]: ./LICENSE.md -[9]: +[6]: ./LICENSE.md +[7]: https://img.shields.io/npm/v/{{project_name}}?style=plastic&color={{badge_color}} -[10]: https://www.npmjs.com/package/{{project_name}} +[8]: https://www.npmjs.com/package/{{project_name}} +[9]: + https://img.shields.io/node/v/excalidraw-brute-export-cli?style=plastic&color={{badge_color}} +[10]: https://www.npmjs.com/package/excalidraw-brute-export-cli [11]: https://github.com/realazthat/{{project_name}}/tree/master -[12]: https://github.com/realazthat/{{project_name}}/tree/develop -[13]: +[12]: https://img.shields.io/github/actions/workflow/status/realazthat/{{project_name}}/build-and-test.yml?branch=master&style=plastic +[13]: + https://github.com/realazthat/{{project_name}}/actions/workflows/build-and-test.yml [14]: - https://img.shields.io/github/actions/workflow/status/realazthat/{{project_name}}/build-and-test.yml?branch=develop&style=plastic + https://img.shields.io/github/commits-since/realazthat/{{project_name}}/v{{last_stable_release}}/master?style=plastic [15]: - https://github.com/realazthat/{{project_name}}/actions/workflows/build-and-test.yml + https://github.com/realazthat/{{project_name}}/compare/v{{last_stable_release}}...master [16]: - https://img.shields.io/github/commits-since/realazthat/{{project_name}}/v{{last_stable_release}}/master?style=plastic -[17]: - https://img.shields.io/github/commits-since/realazthat/{{project_name}}/v{{last_stable_release}}/develop?style=plastic + https://img.shields.io/github/last-commit/realazthat/{{project_name}}/master?style=plastic +[17]: https://github.com/realazthat/{{project_name}}/tree/develop [18]: - https://github.com/realazthat/{{project_name}}/compare/v{{last_stable_release}}...master + https://img.shields.io/github/actions/workflow/status/realazthat/{{project_name}}/build-and-test.yml?branch=develop&style=plastic [19]: - https://github.com/realazthat/{{project_name}}/compare/v{{last_stable_release}}...develop + https://img.shields.io/github/commits-since/realazthat/{{project_name}}/v{{last_stable_release}}/develop?style=plastic [20]: - https://img.shields.io/github/commits-since/realazthat/{{project_name}}/v{{last_unstable_release}}/develop?style=plastic + https://github.com/realazthat/{{project_name}}/compare/v{{last_stable_release}}...develop [21]: - https://github.com/realazthat/{{project_name}}/compare/v{{last_unstable_release}}...develop + https://img.shields.io/github/commits-since/realazthat/{{project_name}}/v{{last_unstable_release}}/develop?style=plastic [22]: - https://img.shields.io/github/last-commit/realazthat/{{project_name}}/master?style=plastic + https://github.com/realazthat/{{project_name}}/compare/v{{last_unstable_release}}...develop [23]: https://img.shields.io/github/last-commit/realazthat/{{project_name}}/develop?style=plastic -[24]: - https://img.shields.io/node/v/excalidraw-brute-export-cli?style=plastic&color={{badge_color}} -[25]: https://www.npmjs.com/package/excalidraw-brute-export-cli +[24]: https://playwright.dev/ +[25]: https://excalidraw.com/ diff --git a/.github/README.remotified.md b/.github/README.remotified.md index 9bafb3b..f35994b 100644 --- a/.github/README.remotified.md +++ b/.github/README.remotified.md @@ -20,7 +20,7 @@ SOURCE: `.github/README.md.jinja2`. -![**Audience:** Developers][4] ![**Platform:** Linux][5] +![**Audience:** Developers][2] ![**Platform:** Linux][3] @@ -44,9 +44,9 @@ SOURCE: `.github/README.md.jinja2`.
-![Top language][6] [![GitHub License][7]][8] [![npm - version][9]][10] +![Top language][4] [![GitHub License][5]][6] [![npm - version][7]][8] -[![Node Version][24]][25] +[![Node Version][9]][10] **Export Excalidraw diagrams to SVG or PNG using a headless browser, using the exact same export process as Excalidraw itself** @@ -59,15 +59,15 @@ exact same export process as Excalidraw itself** | | Status | Stable | Unstable | | | ----------------- | --------------------------- | ------------------------- | ------------------------- | ------------------ | -| **[Master][11]** | [![Build and Test][13]][15] | [![since tagged][16]][18] | | ![last commit][22] | -| **[Develop][12]** | [![Build and Test][14]][15] | [![since tagged][17]][19] | [![since tagged][20]][21] | ![last commit][23] | +| **[Master][11]** | [![Build and Test][12]][13] | [![since tagged][14]][15] | | ![last commit][16] | +| **[Develop][17]** | [![Build and Test][18]][13] | [![since tagged][19]][20] | [![since tagged][21]][22] | ![last commit][23] |
Demo -- ❔ What: Uses [🎭 playwright][2] to run a headless firefox browser to export - [Excalidraw][3] diagrams to svg/png files. Using a browser bypasses certain +- ❔ What: Uses [🎭 playwright][24] to run a headless firefox browser to export + [Excalidraw][25] diagrams to svg/png files. Using a browser bypasses certain bugs that happen with other projects that attempt to export by emulating the DOM (without a browser). - Why: @@ -152,7 +152,7 @@ ls "./examples/simple_example_output.svg" And the resulting image (svg): -Simple Excalidraw Diagram as a SVG +Simple Excalidraw Diagram as an SVG ## 💻 Command Line Options @@ -238,6 +238,7 @@ tag. docker run --rm --tty \ -u "$(id -u):$(id -g)" \ -v "${PWD}:/data" \ + -e EXCALIDRAW_BRUTE_EXPORT_CLI_URL --network host \ ghcr.io/realazthat/excalidraw-brute-export-cli:v0.4.0 \ -i ./examples/simple.excalidraw \ --background 1 \ @@ -264,6 +265,7 @@ docker build -t my-excalidraw-brute-export-cli-image . docker run --rm --tty \ -u "$(id -u):$(id -g)" \ -v "${PWD}:/data" \ + -e EXCALIDRAW_BRUTE_EXPORT_CLI_URL --network host \ my-excalidraw-brute-export-cli-image \ -i ./examples/simple.excalidraw \ --background 1 \ @@ -383,34 +385,32 @@ These instructions are for maintainers of the project. `git checkout develop && git merge master`. 9. Push the develop branch to GitHub: `git push origin develop`. -[1]: https://raw.githubusercontent.com/realazthat/excalidraw-brute-export-cli/v0.4.0/.github/logo-exported.svg -[2]: https://playwright.dev/ -[3]: https://excalidraw.com/ - -[4]: https://img.shields.io/badge/Audience-Developers|Users-0A1E1E?style=plastic&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLXVzZXJzIj48cGF0aCBkPSJNMTYgMjF2LTJhNCA0IDAgMCAwLTQtNEg2YTQgNCAwIDAgMC00IDR2MiIvPjxjaXJjbGUgY3g9IjkiIGN5PSI3IiByPSI0Ii8+PHBhdGggZD0iTTIyIDIxdi0yYTQgNCAwIDAgMC0zLTMuODciLz48cGF0aCBkPSJNMTYgMy4xM2E0IDQgMCAwIDEgMCA3Ljc1Ii8+PC9zdmc+ - -[5]: https://img.shields.io/badge/Platform-Node-0A1E1E?style=plastic&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLWxhcHRvcC1taW5pbWFsIj48cmVjdCB3aWR0aD0iMTgiIGhlaWdodD0iMTIiIHg9IjMiIHk9IjQiIHJ4PSIyIiByeT0iMiIvPjxsaW5lIHgxPSIyIiB4Mj0iMjIiIHkxPSIyMCIgeTI9IjIwIi8+PC9zdmc+ -[6]: https://img.shields.io/github/languages/top/realazthat/excalidraw-brute-export-cli.svg?&cacheSeconds=28800&style=plastic&color=0A1E1E -[7]: https://img.shields.io/github/license/realazthat/excalidraw-brute-export-cli?style=plastic&color=0A1E1E -[8]: https://github.com/realazthat/excalidraw-brute-export-cli/blob/v0.4.0/LICENSE.md -[9]: https://img.shields.io/npm/v/excalidraw-brute-export-cli?style=plastic&color=0A1E1E +[1]: https://raw.githubusercontent.com/realazthat/excalidraw-brute-export-cli/v0.4.0/.github/logo-exported.svg +[2]: https://img.shields.io/badge/Audience-Developers|Users-0A1E1E?style=plastic&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLXVzZXJzIj48cGF0aCBkPSJNMTYgMjF2LTJhNCA0IDAgMCAwLTQtNEg2YTQgNCAwIDAgMC00IDR2MiIvPjxjaXJjbGUgY3g9IjkiIGN5PSI3IiByPSI0Ii8+PHBhdGggZD0iTTIyIDIxdi0yYTQgNCAwIDAgMC0zLTMuODciLz48cGF0aCBkPSJNMTYgMy4xM2E0IDQgMCAwIDEgMCA3Ljc1Ii8+PC9zdmc+ +[3]: https://img.shields.io/badge/Platform-Node-0A1E1E?style=plastic&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLWxhcHRvcC1taW5pbWFsIj48cmVjdCB3aWR0aD0iMTgiIGhlaWdodD0iMTIiIHg9IjMiIHk9IjQiIHJ4PSIyIiByeT0iMiIvPjxsaW5lIHgxPSIyIiB4Mj0iMjIiIHkxPSIyMCIgeTI9IjIwIi8+PC9zdmc+ +[4]: https://img.shields.io/github/languages/top/realazthat/excalidraw-brute-export-cli.svg?&cacheSeconds=28800&style=plastic&color=0A1E1E +[5]: https://img.shields.io/github/license/realazthat/excalidraw-brute-export-cli?style=plastic&color=0A1E1E +[6]: https://github.com/realazthat/excalidraw-brute-export-cli/blob/v0.4.0/LICENSE.md +[7]: https://img.shields.io/npm/v/excalidraw-brute-export-cli?style=plastic&color=0A1E1E +[8]: https://www.npmjs.com/package/excalidraw-brute-export-cli +[9]: https://img.shields.io/node/v/excalidraw-brute-export-cli?style=plastic&color=0A1E1E [10]: https://www.npmjs.com/package/excalidraw-brute-export-cli [11]: https://github.com/realazthat/excalidraw-brute-export-cli/tree/master -[12]: https://github.com/realazthat/excalidraw-brute-export-cli/tree/develop -[13]: https://img.shields.io/github/actions/workflow/status/realazthat/excalidraw-brute-export-cli/build-and-test.yml?branch=master&style=plastic -[14]: https://img.shields.io/github/actions/workflow/status/realazthat/excalidraw-brute-export-cli/build-and-test.yml?branch=develop&style=plastic -[15]: https://github.com/realazthat/excalidraw-brute-export-cli/actions/workflows/build-and-test.yml -[16]: https://img.shields.io/github/commits-since/realazthat/excalidraw-brute-export-cli/v0.4.0/master?style=plastic -[17]: https://img.shields.io/github/commits-since/realazthat/excalidraw-brute-export-cli/v0.4.0/develop?style=plastic -[18]: https://github.com/realazthat/excalidraw-brute-export-cli/compare/v0.4.0...master -[19]: https://github.com/realazthat/excalidraw-brute-export-cli/compare/v0.4.0...develop -[20]: https://img.shields.io/github/commits-since/realazthat/excalidraw-brute-export-cli/v0.4.0/develop?style=plastic -[21]: https://github.com/realazthat/excalidraw-brute-export-cli/compare/v0.4.0...develop -[22]: https://img.shields.io/github/last-commit/realazthat/excalidraw-brute-export-cli/master?style=plastic +[12]: https://img.shields.io/github/actions/workflow/status/realazthat/excalidraw-brute-export-cli/build-and-test.yml?branch=master&style=plastic +[13]: https://github.com/realazthat/excalidraw-brute-export-cli/actions/workflows/build-and-test.yml +[14]: https://img.shields.io/github/commits-since/realazthat/excalidraw-brute-export-cli/v0.4.0/master?style=plastic +[15]: https://github.com/realazthat/excalidraw-brute-export-cli/compare/v0.4.0...master +[16]: https://img.shields.io/github/last-commit/realazthat/excalidraw-brute-export-cli/master?style=plastic +[17]: https://github.com/realazthat/excalidraw-brute-export-cli/tree/develop +[18]: https://img.shields.io/github/actions/workflow/status/realazthat/excalidraw-brute-export-cli/build-and-test.yml?branch=develop&style=plastic +[19]: https://img.shields.io/github/commits-since/realazthat/excalidraw-brute-export-cli/v0.4.0/develop?style=plastic +[20]: https://github.com/realazthat/excalidraw-brute-export-cli/compare/v0.4.0...develop +[21]: https://img.shields.io/github/commits-since/realazthat/excalidraw-brute-export-cli/v0.4.0/develop?style=plastic +[22]: https://github.com/realazthat/excalidraw-brute-export-cli/compare/v0.4.0...develop [23]: https://img.shields.io/github/last-commit/realazthat/excalidraw-brute-export-cli/develop?style=plastic -[24]: https://img.shields.io/node/v/excalidraw-brute-export-cli?style=plastic&color=0A1E1E -[25]: https://www.npmjs.com/package/excalidraw-brute-export-cli +[24]: https://playwright.dev/ +[25]: https://excalidraw.com/ diff --git a/README.md b/README.md index c5e337f..6369514 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ SOURCE: `.github/README.md.jinja2`. -![**Audience:** Developers][4] ![**Platform:** Linux][5] +![**Audience:** Developers][2] ![**Platform:** Linux][3] @@ -44,9 +44,9 @@ SOURCE: `.github/README.md.jinja2`.
-![Top language][6] [![GitHub License][7]][8] [![npm - version][9]][10] +![Top language][4] [![GitHub License][5]][6] [![npm - version][7]][8] -[![Node Version][24]][25] +[![Node Version][9]][10] **Export Excalidraw diagrams to SVG or PNG using a headless browser, using the exact same export process as Excalidraw itself** @@ -59,15 +59,15 @@ exact same export process as Excalidraw itself** | | Status | Stable | Unstable | | | ----------------- | --------------------------- | ------------------------- | ------------------------- | ------------------ | -| **[Master][11]** | [![Build and Test][13]][15] | [![since tagged][16]][18] | | ![last commit][22] | -| **[Develop][12]** | [![Build and Test][14]][15] | [![since tagged][17]][19] | [![since tagged][20]][21] | ![last commit][23] | +| **[Master][11]** | [![Build and Test][12]][13] | [![since tagged][14]][15] | | ![last commit][16] | +| **[Develop][17]** | [![Build and Test][18]][13] | [![since tagged][19]][20] | [![since tagged][21]][22] | ![last commit][23] |
Demo -- ❔ What: Uses [🎭 playwright][2] to run a headless firefox browser to export - [Excalidraw][3] diagrams to svg/png files. Using a browser bypasses certain +- ❔ What: Uses [🎭 playwright][24] to run a headless firefox browser to export + [Excalidraw][25] diagrams to svg/png files. Using a browser bypasses certain bugs that happen with other projects that attempt to export by emulating the DOM (without a browser). - Why: @@ -152,7 +152,7 @@ ls "./examples/simple_example_output.svg" And the resulting image (svg): -Simple Excalidraw Diagram as a SVG +Simple Excalidraw Diagram as an SVG ## 💻 Command Line Options @@ -238,6 +238,7 @@ tag. docker run --rm --tty \ -u "$(id -u):$(id -g)" \ -v "${PWD}:/data" \ + -e EXCALIDRAW_BRUTE_EXPORT_CLI_URL --network host \ ghcr.io/realazthat/excalidraw-brute-export-cli:v0.4.0 \ -i ./examples/simple.excalidraw \ --background 1 \ @@ -264,6 +265,7 @@ docker build -t my-excalidraw-brute-export-cli-image . docker run --rm --tty \ -u "$(id -u):$(id -g)" \ -v "${PWD}:/data" \ + -e EXCALIDRAW_BRUTE_EXPORT_CLI_URL --network host \ my-excalidraw-brute-export-cli-image \ -i ./examples/simple.excalidraw \ --background 1 \ @@ -384,51 +386,49 @@ These instructions are for maintainers of the project. `git checkout develop && git merge master`. 9. Push the develop branch to GitHub: `git push origin develop`. -[1]: ./.github/logo-exported.svg -[2]: https://playwright.dev/ -[3]: https://excalidraw.com/ - -[4]: - https://img.shields.io/badge/Audience-Developers|Users-0A1E1E?style=plastic&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLXVzZXJzIj48cGF0aCBkPSJNMTYgMjF2LTJhNCA0IDAgMCAwLTQtNEg2YTQgNCAwIDAgMC00IDR2MiIvPjxjaXJjbGUgY3g9IjkiIGN5PSI3IiByPSI0Ii8+PHBhdGggZD0iTTIyIDIxdi0yYTQgNCAwIDAgMC0zLTMuODciLz48cGF0aCBkPSJNMTYgMy4xM2E0IDQgMCAwIDEgMCA3Ljc1Ii8+PC9zdmc+ - -[5]: +[1]: ./.github/logo-exported.svg +[2]: + https://img.shields.io/badge/Audience-Developers|Users-0A1E1E?style=plastic&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLXVzZXJzIj48cGF0aCBkPSJNMTYgMjF2LTJhNCA0IDAgMCAwLTQtNEg2YTQgNCAwIDAgMC00IDR2MiIvPjxjaXJjbGUgY3g9IjkiIGN5PSI3IiByPSI0Ii8+PHBhdGggZD0iTTIyIDIxdi0yYTQgNCAwIDAgMC0zLTMuODciLz48cGF0aCBkPSJNMTYgMy4xM2E0IDQgMCAwIDEgMCA3Ljc1Ii8+PC9zdmc+ +[3]: https://img.shields.io/badge/Platform-Node-0A1E1E?style=plastic&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLWxhcHRvcC1taW5pbWFsIj48cmVjdCB3aWR0aD0iMTgiIGhlaWdodD0iMTIiIHg9IjMiIHk9IjQiIHJ4PSIyIiByeT0iMiIvPjxsaW5lIHgxPSIyIiB4Mj0iMjIiIHkxPSIyMCIgeTI9IjIwIi8+PC9zdmc+ -[6]: +[4]: https://img.shields.io/github/languages/top/realazthat/excalidraw-brute-export-cli.svg?&cacheSeconds=28800&style=plastic&color=0A1E1E -[7]: +[5]: https://img.shields.io/github/license/realazthat/excalidraw-brute-export-cli?style=plastic&color=0A1E1E -[8]: ./LICENSE.md -[9]: +[6]: ./LICENSE.md +[7]: https://img.shields.io/npm/v/excalidraw-brute-export-cli?style=plastic&color=0A1E1E +[8]: https://www.npmjs.com/package/excalidraw-brute-export-cli +[9]: + https://img.shields.io/node/v/excalidraw-brute-export-cli?style=plastic&color=0A1E1E [10]: https://www.npmjs.com/package/excalidraw-brute-export-cli [11]: https://github.com/realazthat/excalidraw-brute-export-cli/tree/master -[12]: https://github.com/realazthat/excalidraw-brute-export-cli/tree/develop -[13]: +[12]: https://img.shields.io/github/actions/workflow/status/realazthat/excalidraw-brute-export-cli/build-and-test.yml?branch=master&style=plastic +[13]: + https://github.com/realazthat/excalidraw-brute-export-cli/actions/workflows/build-and-test.yml [14]: - https://img.shields.io/github/actions/workflow/status/realazthat/excalidraw-brute-export-cli/build-and-test.yml?branch=develop&style=plastic + https://img.shields.io/github/commits-since/realazthat/excalidraw-brute-export-cli/v0.4.0/master?style=plastic [15]: - https://github.com/realazthat/excalidraw-brute-export-cli/actions/workflows/build-and-test.yml + https://github.com/realazthat/excalidraw-brute-export-cli/compare/v0.4.0...master [16]: - https://img.shields.io/github/commits-since/realazthat/excalidraw-brute-export-cli/v0.4.0/master?style=plastic -[17]: - https://img.shields.io/github/commits-since/realazthat/excalidraw-brute-export-cli/v0.4.0/develop?style=plastic + https://img.shields.io/github/last-commit/realazthat/excalidraw-brute-export-cli/master?style=plastic +[17]: https://github.com/realazthat/excalidraw-brute-export-cli/tree/develop [18]: - https://github.com/realazthat/excalidraw-brute-export-cli/compare/v0.4.0...master + https://img.shields.io/github/actions/workflow/status/realazthat/excalidraw-brute-export-cli/build-and-test.yml?branch=develop&style=plastic [19]: - https://github.com/realazthat/excalidraw-brute-export-cli/compare/v0.4.0...develop -[20]: https://img.shields.io/github/commits-since/realazthat/excalidraw-brute-export-cli/v0.4.0/develop?style=plastic -[21]: +[20]: https://github.com/realazthat/excalidraw-brute-export-cli/compare/v0.4.0...develop +[21]: + https://img.shields.io/github/commits-since/realazthat/excalidraw-brute-export-cli/v0.4.0/develop?style=plastic [22]: - https://img.shields.io/github/last-commit/realazthat/excalidraw-brute-export-cli/master?style=plastic + https://github.com/realazthat/excalidraw-brute-export-cli/compare/v0.4.0...develop [23]: https://img.shields.io/github/last-commit/realazthat/excalidraw-brute-export-cli/develop?style=plastic -[24]: - https://img.shields.io/node/v/excalidraw-brute-export-cli?style=plastic&color=0A1E1E -[25]: https://www.npmjs.com/package/excalidraw-brute-export-cli +[24]: https://playwright.dev/ +[25]: https://excalidraw.com/ diff --git a/examples/simple-local-docker_example.sh b/examples/simple-local-docker_example.sh index 9219fa8..1a698d0 100755 --- a/examples/simple-local-docker_example.sh +++ b/examples/simple-local-docker_example.sh @@ -34,6 +34,7 @@ docker build -t my-excalidraw-brute-export-cli-image . docker run --rm --tty \ -u "$(id -u):$(id -g)" \ -v "${PWD}:/data" \ + -e EXCALIDRAW_BRUTE_EXPORT_CLI_URL --network host \ my-excalidraw-brute-export-cli-image \ -i ./examples/simple.excalidraw \ --background 1 \ diff --git a/examples/simple-remote-docker_example-noautorun.sh b/examples/simple-remote-docker_example-noautorun.sh old mode 100644 new mode 100755 index 254b418..ead8ac5 --- a/examples/simple-remote-docker_example-noautorun.sh +++ b/examples/simple-remote-docker_example-noautorun.sh @@ -33,6 +33,7 @@ fi docker run --rm --tty \ -u "$(id -u):$(id -g)" \ -v "${PWD}:/data" \ + -e EXCALIDRAW_BRUTE_EXPORT_CLI_URL --network host \ ghcr.io/realazthat/excalidraw-brute-export-cli:v0.4.0 \ -i ./examples/simple.excalidraw \ --background 1 \ diff --git a/examples/simple_example.sh.jinja2 b/examples/simple_example.sh.jinja2 index 823ed2b..3a4a30c 100644 --- a/examples/simple_example.sh.jinja2 +++ b/examples/simple_example.sh.jinja2 @@ -26,7 +26,7 @@ fi {%- endmacro -%} {%- if example_type in ['docker-remote', 'docker-local'] -%} - {% set cmd='docker run --rm --tty \\\n -u \"$(id -u):$(id -g)\" \\\n -v \"${PWD}:/data\" \\\n ' ~ docker_image_name %} + {% set cmd='docker run --rm --tty \\\n -u \"$(id -u):$(id -g)\" \\\n -v \"${PWD}:/data\" \\\n -e EXCALIDRAW_BRUTE_EXPORT_CLI_URL --network host \\\n ' ~ docker_image_name %} {%- elif example_type=='npm-module' -%} {% set cmd='npx ' ~ module_name %} {%- else -%} diff --git a/scripts/format.sh b/scripts/format.sh index 4a8ead3..fbc030e 100755 --- a/scripts/format.sh +++ b/scripts/format.sh @@ -2,4 +2,26 @@ # https://gist.github.com/mohanpedala/1e2ff5661761d3abd0385e8223e16425 set -e -x -v -u -o pipefail + +################################################################################ +SCRIPT_DIR=$(realpath "$(dirname "${BASH_SOURCE[0]}")") +source "${SCRIPT_DIR}/utilities/common.sh" +################################################################################ +PYTHON_VERSION_PATH=${PWD}/scripts/.python-version \ + VENV_PATH=${PWD}/.cache/scripts/.venv \ + source "${PROJ_PATH}/scripts/utilities/ensure-venv.sh" +PYTHON_VERSION_PATH=${PWD}/scripts/.python-version \ + TOML=${PROJ_PATH}/scripts/pyproject.toml EXTRA=dev \ + DEV_VENV_PATH="${PWD}/.cache/scripts/.venv" \ + TARGET_VENV_PATH="${PWD}/.cache/scripts/.venv" \ + bash "${PROJ_PATH}/scripts/utilities/ensure-reqs.sh" +################################################################################ +NODE_VERSION_PATH=${PWD}/.nvmrc \ + bash "${PROJ_PATH}/scripts/utilities/ensure-node-version.sh" +################################################################################ + + +python -m mdreftidy.cli "${PWD}/.github/README.md.jinja2" \ + --renumber --remove-unused --move-to-bottom --sort-ref-blocks --inplace + npm install && npm run format diff --git a/scripts/generate-examples.sh b/scripts/generate-examples.sh index afc6062..16e67f5 100755 --- a/scripts/generate-examples.sh +++ b/scripts/generate-examples.sh @@ -15,6 +15,9 @@ PYTHON_VERSION_PATH=${PWD}/scripts/.python-version \ TARGET_VENV_PATH="${PWD}/.cache/scripts/.venv" \ bash "${PROJ_PATH}/scripts/utilities/ensure-reqs.sh" ################################################################################ +NODE_VERSION_PATH=${PWD}/.nvmrc \ + bash "${PROJ_PATH}/scripts/utilities/ensure-node-version.sh" +################################################################################ CUSTOM_WARNING=$(cat << 'EOF' diff --git a/scripts/generate.sh b/scripts/generate.sh index efb1125..9506ad5 100755 --- a/scripts/generate.sh +++ b/scripts/generate.sh @@ -15,6 +15,9 @@ PYTHON_VERSION_PATH=${PWD}/scripts/.python-version \ TARGET_VENV_PATH="${PWD}/.cache/scripts/.venv" \ bash "${PROJ_PATH}/scripts/utilities/ensure-reqs.sh" ################################################################################ +NODE_VERSION_PATH=${PWD}/.nvmrc \ + bash "${PROJ_PATH}/scripts/utilities/ensure-node-version.sh" +################################################################################ npm install if [[ -z "${EXCALIDRAW_BRUTE_EXPORT_CLI_URL:-}" ]]; then diff --git a/scripts/pre.sh b/scripts/pre.sh index e27140d..fae1428 100755 --- a/scripts/pre.sh +++ b/scripts/pre.sh @@ -15,7 +15,6 @@ export EXCALIDRAW_TAG=${EXCALIDRAW_TAG-"${IDEAL_EXCALIDRAW_TAG}"} # This variable will be 1 when we are the ideal version in the GH action matrix. IDEAL="0" - if [[ "${WANTED_NODE_VERSION}" == "${IDEAL_NODE_VERSION}" && "${EXCALIDRAW_TAG}" == "${IDEAL_EXCALIDRAW_TAG}" ]]; then IDEAL="1" fi diff --git a/scripts/pyproject.toml b/scripts/pyproject.toml index dff79b3..b18519d 100644 --- a/scripts/pyproject.toml +++ b/scripts/pyproject.toml @@ -26,6 +26,7 @@ dev = [ "jinja2==3.1.3", "markdown-it-py==3.0.0", "markupsafe==2.1.5", + "mdreftidy==0.6.1", "mdremotifier==0.3.1", "mdurl==0.1.2", "mistletoe==1.3.0", diff --git a/scripts/utilities/bump-n-tag-npm.sh b/scripts/utilities/bump-n-tag-npm.sh new file mode 100755 index 0000000..830b5f2 --- /dev/null +++ b/scripts/utilities/bump-n-tag-npm.sh @@ -0,0 +1,129 @@ +#!/bin/bash +# https://gist.github.com/mohanpedala/1e2ff5661761d3abd0385e8223e16425 +set -e -x -v -u -o pipefail + +################################################################################ +SCRIPT_DIR=$(realpath "$(dirname "${BASH_SOURCE[0]}")") +source "${SCRIPT_DIR}/common.sh" +################################################################################ +BUMP=${BUMP:-""} +DEVELOP_BRANCH=${DEVELOP_BRANCH:-"develop"} +MASTER_BRANCH=${MASTER_BRANCH:-"master"} +DRY=${DRY:-"true"} +################################################################################ +if [[ "${BUMP}" != "major" && "${BUMP}" != "minor" && "${BUMP}" != "patch" && "${BUMP}" != "prerelease" && "${BUMP}" != "build" ]]; then + echo -e "${RED}BUMP is not set. Please set it to one of the following: major, minor, patch, prerelease, or build.${NC}" + exit 1 +fi +if [[ "${DRY}" != "true" && "${DRY}" != "false" ]]; then + echo -e "${RED}DRY must be either true or false.${NC}" + exit 1 +fi +################################################################################ +_TMP_DIR=$(mktemp -d) +trap 'rm -rf "${_TMP_DIR}"||true' EXIT +################################################################################ +( + +LOCAL_COMMIT=$(git rev-parse "${DEVELOP_BRANCH}") +REMOTE_COMMIT=$(git ls-remote origin -h "refs/heads/${DEVELOP_BRANCH}" | awk '{print $1}') +if [ "${LOCAL_COMMIT}" != "${REMOTE_COMMIT}" ]; then + echo -e "${RED}Local ${DEVELOP_BRANCH} is not up to date, or has unpushed changes.${NC}" + exit 1 +fi + +################################################################################ +REPO_URL=$(git remote get-url origin) +################################################################################ +TMP_DIR=$(mktemp -d) +trap 'chmod -R +w "${TMP_DIR}" && rm -rf "${TMP_DIR}"' EXIT + +cd "${TMP_DIR}" +git clone "${REPO_URL}" "${TMP_DIR}/cloned-project" + +cd "${TMP_DIR}/cloned-project" + +# Show existing tag. +git tag + +git checkout "${MASTER_BRANCH}" +git pull origin "${MASTER_BRANCH}" +git fetch --tags + +# Show existing tag. +git tag + +git checkout "${DEVELOP_BRANCH}" +git pull origin "${DEVELOP_BRANCH}" +git fetch --tags + +# Show existing tag. +git tag + +echo -e "${BLUE}Current Branch: $(git branch)${NC}" +OLD_VERSION=$(node -p "require('./package.json').version") + +echo -e "${BLUE}Current Version: ${OLD_VERSION}${NC}" + +echo -e "${BLUE}Bumping Version${NC}" +npm version "${BUMP}" --no-git-tag-version + +git status +VERSION=$(node -p "require('./package.json').version") +GIT_TAG="v${VERSION}" +echo -e "${BLUE}New Version: ${VERSION}${NC}" +echo -e "${BLUE}${OLD_VERSION} -> ${VERSION}${NC}" + +git --no-pager diff + +bash scripts/generate.sh +git status +# bash scripts/pre.sh + +# Stage all changes, but not untracked files. +git add -u +git status + +git commit -m "Prepare Release ${VERSION}" + +echo -e "${BLUE}Merging ${DEVELOP_BRANCH} into ${MASTER_BRANCH}${NC}" +git checkout "${MASTER_BRANCH}" + +# Show existing tag. +git tag + +git merge --no-edit "${DEVELOP_BRANCH}" --no-ff + +# Show existing tag. +git tag + +echo -e "${BLUE}Tagging ${MASTER_BRANCH} with ${GIT_TAG}${NC}" +git tag -a "${GIT_TAG}" -m "Version ${VERSION}" + + +if [[ "${DRY}" == "false" ]]; then + echo -e "${BLUE}Pushing to origin${NC}" + git push origin "${MASTER_BRANCH}" + echo -e "${BLUE}Pushing tags to origin${NC}" + git push --tags +fi + +echo -e "${BLUE}Merging ${MASTER_BRANCH} back into ${DEVELOP_BRANCH}${NC}" +git checkout "${DEVELOP_BRANCH}" +git merge --no-edit "${MASTER_BRANCH}" + +if [[ "${DRY}" == "false" ]]; then + git push origin "${DEVELOP_BRANCH}" +fi + + +echo "export GIT_TAG=${GIT_TAG}" > "${_TMP_DIR}/.env" + +echo -e "${BLUE}GIT_TAG=\"${GIT_TAG}\"${NC}" + +echo -e "${GREEN}Success: bump-n-tag.sh ${OLD_VERSION} -> ${VERSION}${NC}" +) + +################################################################################ +source "${_TMP_DIR}/.env" +export GIT_TAG diff --git a/scripts/utilities/changeguard.sh b/scripts/utilities/changeguard.sh index dcfdfb9..c457498 100755 --- a/scripts/utilities/changeguard.sh +++ b/scripts/utilities/changeguard.sh @@ -13,7 +13,7 @@ source "${SCRIPT_DIR}/common.sh" TOML=${TOML:-"${PROJ_PATH}/pyproject.toml"} VENV_PATH="${PWD}/.cache/scripts/.venv" source "${PROJ_PATH}/scripts/utilities/ensure-venv.sh" -TOML=${TOML} EXTRA=dev \ +TOML="${TOML}" EXTRA=dev \ DEV_VENV_PATH="${PWD}/.cache/scripts/.venv" \ TARGET_VENV_PATH="${PWD}/.cache/scripts/.venv" \ bash "${PROJ_PATH}/scripts/utilities/ensure-reqs.sh" diff --git a/scripts/utilities/deploy-to-ghr.sh b/scripts/utilities/deploy-to-ghr.sh new file mode 100755 index 0000000..11ff5c2 --- /dev/null +++ b/scripts/utilities/deploy-to-ghr.sh @@ -0,0 +1,75 @@ +#!/bin/bash +# https://gist.github.com/mohanpedala/1e2ff5661761d3abd0385e8223e16425 +set -e -x -v -u -o pipefail + +SCRIPT_DIR=$(realpath "$(dirname "${BASH_SOURCE[0]}")") +source "${SCRIPT_DIR}/common.sh" + +################################################################################ +TOML=${TOML:-"${PROJ_PATH}/pyproject.toml"} + +# TOML="${TOML}" VENV_PATH="${PWD}/.cache/scripts/.venv" source "${PROJ_PATH}/scripts/utilities/ensure-venv.sh" +# TOML="${TOML}" EXTRA=dev \ +# DEV_VENV_PATH="${PWD}/.cache/scripts/.venv" \ +# TARGET_VENV_PATH="${PWD}/.cache/scripts/.venv" \ +# bash "${PROJ_PATH}/scripts/utilities/ensure-reqs.sh" +################################################################################ + +# E.g https://github.com/realazthat/snipinator. +REPO_URL=$(git remote get-url origin) +# E.g realazthat/snipinator. +REPO_NAME=$(python -c 'from urllib.parse import urlparse; from pathlib import PurePath; repo_url = "'"${REPO_URL}"'"; parsed_url = urlparse(repo_url); path = PurePath(parsed_url.path); print(f"{path.parts[-2]}/{path.stem}")') +# Compute project name in terms of REPO_NAME. +# e.g snipinator. +PROJECT_NAME=$(basename "${REPO_NAME}") + +# Example: v0.1.0 +GIT_TAG=${GIT_TAG:-} +IMAGE_TAG=${IMAGE_TAG:-} + +if [[ -z "${REPO_URL}" ]]; then + echo -e "${RED}REPO_URL is not set${NC}" + exit 1 +fi + +if [[ -z "${REPO_NAME}" ]]; then + echo -e "${RED}REPO_NAME is not set${NC}" + exit 1 +fi + +if [[ -z "${PROJECT_NAME}" ]]; then + echo -e "${RED}PROJECT_NAME is not set${NC}" + exit 1 +fi + +if [[ -z "${GIT_TAG}" ]]; then + echo -e "${RED}GIT_TAG is not set${NC}" + exit 1 +fi + +if [[ -z "${IMAGE_TAG}" ]]; then + echo -e "${RED}IMAGE_TAG is not set${NC}" + exit 1 +fi + +TMP_DIR=$(mktemp -d) +trap 'rm -rf "${TMP_DIR}"' EXIT + +git clone "${REPO_URL}" "${TMP_DIR}/project" +cd "${TMP_DIR}/project" +git checkout "${GIT_TAG}" + +cp "${PROJ_PATH}/Dockerfile" . + +docker build \ + --tag "${PROJECT_NAME}:${IMAGE_TAG}" \ + --label "org.opencontainers.image.source=https://github.com/${REPO_NAME}" \ + . + +docker run --rm -it \ + --name "${PROJECT_NAME}-instance" \ + "${PROJECT_NAME}:${IMAGE_TAG}" + +docker tag "${PROJECT_NAME}:${IMAGE_TAG}" "ghcr.io/${REPO_NAME}:${IMAGE_TAG}" + +docker push "ghcr.io/${REPO_NAME}:${IMAGE_TAG}" diff --git a/scripts/utilities/ensure-reqs2.sh b/scripts/utilities/ensure-reqs2.sh new file mode 100755 index 0000000..ebcd483 --- /dev/null +++ b/scripts/utilities/ensure-reqs2.sh @@ -0,0 +1,91 @@ +#!/bin/bash +# https://gist.github.com/mohanpedala/1e2ff5661761d3abd0385e8223e16425 +set -e -x -v -u -o pipefail + +SCRIPT_DIR=$(realpath "$(dirname "${BASH_SOURCE[0]}")") +source "${SCRIPT_DIR}/common.sh" + +TOML=${TOML:-""} +EXTRAS=${EXTRAS:-""} +PIN=${PIN:-""} +DEV_VENV_PATH=${DEV_VENV_PATH:-} +TARGET_VENV_PATH=${TARGET_VENV_PATH:-} + +if [[ $(realpath "$0"||true) == $(realpath "${BASH_SOURCE[0]}"||true) ]]; then + : +else + echo -e "${RED}This script should NOT be sourced, execute it like a normal script.${NC}" + return 1 +fi +if [[ -z "${TOML}" ]]; then + echo -e "${RED}TOML is not set${NC}" + [[ $(realpath "$0"||true) == $(realpath "${BASH_SOURCE[0]}"||true) ]] && EXIT="exit" || EXIT="return" + ${EXIT} 1 +fi + +if [[ -z "${PIN}" ]]; then + echo -e "${RED}PIN is not set${NC}" + [[ $(realpath "$0"||true) == $(realpath "${BASH_SOURCE[0]}"||true) ]] && EXIT="exit" || EXIT="return" + ${EXIT} 1 +fi +if [[ -z "${DEV_VENV_PATH}" ]]; then + echo -e "${RED}DEV_VENV_PATH is not set${NC}" + [[ $(realpath "$0"||true) == $(realpath "${BASH_SOURCE[0]}"||true) ]] && EXIT="exit" || EXIT="return" + ${EXIT} 1 +fi +if [[ -z "${TARGET_VENV_PATH}" ]]; then + echo -e "${RED}TARGET_VENV_PATH is not set${NC}" + [[ $(realpath "$0"||true) == $(realpath "${BASH_SOURCE[0]}"||true) ]] && EXIT="exit" || EXIT="return" + ${EXIT} 1 +fi +################################################################################ +# Get the target python executable, where we want to install all the +# requirements to. +VENV_PATH=${TARGET_VENV_PATH} source "${PROJ_PATH}/scripts/utilities/ensure-venv.sh" +PYTHON_EXECUTABLE=$(command -v python) +################################################################################ +# Activate the dev venv to install pip-tools to etc. +VENV_PATH=${DEV_VENV_PATH} source "${PROJ_PATH}/scripts/utilities/ensure-venv.sh" +################################################################################ + +SYNC_TOUCH_FILE="${PWD}/.cache/scripts/${PIN}-requirements.touch" +OUTPUT_REQUIREMENTS_FILE="${PWD}/.cache/scripts/${PIN}-requirements.txt" + +export FILE=${TOML} +export TOUCH_FILE=${SYNC_TOUCH_FILE} +if bash "${PROJ_PATH}/scripts/utilities/is_not_dirty.sh"; then + echo -e "${GREEN}Syncing is not needed${NC}" + [[ $(realpath "$0"||true) == $(realpath "${BASH_SOURCE[0]}"||true) ]] && EXIT="exit" || EXIT="return" + ${EXIT} 0 +fi +echo -e "${BLUE}Syncing requirements${NC}" + +python -m pip install pip-tools + +mkdir -p "$(dirname "${OUTPUT_REQUIREMENTS_FILE}")" + + +EXTRA_FLAGS=$(echo "${EXTRAS}" | python -c 'import sys; import shlex; extras=sys.stdin.read().split(","); print("\n".join([f" --extra {extra}" for extra in extras]))') +python -m piptools compile \ + ${EXTRA_FLAGS} \ + -o "${OUTPUT_REQUIREMENTS_FILE}" \ + "${TOML}" + +python -m piptools sync "${OUTPUT_REQUIREMENTS_FILE}" \ + --python-executable "${PYTHON_EXECUTABLE}" + +export FILE=${TOML} +export TOUCH_FILE=${SYNC_TOUCH_FILE} +bash "${PROJ_PATH}/scripts/utilities/mark_dirty.sh" + +export FILE=${TOML} +export TOUCH_FILE=${SYNC_TOUCH_FILE} +if bash "${PROJ_PATH}/scripts/utilities/is_not_dirty.sh"; then + : +else + echo -e "${RED}Syncing failed${NC}" + [[ $(realpath "$0"||true) == $(realpath "${BASH_SOURCE[0]}"||true) ]] && EXIT="exit" || EXIT="return" + ${EXIT} 1 +fi + +echo -e "${GREEN}Synced requirements for ${EXTRAS}, ${PIN}, using ${OUTPUT_REQUIREMENTS_FILE}${NC}" diff --git a/scripts/utilities/pin-extra-reqs.py b/scripts/utilities/pin-extra-reqs.py index 2546ebd..f7f3044 100644 --- a/scripts/utilities/pin-extra-reqs.py +++ b/scripts/utilities/pin-extra-reqs.py @@ -111,4 +111,4 @@ def _StripContinuation(line) -> Tuple[bool, str]: exit(0) # Write the updated pyproject.toml back to disk -pyproject_path.write_text(tomlkit.dumps(pyproject_data)) +pyproject_path.write_text(output) diff --git a/scripts/utilities/pin-extra-reqs.sh b/scripts/utilities/pin-extra-reqs.sh index 40e236b..e0cde3d 100755 --- a/scripts/utilities/pin-extra-reqs.sh +++ b/scripts/utilities/pin-extra-reqs.sh @@ -52,6 +52,7 @@ else PINNED_REQ_DIR=$(dirname "${PINNED_REQ_FILE}") mkdir -p "${PINNED_REQ_DIR}" + python -m pip install pip-tools python -m piptools compile --generate-hashes \ --extra "${EXTRA}" \ "${TOML}" \ diff --git a/scripts/utilities/pin-extra-reqs2.py b/scripts/utilities/pin-extra-reqs2.py new file mode 100644 index 0000000..c208ff5 --- /dev/null +++ b/scripts/utilities/pin-extra-reqs2.py @@ -0,0 +1,121 @@ +# -*- coding: utf-8 -*- +import argparse +from pathlib import Path +from typing import List, Tuple + +# tomlkit is used, so that everything is preserved, e.g comments etc. +import tomlkit +import tomlkit.container +import tomlkit.items +from tomlkit.toml_document import TOMLDocument + +_VALID_EXTRA_NAMES = ['dev', 'prod'] + +_DESCRIPTION = f""" +Pin the {{{",".join(_VALID_EXTRA_NAMES)}}} requirements in pyproject.toml. + +The purpose of this program is to take the output of +`pip-compile --extra EXTRA pyproject.toml` and reinsert the exactly +to-be-installed version numbers back into the updated pyproject.toml. + +This ensures that there is a valid, and consistent version of dependencies that +are known to work. +""" +parser = argparse.ArgumentParser(description=_DESCRIPTION) +parser.add_argument('--toml', + type=Path, + required=True, + help='Path to the pyproject.toml file') +parser.add_argument('--extra', + type=str, + action='append', + help='Which extra requirements to pin from') +parser.add_argument('--pin', + type=str, + required=True, + help='Which extra requirements to pin to') +parser.add_argument( + '--reqs', + type=Path, + required=True, + help='Path to the generated requirements.txt file (from pip-compile)') +args = parser.parse_args() + +pyproject_path: Path = args.toml +requirements_path: Path = args.reqs +extras: List[str] = args.extra +pin: str = args.pin + +pyproject_data: TOMLDocument = tomlkit.loads(pyproject_path.read_text()) +lines = requirements_path.read_text().splitlines() + + +def _StripContinuation(line) -> Tuple[bool, str]: + line = line.strip() + if line.endswith('\\'): + return (True, line[:-1].strip()) + return (False, line) + + +existing_dependencies: List[str] = [] +is_continuation = False +for i in range(len(lines)): + line = lines[i] + append_to_last = is_continuation + is_continuation, stripped_line = _StripContinuation(line) + if not stripped_line: + continue + if stripped_line.startswith('#'): + continue + if stripped_line.startswith('--'): + continue + if append_to_last: + existing_dependencies[-1] += stripped_line + else: + existing_dependencies.append(stripped_line) + +if 'project' not in pyproject_data: + raise ValueError('Invalid pyproject.toml file, missing "project" section.') +project_item = pyproject_data['project'] +if not isinstance(project_item, tomlkit.items.Table): + raise ValueError( + f'Invalid pyproject.toml file, expected "project" to be a table. Got {type(project_item)}.' + ) + +if 'optional-dependencies' not in project_item: + raise ValueError( + 'Invalid pyproject.toml file, expected "project" to have an entry for "optional-dependencies".' + ) +opt_deps = project_item['optional-dependencies'] +if not isinstance(opt_deps, tomlkit.items.Table): + raise ValueError( + f'Invalid pyproject.toml file, expected "project.optional-dependencies" to be a table. Got {type(opt_deps)}.' + ) + +for extra_or_pin in extras + [pin]: + if extra_or_pin not in opt_deps: + raise ValueError( + f'Invalid pyproject.toml file, expected "project.optional-dependencies" to contain {extra_or_pin}.' + ) + toml_extra_dependencies = opt_deps[extra_or_pin] + if not isinstance(toml_extra_dependencies, tomlkit.items.Array): + raise ValueError( + f'Invalid pyproject.toml file, expected "project.optional-dependencies.{extra_or_pin}" to be an array. Got {type(toml_extra_dependencies)}.' + ) + +if sorted(list(toml_extra_dependencies)) == sorted(existing_dependencies): + print('No changes detected') + exit(0) + +toml_extra_dependencies.clear() +for dep in existing_dependencies: + toml_extra_dependencies.append(dep) +opt_deps[pin] = toml_extra_dependencies.multiline(True) + +output = tomlkit.dumps(pyproject_data) +if output == pyproject_path.read_text(): + print('No changes detected') + exit(0) + +# Write the updated pyproject.toml back to disk +pyproject_path.write_text(output) diff --git a/scripts/utilities/pin-extra-reqs2.sh b/scripts/utilities/pin-extra-reqs2.sh new file mode 100755 index 0000000..06af2c4 --- /dev/null +++ b/scripts/utilities/pin-extra-reqs2.sh @@ -0,0 +1,104 @@ +#!/bin/bash +# https://gist.github.com/mohanpedala/1e2ff5661761d3abd0385e8223e16425 +set -e -x -v -u -o pipefail + +SCRIPT_DIR=$(realpath "$(dirname "${BASH_SOURCE[0]}")") +source "${SCRIPT_DIR}/common.sh" + +TOML="${TOML:-}" +if [[ -z "${TOML}" ]]; then + echo -e "${RED}TOML must be set${NC}" + [[ $(realpath "$0"||true) == $(realpath "${BASH_SOURCE[0]}"||true) ]] && EXIT="exit" || EXIT="return" + ${EXIT} 1 +fi + +VENV_PATH="${PWD}/.cache/scripts/.venv" source "${PROJ_PATH}/scripts/utilities/ensure-venv.sh" +TOML="${TOML}" EXTRA=dev \ + DEV_VENV_PATH="${PWD}/.cache/scripts/.venv" \ + TARGET_VENV_PATH="${PWD}/.cache/scripts/.venv" \ + bash "${PROJ_PATH}/scripts/utilities/ensure-reqs.sh" + + + +EXTRAS=${EXTRAS:-} +PIN=${PIN:-} + +if [[ -z "${PIN}" ]]; then + echo -e "${RED}PIN must be set${NC}" + [[ $(realpath "$0"||true) == $(realpath "${BASH_SOURCE[0]}"||true) ]] && EXIT="exit" || EXIT="return" + ${EXIT} 1 +fi + +################################################################################ +PINNED_REQ_FILE="${PWD}/.cache/scripts/${PIN}-requirements.pinned.txt" +PINNED_REQ_TOUCH_FILE="${PWD}/.cache/scripts/${PIN}-requirements.pinned.touch" +TOML_UPDATE_TOUCH_FILE="${PWD}/.cache/scripts/${PIN}-pyproject.toml.pinned.touch" +################################################################################ +# Extract the requirements from the pyproject.toml file into a requirements +# file. +# +# Check if we already did this. +export FILE="${TOML}" +export TOUCH_FILE="${PINNED_REQ_TOUCH_FILE}" + +EXTRA_FLAGS=$(echo "${EXTRAS}" | python -c 'import sys; import shlex; extras=sys.stdin.read().split(","); print("\n".join([f" --extra {extra}" for extra in extras]))') +# Add --extra ${PIN} to the EXTRA_FLAGS. This way previous pins are sticky. To +# change them, they have to be changed explicitly. Otherwise there will be a +# conflict. +EXTRA_FLAGS="${EXTRA_FLAGS} --extra ${PIN}" + +if bash "${PROJ_PATH}/scripts/utilities/is_not_dirty.sh"; then + echo -e "${GREEN}Requirements ${PINNED_REQ_FILE} are up to date${NC}" + [[ $(realpath "$0"||true) == $(realpath "${BASH_SOURCE[0]}"||true) ]] && EXIT="exit" || EXIT="return" +else + echo -e "${BLUE}Requirements ${PINNED_REQ_FILE} need updating${NC}" + echo -e "${BLUE}Generating ${PINNED_REQ_FILE}${NC}" + + PINNED_REQ_DIR=$(dirname "${PINNED_REQ_FILE}") + mkdir -p "${PINNED_REQ_DIR}" + python -m piptools compile --generate-hashes \ + ${EXTRA_FLAGS} \ + "${TOML}" \ + -o "${PINNED_REQ_FILE}" + echo -e "${GREEN}Generated ${PINNED_REQ_FILE}${NC}" + + export FILE="${TOML}" + export TOUCH_FILE="${PINNED_REQ_TOUCH_FILE}" + bash "${PROJ_PATH}/scripts/utilities/mark_dirty.sh" +fi +################################################################################ +# Pin extra requirements in pyproject.toml file. + +export FILE="${TOML}" +export TOUCH_FILE="${TOML_UPDATE_TOUCH_FILE}" +if bash "${PROJ_PATH}/scripts/utilities/is_not_dirty.sh"; then + echo -e "${GREEN}pyproject.toml is up to date${NC}" +else + echo -e "${BLUE}Altering pyproject.toml${NC}" + python "${PROJ_PATH}/scripts/utilities/pin-extra-reqs2.py" \ + --reqs "${PINNED_REQ_FILE}" \ + ${EXTRA_FLAGS} \ + --pin "${PIN}" \ + --toml "${TOML}" + ################################################################################ + # Format the pyproject.toml file + if toml-sort "${TOML}" --check; then + echo -e "${GREEN}pyproject.toml needs no formatting${NC}" + else + echo -e "${BLUE}pyproject.toml needs formatting${NC}" + toml-sort --in-place "${TOML}" + echo -e "${GREEN}pyproject.toml formatted${NC}" + fi + if toml-sort "${TOML}" --check; then + echo -e "${GREEN}pyproject.toml is formatted${NC}" + else + echo -e "${RED}pyproject.toml is not formatted${NC}" + [[ $(realpath "$0"||true) == $(realpath "${BASH_SOURCE[0]}"||true) ]] && EXIT="exit" || EXIT="return" + ${EXIT} 1 + fi + ################################################################################ + export FILE="${TOML}" + export TOUCH_FILE="${TOML_UPDATE_TOUCH_FILE}" + bash "${PROJ_PATH}/scripts/utilities/mark_dirty.sh" + echo -e "${GREEN}Pinned ${EXTRAS} => ${PIN} requirements${NC}" +fi