libwally/commands/
init.rs

1use std::env::current_dir;
2use std::path::PathBuf;
3
4use anyhow::{bail, Context};
5use structopt::StructOpt;
6use toml_edit::{value, Document};
7
8use crate::manifest::MANIFEST_FILE_NAME;
9
10const DEFAULT_MANIFEST: &str = r#"[package]
11name = "placeholder/placeholder"
12version = "0.1.0"
13registry = "https://github.com/UpliftGames/wally-index"
14realm = "shared"
15
16[dependencies]
17"#;
18
19/// Initialize a new Wally project.
20#[derive(Debug, StructOpt)]
21pub struct InitSubcommand {
22    /// The path to the project to initialize. Defaults to the current
23    /// directory.
24    path: Option<PathBuf>,
25}
26
27impl InitSubcommand {
28    pub fn run(self) -> anyhow::Result<()> {
29        let path = match self.path {
30            Some(path) => path,
31            None => current_dir()?,
32        };
33
34        let manifest_path = path.join(MANIFEST_FILE_NAME);
35
36        match fs_err::metadata(&manifest_path) {
37            Ok(_) => bail!(
38                "There is already a Wally project in this directory. Manifest file ({}) already exists.",
39                MANIFEST_FILE_NAME
40            ),
41
42            Err(err) => {
43                if err.kind() == std::io::ErrorKind::NotFound {
44                    // Perfect! This is the state that we want
45                } else {
46                    bail!("Error accessing manifest file ({}): {}", MANIFEST_FILE_NAME, err);
47                }
48            }
49        }
50
51        let canonical = fs_err::canonicalize(&path);
52        let package_name = match &canonical {
53            Ok(canonical) => canonical
54                .file_name()
55                .and_then(|name| name.to_str())
56                .context("Folder name contained invalid Unicode")?,
57            Err(_) => "unknown",
58        };
59
60        let mut doc = DEFAULT_MANIFEST
61            .parse::<Document>()
62            .expect("Built-in default manifest was invalid TOML");
63
64        let full_name = format!("{}/{}", whoami::username(), package_name)
65            .to_lowercase()
66            .replace(" ", "-");
67        doc["package"]["name"] = value(full_name.clone());
68
69        fs_err::write(manifest_path, doc.to_string())?;
70        println!("Initialized project {} in {}", full_name, path.display());
71
72        Ok(())
73    }
74}