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 123 124 125 126 127 128 129 130 131
use crate::error::Error; use cargo::core::{Package, Workspace}; use cargo::util::important_paths::find_root_manifest_for_wd; use cargo::util::Config; use std::io::Read; use std::path::PathBuf; use std::process::{Command, Stdio}; pub struct Cargo<'a> { args: Vec<&'a str>, workspace: Workspace<'a>, } impl<'a> Cargo<'a> { pub fn new(config: &'a mut Config, args: Vec<&'a str>) -> Result<Self, Error> { let root_manifest = find_root_manifest_for_wd(config.cwd())?; let target_dir = root_manifest .parent() .unwrap() .join("target") .join("flutter"); config .configure(0, None, &None, false, false, false, &Some(target_dir), &[]) .unwrap(); let workspace = Workspace::new(&root_manifest, config)?; Ok(Self { args, workspace }) } fn arg<F: Fn(&str) -> bool>(&self, matches: F) -> Option<&str> { self.args .iter() .position(|f| matches(f)) .map(|pos| self.args.get(pos + 1)) .unwrap_or_default() .cloned() } pub fn cmd(&self) -> &str { self.args.iter().next().expect("Expected command") } pub fn target(&self) -> Option<&str> { self.arg(|f| f == "--target") } pub fn package(&self) -> Result<&Package, Error> { Ok( if let Some(package) = self.arg(|f| f == "--package" || f == "-p") { self.workspace() .members() .find(|pkg| pkg.name().as_str() == package) .ok_or(Error::PackageNotMember)? } else { self.workspace().current()? }, ) } pub fn release(&self) -> bool { self.args.iter().any(|f| *f == "--release") } pub fn host_target(&self) -> Result<String, Error> { let rustc = self .workspace .config() .load_global_rustc(Some(&self.workspace))?; Ok(rustc.host.as_str().to_string()) } pub fn triple(&self) -> Result<String, Error> { if let Some(target) = self.target() { Ok(target.to_string()) } else { self.host_target() } } pub fn workspace(&self) -> &Workspace { &self.workspace } pub fn target_dir(&self) -> PathBuf { self.workspace().target_dir().into_path_unlocked() } pub fn build_dir(&self) -> PathBuf { let flutter_dir = self.target_dir(); let triple_dir = if let Some(target) = self.target() { flutter_dir.join(target) } else { flutter_dir }; if self.release() { triple_dir.join("release") } else { triple_dir.join("debug") } } fn cargo_command(&self) -> Command { let mut cmd = Command::new("cargo"); cmd.current_dir(self.workspace.config().cwd()) .args(&self.args) .arg("--target-dir") .arg(self.target_dir()); cmd } pub fn build(&self) -> Result<(), Error> { let status = self.cargo_command().status().expect("Success"); if status.code() != Some(0) { return Err(Error::CargoError); } Ok(()) } pub fn run(&self) -> Result<String, Error> { let mut child = self .cargo_command() .stdout(Stdio::piped()) .spawn() .expect("Success"); let stdout = child.stdout.as_mut().unwrap(); let mut buffer = [0; 70]; stdout.read_exact(&mut buffer)?; let string = std::str::from_utf8(&buffer)?; Ok(string[34..].to_string()) } }