new: add interactive wizard and remaining ecosystem templates
This commit is contained in:
+51
-12
@@ -19,9 +19,8 @@ use crate::new::detect::{self, Detection};
|
||||
/// Build systems / project kinds `pkh new` knows about.
|
||||
///
|
||||
/// The identifiers are stable CLI surface: `--lang` accepts every variant,
|
||||
/// even the ones that have no template implementation yet (those fail at
|
||||
/// scaffold time with a "not implemented yet" error instead of a parse
|
||||
/// error, so scripts written today keep working once they land).
|
||||
/// and every variant has a template implementation registered in
|
||||
/// [`crate::new::templates`].
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum TemplateId {
|
||||
/// Rust project (`Cargo.toml`)
|
||||
@@ -93,10 +92,27 @@ impl TemplateId {
|
||||
})
|
||||
}
|
||||
|
||||
/// Whether a template implementation (and therefore scaffolding) exists
|
||||
/// for this id. The remaining templates land with the follow-up work.
|
||||
pub fn implemented(&self) -> bool {
|
||||
matches!(self, TemplateId::Shell | TemplateId::Empty)
|
||||
/// Human-readable menu label of this template, as offered by the wizard
|
||||
/// language question (and reused in the summary screen).
|
||||
pub fn display_name(&self) -> &'static str {
|
||||
match self {
|
||||
TemplateId::Rust => "Rust (Cargo.toml)",
|
||||
TemplateId::Python => "Python (pyproject.toml / setup.py)",
|
||||
TemplateId::Meson => "C/C++ (Meson)",
|
||||
TemplateId::Cmake => "C/C++ (CMake)",
|
||||
TemplateId::Autotools => "C/C++ (Autotools)",
|
||||
TemplateId::Go => "Go module",
|
||||
TemplateId::Shell => "Shell script / single interpreted file",
|
||||
TemplateId::Makefile => "Generic (Makefile)",
|
||||
TemplateId::Empty => "Metapackage / empty base (no build system)",
|
||||
}
|
||||
}
|
||||
|
||||
/// The template whose menu label (or CLI identifier) is `label`.
|
||||
pub fn from_label(label: &str) -> Option<TemplateId> {
|
||||
TemplateId::all()
|
||||
.into_iter()
|
||||
.find(|id| id.display_name() == label || id.as_str() == label)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,6 +246,17 @@ pub struct NewOptions {
|
||||
pub native: bool,
|
||||
/// Initialize a git repository (gitignores are written regardless).
|
||||
pub git: bool,
|
||||
/// Write the autopkgtest smoke test (`debian/tests/control` +
|
||||
/// `debian/tests/smoke`) running `<command> --help`/`--version`.
|
||||
/// Wizard-only extra, off by default.
|
||||
pub autopkgtest: bool,
|
||||
/// Add `pkg-config` to Build-Depends (the meson/cmake opt-in question;
|
||||
/// most such projects resolve their dependencies through it).
|
||||
/// Wizard-only extra, off by default.
|
||||
pub pkg_config: bool,
|
||||
/// Contents of a `debian/watch` release watcher (GitHub/GitLab tarball
|
||||
/// template). Wizard-only extra, off by default.
|
||||
pub watch: Option<String>,
|
||||
}
|
||||
|
||||
impl NewOptions {
|
||||
@@ -568,7 +595,8 @@ pub async fn resolve(cli: NewCli) -> Result<NewOptions, String> {
|
||||
if !missing.is_empty() {
|
||||
return Err(format!(
|
||||
"Missing required answers (use --defaults to take every default, \
|
||||
or answer interactively once the wizard lands):\n - {}",
|
||||
or re-run pkh new on an interactive terminal to answer the \
|
||||
wizard):\n - {}",
|
||||
missing.join("\n - ")
|
||||
));
|
||||
}
|
||||
@@ -647,6 +675,9 @@ pub async fn resolve(cli: NewCli) -> Result<NewOptions, String> {
|
||||
depends,
|
||||
native: cli.native,
|
||||
git: cli.git,
|
||||
autopkgtest: false,
|
||||
pkg_config: false,
|
||||
watch: None,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -671,12 +702,17 @@ mod tests {
|
||||
fn template_ids_roundtrip() {
|
||||
for id in TemplateId::all() {
|
||||
assert_eq!(TemplateId::parse(id.as_str()).unwrap(), id);
|
||||
// Every id resolves from its menu label too, and labels are
|
||||
// unique.
|
||||
assert_eq!(TemplateId::from_label(id.display_name()), Some(id));
|
||||
}
|
||||
assert!(TemplateId::parse("cobol").is_err());
|
||||
// Every id is accepted by the parser; only some are implemented.
|
||||
assert!(!TemplateId::Rust.implemented());
|
||||
assert!(TemplateId::Shell.implemented());
|
||||
assert!(TemplateId::Empty.implemented());
|
||||
assert_eq!(
|
||||
TemplateId::from_label("Rust (Cargo.toml)"),
|
||||
Some(TemplateId::Rust)
|
||||
);
|
||||
assert_eq!(TemplateId::from_label("rust"), Some(TemplateId::Rust));
|
||||
assert_eq!(TemplateId::from_label("nope"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -754,6 +790,9 @@ mod tests {
|
||||
depends: Vec::new(),
|
||||
native: false,
|
||||
git: false,
|
||||
autopkgtest: false,
|
||||
pkg_config: false,
|
||||
watch: None,
|
||||
};
|
||||
assert_eq!(opts.full_version(), "0.1.0-1");
|
||||
assert_eq!(
|
||||
|
||||
Reference in New Issue
Block a user