Skip to content

Commit 6b3878c

Browse files
committed
deploy: 556bf65
1 parent aebafbe commit 6b3878c

File tree

84 files changed

+25392
-629
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+25392
-629
lines changed

.buildinfo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# Sphinx build info version 1
22
# This file records the configuration used when building these files. When it is not found, a full rebuild will be done.
3-
config: 6a3f85e7ba2770da1364307931195e9e
3+
config: ae7b7e36dd37d83150154f5664198a3d
44
tags: 645f666f9bcd5a90fca523b33c5a78b7
31 KB
Binary file not shown.
Binary file not shown.
0 Bytes
Binary file not shown.

.doctrees/environment.pickle

78.2 KB
Binary file not shown.
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
---
2+
tags: python, bootstrap, venv
3+
category: review
4+
date: 2025-11-24
5+
title: SPL Bootstrap - Handle Python Version
6+
---
7+
8+
## SPL Bootstrap - Handle Python Version
9+
10+
### Introduction
11+
12+
The pipeline implementation for our Software Product Line (SPL) repositories uses the [pypeline](https://github.com/cuinixam/pypeline) Python application.
13+
In order to start the `pypeline` application, we need to install Python (with a specified version) and create the Python virtual environment.
14+
This step we call `bootstrap` and it is implemented [here](https://github.com/avengineers/bootstrap).
15+
16+
```{note}
17+
Currently bootstrap supports only Windows for installing Python.
18+
```
19+
20+
### Workflow
21+
22+
The bootstrap process is managed by two main scripts: a PowerShell script (`bootstrap.ps1`) for environment setup and a Python script (`bootstrap.py`) for dependency management. The diagram below shows the high-level workflow.
23+
24+
```{mermaid}
25+
flowchart TD
26+
A[bootstrap.ps1] --> B{Python installed?};
27+
B -- No --> C[Install Python w/ Scoop 1️⃣];
28+
B -- Yes --> D;
29+
C --> D[Execute bootstrap.py];
30+
31+
D --> E{Dependencies changed?};
32+
E -- No --> F[End];
33+
E -- Yes --> G[Create/Update .venv 2️⃣];
34+
G --> H[Install Dependencies];
35+
H --> F;
36+
```
37+
38+
1. This step will first install the `scoop` windows package manager and then call `scoop` to install the configured python version.
39+
2. The python virtual environment is updated in multiple steps:
40+
- create an empty virtual environment with python `venv.create`
41+
- install the package manager (e.g., poetry, uv, etc.) and `pip-system-certs` for using the system SSL certificates
42+
- run the package manager to install the python dependencies
43+
44+
#### bootstrap.ps1
45+
46+
- Scoop configuration and installation
47+
- Python version detection and installation
48+
- Delegates to `bootstrap.py` for virtual environment setup
49+
50+
#### bootstrap.py
51+
52+
- OS-agnostic virtual environment creation (Windows/Unix)
53+
- Smart caching with hash-based dependency tracking. Only runs if dependencies have been updated.
54+
- Package manager support: Poetry, UV, Pipenv
55+
- Automatic pip configuration for custom PyPI sources
56+
57+
#### bootstrap.json Configuration
58+
59+
```json
60+
{
61+
"python_version": "3.11",
62+
"python_package_manager": "poetry>=2.1.0",
63+
"scoop_ignore_scoopfile": true
64+
}
65+
```
66+
67+
### Things to Improve
68+
69+
#### Python Version Management
70+
71+
Currently the bootstrap process installs a fixed Python version as specified in the `bootstrap.json` configuration file.
72+
When checking if python is installed, it only verifies that the major and minor version match (e.g., `3.11`),
73+
but does not check for patch versions (e.g., `3.11.4` vs `3.11.5`).
74+
This can lead to situations that on different machines, slightly different patch versions of Python are installed.
75+
76+
```{note}
77+
This might not be a big issue in most cases, but it can lead to inconsistencies in our particular case,
78+
because we use the python `venv` module to create the initial virtual environment,
79+
which will include the standard library of the installed Python version.
80+
```
81+
82+
The solution could be:
83+
84+
- to find all installed python versions in path and check if the exact version is already installed
85+
- it might be that python versions installed with scoop are not available in path, so we need to query scoop for installed versions
86+
- if the exact version is not installed, install it with scoop
87+
- the `bootstrap.py` shall fail if the python interpreter version does not match exactly the configured version.
88+
This can happen if the user runs the `pypeline` including the `CreateVEnv` step which calls directly the `bootstrap.py` script.
89+
90+
#### Virtual Environment Management
91+
92+
As mention above, the virtual environment is created in three steps:
93+
94+
1. create an empty virtual environment with python `venv.create`
95+
1. install the package manager (e.g., poetry, uv, etc.) and `pip-system-certs` for using the system SSL certificates
96+
1. run the package manager to install the python dependencies
97+
98+
There is a problem with the second step: the package manager and pip-system certs are installed with pip.
99+
These packages have their own dependencies, which are not tracked by pip because pip has no support for `.lock` files.
100+
101+
When step three is executed, the package manager might need to upgrade/downgrade some packages which were implicitly installed in step two
102+
and this can cause crashes due to dependency conflicts.
103+
104+
#### Solution 1: User-defined Initial Packages
105+
106+
One way to solve this is to let the user define the list of package to install in step two in the `bootstrap.json` configuration file.
107+
For example:
108+
109+
```{code-block} json
110+
{
111+
"python_version": "3.11.4",
112+
"venv_initial_packages": [
113+
"poetry==2.1.0",
114+
"pip-system-certs==2.2.1",
115+
"wrapt==1.14.0"
116+
],
117+
}
118+
```
119+
120+
In case there is a conflict between the initial packages and the packages defined in the package manager lock file,
121+
the user can adjust the versions in the configuration file accordingly.
122+
123+
#### Solution 2: Install Package Manager with Scoop
124+
125+
Another way could be to install both python and the package manager with scoop in the `bootstrap.ps1` script,
126+
so that pip is not involved at all in step two. This means that package manager will install exactly the version specified in the `.lock` file
127+
and therefore always have a consistent set of dependencies.
128+
129+
The problem with this approach is that `pip-system-certs` is not available as a scoop package
130+
and package installation will fail when ran against an on-premise PyPI server with self-signed certificates.
131+
132+
#### Package manager command
133+
134+
Currently the command to install dependencies with the package manager is hardcoded in the `bootstrap.py` script
135+
with extra arguments being supported via the `bootstrap.json` configuration file.
136+
137+
```{code-block} json
138+
{
139+
"python_package_manager_args": "--clean"
140+
}
141+
```
142+
143+
We added the feature to support extra arguments because we needed for some projects to pass the `--clean` to `pipenv`
144+
to remove unused packages already existing in the virtual environment.
145+
146+
A better approach would be to let the user define the full command to install dependencies with the package manager.
147+
For example:
148+
149+
```{code-block} json
150+
{
151+
"venv_install_command": "poetry install --no-dev --clean"
152+
}
153+
```
154+
155+
This would give the user full control over how dependencies are installed.
156+
157+
## Conclusion
158+
159+
If all these improvements are implemented, the bootstrap process will be more reliable and flexible, ensuring consistent Python environments.
160+
161+
The configuration will allow users to tailor the bootstrap process to their specific needs.
162+
163+
```{code-block} json
164+
{
165+
"python_version": "3.11.4",
166+
"venv_initial_packages": [
167+
"poetry==2.1.0",
168+
"pip-system-certs==2.2.1"
169+
],
170+
"venv_install_command": "poetry install --no-dev --clean"
171+
}
172+
```
173+
174+
This configuration will ensure that:
175+
176+
- Python 3.11.4 is installed
177+
- The package manager and pip-system-certs are installed with the specified versions
178+
- Dependencies are installed with the specified command
179+
180+
Have fun bootstrapping! ✌️

_sources/blogs/2025/what_you_did_not_want_to_know_about_your_code.md.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ For this I added a new command in a Python app I use to parse and analyze C/C++
2828

2929
The new `analyze` command does the following:
3030

31-
* parse the `compile_commands.json` file to find all the object files
32-
* run `nm` on each object file to get the global symbols and determine their type:
33-
* `extern` for undefined globals - these are the `required` symbols
34-
* `local` for local globals - these are the `provided` symbols
35-
* create an html report using [cytoscape.js](https://cytoscape.org/) to visualize the dependencies between the object files.
31+
- parse the `compile_commands.json` file to find all the object files
32+
- run `nm` on each object file to get the global symbols and determine their type:
33+
- `extern` for undefined globals - these are the `required` symbols
34+
- `local` for local globals - these are the `provided` symbols
35+
- create an html report using [cytoscape.js](https://cytoscape.org/) to visualize the dependencies between the object files.
3636
I also added an option to group the object files in named containers based on their path.
3737

3838
The result is a nice interactive graph where you can zoom in and out, drag the nodes around and enjoy the complexity of the code base.

_sources/blogs/2025/yanga_spl_components.md.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ These variants consist of *components* that implement the features required for
1212
Each variant might be built for different *platforms*, different hardware environments with their own constraints and capabilities.
1313

1414
When thinking about components, there are two main categories:
15+
1516
- Components which implement your product's features
1617
- Components which provide the functionality for other components to run on a certain hardware platform
1718

@@ -37,6 +38,7 @@ variants:
3738
```
3839

3940
Example for a platform configuration:
41+
4042
```{code-block} yaml
4143
platforms:
4244
- name: arduino_uno
@@ -55,6 +57,7 @@ I had a component that it only worked for Arduino, but I used it only for one of
5557
YANGA gives you three places to define components:
5658

5759
### 1. In Your Product Variant
60+
5861
For components that define what your product does, regardless of platform.
5962

6063
```{code-block} yaml
@@ -67,6 +70,7 @@ variants:
6770
```
6871

6972
### 2. In Your Platform Configuration
73+
7074
For components that every product needs when targeting this platform.
7175

7276
```{code-block} yaml
@@ -79,6 +83,7 @@ platforms:
7983
```
8084

8185
### 3. In Your Variant's Platform-Specific Section
86+
8287
For components that only some products need, and only on specific platforms.
8388

8489
```{code-block} yaml
@@ -122,4 +127,4 @@ Each place has its purpose, and using them correctly can make your project easie
122127

123128
If you want to learn more about YANGA please check the [documentation](https://yanga.readthedocs.io/).
124129

125-
✌️
130+
✌️

about.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
<meta name="viewport" content="width=device-width, initial-scale=1"/>
5858
<meta name="docsearch:language" content="en"/>
5959
<meta name="docsearch:version" content="" />
60-
<meta name="docbuild:last-update" content="Oct 26, 2025"/>
60+
<meta name="docbuild:last-update" content="Nov 24, 2025"/>
6161
<link
6262
rel="alternate"
6363
type="application/atom+xml"

0 commit comments

Comments
 (0)