Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ template*
*.bak
cov-int/
__pycache__
*.egg-info/
tags
9 changes: 9 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
graft include
graft lib
graft python
graft ext/uuid
include README.rst
include LICENSE
include heatshrink.LICENSE
include setup.py
include pyproject.toml
13 changes: 11 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,17 @@ Documentation is available here: `BPAK documentation`_
Building and installing
-----------------------

The library depends to mbedtls, liblzma, uuid
The library depends on mbedtls and liblzma.

Build library and tool::
Install Python module::

$ pip install .

This compiles the library and Python extension from source. Requires
``libmbedtls-dev`` and ``liblzma-dev`` (or equivalent) installed on the
system.

Build C library and tool::

$ mkdir build && cd build
$ cmake ..
Expand All @@ -43,6 +51,7 @@ Build library and tool::

Running tests::

$ mkdir build && cd build
$ cmake .. -DBPAK_BUILD_TESTS=1
$ make && make test

Expand Down
33 changes: 22 additions & 11 deletions docs/build.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,33 @@
Building and installing
-----------------------

The library depends on mbedtls and liblzma
The library depends on mbedtls and liblzma.

Build library and tool::
Install Python module
---------------------

$ cmake
$ make
$ sudo make install
::

$ pip install .

This compiles the library and Python extension from source. Requires
``libmbedtls-dev`` and ``liblzma-dev`` (or equivalent) installed on the
system.

Optionally build with python support::
Build C library and tool
------------------------

$ cmake -DBPAK_BUILD_PYTHON_WRAPPER=1
::

$ mkdir build && cd build
$ cmake ..
$ make
$ sudo make install

Running tests::

$ cmake -DBPAK_BUILD_TESTS=1
$ mkdir build && cd build
$ cmake .. -DBPAK_BUILD_TESTS=1
$ make && make test


Expand All @@ -29,12 +41,11 @@ cmake configure options
Option Description
=========================== ====================================================
BPAK_BUILD_MINIMAL Build a minimal version of the library
BPAK_BUILD_PYTHON_WRAPPER Build the python wrapper
BPAK_BUILD_TOOL Build the bpak command-line tool (default: ON)
BPAK_BUILD_TESTS Build tests
=========================== ====================================================

The default setting is that everything is enabled except the python wrapper and
the tests.
The default setting builds the library and tool. Tests are disabled by default.


Build settings
Expand Down
9 changes: 8 additions & 1 deletion docs/ug/01_basics.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
Basic example
=============

.. note::

The examples in this user guide use the C ``bpak`` command-line tool. The
``bpak`` CLI installed from the Python package has a different, idiomatic
Click argv; see :doc:`99_python_cli` for its command reference and a
migration table.

In the simplest use-case for bitpacker the archive can be viewed as a container
format for other binaries with metadata on sizes and offsets of the parts it
format for other binaries with metadata on sizes and offsets of the parts it
contains.

Create an empty archive::
Expand Down
161 changes: 161 additions & 0 deletions docs/ug/99_python_cli.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
Python CLI
==========

The ``bpak`` command shipped by the ``bpak`` Python package (``pip install bpak``)
is an idiomatic Click application. Its command-line interface is **not** the
same as the C ``bpak`` binary documented in the preceding chapters. The C
binary is unchanged; anyone needing the historical argv should continue to
install and run it directly.

If you were using a previous version of the Python ``bpak`` script, see the
migration table below for the new shape of every subcommand.

Overview
--------

- Two-level command groups: operations on parts and metadata are written as
``noun verb``, e.g. ``bpak add part`` / ``bpak delete meta``.
- ``-v/--verbose`` is global on the root group: ``bpak -v add part ...`` rather
than per-command.
- The IDs of parts and metadata are positional arguments on every command that
addresses a single item. Where the C CLI accepted ``--part foo``, the Python
CLI takes ``foo`` positionally.
- Commands that produce binary data (``extract part``, ``extract meta``,
``show hash --binary``) refuse to write to stdout when stdout is a terminal.
Redirect to a file or pass ``--output PATH``.
- ``generate keystore --name`` validates its argument as a C identifier
(``[A-Za-z_][A-Za-z0-9_]*``) before emitting any generated C source.

