1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//! The Python bindings must not cost the Rust crate anything (P0, D-098).
//!
//! Adding `bindings/python` as a workspace member is safe only because of a
//! specific Cargo behaviour: when a workspace root is *itself* a package,
//! unspecified `default-members` is that package alone. Verified with
//! `cargo metadata` — `workspace_default_members` reports `macrame-db` and
//! nothing else — which is what keeps `cargo test`, `cargo clippy
//! --all-targets`, `cargo check --all-features` and `cargo publish` scoped to
//! this crate, with pyo3 compiled only when something names it.
//!
//! That property is one line away from being lost, in two different ways, and
//! **neither failure is loud**. Adding `default-members` makes every `cargo
//! test` build pyo3 and the libSQL amalgamation a second time; turning the root
//! into a virtual manifest changes what bare cargo commands mean everywhere.
//! Both would be noticed as "the build got slow" or "publish broke", weeks
//! later. These are the tripwires.
//!
//! # Why this file only reads the root manifest
//!
//! It would be natural to also assert that `pyproject.toml`'s `module-name`
//! agrees with `[lib] name` in `bindings/python/Cargo.toml`, since a mismatch
//! there is an `ImportError` at first import and nothing catches it at build
//! time. **That check cannot live here**, and the reason is the property this
//! file exists to protect: Cargo excludes a subdirectory carrying its own
//! `Cargo.toml`, and the `exclude` list drops `pyproject.toml`, so neither file
//! is in the `.crate` tarball. An `include_str!` of either compiles here and is
//! broken for everyone who gets the crate from crates.io.
//!
//! **And `cargo publish` would not catch it**, which makes the trap worse
//! rather than better: the verify step *builds* the unpacked tarball, it does
//! not test it, so a missing file referenced only from `tests/` sails through a
//! clean `--dry-run` and surfaces as a compile error in somebody else's
//! `cargo test`. Same hazard as the one that kept the crate at the repo root —
//! `tests/` reaches `docs/` and `src/` exactly this way, and those are in the
//! tarball only because the package root is the repo root.
//!
//! So that agreement is asserted where it can be — `tests_py/test_packaging.py`
//! proves it empirically by importing the built wheel, which is a better test
//! of it anyway.
const MANIFEST: &str = include_str!;
/// Lines with comments and indentation stripped, so a `#`-commented example of
/// a key cannot satisfy or trip an assertion about the key itself.
/// The root is still a package, not a virtual manifest.
///
/// The single change that would undo everything else here. A virtual root has
/// no default package, so `default-members` falls back to *all* members and
/// every bare cargo command picks up the binding; `cargo publish` at the root
/// stops having a package to publish at all.
/// `default-members` stays absent, which is what scopes bare cargo commands.
///
/// Spelling it out — even as `default-members = ["."]`, which looks harmless
/// and equivalent — is worth failing on: the moment the key exists, the next
/// person to add a member has an obvious-looking place to add it, and the
/// separation is gone with no other symptom than a slower build.
/// The binding is a member, and it is the only one.
///
/// Pinned as a set rather than as a substring so that adding a second member
/// is a decision someone makes here, in the file that explains what membership
/// costs, rather than a line that slides in.
/// The Python tree stays out of the `.crate` tarball.
///
/// The package root is the repo root — deliberately, since `tests/` reaches
/// `docs/` and `src/` through `include_str!` — so *everything* at the root is
/// packaged unless excluded. Shipping `python/` and `pyproject.toml` inside a
/// crates.io tarball is not an error and produces no warning; it just quietly
/// puts a second, unbuildable copy of the wheel's packaging in front of anyone
/// reading the crate.
///
/// `bindings/` is deliberately not in the list and does not need to be: Cargo
/// skips a subdirectory carrying its own `Cargo.toml`. Confirmed with
/// `cargo package --list`, which reports the same 105 files and the same
/// top-level entries as before the workspace existed.