Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Unreleased

* feat: `icp new --init` no longer requires specifying a project name. If non is provided, the containing folder's name is used as the project name
* fix: `icp canister call --json` no longer produces blank output.

# v0.2.4
Expand Down
57 changes: 28 additions & 29 deletions crates/icp-cli/src/commands/new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,16 @@ fn validate_name(s: &str) -> Result<String, String> {
/// Under the hood templates are generated with `cargo-generate`.
/// See the cargo-generate docs for a guide on how to write your own templates:
/// https://docs.rs/cargo-generate/0.23.7/cargo_generate/
#[derive(Clone, Debug, Args)]
#[derive(Clone, Debug, Default, Args)]
pub struct IcpGenerateArgs {
#[command(flatten)]
pub template_path: IcpTemplatePath,

/// Directory to create / project name; if the name isn't in kebab-case, it will be converted
/// to kebab-case unless `--force` is given.
#[arg(value_parser = validate_name)]
pub name: String,
/// Optional when `--init` is used: defaults to the name of the current directory.
#[arg(value_parser = validate_name, required_unless_present = "init")]
pub name: Option<String>,

/// Don't convert the project name to kebab-case before creating the directory. Note that
/// `icp-cli` won't overwrite an existing directory, even if `--force` is given.
Expand All @@ -62,7 +63,7 @@ pub struct IcpGenerateArgs {
/// template-defined defaults; generation fails if a required variable has no default.
/// Combine with --define to supply values for variables that have no default in the template.
/// Use for CI or automated/agent contexts.
#[arg(long, short, requires("name"), action)]
#[arg(long, short, action)]
pub silent: bool,

/// Specify the VCS used to initialize the generated template.
Expand Down Expand Up @@ -108,33 +109,11 @@ pub struct IcpGenerateArgs {
pub skip_submodules: bool,
}

impl Default for IcpGenerateArgs {
fn default() -> Self {
Self {
template_path: IcpTemplatePath::default(),
name: "".to_string(), // name is a required arg
force: false,
quiet: false,
continue_on_error: false,
silent: false,
vcs: None,
ssh_identity: None,
gitconfig: None,
define: Vec::default(),
init: false,
destination: None,
force_git_init: false,
overwrite: false,
skip_submodules: false,
}
}
}

impl From<IcpGenerateArgs> for GenerateArgs {
fn from(f: IcpGenerateArgs) -> Self {
Self {
template_path: f.template_path.into(),
name: Some(f.name),
name: f.name,
force: f.force,
quiet: f.quiet,
continue_on_error: f.continue_on_error,
Expand Down Expand Up @@ -200,6 +179,23 @@ impl From<IcpTemplatePath> for TemplatePath {
}
}

fn resolve_name(args: &IcpGenerateArgs) -> Result<Option<String>, anyhow::Error> {
if args.name.is_some() {
return Ok(args.name.clone());
}

let cwd = std::env::current_dir().context("Failed to get current directory")?;
let dir_name = cwd
.file_name()
.context("Current directory has no name")?
.to_str()
.context("Current directory name is not valid UTF-8")?;
let name = validate_name(dir_name).map_err(|e| {
anyhow::anyhow!("Current directory name '{dir_name}' is not a valid project name: {e}")
})?;
Ok(Some(name))
}

pub(crate) async fn exec(
ctx: &icp::context::Context,
args: &IcpGenerateArgs,
Expand All @@ -210,8 +206,11 @@ pub(crate) async fn exec(
anyhow::bail!("--quiet and --debug cannot be used together");
}

let mut generate_args: GenerateArgs = args.clone().into();
generate_args.verbose = ctx.debug; // There is a global --debug flag
let mut args = args.clone();
args.name = resolve_name(&args)?;

let mut generate_args: GenerateArgs = args.into();
generate_args.verbose = ctx.debug;
let generate_args = generate_args.clone();

debug!("Generating project with {generate_args:#?}");
Expand Down
4 changes: 2 additions & 2 deletions docs/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -1414,11 +1414,11 @@ Create a new ICP project from a template

Under the hood templates are generated with `cargo-generate`. See the cargo-generate docs for a guide on how to write your own templates: https://docs.rs/cargo-generate/0.23.7/cargo_generate/

**Usage:** `icp new [OPTIONS] <NAME>`
**Usage:** `icp new [OPTIONS] [NAME]`

###### **Arguments:**

* `<NAME>` — Directory to create / project name; if the name isn't in kebab-case, it will be converted to kebab-case unless `--force` is given
* `<NAME>` — Directory to create / project name; if the name isn't in kebab-case, it will be converted to kebab-case unless `--force` is given. Optional when `--init` is used: defaults to the name of the current directory

###### **Options:**

Expand Down
Loading