1use std::fs;
2use std::fs::{File, OpenOptions};
3use std::io::prelude::*;
4use std::path::Path;
5use std::process::Command;
6
7use super::Error;
8use command_ext::CommandExt;
9use config::NewCmd;
10use fel4_config::get_exemplar_default_toml;
11
12pub fn handle_new_cmd(subcmd: &NewCmd) -> Result<(), Error> {
17 generate_baseline_cargo_package(subcmd)?;
18
19 generate_fel4_project_files(subcmd)?;
20
21 generate_tests_source_files(Some(&subcmd.path))?;
22
23 generate_target_specs(subcmd)?;
24
25 Ok(())
26}
27
28fn generate_baseline_cargo_package(subcmd: &NewCmd) -> Result<(), Error> {
29 let mut cmd = Command::new("cargo");
30 cmd.arg("new").add_loudness_args(&subcmd.loudness);
31
32 if let Some(ref n) = subcmd.name {
33 cmd.arg("--name").arg(&n);
34 }
35
36 cmd.arg("--edition").arg("2015");
38
39 cmd.arg("--lib").arg(&subcmd.path).run_cmd()
40}
41
42fn generate_fel4_project_files(subcmd: &NewCmd) -> Result<(), Error> {
43 let mut lib_src_file = File::create(Path::new(&subcmd.path).join("src").join("lib.rs"))?;
45 lib_src_file.write_all(APP_LIB_CODE.as_bytes())?;
46
47 let mut cargo_toml_file = OpenOptions::new()
49 .append(true)
50 .open(Path::new(&subcmd.path).join("Cargo.toml"))?;
51
52 cargo_toml_file.write_all(CARGO_TOML_TEXT.as_bytes())?;
54
55 let mut fel4_toml_file = File::create(Path::new(&subcmd.path).join("fel4.toml"))?;
56 fel4_toml_file.write_all(get_exemplar_default_toml().as_bytes())?;
57
58 let mut xargo_toml_file = File::create(Path::new(&subcmd.path).join("Xargo.toml"))?;
60 xargo_toml_file.write_all(XARGO_TOML_TEXT.as_bytes())?;
61
62 let mut toolchain_file = File::create(Path::new(&subcmd.path).join("rust-toolchain"))?;
64 toolchain_file.write_all(b"nightly\n")?;
65
66 Ok(())
67}
68
69fn generate_target_specs(subcmd: &NewCmd) -> Result<(), Error> {
70 let target_specs_path = Path::new(&subcmd.path).join("target_specs");
72 fs::create_dir(Path::new(&target_specs_path))?;
73
74 let mut target_spec_readme_file = File::create(&target_specs_path.join("README.md"))?;
75 target_spec_readme_file.write_all(FEL4_TARGET_SPEC_README.as_bytes())?;
76
77 let mut target_spec_x86_64_file =
78 File::create(&target_specs_path.join("x86_64-sel4-fel4.json"))?;
79 target_spec_x86_64_file.write_all(FEL4_TARGET_SPEC_X86_64_SEL4_FEL4.as_bytes())?;
80
81 let mut target_spec_armv7_file = File::create(&target_specs_path.join("armv7-sel4-fel4.json"))?;
82 target_spec_armv7_file.write_all(FEL4_TARGET_SPEC_ARMV7_SEL4_FEL4.as_bytes())?;
83
84 let mut target_spec_aarch64_file =
85 File::create(&target_specs_path.join("aarch64-sel4-fel4.json"))?;
86 target_spec_aarch64_file.write_all(FEL4_TARGET_SPEC_AARCH64_SEL4_FEL4.as_bytes())?;
87
88 Ok(())
89}
90
91pub fn generate_tests_source_files(base_dir: Option<&Path>) -> Result<(), Error> {
92 let src_path = if let Some(path) = base_dir {
93 path.join("src").join("fel4_test.rs")
94 } else {
95 Path::new("src").join("fel4_test.rs")
96 };
97
98 if !src_path.exists() {
99 let mut test_src_file = File::create(&src_path)
100 .map_err(|e| Error::IO(format!("Could not create fel4_test.rs {}", e)))?;
101 test_src_file
102 .write_all(TEST_LIB_CODE.as_bytes())
103 .map_err(|e| Error::IO(format!("Could not write to fel4_test.rs {}", e)))?;
104 }
105
106 Ok(())
107}
108
109const FEL4_TARGET_SPEC_README: &str = include_str!("../target_specs/README.md");
110
111const FEL4_TARGET_SPEC_X86_64_SEL4_FEL4: &str =
112 include_str!("../target_specs/x86_64-sel4-fel4.json");
113
114const FEL4_TARGET_SPEC_ARMV7_SEL4_FEL4: &str = include_str!("../target_specs/armv7-sel4-fel4.json");
115
116const FEL4_TARGET_SPEC_AARCH64_SEL4_FEL4: &str =
117 include_str!("../target_specs/aarch64-sel4-fel4.json");
118
119const APP_LIB_CODE: &str = include_str!("../templates/lib.rs");
120
121const XARGO_TOML_TEXT: &str = include_str!("../templates/Xargo.toml");
122
123const CARGO_TOML_TEXT: &str = include_str!("../templates/Cargo.toml.part");
124
125const TEST_LIB_CODE: &str = include_str!("../templates/fel4_test.rs");