pint_cli/
new.rs

1//! `pint new` implementation.
2
3use clap::{builder::styling::Style, Parser};
4use pint_pkg::{
5    manifest::{ManifestFile, PackageKind},
6    new::new_pkg,
7};
8use std::path::PathBuf;
9
10/// Create a new package.
11#[derive(Parser, Debug)]
12pub struct Args {
13    /// Specify the "contract" package kind.
14    ///
15    /// This is the default behaviour.
16    #[arg(long)]
17    contract: bool,
18    /// Specify the "library" package kind.
19    ///
20    /// By default, new packages are created with the "contract" kind.
21    #[arg(long)]
22    lib: bool,
23    /// Optionally provide a name.
24    ///
25    /// By default, the package name is the last directory in the canonicalized
26    /// representation of the given path.
27    #[arg(long)]
28    name: Option<String>,
29    /// The directory path in which the package should be created.
30    path: PathBuf,
31}
32
33fn kind_from_bools(contract: bool, lib: bool) -> anyhow::Result<Option<PackageKind>> {
34    let opt = match (contract, lib) {
35        (false, false) => None,
36        (true, false) => Some(PackageKind::Contract),
37        (false, true) => Some(PackageKind::Library),
38        (true, true) => anyhow::bail!("must choose either `contract` or `lib`, not both"),
39    };
40    Ok(opt)
41}
42
43pub(crate) fn cmd(args: Args) -> anyhow::Result<()> {
44    let name = args.name;
45    let kind = kind_from_bools(args.contract, args.lib)?;
46    let opts = pint_pkg::new::Options { name, kind };
47    let manifest_path = new_pkg(&args.path, opts)?;
48    let manifest = ManifestFile::from_path(&manifest_path)?;
49    let bold = Style::new().bold();
50    println!(
51        "     {}Created{} {} [{}] ({})",
52        bold.render(),
53        bold.render_reset(),
54        manifest.pkg.name,
55        manifest.pkg.kind,
56        manifest.dir().display(),
57    );
58    Ok(())
59}