Command reference
-----------------

.. code-block:: text

bpak [--version] [-v/--verbose...]

Package lifecycle
bpak create FILE [--hash {sha256|sha384|sha512}]
[--signature {prime256v1|secp384r1|secp521r1|rsa4096}]
[--force]
bpak compare FILE1 FILE2

Inspection
bpak show FILE # full package overview
bpak show meta FILE [ID] [--part-ref REF]
bpak show part FILE ID [--hash]
bpak show hash FILE [--binary] # header hash (Package.digest)

Content
bpak add part FILE ID --from PATH [--no-hash]
bpak add meta FILE ID (--from-string VAL | --from-file PATH)
[--encoder {uuid|integer|id}] [--part-ref REF]
bpak add key FILE ID --from PATH
bpak add merkle FILE ID --from PATH

bpak set meta FILE ID VALUE [--encoder {integer|id}] [--part-ref REF]
bpak set header FILE [--key-id ID] [--keystore-id ID]

bpak delete part FILE (ID | --all) [--keep-meta]
bpak delete meta FILE ID [--part-ref REF]

bpak extract part FILE ID [--output PATH]
bpak extract meta FILE ID [--output PATH] [--part-ref REF]

Signing
bpak sign FILE (--key PATH | --signature PATH)
bpak verify FILE (--key PATH | --keystore PATH)

Transport
bpak transport add FILE ID --encoder NAME --decoder NAME
bpak transport encode FILE --output PATH [--origin PATH]
bpak transport decode FILE --output PATH [--origin PATH]

Code generation
bpak generate id STRING
bpak generate keystore FILE --name NAME [--decorate]

Notable differences from the C CLI
----------------------------------

``show`` prints a single ``Header hash`` line in its overview output. The C
CLI's full ``bpak show`` additionally prints a ``Payload hash`` value. The
Python wrapper only exposes the header hash today; use the C ``bpak show``
binary when you need the payload hash.

``show hash`` prints the header hash. It replaces the overloaded
C-style ``-H`` / ``-B`` / ``-P`` flag combinations. For a part-level hash,
use ``bpak show part FILE ID --hash``.

``compare`` diffs part contents via ``Package.part_sha256`` on both sides
in addition to part-header fields. The previous Python CLI only compared
part *sizes*, so same-size-different-content parts were silently reported
as equal.

Migration from the previous Python CLI
--------------------------------------

+----------------------------------------------------+----------------------------------------------------------+
| Previous Python CLI | New Python CLI |
+====================================================+==========================================================+
| ``bpak create FILE -H sha256 -S prime256v1 -Y`` | ``bpak create FILE --hash sha256 --signature prime256v1 |
| | --force`` |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak add FILE -p fs -f rootfs.img`` | ``bpak add part FILE fs --from rootfs.img`` |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak add FILE -m version -s 1.0.0`` | ``bpak add meta FILE version --from-string 1.0.0`` |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak add FILE -p key --encoder key -f k.pem`` | ``bpak add key FILE key --from k.pem`` |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak add FILE -p fs --encoder merkle -f r.img`` | ``bpak add merkle FILE fs --from r.img`` |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak show FILE`` | ``bpak show FILE`` (unchanged shape; overview) |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak show FILE -m version`` | ``bpak show meta FILE version`` |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak show FILE -P fs`` | ``bpak show part FILE fs --hash`` |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak show FILE -H`` | ``bpak show hash FILE`` |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak show FILE -B`` | ``bpak show hash FILE --binary`` |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak set FILE -m version -s 2.0.0`` | ``bpak set meta FILE version 2.0.0`` |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak set FILE --key-id X --keystore-id Y`` | ``bpak set header FILE --key-id X --keystore-id Y`` |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak delete FILE -p fs`` | ``bpak delete part FILE fs`` |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak delete FILE -a`` | ``bpak delete part FILE --all`` |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak extract FILE -p fs -o fs.img`` | ``bpak extract part FILE fs --output fs.img`` |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak extract FILE -m version`` | ``bpak extract meta FILE version`` (stdout, non-TTY) |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak transport FILE --add --part fs`` | ``bpak transport add FILE fs --encoder ENC --decoder D`` |
| ``--encoder E --decoder D`` | |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak transport FILE --encode --output o.bpak`` | ``bpak transport encode FILE --output o.bpak`` |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak transport FILE --decode --output o.bpak`` | ``bpak transport decode FILE --output o.bpak`` |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak sign FILE -k priv.pem`` | ``bpak sign FILE --key priv.pem`` |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak verify FILE -k pub.pem`` | ``bpak verify FILE --key pub.pem`` |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak verify FILE -K keystore.bpak`` | ``bpak verify FILE --keystore keystore.bpak`` |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak generate id STRING`` | ``bpak generate id STRING`` (unchanged) |
+----------------------------------------------------+----------------------------------------------------------+
| ``bpak generate keystore FILE -n NAME`` | ``bpak generate keystore FILE --name NAME`` |
+----------------------------------------------------+----------------------------------------------------------+

