Skip to main content

wolf_project/
lib.rs

1//! Projects: the manifest `wolfpack.toml`, the fixed layout, and `wolf new` (spec chapter 6).
2
3mod layout;
4mod manifest;
5
6use std::fs;
7use std::path::Path;
8
9pub use layout::{ModuleFile, NATIVE_DIRS, Role, discover, find_root, is_snake_case, native_files};
10pub use manifest::{
11    ConfigOverride, ConfigValue, Kind, Manifest, Target, is_kebab_case, parse_manifest,
12};
13
14/// Creates a new project in `dir` (spec chapter 6, rule 7.6). `dir` must not exist or be empty.
15pub fn create(dir: &Path, name: &str, kind: Kind) -> Result<(), String> {
16    if !is_kebab_case(name) {
17        return Err(format!(
18            "invalid project name `{name}`: use lower-case words separated by `-`, for example `my-app`"
19        ));
20    }
21    if dir.exists() {
22        let empty = fs::read_dir(dir)
23            .map(|mut entries| entries.next().is_none())
24            .unwrap_or(false);
25        if !empty {
26            return Err(format!(
27                "`{}` already exists and is not empty",
28                dir.display()
29            ));
30        }
31    }
32    let kind_name = match kind {
33        Kind::Cli => "cli",
34        Kind::Lib => "lib",
35    };
36    let manifest = format!(
37        "[package]\nname = \"{name}\"\nversion = \"0.1.0\"\nkind = \"{kind_name}\"\n\n[targets]\ndefault = \"ts\"\nenabled = [\"ts\", \"go\", \"rust\"]\n"
38    );
39    let (entry, source) = match kind {
40        Kind::Cli => (
41            "main.wolf",
42            "module main\n\nmain {\n    print(\"Hello, wolfpack!\")\n}\n",
43        ),
44        Kind::Lib => (
45            "lib.wolf",
46            "module lib\n\nfunctions {\n    /// Returns a greeting for `name`.\n    pub fn greet(name: String) -> String {\n        \"Hello, \" + name + \"!\"\n    }\n}\n",
47        ),
48    };
49    let write = |path: &Path, text: &str| {
50        fs::write(path, text).map_err(|e| format!("cannot write `{}`: {e}", path.display()))
51    };
52    let mkdir = |path: &Path| {
53        fs::create_dir_all(path).map_err(|e| format!("cannot create `{}`: {e}", path.display()))
54    };
55    mkdir(&dir.join("src"))?;
56    mkdir(&dir.join("tests"))?;
57    mkdir(&dir.join("examples"))?;
58    write(&dir.join("wolfpack.toml"), &manifest)?;
59    write(&dir.join("src").join(entry), source)?;
60    write(&dir.join(".gitignore"), "/out/\n")?;
61    Ok(())
62}