Skip to content

Commit 59b2125

Browse files
authored
Merge pull request #1872 from itowlson/template-app-name-first
Changes to the `spin new` experience
2 parents c2bde92 + d9ed79b commit 59b2125

File tree

3 files changed

+35
-7
lines changed

3 files changed

+35
-7
lines changed

crates/e2e-testing/src/spin.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,14 @@ pub fn new_app<'a>(
3030
mut args: Vec<&'a str>,
3131
) -> Result<Output> {
3232
let basedir = utils::testcases_base_dir();
33-
let mut cmd = vec!["spin", "new", template_name, app_name, "--accept-defaults"];
33+
let mut cmd = vec![
34+
"spin",
35+
"new",
36+
app_name,
37+
"-t",
38+
template_name,
39+
"--accept-defaults",
40+
];
3441
if !args.is_empty() {
3542
cmd.append(&mut args);
3643
}

crates/templates/src/interaction.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ impl InteractionStrategy for Interactive {
4242
fn allow_generate_into(&self, target_dir: &Path) -> Cancellable<(), anyhow::Error> {
4343
if !is_directory_empty(target_dir) {
4444
let prompt = format!(
45-
"{} already contains other files. Generate into it anyway?",
45+
"Directory '{}' already contains other files. Generate into it anyway?",
4646
target_dir.display()
4747
);
4848
match crate::interaction::confirm(&prompt) {

src/commands/new.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@ use crate::opts::{APP_MANIFEST_FILE_OPT, DEFAULT_MANIFEST_FILE};
1717
/// Scaffold a new application based on a template.
1818
#[derive(Parser, Debug)]
1919
pub struct TemplateNewCommandCore {
20-
/// The template from which to create the new application or component. Run `spin templates list` to see available options.
21-
pub template_id: Option<String>,
22-
2320
/// The name of the new application or component.
2421
#[clap(value_parser = validate_name)]
2522
pub name: Option<String>,
2623

24+
/// The template from which to create the new application or component. Run `spin templates list` to see available options.
25+
#[clap(short = 't', long = "template")]
26+
pub template_id: Option<String>,
27+
2728
/// Filter templates to select by tags.
2829
#[clap(
2930
long = "tag",
@@ -34,9 +35,13 @@ pub struct TemplateNewCommandCore {
3435

3536
/// The directory in which to create the new application or component.
3637
/// The default is the name argument.
37-
#[clap(short = 'o', long = "output")]
38+
#[clap(short = 'o', long = "output", group = "location")]
3839
pub output_path: Option<PathBuf>,
3940

41+
/// Create the new application or component in the current directory.
42+
#[clap(long = "init", takes_value = false, group = "location")]
43+
pub init: bool,
44+
4045
/// Parameter values to be passed to the template (in name=value format).
4146
#[clap(short = 'v', long = "value", multiple_occurrences = true)]
4247
pub values: Vec<ParameterValue>,
@@ -113,6 +118,17 @@ impl TemplateNewCommandCore {
113118
let template_manager = TemplateManager::try_default()
114119
.context("Failed to construct template directory path")?;
115120

121+
// If a user types `spin new http-rust` etc. then it's *probably* Spin 1.x muscle memory;
122+
// try to be helpful without getting in the way.
123+
if let Some(name) = &self.name {
124+
if self.template_id.is_none() && matches!(template_manager.get(name), Ok(Some(_))) {
125+
terminal::einfo!(
126+
"This will create an app called {name}.",
127+
"If you meant to use the {name} template, write '-t {name}'."
128+
)
129+
}
130+
}
131+
116132
let template = match &self.template_id {
117133
Some(template_id) => match template_manager
118134
.get(template_id)
@@ -146,7 +162,12 @@ impl TemplateNewCommandCore {
146162
None => prompt_name(&variant).await?,
147163
};
148164

149-
let output_path = self.output_path.clone().unwrap_or_else(|| path_safe(&name));
165+
let output_path = if self.init {
166+
PathBuf::from(".")
167+
} else {
168+
self.output_path.clone().unwrap_or_else(|| path_safe(&name))
169+
};
170+
150171
let values = {
151172
let mut values = match self.values_file.as_ref() {
152173
Some(file) => values_from_file(file.as_path()).await?,

0 commit comments

Comments
 (0)