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 if !initdir.is_dir() {
40 bail!("{} exists and is not a directory", initdir.display());
41 }
42 if fs::read_dir(&initdir)?.next().is_some() {
43 bail!("{} exists and is not empty", initdir.display());
44 }
45 }
46
47 let Some(initdir_str) = initdir.to_str() else {
48 bail!("Sorry, configuration directory must be valid UTF-8");
49 };
50
51 println!("Initialising new configuration directory {}:", initdir_str);
52
53 let confstr = match env::consts::OS {
54 "illumos" => include_str!("../config/illumos.lua"),
55 "linux" => include_str!("../config/linux.lua"),
56 "macos" => include_str!("../config/macos.lua"),
57 "netbsd" => include_str!("../config/netbsd.lua"),
58 "solaris" => include_str!("../config/illumos.lua"),
59 os => {
60 eprintln!(
61 "WARNING: OS '{}' not explicitly supported, using generic config",
62 os
63 );
64 include_str!("../config/generic.lua")
65 }
66 };
67
68 let confstr = confstr.replace("@INITDIR@", initdir_str);
69 let conffile = initdir.join("config.lua");
70 fs::create_dir_all(conffile.parent().unwrap())?;
71 fs::write(&conffile, confstr)?;
72 println!("\t{}", conffile.display());
73
74 for script in Scripts::iter() {
75 if let Some(content) = Scripts::get(&script) {
76 let fp = initdir.join("scripts").join(&*script);
77 fs::create_dir_all(fp.parent().unwrap())?;
78 fs::write(&fp, content.data)?;
79 #[cfg(unix)]
80 {
81 let mut perms = fs::metadata(&fp)?.permissions();
82 perms.set_mode(0o755);
83 fs::set_permissions(&fp, perms)?;
84 }
85 println!("\t{}", fp.display());
86 }
87 }
88
89 Ok(())
90 }
91}