new: give wizard select labels their own separator
This commit is contained in:
+38
-9
@@ -51,6 +51,26 @@ pub const KNOWN_LICENSES: [&str; 9] = [
|
|||||||
"ISC",
|
"ISC",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/// Labels of the interactive `select` questions. `prompt::select` renders
|
||||||
|
/// `> <label><answer>` verbatim — unlike [`prompt::text`], it appends no
|
||||||
|
/// formatting of its own — so each label carries its own separator:
|
||||||
|
/// field-style prompts end with `": "`, question-style ones with `"? "`.
|
||||||
|
const LANGUAGE_LABEL: &str = "Which language/build system is your program using? ";
|
||||||
|
const SOURCE_LABEL: &str = "Where is the source code? ";
|
||||||
|
const LICENSE_LABEL: &str = "License: ";
|
||||||
|
const DIST_LABEL: &str = "Target distribution: ";
|
||||||
|
const SERIES_LABEL: &str = "Target series: ";
|
||||||
|
|
||||||
|
/// All select labels, so the separator test can check them in one place.
|
||||||
|
#[cfg(test)]
|
||||||
|
const SELECT_LABELS: [&str; 5] = [
|
||||||
|
LANGUAGE_LABEL,
|
||||||
|
SOURCE_LABEL,
|
||||||
|
LICENSE_LABEL,
|
||||||
|
DIST_LABEL,
|
||||||
|
SERIES_LABEL,
|
||||||
|
];
|
||||||
|
|
||||||
/// Run the `pkh new` flow: the wizard on an interactive terminal, plain
|
/// Run the `pkh new` flow: the wizard on an interactive terminal, plain
|
||||||
/// [`options::resolve`] otherwise (and with `--defaults`).
|
/// [`options::resolve`] otherwise (and with `--defaults`).
|
||||||
pub async fn run(cli: NewCli) -> Result<NewOptions, Box<dyn Error>> {
|
pub async fn run(cli: NewCli) -> Result<NewOptions, Box<dyn Error>> {
|
||||||
@@ -154,7 +174,7 @@ async fn run_wizard(mut cli: NewCli) -> Result<NewOptions, Box<dyn Error>> {
|
|||||||
} else {
|
} else {
|
||||||
SOURCE_HERE
|
SOURCE_HERE
|
||||||
};
|
};
|
||||||
let answer = select_from("Where is the source code?", &options, default, |answer| {
|
let answer = select_from(SOURCE_LABEL, &options, default, |answer| {
|
||||||
options.contains(&answer.to_string())
|
options.contains(&answer.to_string())
|
||||||
})?;
|
})?;
|
||||||
if answer == SOURCE_HERE {
|
if answer == SOURCE_HERE {
|
||||||
@@ -234,7 +254,7 @@ async fn run_wizard(mut cli: NewCli) -> Result<NewOptions, Box<dyn Error>> {
|
|||||||
.or_else(|| detect::sniff_license(&detect_dir));
|
.or_else(|| detect::sniff_license(&detect_dir));
|
||||||
let (default, custom_default) = license_question_default(detected.as_deref());
|
let (default, custom_default) = license_question_default(detected.as_deref());
|
||||||
let options = license_menu();
|
let options = license_menu();
|
||||||
let answer = select_from("License", &options, &default, |answer| {
|
let answer = select_from(LICENSE_LABEL, &options, &default, |answer| {
|
||||||
options.contains(&answer.to_string())
|
options.contains(&answer.to_string())
|
||||||
})?;
|
})?;
|
||||||
if answer == LICENSE_OTHER {
|
if answer == LICENSE_OTHER {
|
||||||
@@ -304,7 +324,7 @@ async fn run_wizard(mut cli: NewCli) -> Result<NewOptions, Box<dyn Error>> {
|
|||||||
} else {
|
} else {
|
||||||
"ubuntu".to_string()
|
"ubuntu".to_string()
|
||||||
};
|
};
|
||||||
let answer = select_from("Target distribution", &options, &default, |answer| {
|
let answer = select_from(DIST_LABEL, &options, &default, |answer| {
|
||||||
answer == "ubuntu" || answer == "debian"
|
answer == "ubuntu" || answer == "debian"
|
||||||
})?;
|
})?;
|
||||||
cli.dist = Some(answer);
|
cli.dist = Some(answer);
|
||||||
@@ -318,7 +338,7 @@ async fn run_wizard(mut cli: NewCli) -> Result<NewOptions, Box<dyn Error>> {
|
|||||||
if cli.series.is_none() {
|
if cli.series.is_none() {
|
||||||
match crate::distro_info::get_ordered_series_name(&dist).await {
|
match crate::distro_info::get_ordered_series_name(&dist).await {
|
||||||
Ok(series) if !series.is_empty() => {
|
Ok(series) if !series.is_empty() => {
|
||||||
let answer = prompt::select("Target series", &series, &series[0])?;
|
let answer = prompt::select(SERIES_LABEL, &series, &series[0])?;
|
||||||
cli.series = Some(answer);
|
cli.series = Some(answer);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -552,11 +572,7 @@ fn license_question_default(probe_license: Option<&str>) -> (String, String) {
|
|||||||
/// identifier) is answered — the selector allows typing arbitrary text.
|
/// identifier) is answered — the selector allows typing arbitrary text.
|
||||||
fn select_template(options: &[String], default: &str) -> Result<TemplateId, Box<dyn Error>> {
|
fn select_template(options: &[String], default: &str) -> Result<TemplateId, Box<dyn Error>> {
|
||||||
loop {
|
loop {
|
||||||
let answer = prompt::select(
|
let answer = prompt::select(LANGUAGE_LABEL, options, default)?;
|
||||||
"Which language/build system is your program using?",
|
|
||||||
options,
|
|
||||||
default,
|
|
||||||
)?;
|
|
||||||
match TemplateId::from_label(&answer) {
|
match TemplateId::from_label(&answer) {
|
||||||
Some(id) => return Ok(id),
|
Some(id) => return Ok(id),
|
||||||
None => log::warn!(
|
None => log::warn!(
|
||||||
@@ -945,4 +961,17 @@ mod tests {
|
|||||||
assert!(required_answer("x")("").is_err());
|
assert!(required_answer("x")("").is_err());
|
||||||
assert!(required_answer("x")("ok").is_ok());
|
assert!(required_answer("x")("ok").is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn select_labels_carry_their_own_separator() {
|
||||||
|
// prompt::select renders `> <label><answer>` verbatim; a label
|
||||||
|
// without a trailing separator glues the answer to the prompt
|
||||||
|
// (regression: the wizard once rendered "> LicenseMIT").
|
||||||
|
for label in SELECT_LABELS {
|
||||||
|
assert!(
|
||||||
|
label.ends_with(": ") || label.ends_with("? "),
|
||||||
|
"select label {label:?} lacks a trailing separator"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user