aboutsummaryrefslogtreecommitdiff
path: root/launcher/src/main.rs
blob: bf11997a9e93c333095a8706eb3d46f567c12c47 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
mod search_path;
mod constants;

use std::path::PathBuf;
use std::process;
use launcher::AppData;

fn show_system_info() {
    println!(
        "atomic-launcher: Starting atomic-launcher {} on {} ({})",
        constants::VERSION,
        std::env::consts::OS,
        std::env::consts::ARCH
    );

    println!(
        "atomic-launcher: Compiled against rustc {}",
        rustc_version_runtime::version()
    );
}

fn is_valid_path(mut path: PathBuf) -> Option<PathBuf> {
    path.push(constants::BINARY_PATH);
    let as_path = path.as_path();

    if as_path.is_file() {
        Some(path)
    } else {
        None
    }
}

fn main() {
    show_system_info();
    let work_dir = get_working_directory();

    println!(
        "atomic-launcher: Current directory: {}",
        work_dir.to_str().unwrap()
    );

    let app_data = locate_app(&work_dir);
    let runtime_path = locate_runtime();
    launch_app(runtime_path, app_data)
}

fn get_working_directory() -> PathBuf {
    let exec_path = std::env::current_exe().ok();
    exec_path.as_ref()
        .and_then(|p| p.parent())
        .unwrap()
        .to_owned()
}

fn locate_app(work_dir: &PathBuf) -> Option<AppData> {
    let mut app_data: Option<AppData> = None;

    let mut app_path_folder = PathBuf::from(work_dir);
    app_path_folder.push(constants::APP_FOLDER_PATH);

    let mut app_path_asar = PathBuf::from(work_dir);
    app_path_asar.push(constants::APP_ASAR_PATH);

    if app_path_folder.exists() {
        app_data = Some(AppData::Folder(app_path_folder))
    } else if app_path_asar.exists() {
        app_data = Some(AppData::Asar(app_path_asar))
    } else {
        println!(
            "atomic-launcher: Warning: Could not find Electron-compatible app.\
            Looked in {} and {}. The default atomic-runtime application will be opened instead.",
            app_path_folder.to_str().unwrap(),
            app_path_asar.to_str().unwrap()
        );
    }

    app_data
}

fn locate_runtime() -> Option<PathBuf> {
    let runtime_search_paths = search_path::get_search_paths();
    let runtime_search_paths_string = runtime_search_paths
        .iter()
        .map(|i| i.to_str().unwrap())
        .collect::<Vec<&str>>()
        .join(", ");

    println!(
        "atomic-launcher: Looking for atomic-runtime in: {}",
        runtime_search_paths_string
    );

    runtime_search_paths.into_iter()
        .filter_map(is_valid_path)
        .next()
}

fn launch_app(runtime_path: Option<PathBuf>, app_data: Option<AppData>) {
    if let Some(path) = runtime_path {
        println!(
            "atomic-launcher: Found atomic-runtime at {}",
            path.to_str().unwrap()
        );
        let mut cmd = process::Command::new(path);
        cmd.env("ATOMIC_LAUNCHER_VERSION", constants::VERSION);
        println!("atomic-launcher: Executing: {:?}", cmd);

        if let Some(app_data) = app_data {
            cmd.arg(app_data.get_path());
        }

        if let Ok(status) = cmd.status() {
            process::exit(status.code().unwrap_or(255));
        } else {
            eprintln!("atomic-launcher: Application failed to start.");
            process::exit(3);
        }
    } else {
        eprintln!("atomic-launcher: Could not find a valid atomic-runtime path. Aborting.");
        process::exit(2);
    }
}