Skip to main content

nifty_cli/build/
windows.rs

1//! Windows apps are folders holding the executable, named after the app.
2
3use std::fs;
4use std::io;
5use std::path::{Path, PathBuf};
6
7use crate::error::CliError;
8
9/// Writes `<output>/<name>/<name>.exe` from `executable`, replacing an earlier build, and
10/// returns the folder.
11pub(crate) fn write_app(output: &Path, name: &str, executable: &Path) -> Result<PathBuf, CliError> {
12    let app = output.join(name);
13    let failed =
14        |error: io::Error| CliError::new(format!("can't write {}: {error}", app.display()));
15    if app.exists() {
16        fs::remove_dir_all(&app).map_err(failed)?;
17    }
18    fs::create_dir_all(&app).map_err(failed)?;
19    fs::copy(executable, app.join(format!("{name}.exe"))).map_err(failed)?;
20    Ok(app)
21}
22
23#[cfg(test)]
24mod tests {
25    use super::*;
26    use crate::test_support::scratch_dir;
27
28    #[test]
29    fn writes_a_folder_holding_the_executable() {
30        let dir = scratch_dir("build-windows-app");
31        let executable = dir.join("app.exe");
32        fs::write(&executable, "machine code").expect("write a stand-in executable");
33
34        let app = write_app(&dir.join("build"), "todos", &executable).expect("the app is written");
35
36        assert_eq!(app, dir.join("build/todos"));
37        let bundled = app.join("todos.exe");
38        assert_eq!(
39            fs::read_to_string(bundled).expect("executable"),
40            "machine code"
41        );
42    }
43
44    #[test]
45    fn building_again_replaces_the_previous_app() {
46        let dir = scratch_dir("build-windows-rebuild");
47        let executable = dir.join("app.exe");
48        fs::write(&executable, "machine code").expect("write a stand-in executable");
49        let app = write_app(&dir, "app", &executable).expect("first build");
50        fs::write(app.join("stale.txt"), "").expect("write a stale file");
51
52        write_app(&dir, "app", &executable).expect("second build");
53
54        assert!(!app.join("stale.txt").exists());
55    }
56
57    #[test]
58    fn names_with_dots_keep_their_whole_name() {
59        let dir = scratch_dir("build-windows-dotted");
60        let executable = dir.join("app.exe");
61        fs::write(&executable, "machine code").expect("write a stand-in executable");
62
63        let app = write_app(&dir, "todo.v2", &executable).expect("the app is written");
64
65        assert!(app.join("todo.v2.exe").is_file());
66    }
67}