Metadata-Version: 2.5
Name: py-lobs
Version: 0.2.0
Summary: lobs is a framework that aims to provide an easy application and library project generator.
Project-URL: Documentation, https://github.com/rikardonm/lobs#readme
Project-URL: Issues, https://github.com/rikardonm/lobs/issues
Project-URL: Source, https://github.com/rikardonm/lobs
Author-email: Ricardo Marchesan <rikardo.nm@proton.me>
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 4 - Beta
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Requires-Python: >=3.13
Requires-Dist: annotated-types~=0.7.0
Requires-Dist: bigtree[image]~=1.0.2
Requires-Dist: click~=8.3.0
Requires-Dist: filesizelib~=0.12.1
Requires-Dist: gitpython~=3.1.50
Requires-Dist: pydantic~=2.12.2
Provides-Extra: docs
Requires-Dist: myst-parser>=3.0.1; extra == 'docs'
Requires-Dist: sphinx-autobuild>=2025.8.25; extra == 'docs'
Requires-Dist: sphinx-design>=0.6.1; extra == 'docs'
Requires-Dist: sphinx-rtd-theme>=3.0.2; extra == 'docs'
Requires-Dist: sphinx~=8.1.3; extra == 'docs'
Provides-Extra: test
Requires-Dist: pytest~=9.1.1; extra == 'test'
Description-Content-Type: text/markdown

# lobs

[![PyPI - Version](https://img.shields.io/pypi/v/py-lobs.svg)](https://pypi.org/project/py-lobs)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/py-lobs.svg)](https://pypi.org/project/py-lobs)

`lobs` is a framework that aims to provide an easy application and library project generator.
The simple drivers for this are the need to have a single C++ source file used in a project,
used with multiple targets (i.e. ESP IDF, Cmake, Zephyr, etc).

The pillars for the library are:

- Every library is a package
- Every application is a plain script
- Dependency fetching and version resolution is done by Python's package manager (e.g. pip)
- Every package has only one library or application

And the motivation is pretty straightforward: I have a problem that I'm tired of solving manually.
Embedded applications declared in plain CMake do not play well with ESP's IDF, and vice-versa.
So instead of writing if/else's we write a whole new package to wrap that mess somewhere I can't see!


A simple C++ application example

```python
# simple-example.py
from pathlib import Path

import lobs


main_cpp = Path(__file__).with_name("main.cpp")

main_cpp.write_text(r"""
#include <iostream>

int main(int argc, char *argv[])
{
    (void)(argc);
    (void)(argv);
    std::cout << "Howdy!\n";
    return 0;
}
""")

app = lobs.Package(
    lobs.ProjectMeta("example-app", lobs.Version(0, 0, 1)),
    lobs.cpp.ManagedApplication([main_cpp]),
)
"""A simple C++ application project with a single source file,
no dependencies and default flags."""

# Example of modifying the project configuration after object creation
app.project.compilation_flags.w_all = True
# Example of enabling flags using dictionary-like access
app.project.compilation_flags['w_extra'] = True
# Example of adding a flag that was not predefined in the dataclass
app.project.compilation_flags['w_comment'] = True
```

And use it like so:

```
~/lobs » lobs simple-example.py export cmake
Project: simple-example.py

~/lobs » cmake -B build .
-- Configuring done
-- Generating done
-- Build files have been written to: /home/ricardo/git/lobs/build

~/lobs » cmake --build build
[ 50%] Building CXX object CMakeFiles/example-app.dir/main.cpp.o
[100%] Linking CXX executable example-app
[100%] Built target example-app

~/lobs » ./build/example-app
Howdy!
```


-----

## Table of Contents

- [Installation](#installation)
- [Design](#design)
- [Developer](#developer)
- [License](#license)

## Installation

```console
python3 -m pip install lobs
```

## Architecture

The basis for the package is the sequence of steps:

- Create the skeleton for the declared entity (app, lib, etc)
- Recursively populate the required packages to fullfil the entities in the skeleton
- Inflate the skeleton by generating any required configuration files
- Execute operation (e.g. export to CMake)


## Flow

The diagram below shows the sequence of operations the framework executes on the given package.

```mermaid
graph TD;
    Start-->A(Create);
    A-->B(Configure);
    B-->C(Prepare Files);
    C-->D(Materialize);
    D-->E(Exporter);
    E-->F(CMake);
    E-->G(ESP IDF);
```


## Design Inspirations

Various design choices were heavily based on the Zen of Python.


### All files exist in the disk

A limitation imposed by the framework to the Python language is that all executed code must be sourced from a file in disk.
The rationale is the common use of the module's path by the exporters.


### Explicit library imports in project files

The main reason for this is the reuse of editor and linting tools support.
Furthermore, it provides clarity to the user of what is being used and where it comes from.


### Everything is monkey-patchable

In standard Python, almost everything is monkey-patchable by the user.
By design, the library aims to keep it that way.

> "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off".
> Yes, I said something like that (in 1986 or so).
> What people tend to miss, is that what I said there about C++ is to a varying extent true for all powerful languages.
> As you protect people from simple dangers, they get themselves into new and less obvious problems.
> Someone who avoids the simple problems may simply be heading for a not-so-simple one.
> One problem with very supporting and protective environments is that the hard problems may be discovered too late or be too hard to remedy once discovered.
> Also, a rare problem is harder to find than a frequent one because you don't suspect it.
>
> -- <cite>Bjarne Stroustrup @ https://www.stroustrup.com/quotes.html</cite>


## Developer

TODO

## License

`lobs` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.
