summaryrefslogtreecommitdiffstats
path: root/src/config/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/config/mod.rs')
-rw-r--r--src/config/mod.rs32
1 files changed, 31 insertions, 1 deletions
diff --git a/src/config/mod.rs b/src/config/mod.rs
index 0aaccd6..b8a2ba0 100644
--- a/src/config/mod.rs
+++ b/src/config/mod.rs
@@ -122,7 +122,7 @@ pub(crate) const OPTIONS: &[OptionSpec] = &[
Kind::List,
"NAME,[NAME...]",
None,
- "Override checks that otherwise refuse to start: true for all, or names: swarmId (a document to start on is of another swarm than the state file remembers), badDocumentFile (an unusable document file: moved aside, start without it), replaceDocumentFile (recover-from while the document file holds a document).",
+ "Override checks that otherwise refuse to start (command line only: it is for one start): true for all, or names: swarmId (a document to start on is of another swarm than the state file remembers), badDocumentFile (an unusable document file: moved aside, start without it), replaceDocumentFile (recover-from while the document file holds a document).",
),
option(
"recover-from",
@@ -902,6 +902,16 @@ pub(crate) fn load() -> Result<Loaded> {
}
fn resolve(merged: Layer, files: Vec<PathBuf>) -> Result<Loaded> {
+ // An override is for the start it was given for; in a file it would silently apply
+ // to every start, e.g. replacing the document file with a backup each time.
+ if let Some(entry) = merged.get("force").filter(|entry| {
+ !entry.value.is_null() && matches!(entry.origin.provenance, Provenance::File(_))
+ }) {
+ bail!(
+ "force can only be given on the command line: it overrides checks for one start, and in a file ({}) it would apply to every start",
+ entry.origin
+ );
+ }
// Unset options take their defaults.
let object: serde_json::Map<String, JsonValue> = merged
.iter()
@@ -958,6 +968,26 @@ mod tests {
}
#[test]
+ fn force_only_on_the_command_line() {
+ let from = |provenance| Entry {
+ value: json!(["swarmId"]),
+ origin: Origin {
+ provenance,
+ unset: false,
+ imports: Vec::new(),
+ },
+ };
+ let mut merged = layer(json!({ "htpasswd": "u" }));
+ merged.insert(
+ "force".to_owned(),
+ from(Provenance::File(PathBuf::from("continuum.toml"))),
+ );
+ assert!(resolve(merged.clone(), Vec::new()).is_err());
+ merged.insert("force".to_owned(), from(Provenance::Argument));
+ assert!(resolve(merged, Vec::new()).is_ok());
+ }
+
+ #[test]
fn options_and_settings_agree() {
// Every option is a Settings field, and every field an option.
let loaded = resolve(layer(json!({ "htpasswd": "users" })), Vec::new()).unwrap();