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
//! The `$MIDENUP_HOME` layout, in one place.
//!
//! Every path under `MIDENUP_HOME` is named by exactly one function here, so that `install` and
//! `uninstall` cannot disagree about where anything lives. A layout path spelled inline is a
//! second answer to that question, with nothing connecting it to this one.
//!
//! ```text
//! $MIDENUP_HOME/
//! |- state.json local installation state
//! |- publications/
//! | |- <channel>-<publication-id>/ immutable; named opaquely
//! | |- receipt.json
//! | |- bin/ lib/ etc/ opt/
//! |- toolchains/
//! | |- <channel> -> ../publications/<channel>-<publication-id>
//! | |- <network> -> <channel> one per network naming this channel
//! | |- default -> <channel> | <network>
//! |- var/
//! | |- <selector>/ mutable state, keyed by what the user selected:
//! | a network name, or a pinned version
//! |- opt -> toolchains/<active>/opt
//! ```
use ;
use crate::;
/// Local installation state: the sole logical authority on what is installed.
/// The last upstream manifest that was successfully fetched, cached verbatim.
///
/// Consulted only when a fetch fails: an operation that needs upstream can then proceed against a
/// copy that is known to have been real, and say that it is doing so, rather than failing outright
/// because a network was briefly unavailable.
/// The directory of `toolchains/<channel>` symlinks, plus the derived network links and `default`.
/// The stable name for a channel: a symlink into `publications/`.
///
/// This is what every consumer -- `PATH`, `MIDEN_SYSROOT`, `%lib`, `%etc` -- refers to, which is
/// what lets the publication behind it be replaced atomically.
/// A network's symlink: `toolchains/<network>` -> `<channel>`.
///
/// Records the last answer upstream gave about this network *that this machine acted on*. It is
/// deliberately not repointed at a channel that is not installed, which would leave it dangling;
/// `midenup update <network>` is what advances it.
/// Where installed trees live.
/// Mutable, component-owned state: `%var`. The Miden client's database lives here (`%var(data)`).
///
/// Outside the publication, because a publication is replaced wholesale on every change and this
/// must survive that.
///
/// **Keyed by the toolchain selector the user chose, not by the channel it resolves to.** A network
/// is a moving name, so `mainnet` and `testnet` are distinct stores even in the periods when both
/// name one channel -- which is the shipped default, and which mainnet accounts and testnet notes
/// must never be pooled by. The selector is also stable under a pointer move: when `mainnet`
/// advances to a new channel its store is still `var/mainnet`, so there is nothing to carry and no
/// window in which a pointer and a store disagree. A pinned `0.15.0` keys on the version, and that
/// too is the identity the user chose.
///
/// Nothing may move or delete this: not install, not update, not republication, not a pointer move.
/// The three exceptions are explicit and are the whole list -- `uninstall --purge`; channel
/// migration, where the channel a pinned user selected ceases to exist and their data has to follow
/// it; and the one-time conversion of a pre-network home
/// ([`crate::migrate_networks`]), which hands the default network the single store such a home kept
/// under its channel's version.
/// Where an in-flight physical operation records its intent.
///
/// Holds at most one entry, and only while an operation is running: its presence at startup means
/// a previous one was interrupted.
/// One immutable publication.
///
/// The channel is in the name for human legibility only; the publication id is what makes it
/// unique. Nothing may parse identity back out of this path.