1 | | - | mod args; |
2 | | - | mod install; |
3 | | - | |
4 | | - | // Re-export |
5 | | - | pub use crate::args::parse_args; |
| 1 | + | use crate::{args, install, prompt}; |
6 | 2 | | |
7 | 3 | | use serde_json::Value; |
8 | 4 | | use std::collections::HashMap; |
| skipped 74 lines |
83 | 79 | | None |
84 | 80 | | } |
85 | 81 | | |
86 | | - | pub fn dum(app_args: &args::AppArgs) { |
| 82 | + | pub fn run(app_args: &args::AppArgs) { |
87 | 83 | | let pkg_paths = find_closest_files(&app_args.change_dir, "package.json", true); |
88 | 84 | | let pkg_path = if pkg_paths.is_empty() { |
89 | | - | println!("No package.json found"); |
| 85 | + | eprintln!("No package.json found"); |
90 | 86 | | exit(1); |
91 | 87 | | } else { |
92 | 88 | | pkg_paths[0].clone() |
| skipped 11 lines |
104 | 100 | | let contents = read_to_string(pkg_path).expect("failed to read package.json"); |
105 | 101 | | let v: Value = serde_json::from_str(&contents).expect("failed to parse package.json"); |
106 | 102 | | |
107 | | - | if app_args.command == "run" && app_args.script_name.is_empty() { |
108 | | - | if let Some(scripts) = v["scripts"].as_object() { |
109 | | - | println!("\nAvailable scripts:\n"); |
110 | | - | for (name, value) in scripts { |
111 | | - | println!("{}", name); |
112 | | - | println!(" {}", value); |
113 | | - | } |
114 | | - | } else { |
115 | | - | println!("No scripts found."); |
| 103 | + | let scripts = v["scripts"].as_object(); |
| 104 | + | if scripts.is_none() { |
| 105 | + | println!("No scripts found."); |
| 106 | + | return; |
| 107 | + | } |
| 108 | + | |
| 109 | + | let mut script_name = app_args.script_name.clone(); |
| 110 | + | let mut forwarded = app_args.forwared.clone(); |
| 111 | + | |
| 112 | + | if !app_args.interactive && app_args.command == "run" && script_name.is_empty() { |
| 113 | + | println!("\nAvailable scripts:\n"); |
| 114 | + | for (name, value) in scripts.unwrap() { |
| 115 | + | println!("{}", name); |
| 116 | + | println!(" {}", value); |
116 | 117 | | } |
117 | 118 | | return; |
118 | 119 | | } |
119 | 120 | | |
120 | | - | if app_args.script_name.is_empty() { |
121 | | - | println!("No script name specified.\n"); |
122 | | - | println!("{}", args::get_help()); |
123 | | - | return; |
| 121 | + | if !script_name.is_empty() && app_args.interactive { |
| 122 | + | eprintln!("You can't specify script name in interactive mode"); |
| 123 | + | exit(1); |
| 124 | + | } |
| 125 | + | |
| 126 | + | if script_name.is_empty() { |
| 127 | + | if !app_args.interactive { |
| 128 | + | println!("No script name specified.\n"); |
| 129 | + | println!("{}", args::get_help()); |
| 130 | + | return; |
| 131 | + | } |
| 132 | + | |
| 133 | + | // Choose an script interactively |
| 134 | + | // Convert keys of scripts to a vector of &str |
| 135 | + | let names_vec = scripts |
| 136 | + | .unwrap() |
| 137 | + | .keys() |
| 138 | + | .map(|k| k.as_str()) |
| 139 | + | .collect::<Vec<&str>>(); |
| 140 | + | script_name = |
| 141 | + | prompt::select("Select an npm script to run", names_vec).expect("nothing was selected"); |
| 142 | + | forwarded = " ".to_string(); |
| 143 | + | forwarded.push_str(&prompt::input("Enter arguments to pass to the script")); |
124 | 144 | | } |
125 | 145 | | |
126 | 146 | | // Run npm install if the script_name is "install" |
127 | | - | if ["install", "add", "remove"].contains(&app_args.script_name.as_str()) { |
| 147 | + | if ["install", "add", "remove"].contains(&script_name.as_str()) { |
128 | 148 | | let pm = install::guess_package_manager(&execute_dir); |
129 | 149 | | |
130 | 150 | | if pm.is_none() { |
| skipped 2 lines |
133 | 153 | | } |
134 | 154 | | |
135 | 155 | | run_command( |
136 | | - | &[&pm.unwrap(), &app_args.script_name, &app_args.forwared], |
| 156 | + | &[&pm.unwrap(), &script_name, &forwarded], |
137 | 157 | | &RunOptions { |
138 | 158 | | current_dir: execute_dir, |
139 | 159 | | envs: HashMap::new(), |
| skipped 2 lines |
142 | 162 | | return; |
143 | 163 | | } |
144 | 164 | | |
145 | | - | let npm_script = v.get("scripts").and_then(|scripts| { |
146 | | - | scripts.as_object().and_then(|scripts| { |
147 | | - | scripts |
148 | | - | .get(app_args.script_name.as_str()) |
149 | | - | .and_then(|script| { |
150 | | - | let script = script.as_str().map(|script| script.to_string()); |
151 | | - | Some(script.unwrap_or_default()) |
152 | | - | }) |
| 165 | + | let npm_script = scripts.and_then(|scripts| { |
| 166 | + | scripts.get(script_name.as_str()).and_then(|script| { |
| 167 | + | let script = script.as_str().map(|script| script.to_string()); |
| 168 | + | Some(script.unwrap_or_default()) |
153 | 169 | | }) |
154 | 170 | | }); |
155 | 171 | | |
156 | 172 | | if npm_script.is_some() { |
157 | 173 | | let script = npm_script.unwrap(); |
158 | | - | println!("> {}", app_args.script_name); |
159 | | - | println!("> {}{}", script, app_args.forwared); |
| 174 | + | println!("> {}", script_name); |
| 175 | + | println!("> {}{}", script, forwarded); |
160 | 176 | | let envs = HashMap::from([("PATH".to_string(), get_path_env(bin_dirs))]); |
161 | 177 | | run_command( |
162 | | - | &[&script, &app_args.forwared], |
| 178 | + | &[&script, &forwarded], |
163 | 179 | | &RunOptions { |
164 | 180 | | current_dir: execute_dir, |
165 | 181 | | envs, |
| skipped 2 lines |
168 | 184 | | return; |
169 | 185 | | } |
170 | 186 | | |
171 | | - | let resolved_bin = resolve_bin_path(app_args.script_name.as_str(), &bin_dirs); |
| 187 | + | let resolved_bin = resolve_bin_path(script_name.as_str(), &bin_dirs); |
172 | 188 | | if resolved_bin.is_some() { |
173 | 189 | | let bin_path = resolved_bin.unwrap(); |
174 | | - | println!("> {}", app_args.script_name); |
175 | | - | println!("> {}{}", bin_path.to_str().unwrap(), app_args.forwared); |
| 190 | + | println!("> {}", script_name); |
| 191 | + | println!("> {}{}", bin_path.to_str().unwrap(), forwarded); |
176 | 192 | | let envs = HashMap::from([("PATH".to_string(), get_path_env(bin_dirs))]); |
177 | 193 | | run_command( |
178 | | - | &[bin_path.to_str().unwrap(), &app_args.forwared], |
| 194 | + | &[bin_path.to_str().unwrap(), &forwarded], |
179 | 195 | | &RunOptions { |
180 | 196 | | current_dir: execute_dir, |
181 | 197 | | envs, |
| skipped 10 lines |