|
| 1 | +Architecture Overview |
| 2 | +===================== |
| 3 | + |
| 4 | +Fromager rebuilds complete dependency trees of Python wheels from |
| 5 | +source. This document maps the major subsystems and how they connect. |
| 6 | + |
| 7 | +.. seealso:: |
| 8 | + |
| 9 | + :doc:`bootstrap-vs-build` explains the two operating modes. |
| 10 | + :doc:`bootstrapper-architecture` details the bootstrap engine. |
| 11 | + :doc:`resolver-architecture` covers version resolution. |
| 12 | + :doc:`hooks-and-overrides` describes the two plugin systems. |
| 13 | + :doc:`package-settings` explains the settings layering. |
| 14 | + |
| 15 | +Major Subsystems |
| 16 | +---------------- |
| 17 | + |
| 18 | +.. code-block:: text |
| 19 | +
|
| 20 | + ┌───────────────────────────────────────────────────────┐ |
| 21 | + │ CLI & Context │ |
| 22 | + │ command parsing, WorkContext, settings │ |
| 23 | + └───────────────────────────┬───────────────────────────┘ |
| 24 | + │ |
| 25 | + ▼ |
| 26 | + ┌───────────────────────────────────────────────────────┐ |
| 27 | + │ Bootstrap Engine │ |
| 28 | + │ iterative DFS loop over phase pipeline │ |
| 29 | + │ │ |
| 30 | + │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ |
| 31 | + │ │ Resolution │ │ Source │ │ Build │ │ |
| 32 | + │ │ PyPI, graph │ │ Acquisition │ │ System │ │ |
| 33 | + │ │ git URLs │ │ download, │ │ isolated │ │ |
| 34 | + │ │ │ │ patch, Rust │ │ envs, │ │ |
| 35 | + │ │ │ │ vendor │ │ wheels │ │ |
| 36 | + │ └─────────────┘ └─────────────┘ └─────────────┘ │ |
| 37 | + └───────────────────────────┬───────────────────────────┘ |
| 38 | + │ |
| 39 | + ┌────────────────┴────────────────┐ |
| 40 | + ▼ ▼ |
| 41 | + ┌──────────────────┐ ┌──────────────────┐ |
| 42 | + │ Per-Package │ │ Global Hooks │ |
| 43 | + │ Overrides │ │ post_bootstrap, │ |
| 44 | + │ (stevedore) │ │ post_build │ |
| 45 | + └──────────────────┘ └──────────────────┘ |
| 46 | +
|
| 47 | +The **bootstrap engine** orchestrates the other subsystems. For each |
| 48 | +package it resolves a version, downloads the source, builds a wheel, |
| 49 | +and recurses into dependencies. **Resolution**, **source acquisition**, |
| 50 | +and **build** are called as needed during each phase of the pipeline. |
| 51 | + |
| 52 | +**Extension points** intercept the pipeline at specific steps, allowing |
| 53 | +per-package overrides (e.g. custom download logic) and global hooks |
| 54 | +(e.g. post-build notifications). |
| 55 | + |
| 56 | +Data Flow |
| 57 | +--------- |
| 58 | + |
| 59 | +A ``fromager bootstrap`` invocation flows through the subsystems in |
| 60 | +this order: |
| 61 | + |
| 62 | +.. code-block:: text |
| 63 | +
|
| 64 | + requirements.txt |
| 65 | + │ |
| 66 | + ▼ |
| 67 | + ┌─ CLI & Context ───────────────────────────────────────┐ |
| 68 | + │ parse args, load settings, create WorkContext │ |
| 69 | + └───────────────────────────┬───────────────────────────┘ |
| 70 | + │ |
| 71 | + ▼ |
| 72 | + ┌─ Bootstrap Engine ────────────────────────────────────┐ |
| 73 | + │ for each package (iterative DFS): │ |
| 74 | + │ resolve version ──► download source │ |
| 75 | + │ ──► build wheel ──► extract deps │ |
| 76 | + │ ──► recurse into dependencies │ |
| 77 | + └───────────────────────────┬───────────────────────────┘ |
| 78 | + │ |
| 79 | + ▼ |
| 80 | + ┌── Outputs ──┐ |
| 81 | + │ graph.json │ |
| 82 | + │ build-order │ |
| 83 | + │ wheels/ │ |
| 84 | + │ constraints │ |
| 85 | + └─────────────┘ |
| 86 | +
|
| 87 | +The ``build`` command uses the same source acquisition and build |
| 88 | +subsystems but skips resolution and recursion -- it compiles a |
| 89 | +single package given a name, version, and source URL. |
| 90 | + |
| 91 | +Extension Points |
| 92 | +---------------- |
| 93 | + |
| 94 | +Fromager has two plugin systems, both using stevedore: |
| 95 | + |
| 96 | +.. list-table:: |
| 97 | + :header-rows: 1 |
| 98 | + :widths: 25 35 40 |
| 99 | + |
| 100 | + * - System |
| 101 | + - Scope |
| 102 | + - When it fires |
| 103 | + * - **Per-package overrides** |
| 104 | + - One package |
| 105 | + - At each pipeline step (download, build sdist, build wheel, |
| 106 | + dependency extraction, etc.) |
| 107 | + * - **Global hooks** |
| 108 | + - All packages |
| 109 | + - After specific events (``post_bootstrap``, ``post_build``, |
| 110 | + ``prebuilt_wheel``) |
| 111 | + |
| 112 | +Per-package overrides replace the default implementation of a step for |
| 113 | +a specific package. Global hooks run in addition to the default logic |
| 114 | +for every package. See :doc:`hooks-and-overrides` for the full |
| 115 | +breakdown. |
| 116 | + |
| 117 | +Key Data Structures |
| 118 | +------------------- |
| 119 | + |
| 120 | +Four data structures flow between subsystems: |
| 121 | + |
| 122 | +.. list-table:: |
| 123 | + :header-rows: 1 |
| 124 | + :widths: 30 70 |
| 125 | + |
| 126 | + * - Structure |
| 127 | + - Role |
| 128 | + * - ``WorkContext`` |
| 129 | + - Central configuration and state: directory paths, constraints, |
| 130 | + dependency graph, settings, and variant info. Passed to every |
| 131 | + subsystem. |
| 132 | + * - ``DependencyGraph`` |
| 133 | + - In-memory directed graph of all resolved dependencies. |
| 134 | + Serialized to ``graph.json``. Thread-safe. |
| 135 | + * - ``PackageBuildInfo`` |
| 136 | + - Per-package build configuration: environment variables, patches, |
| 137 | + resolver settings, and build options. Derived from settings |
| 138 | + files. |
| 139 | + * - ``BuildEnvironment`` |
| 140 | + - Isolated virtual environment for building one package. Created |
| 141 | + per source build, cleaned up after completion. |
0 commit comments