Skip to content

About

Escape the fragile mess of pre-venv shell scripts with a pure python bootstrapper: single-touch, zero-args, self-contained, no-deps, cross-platform, testable init logic using standard tools to run apps in a custom environment isolated per repository clone

Topics

Resources

Stars

23 stars

Watchers

2 watching

Forks

Latest commit

 

History

139 Commits

Folders and files

Repository files navigation

PyPI version Python versions

GitHub test min python job GitHub test med python job GitHub test max python job GitHub test compatibility job GitHub test invoke condition job GitHub lint job GitHub doc job code coverage

protoprimer

... eliminates shell scripts right off the bootstrap:

logo shell snippet

Want your users to run software isolated in a git repo after a single zero-argument command?

./prime

See the Intro doc.

TL;DR

protoprimer employs ubiquitous python for version pinning to provide a robust alternative to shell:

  • First, a wild python version found in PATH executes a shim that invokes protoprimer.
  • Last, protoprimer executes user code by the required python version from the configured venv.

Compare:

%%{init: {"look": "handDrawn", "theme": "neutral"}}%%
flowchart TD;
    heavy_minus["➖ del `*.sh`"];
    shell_exec["any<br>`shell`<br>executable"];
    subgraph sh[" "]
        sh_entry_script["&nbsp;`shell`<br>entry script<br>like<br>`prime`"];
        embedded_code["re-invented<br>ad-hoc<br>non-modular<br>`shell` hacks"];
    end

    heavy_plus["➕ add `*.py`"];
    python_exec["any<br>`python`<br>executable"];
    subgraph py[" "]
        py_entry_script["&nbsp;`python`<br>entry script<br>like<br>`prime`"];
        py_bootstrap_code["tested<br>bootstrap code<br>from<br>`protoprimer`"];
    end

    pinned_python["<br>user code<br>in<br>pinned<br>`python`<br>with<br>dependencies<br>&nbsp;"];

    invis_block[ ];

    heavy_minus ~~~ shell_exec;
    shell_exec --runs--> sh_entry_script;
    sh_entry_script --with--> embedded_code;

    heavy_plus ~~~ python_exec;
    python_exec --runs--> py_entry_script;
    py_entry_script --with--> py_bootstrap_code;

    embedded_code --bootstraps--> pinned_python;
    py_bootstrap_code --bootstraps--> pinned_python;

    pinned_python ~~~ invis_block;

    style heavy_minus fill:none,stroke:none;
    style heavy_plus fill:none,stroke:none;

    style sh fill:none;
    style py fill:none;

    style invis_block fill:none,stroke:none;
Loading

It works without shebang for venv to avoid hardcoding absolute paths and keep repo clones relocatable.

Direct usage

  • Bootstrap (default env):

    ./prime
    
  • Bootstrap (special env):

    ./prime --env dst/special_env
    
  • Run some app without venv activation:

    ./some_app
    
and more...
  • From scratch: re-create venv, re-solve and re-install deps, re-pin versions:

    ./prime reset
    
  • Evaluate the effective config:

    ./prime eval
    
  • Start an interactive shell with an activated venv:

    ./prime shell
    
  • Run a function from a module in venv:

    ./prime start "some_module:some_func"
    
  • Run a function from a module in venv with some args:

    ./prime start "some_module:some_func" -- some args
    

Initial integration

See the Tutorial doc.

You need to "seed" your repo with a copy of the proto_kernel.py script:

%%{init: {"look": "handDrawn", "theme": "neutral"}}%%
graph LR;

    install_link["<b>1 x install:</b>"]
    github_web["<br>from github.com<br>`protoprimer`<br>repo"]

    bootstrap_link["<b>N x bootstrap:</b>"];
    pypi_web["<br>from pypi.org<br>`protoprimer`<br>package"]

    client_repo["client repo<br>with<br><b>own copy</b><br>of<br>`proto_kernel.py`"];

    install_link ~~~ github_web;
    github_web --manual copy--> client_repo;

    bootstrap_link ~~~ pypi_web;
    pypi_web --auto update--> client_repo;

    style install_link fill:none,stroke:none;
    style bootstrap_link fill:none,stroke:none;
Loading
  • Copy (one time):

    Commit your own copy next to pyproject.toml:

    ./
    ├── proto_kernel.py    <--- own copy
    ├── pyproject.toml
    └── *
    

    The location, name, and details can be changed through optional config.

First examples

Minimal bootstrap invoked via boot_env

This entry_script extends the bootstrap sequence via the cmd_boot_env_example script:

./cmd/boot_env_example
proto_kernel.boot_env triggers the bootstrap process before invoking a user function:
# ./cmd/boot_env_example:
# ...
proto_kernel.boot_env(
    # module_name:function_name
    "local_doc.cmd_boot_env_example:custom_boot_env_main"
)

See Boot env.

Minimal application invoked via start_app

This entry_script invokes the cmd_start_app_example script:

./cmd/start_app_example
proto_kernel.start_app delegates execution to a user function:
# ./cmd/start_app_example:
# ...
proto_kernel.start_app(
    # module_name:function_name
    "local_doc.cmd_start_app_example:custom_start_app_main"
)

See Start app.

Main terms

See the Dictionary.

Any code designed to be executed by an arbitrary (wild) python version is called proto_code.

In short, proto_code is what runs outside venv (before switching into it).

Your own copy of proto_kernel.py is an example of proto_code.

It implements in-flight python runtime switching - the hard part provided by protoprimer.

An entry_script is also proto_code - a shim to invoke proto_kernel.

It is a convenient wrapper around a venv function - the easy (generatable) part, as it only delegates:

./cmd/boot_env_example
./cmd/start_app_example

Entry functions

There are two primary entry functions - see details in boot_vs_start:

Function: boot_env start_app
Purpose: extend the default bootstrap
with custom steps
run an arbitrary script
from venv with the required python
Cardinality: one script per project many scripts per project
Assumes: venv is not ready venv is ready
Example: ./cmd/boot_env_example ./cmd/start_app_example

Docs

About

Escape the fragile mess of pre-venv shell scripts with a pure python bootstrapper: single-touch, zero-args, self-contained, no-deps, cross-platform, testable init logic using standard tools to run apps in a custom environment isolated per repository clone

Topics

Resources

Stars

23 stars

Watchers

2 watching

Forks

Releases

Used by

Contributors

Languages