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
use std::collections::BTreeMap;
use clap::{Parser, ValueEnum};
use crate::{manifest::Component, profile::Profile, resolve::Intent, toolchain::Patch};
/// How an installation affects the selection persisted for a channel.
///
/// Installing and *recording what the user wants* are separate concerns. A toolchain-file
/// activation installs a narrowed set but must only ever add to the recorded selection; a direct
/// install records exactly what was asked for, and is allowed to shrink it.
#[derive(Debug, Clone)]
pub enum IntentUpdate {
/// Replace the recorded selection. A direct `midenup install`.
Replace(Intent),
/// Merge into the recorded selection, never removing. Toolchain-file activation.
Union(Intent),
/// Leave the recorded selection alone. An update re-resolves existing intent rather than
/// restating it.
Preserve,
}
pub const DEFAULT_USER_DATA_DIR: &str = "XDG_DATA_HOME";
/// Optional installation settings.
#[derive(Default, Debug, Parser, Clone)]
pub struct InstallationOptions {
/// The toolchain profile to install
#[arg(long, short, default_value = "minimal")]
pub profile: Profile,
/// Components to install in addition to the profile's members
#[arg(long = "component", value_name = "COMPONENT")]
pub components: Vec<String>,
/// Components whose files must be re-acquired rather than carried forward from the previous
/// publication.
///
/// Empty for a fresh install: there is nothing to carry forward. An update fills it with the
/// components it determined have actually changed. The install itself adds every component
/// whose patch differs from the installed one.
#[arg(skip)]
pub stale: Vec<String>,
/// Components to record exactly as they are already installed, rather than as upstream
/// describes them.
///
/// Only `--path-update=off`/`interactive` produces these. Recording the upstream definition
/// for a component the user declined to update would mark it up to date without having
/// rebuilt it, so the next update would stop offering.
#[arg(skip)]
pub held_back: Vec<Component>,
/// How this installation affects the recorded selection.
///
/// `None` means "derive a `Replace` from the profile and components given on the command
/// line", which is what a direct `midenup install` wants. Callers that are not the CLI set
/// this explicitly.
#[arg(skip)]
pub intent_update: Option<IntentUpdate>,
/// The network the user named, which `toolchains/<network>` will point at the installed
/// channel. `None` when a version was requested directly: no network link is written.
#[arg(skip)]
pub network: Option<String>,
/// The toolchain file patches applied to the channel being installed.
#[arg(skip)]
pub patches: BTreeMap<String, Patch>,
}
/// Optional update settings.
#[derive(Default, Debug, Parser, Clone, Copy)]
pub struct UpdateOptions {
/// Determines how midenup will handle updates for components installed from a path
#[clap(value_enum, short, long, default_value = "off")]
pub path_update: PathUpdate,
}
/// Represents the behavior chosen when a component being updated was installed from a path
#[derive(Default, Debug, Parser, Clone, Copy, ValueEnum)]
pub enum PathUpdate {
/// Skip updating the component
#[default]
Off,
/// Rebuild the component from its source whenever the source or its definition changed
All,
/// Prompt the user to determine how to proceed
Interactive,
}
impl From<InstallationOptions> for UpdateOptions {
fn from(_value: InstallationOptions) -> Self {
UpdateOptions::default()
}
}
impl From<UpdateOptions> for InstallationOptions {
fn from(_value: UpdateOptions) -> Self {
InstallationOptions {
profile: Profile::Minimal,
components: Vec::new(),
stale: Vec::new(),
held_back: Vec::new(),
// An update re-resolves what is already recorded; it does not restate intent.
intent_update: Some(IntentUpdate::Preserve),
network: None,
patches: BTreeMap::new(),
}
}
}