// install-component: Install a component from an artefact to a directory. // // This example shows how to extract a component from a Rust release artefact // and install it to a given directory. extern crate env_logger; #[macro_use] extern crate log; extern crate rust_release_artefact as rra; extern crate tempfile; use std::env; use std::error; use std::fs; use std::io; use std::path; use std::process; // Ordinarily, the artefact source (such as the release channel // manifest, or the Content-Type header from an HTTP response) will tell // you what kind of artefact to expect, so this kind of guessing isn't // required. It's only because we're reading directly from a file that // this is necessary. fn open_artefact( src_path: &path::Path, ) -> Result> { // Here we're extracting to a temporary directory, which will hang around // until somebody else cleans it up. // Note that we are canonicalising the path so that we can exceed the // standard Windows 260-character path limit - some artefacts have much // deeper directory structures than that. let dst_path = tempfile::tempdir()?.into_path().canonicalize()?; let artefact_handle = io::BufReader::new(fs::File::open(src_path)?); let extension = src_path .extension() .and_then(|ext| ext.to_str()) .unwrap_or(""); Ok(match extension { "gz" => rra::ExtractedArtefact::from_tar_gz(artefact_handle, dst_path)?, "xz" => rra::ExtractedArtefact::from_tar_xz(artefact_handle, dst_path)?, _ => Err(format!("Unrecognised extension: {:?}", extension))?, }) } fn main() { env_logger::init(); info!("Parsing command-line arguments..."); let args = env::args_os().collect::>(); if args.len() != 4 { error!("Usage: install-component ARTEFACT COMPONENT DESTINATION"); process::exit(1); } let src_path = path::Path::new(&args[1]).canonicalize().unwrap_or_else( |err| { error!("Could not canonicalize artefact path: {}", err); process::exit(1) }, ); let component_name = args[2].to_str().unwrap_or_else(|| { error!("Component name had invalid UTF-8: {:?}", &args[2]); process::exit(1) }); let dst_path = path::Path::new(&args[3]); fs::create_dir_all(&dst_path).unwrap_or_else(|err| { error!("Could not create destination path: {}", err); process::exit(1) }); let dst_path = dst_path.canonicalize().unwrap_or_else(|err| { error!("Could not canonicalize path: {}", err); process::exit(1) }); info!("Extracting artefact to temporary directory..."); let extracted_artefact = open_artefact(&src_path).unwrap_or_else(|err| { error!("{}", err); process::exit(1) }); info!("Reading component {:?}...", component_name); let component = extracted_artefact .components .get(component_name) .unwrap_or_else(|| { error!( "Artefact has no component named {:?}, components are {:?}", component_name, extracted_artefact.components.keys().collect::>() ); process::exit(1) }); info!("Installing component to {:?}...", dst_path); component.install_to(&dst_path).unwrap_or_else(|err| { error!("Could not install component: {}", err); process::exit(1) }); }