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
use std::fs; use std::path::{Path, PathBuf}; use std::env; use std::process; use std::process::{Command, Stdio}; use clap::ArgMatches; use kuchiki::traits::*; use hyper::{Client, Url}; use hyper::client::Response; use hyper::Result as HyperResult; use util; pub fn versions() { let groonga_versioned_dir = util::obtain_groonga_versioned_path(); let paths = fs::read_dir(&Path::new(&groonga_versioned_dir)).unwrap(); let names = paths.filter_map(|entry| { entry.ok().and_then(|e| { e.path() .file_name() .and_then(|n| n.to_str().map(|s| String::from(s))) }) }) .collect::<Vec<String>>(); println!("Installed Groonga:"); println!("\tsystem"); for entry in names { let e = entry.split("-").collect::<Vec<_>>(); println!("\t{} ({})", e.get(1).unwrap_or(&""), e.get(2).unwrap_or(&"build from source")); } } pub struct MaybeProxyUrl { pub url: Url, } impl<'a> IntoResponse for MaybeProxyUrl { fn into_response(self) -> HyperResult<Response> { extern crate env_proxy; let maybe_proxy = env_proxy::for_url(&self.url); let client = match maybe_proxy { None => Client::new(), Some(host_port) => Client::with_http_proxy(host_port.0, host_port.1), }; client.get(self.url).send() } } pub fn execute_external_command(cmd: &str, ext_m: &ArgMatches) { let command_exe = format!("grnenv-{}{}", cmd, env::consts::EXE_SUFFIX); let ext_args: Vec<&str> = match ext_m.values_of("") { Some(c) => c.collect(), None => vec![], }; let path = search_directories() .iter() .map(|dir| dir.join(&command_exe)) .find(|file| is_executable(file)); let command = match path { Some(command) => command, None => { println!("no such subcommand: `{}`", cmd); process::exit(1); } }; let err = match Command::new(command) .args(&ext_args.as_slice()[0..]) .stdout(Stdio::inherit()) .stderr(Stdio::inherit()) .spawn() { Ok(_) => return (), Err(e) => e, }; println!("Failed to execute external subcommand. reason: {:?}", err); process::exit(1); } fn search_directories() -> Vec<PathBuf> { let home = env::home_dir().unwrap(); let mut dirs = vec![home.join("bin")]; if let Some(val) = env::var_os("PATH") { dirs.extend(env::split_paths(&val)); } dirs } #[cfg(unix)] fn is_executable<P: AsRef<Path>>(path: P) -> bool { use std::os::unix::prelude::*; fs::metadata(path) .map(|metadata| metadata.is_file() && metadata.permissions().mode() & 0o111 != 0) .unwrap_or(false) } #[cfg(windows)] fn is_executable<P: AsRef<Path>>(path: P) -> bool { fs::metadata(path).map(|metadata| metadata.is_file()).unwrap_or(false) }