From e722d637f8fc4de99f024ecaa12972eb7cb5de45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jiri=20Dan=C4=9Bk?= Date: Fri, 31 Oct 2025 18:51:52 +0100 Subject: [PATCH 1/7] NO-JIRA: chore(docs/adr): document language preference for Python, Go, and TypeScript --- ...-python-go-and-typescript-in-this-order.md | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md diff --git a/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md b/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md new file mode 100644 index 0000000000..15a43a5074 --- /dev/null +++ b/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md @@ -0,0 +1,54 @@ +# 3. Prefer Python, Go, and Typescript (in this order) + +Date: 2025-10-31 + +## Status + +Accepted + +## Context + +We have many Bash scripts, often they are inline scripts embedded in Dockerfiles. +This is hindering code reuse, and makes using good software engineering practices difficult. + +The current team self-reported that they are comfortable with Python, Go, and (to a lesser degree) TypeScript. +Use these languages in preference to Bash. + +## Decision + +The team has agreed to use Python, Go, and Typescript, in this order. + +For any new development, we should use the most appropriate language out of these. +Old code should be gradually migrated to one of the preferred languages. + +Avoid using Bash for anything more complicated than a `RUN dnf install -y ... && dnf clean all`. + +### Python + +_The language of AI._ + +Pytest as the currently most popular test discovery and execution tool. + +Rewriting Bash scripts to Python is verbose. Library to help with this is [sh](https://github.com/amoffat/sh) and others. + +The indentation-based syntax is obnoxious, multiline lambdas are not available. + +### Go + +_90% Perfect, 100% of the time._ [Brad Fitzpatrick, 2014](https://go.dev/talks/2014/gocon-tokyo.slide), [slide #36](https://go.dev/talks/2014/gocon-tokyo.slide#36) + +Good performance, creates native executables, first class library support for dealing with Kubernetes. + +### TypeScript + +_The language of the web._ + +Playwright has best support for TypeScript, other language bindings are a bit of a second class citizen. + +We will consider using full-stack TypeScript in preference to having either a Python or Go backend to a TypeScript frontend. + +## Consequences + +Less duplication of code due to easier maintenance, and testing of Python code, which should promote reuse. + +Simple scripts will be more verbose in Python, but this is a trade-off we can make. From 0c1b53f003e374706edca920f31554d91ed2a4d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jiri=20Dan=C4=9Bk?= Date: Fri, 5 Dec 2025 20:09:38 +0100 Subject: [PATCH 2/7] add bash section, add bulets to lists, expand on python typechecking --- ...-python-go-and-typescript-in-this-order.md | 88 ++++++++++++++++--- 1 file changed, 76 insertions(+), 12 deletions(-) diff --git a/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md b/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md index 15a43a5074..03f22b455a 100644 --- a/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md +++ b/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md @@ -4,51 +4,115 @@ Date: 2025-10-31 ## Status -Accepted +Proposed ## Context -We have many Bash scripts, often they are inline scripts embedded in Dockerfiles. -This is hindering code reuse, and makes using good software engineering practices difficult. +We have many Bash scripts; often they are inline scripts embedded in Dockerfiles. +This is hindering code reuse and makes using good software engineering practices difficult. The current team self-reported that they are comfortable with Python, Go, and (to a lesser degree) TypeScript. Use these languages in preference to Bash. ## Decision -The team has agreed to use Python, Go, and Typescript, in this order. +The team has agreed to use Python, Go, and TypeScript, in this order. For any new development, we should use the most appropriate language out of these. Old code should be gradually migrated to one of the preferred languages. -Avoid using Bash for anything more complicated than a `RUN dnf install -y ... && dnf clean all`. +We should avoid using Bash for anything more complicated than a `RUN dnf install -y ... && dnf clean all`. + +### Bash + +Titus Winters presented about programming languages being [software-engineering-friendly](https://youtu.be/yA_wUiNuhSc&t=649) or unfriendly. +Bash was not mentioned but it should fall into the unfriendly category. +It does not have proper runtime types (everything in Bash is a string, or possibly an array of strings), +it does not even have proper value-returning functions! + +There are efforts to level up Bash scripting, such as the `set -Eeuxo pipefail`, but it has +[problems of its own](https://www.reddit.com/r/bash/comments/mivbcm/comment/gt8harr/): + +> `errexit`, `nounset` and `pipefail` are imperfect implementations of otherwise sane ideas, and unfortunately they often amount to being unreliable interfaces that are less familiar and less understood than simply living without them. It's perfectly fine to want them to work as advertised, and I think we all would like that, but they don't, so shouldn't be recommended so blindly, nor advertised as a "best practice"—they aren't. + +There is the [bats](https://github.com/bats-core/bats-core) testing framework. ### Python -_The language of AI._ + The semantics of Python are mostly familiar to the team members and they are comfortable using Python. -Pytest as the currently most popular test discovery and execution tool. + Pytest as the currently most popular test discovery and execution tool. -Rewriting Bash scripts to Python is verbose. Library to help with this is [sh](https://github.com/amoffat/sh) and others. + Rewriting Bash scripts to Python is verbose. Library to help with this is [sh](https://github.com/amoffat/sh) and others. -The indentation-based syntax is obnoxious, multiline lambdas are not available. + The indentation-based syntax is obnoxious, multiline lambdas are not available. ### Go _90% Perfect, 100% of the time._ [Brad Fitzpatrick, 2014](https://go.dev/talks/2014/gocon-tokyo.slide), [slide #36](https://go.dev/talks/2014/gocon-tokyo.slide#36) -Good performance, creates native executables, first class library support for dealing with Kubernetes. + Good performance, +creates native executables, +first-class library support for dealing with Kubernetes. + + Often competes with Python in language choice debates, +vastly superior performance to Python and TypeScript both. + + Requires compilation step, +type system is not very expressive, +the language does not believe in programming in types (the way some typed functional languages or Rust do). + + Has little syntactic sugar, already felt dated the year it came out. ### TypeScript _The language of the web._ -Playwright has best support for TypeScript, other language bindings are a bit of a second class citizen. + Playwright has best support for TypeScript, other language bindings are a bit of a second class citizen. + +🛈 We will consider using full-stack TypeScript in preference to having either a Python or Go backend to a TypeScript frontend. + + It's still JavaScript underneath, so there is much inherited weirdness, +such as the `this` keyword being different depending on how a function is called. + +## Typechecking -We will consider using full-stack TypeScript in preference to having either a Python or Go backend to a TypeScript frontend. +Static analyzability and specifically typechecking is (according to Winters) +an important step to achieving software-engineering friendliness. + +The choice is between + +* Pyrefly +* Pyright (or basedpyright) +* ty + +Currently, the project is configured with Pyright, but with type checking disabled. +We should first fix the types with Pyright, gain experience, and then either decide not to use typed Python, or migrate off to one of the other options. + +Pyrefly is more complete, whereas ty seems to be more vibrant and dynamic. +Either case, Python type annotations are language standard, so the core does not change, +but the checkers still have lots of implementation-specific behavior left to define themselves. + +### Editor support for Python type checkers + +VSCode support is pretty much given these days. + +In IntelliJ world, +[version 2025.3+ is required for Python tools](https://www.jetbrains.com/help/pycharm/2025.3/lsp-tools.html) +support, as previous versions don't yet have +[LSP support built in](https://plugins.jetbrains.com/docs/intellij/language-server-protocol.html). +There is a +[plugin from Red Hat](https://github.com/redhat-developer/lsp4ij) +that adds LSP client support to IntelliJ, but I did not try to use it. ## Consequences Less duplication of code due to easier maintenance, and testing of Python code, which should promote reuse. Simple scripts will be more verbose in Python, but this is a trade-off we can make. + +Obvious location to place shared code, sane `import` mechanism. + +Allow for fearless refactoring . + +We will need to fight the ever-present tendency to overengineer, and instead we shall promote low-ceremony code. From b1f276bd8150e48c81ef7053f3c92b5ff3136770 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jiri=20Dan=C4=9Bk?= Date: Fri, 5 Dec 2025 20:14:30 +0100 Subject: [PATCH 3/7] polish --- ...03-prefer-python-go-and-typescript-in-this-order.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md b/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md index 03f22b455a..8e84a24177 100644 --- a/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md +++ b/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md @@ -35,7 +35,7 @@ There are efforts to level up Bash scripting, such as the `set -Eeuxo pipefail`, > `errexit`, `nounset` and `pipefail` are imperfect implementations of otherwise sane ideas, and unfortunately they often amount to being unreliable interfaces that are less familiar and less understood than simply living without them. It's perfectly fine to want them to work as advertised, and I think we all would like that, but they don't, so shouldn't be recommended so blindly, nor advertised as a "best practice"—they aren't. -There is the [bats](https://github.com/bats-core/bats-core) testing framework. +There is also the [bats](https://github.com/bats-core/bats-core) testing framework which does show promise if forced to live with a Bash codebase. ### Python @@ -80,7 +80,7 @@ such as the `this` keyword being different depending on how a function is called Static analyzability and specifically typechecking is (according to Winters) an important step to achieving software-engineering friendliness. -The choice is between +The choice in Python is currently between * Pyrefly * Pyright (or basedpyright) @@ -113,6 +113,10 @@ Simple scripts will be more verbose in Python, but this is a trade-off we can ma Obvious location to place shared code, sane `import` mechanism. -Allow for fearless refactoring . +Allow for [fearless refactoring](https://www.jamesshore.com/v2/blog/2005/merciless-refactoring.html). + +> Imagine! +> Do this right, and your code gets cheaper to modify over time! +> That's so amazing, most people don't even think it's possible. We will need to fight the ever-present tendency to overengineer, and instead we shall promote low-ceremony code. From c089172d2efbe514a2d9e9b39c287e9dada7e74b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jiri=20Dan=C4=9Bk?= Date: Fri, 5 Dec 2025 20:17:23 +0100 Subject: [PATCH 4/7] language --- .../0003-prefer-python-go-and-typescript-in-this-order.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md b/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md index 8e84a24177..40b976a783 100644 --- a/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md +++ b/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md @@ -1,4 +1,4 @@ -# 3. Prefer Python, Go, and Typescript (in this order) +# 3. Prefer Python, Go, and TypeScript (in this order) Date: 2025-10-31 @@ -70,7 +70,7 @@ _The language of the web._ Playwright has best support for TypeScript, other language bindings are a bit of a second class citizen. -🛈 We will consider using full-stack TypeScript in preference to having either a Python or Go backend to a TypeScript frontend. +🛈 We will consider using full-stack TypeScript over Python or Go backends with a TypeScript frontend. It's still JavaScript underneath, so there is much inherited weirdness, such as the `this` keyword being different depending on how a function is called. From bd6bd54e58b96f18ab88a11e7fdac1c46bd34616 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jiri=20Dan=C4=9Bk?= Date: Fri, 5 Dec 2025 20:22:46 +0100 Subject: [PATCH 5/7] rabbit suggested fixes --- .../0003-prefer-python-go-and-typescript-in-this-order.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md b/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md index 40b976a783..154a595af1 100644 --- a/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md +++ b/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md @@ -12,7 +12,7 @@ We have many Bash scripts; often they are inline scripts embedded in Dockerfiles This is hindering code reuse and makes using good software engineering practices difficult. The current team self-reported that they are comfortable with Python, Go, and (to a lesser degree) TypeScript. -Use these languages in preference to Bash. +Always consider using one of these languages rather than Bash. ## Decision @@ -68,7 +68,7 @@ the language does not believe in programming in types (the way some typed functi _The language of the web._ - Playwright has best support for TypeScript, other language bindings are a bit of a second class citizen. + Playwright has best support for TypeScript, other language bindings are a bit of a second-class citizen. 🛈 We will consider using full-stack TypeScript over Python or Go backends with a TypeScript frontend. @@ -89,13 +89,13 @@ The choice in Python is currently between Currently, the project is configured with Pyright, but with type checking disabled. We should first fix the types with Pyright, gain experience, and then either decide not to use typed Python, or migrate off to one of the other options. -Pyrefly is more complete, whereas ty seems to be more vibrant and dynamic. +Pyrefly is more complete, whereas ty is more vibrant and dynamic. Either case, Python type annotations are language standard, so the core does not change, but the checkers still have lots of implementation-specific behavior left to define themselves. ### Editor support for Python type checkers -VSCode support is pretty much given these days. +VSCode support is pretty much a given these days. In IntelliJ world, [version 2025.3+ is required for Python tools](https://www.jetbrains.com/help/pycharm/2025.3/lsp-tools.html) From a59774ade48ce3466fdbaf2717c6d1c453036da4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jiri=20Dan=C4=9Bk?= Date: Fri, 5 Dec 2025 20:54:31 +0100 Subject: [PATCH 6/7] more rabbit suggested fixes --- .../0003-prefer-python-go-and-typescript-in-this-order.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md b/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md index 154a595af1..8463e1cde1 100644 --- a/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md +++ b/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md @@ -25,7 +25,7 @@ We should avoid using Bash for anything more complicated than a `RUN dnf install ### Bash -Titus Winters presented about programming languages being [software-engineering-friendly](https://youtu.be/yA_wUiNuhSc&t=649) or unfriendly. +Titus Winters presented about programming languages being [software-engineering-friendly](https://youtu.be/yA_wUiNuhSc?t=649) or unfriendly. Bash was not mentioned but it should fall into the unfriendly category. It does not have proper runtime types (everything in Bash is a string, or possibly an array of strings), it does not even have proper value-returning functions! @@ -70,7 +70,7 @@ _The language of the web._ Playwright has best support for TypeScript, other language bindings are a bit of a second-class citizen. -🛈 We will consider using full-stack TypeScript over Python or Go backends with a TypeScript frontend. +🛈 We may consider using full-stack TypeScript over Python or Go backends with a TypeScript frontend. It's still JavaScript underneath, so there is much inherited weirdness, such as the `this` keyword being different depending on how a function is called. From 04678ce35109cf0b83ee184b0eac41101bad9f9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jiri=20Dan=C4=9Bk?= Date: Fri, 5 Dec 2025 21:32:47 +0100 Subject: [PATCH 7/7] more bash bashing links --- .../0003-prefer-python-go-and-typescript-in-this-order.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md b/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md index 8463e1cde1..d7a0249027 100644 --- a/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md +++ b/docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md @@ -31,9 +31,13 @@ It does not have proper runtime types (everything in Bash is a string, or possib it does not even have proper value-returning functions! There are efforts to level up Bash scripting, such as the `set -Eeuxo pipefail`, but it has -[problems of its own](https://www.reddit.com/r/bash/comments/mivbcm/comment/gt8harr/): +[problems](https://mywiki.wooledge.org/BashPitfalls#set_-euo_pipefail) +[of](https://lobste.rs/s/gwzjjw/modern_bash_scripting) +[its](https://www.mulle-kybernetik.com/modern-bash-scripting/) +[own](https://www.reddit.com/r/bash/comments/mivbcm/comment/gt8harr/): -> `errexit`, `nounset` and `pipefail` are imperfect implementations of otherwise sane ideas, and unfortunately they often amount to being unreliable interfaces that are less familiar and less understood than simply living without them. It's perfectly fine to want them to work as advertised, and I think we all would like that, but they don't, so shouldn't be recommended so blindly, nor advertised as a "best practice"—they aren't. +> `errexit`, `nounset` and `pipefail` are imperfect implementations of otherwise sane ideas, and unfortunately they often amount to being unreliable interfaces that are less familiar and less understood than simply living without them. +> It's perfectly fine to want them to work as advertised, and I think we all would like that, but they don't, so shouldn't be recommended so blindly, nor advertised as a "best practice"—they aren't. There is also the [bats](https://github.com/bats-core/bats-core) testing framework which does show promise if forced to live with a Bash codebase.