extern crate nix;
extern crate python_launcher;
use std::collections;
use std::env;
use std::ffi;
use std::os::unix::ffi::OsStrExt;
use std::path;
use nix::unistd;
use python_launcher as py;
fn main() {
let mut args = env::args().collect::<Vec<String>>();
args.remove(0); let mut requested_version = py::RequestedVersion::Any;
if args.len() >= 1 {
if let Ok(version) = py::parse_version_from_flag(&args[0]) {
requested_version = version;
args.remove(0);
}
}
let mut found_versions = collections::HashMap::new();
for path in py::path_entries() {
let all_contents = py::directory_contents(&path);
for (version, path) in py::filter_python_executables(all_contents) {
match version.matches(&requested_version) {
py::VersionMatch::NotAtAll => continue,
py::VersionMatch::Loosely => {
if !found_versions.contains_key(&version) && path.is_file() {
found_versions.insert(version, path);
}
}
py::VersionMatch::Exactly => {
if path.is_file() {
found_versions.insert(version, path);
break;
}
}
};
}
}
println!("Found {:?}", found_versions);
let chosen_path = py::choose_executable(&found_versions).unwrap();
match run(&chosen_path, &args) {
Err(e) => println!("{:?}", e),
Ok(_) => (),
};
}
fn run(executable: &path::PathBuf, args: &Vec<String>) -> nix::Result<()> {
println!("Args: {:?}", args);
let executable_as_cstring = ffi::CString::new(executable.as_os_str().as_bytes()).unwrap();
let mut argv = vec![executable_as_cstring.clone()];
argv.extend(
args.iter()
.map(|arg| ffi::CString::new(arg.as_str()).unwrap()),
);
let result = unistd::execv(&executable_as_cstring, &argv);
match result {
Ok(_) => Ok(()),
Err(e) => Err(e),
}
}