1use anyhow::bail;
18use rust_embed::RustEmbed;
19use std::env;
20use std::fs;
21#[cfg(unix)]
22use std::os::unix::fs::PermissionsExt;
23use std::path::PathBuf;
24
25#[derive(Debug, RustEmbed)]
26#[folder = "scripts/"]
27struct Scripts;
28
29pub struct Init {}
30
31impl Init {
32 pub fn create(dir: &PathBuf) -> anyhow::Result<()> {
33 let initdir = if dir.is_absolute() {
34 dir.to_path_buf()
35 } else {
36 env::current_dir()?.join(dir)
37 };
38 if initdir.exists() {
39 bail!("{} already exists", initdir.display());
40 }
41
42 let Some(initdir_str) = initdir.to_str() else {
43 bail!("Sorry, configuration directory must be valid UTF-8");
44 };
45
46 println!("Initialising new configuration directory {}:", initdir_str);
47
48 let confstr = match env::consts::OS {
49 "illumos" => include_str!("../config/illumos.lua"),
50 "linux" => include_str!("../config/linux.lua"),
51 "macos" => include_str!("../config/macos.lua"),
52 "netbsd" => include_str!("../config/netbsd.lua"),
53 "solaris" => include_str!("../config/illumos.lua"),
54 os => {
55 eprintln!(
56 "WARNING: OS '{}' not explicitly supported, using generic config",
57 os
58 );
59 include_str!("../config/generic.lua")
60 }
61 };
62
63 let confstr = confstr.replace("@INITDIR@", initdir_str);
64 let conffile = initdir.join("config.lua");
65 fs::create_dir_all(conffile.parent().unwrap())?;
66 fs::write(&conffile, confstr)?;
67 println!("\t{}", conffile.display());
68
69 for script in Scripts::iter() {
70 if let Some(content) = Scripts::get(&script) {
71 let fp = initdir.join("scripts").join(&*script);
72 fs::create_dir_all(fp.parent().unwrap())?;
73 fs::write(&fp, content.data)?;
74 #[cfg(unix)]
75 {
76 let mut perms = fs::metadata(&fp)?.permissions();
77 perms.set_mode(0o755);
78 fs::set_permissions(&fp, perms)?;
79 }
80 println!("\t{}", fp.display());
81 }
82 }
83
84 Ok(())
85 }
86}