1#[cfg(test)]
7#[path = "cli_test.rs"]
8mod cli_test;
9
10use crate::cli_commands;
11use crate::cli_parser;
12use crate::config;
13use crate::descriptor;
14use crate::environment;
15use crate::error::CargoMakeError;
16use crate::logger;
17use crate::logger::LoggerOptions;
18use crate::profile;
19use crate::recursion_level;
20use crate::runner;
21use crate::time_summary;
22use crate::toolchain;
23use crate::types::{CliArgs, GlobalConfig};
24use crate::version;
25use std::time::SystemTime;
26
27pub(crate) static VERSION: &str = env!("CARGO_PKG_VERSION");
28pub(crate) static AUTHOR: &str = env!("CARGO_PKG_AUTHORS");
29pub(crate) static DESCRIPTION: &str = env!("CARGO_PKG_DESCRIPTION");
30pub(crate) static DEFAULT_TOML: &str = "Makefile.toml";
31pub(crate) static DEFAULT_LOG_LEVEL: &str = "info";
32pub(crate) static DEFAULT_TASK_NAME: &str = "default";
33pub(crate) static DEFAULT_OUTPUT_FORMAT: &str = "default";
34
35pub fn run(
36    cli_args: &CliArgs,
37    global_config: &GlobalConfig,
38    logger_options: Option<LoggerOptions>,
39) -> Result<(), CargoMakeError> {
40    let start_time = SystemTime::now();
41
42    recursion_level::increment();
43
44    logger::init(&logger_options.unwrap_or(LoggerOptions {
45        name: String::from(env!("CARGO_PKG_NAME")),
46        level: cli_args.log_level.clone(),
47        color: !cli_args.disable_color,
48    }));
49
50    if recursion_level::is_top() {
51        info!("{} {}", &cli_args.command, &VERSION);
52        debug!("Written By {}", &AUTHOR);
53    }
54
55    debug!("Cli Args {:#?}", &cli_args);
56    debug!("Global Configuration {:#?}", &global_config);
57
58    if version::should_check(&cli_args, &global_config) {
59        version::check();
60    }
61
62    toolchain::remove_rust_env_vars();
64
65    let cwd_string_option = match cli_args.cwd.clone() {
66        Some(value) => Some(value),
67        None => match global_config.search_project_root {
68            Some(search) => {
69                if search {
70                    match environment::get_project_root() {
71                        Some(value) => Some(value.clone()),
72                        None => None,
73                    }
74                } else {
75                    None
76                }
77            }
78            None => None,
79        },
80    };
81    let cwd = match cwd_string_option {
82        Some(ref value) => Some(value.as_ref()),
83        None => None,
84    };
85    let home = environment::setup_cwd(cwd);
86
87    let force_makefile = cli_args.build_file.is_some();
88    let build_file = &cli_args
89        .build_file
90        .clone()
91        .unwrap_or(DEFAULT_TOML.to_string());
92    let task = &cli_args.task;
93    let profile_name = &cli_args
94        .profile
95        .clone()
96        .unwrap_or_else(profile::default_profile);
97    let normalized_profile_name = profile::set(&profile_name);
98
99    environment::load_env_file(cli_args.env_file.clone());
100
101    let env = cli_args.env.clone();
102
103    let experimental = cli_args.experimental;
104    let config = descriptor::load(&build_file, force_makefile, env, experimental)?;
105
106    let mut time_summary_vec = vec![];
107    time_summary::add(
108        &mut time_summary_vec,
109        "[Load Makefiles]",
110        start_time.clone(),
111    );
112    let step_time = SystemTime::now();
113
114    match config.config.additional_profiles {
115        Some(ref profiles) => profile::set_additional(profiles),
116        None => profile::set_additional(&vec![]),
117    };
118
119    let env_info = environment::setup_env(&cli_args, &config, &task, home, &mut time_summary_vec)?;
120    time_summary::add(&mut time_summary_vec, "[Setup Env]", step_time);
121
122    let crate_name = envmnt::get_or("CARGO_MAKE_CRATE_NAME", "");
123    info!("");
124    if crate_name.len() > 0 {
125        info!("Project: {}", &crate_name);
126    }
127    info!("Build File: {}", &build_file);
128    info!("Task: {}", &task);
129    info!("Profile: {}", &normalized_profile_name);
130
131    profile::set(&normalized_profile_name);
133
134    if cli_args.list_all_steps || cli_args.list_category_steps.is_some() {
135        cli_commands::list_steps::run(
136            &config,
137            &cli_args.output_format,
138            &cli_args.output_file,
139            &cli_args.list_category_steps,
140            cli_args.hide_uninteresting,
141        )
142    } else if cli_args.diff_execution_plan {
143        let default_config = descriptor::load_internal_descriptors(true, experimental, None)?;
144        cli_commands::diff_steps::run(
145            &default_config,
146            &config,
147            &task,
148            &cli_args,
149            &env_info.crate_info,
150        )
151    } else if cli_args.print_only {
152        cli_commands::print_steps::print(
153            &mut std::io::stdout(),
154            &config,
155            &task,
156            &cli_args.output_format,
157            cli_args.disable_workspace,
158            &cli_args.skip_tasks_pattern,
159            &env_info.crate_info,
160            cli_args.skip_init_end_tasks,
161        )
162    } else {
163        runner::run(
164            config,
165            &task,
166            env_info,
167            &cli_args,
168            start_time,
169            time_summary_vec,
170        )
171    }?;
172
173    Ok(())
174}
175
176pub fn run_cli(command_name: String, sub_command: bool) -> Result<CliArgs, CargoMakeError> {
178    let global_config = config::load()?;
179
180    let cli_args = cli_parser::parse(&global_config, &command_name, sub_command)?;
181
182    run(&cli_args, &global_config, None)?;
183    Ok(cli_args)
184}