Breaking changes (no compatibility shims)
-----------------------------------------

- All short flags that differ from the common ``-o`` / ``-v`` set are removed.
- ``-Y`` is replaced by ``--force`` on ``create``.
- ``show`` no longer overloads ``-p`` to mean "filter by part reference" when
``-m`` is given. Use ``--part-ref REF`` explicitly.
- ``add``, ``set``, ``delete``, and ``extract`` are split into two-level
subgroups (``part`` / ``meta`` / ``key`` / ``merkle`` / ``header``).
- ``transport`` subcommands replace the ``--add / --encode / --decode`` mode
flags.
19 changes: 6 additions & 13 deletions examples/python/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
# build image from bpak root folder
from python:slim
FROM python:slim

RUN apt-get update -y

RUN apt-get install -y gcc
RUN apt-get install -y pkgconf
RUN apt-get install -y autoconf-archive
RUN apt-get install -y libtool
RUN apt-get install -y make
RUN apt-get update -y && apt-get install -y \
gcc \
libmbedtls-dev \
liblzma-dev

COPY . .

RUN autoreconf -fi
RUN ./configure --enable-python-library --disable-dependency-tracking
RUN make
RUN make install
RUN ldconfig
RUN pip install .
79 changes: 79 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "bpak"
requires-python = ">=3.10"
dynamic = [
"version",
"description",
"readme",
"authors",
"license",
"classifiers",
"dependencies",
"scripts",
"urls",
]

[dependency-groups]
dev = [
"ruff>=0.6",
"mypy>=1.11",
]

[tool.ruff]
line-length = 100
extend-exclude = [
"docs",
"build",
]
target-version = "py310"

[tool.ruff.lint]
# See: https://docs.astral.sh/ruff/rules/ for details
select = ["ALL"]
ignore = [
"COM812", # Conflicts with the formatter
"ISC001", # Conflicts with the formatter
"PLE0605", # ruff does not handle += in __all__
"FBT", # don't care for these at the moment
"PT001", # https://github.com/astral-sh/ruff/issues/8796#issuecomment-1825907715
"PT023", # https://github.com/astral-sh/ruff/issues/8796#issuecomment-1825907715
"TRY003", # external message strings on ClickException raises
"EM101", # ditto: tolerate string-literal in exception constructors
"EM102", # ditto: tolerate f-string in exception constructors
"D203", # conflicts with D211 (pydocstyle pep257 convention)
"D213", # conflicts with D212 (pydocstyle pep257 convention)
"ERA001", # commented-out-code false positives
]

pyupgrade.keep-runtime-typing = true
pylint.max-args = 8

[tool.ruff.lint.per-file-ignores]
"python/bpak/__init__.py" = ["F401", "A004"]
"python/bpak/_bpak.pyi" = ["A001", "A002"]
"python/bpak/_cli/__init__.py" = ["E402", "PLC0415"]
"python/bpak/_cli/*.py" = ["S101"]
"test/**/*.py" = [
"S101", "T201", "ANN", "D", "INP001", "PLR2004",
"PLC0415", "E402", "I001", "S603", "S605", "S607", "S108",
]

[tool.ruff.lint.pydocstyle]
convention = "pep257"

[tool.ruff.format]
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"

[tool.mypy]
warn_return_any = true
exclude = [
"^build.*",
"^docs.*",
]
Loading
Loading