4 releases
Uses old Rust 2015
0.1.3 | May 8, 2018 |
---|---|
0.1.2 | May 8, 2018 |
0.1.1 | May 1, 2018 |
0.1.0 | Apr 19, 2018 |
#1402 in Data structures
5MB
586 lines
rust_release_artefact: Extract and install Rust release artefacts
Repository: https://gitlab.com/Screwtapello/rust_release_artefact
Documentation: https://docs.rs/rust_release_artefact
TODO
- Update
ExtractedArtefact::new()
to usewalkdir
to search for artefact marker files. - Would it be neater to toss the first path-component of archives, rather than extracting it and having to rummage around to find the artefact metadata?
lib.rs
:
Safely extract installable files from Rust release artefacts.
Introduction
Each new release of the Rust toolchain includes a number of components—some required, some optional—that can be combined together. These components are made available as artefacts in a standard format that includes the files to be installed, as well as metadata describing them. Installing a component is therefore more complex than just extracting an archive, since not all files should be placed in the destination.
This library interprets a Rust artefact's metadata, and provides a list of the components it contains, as well as the specific list of installable files in each component.
Once you've downloaded an artefact,
use ExtractedArtefact::from_tar_gz()
or ExtractedArtefact::from_tar_xz()
to extract it and retrieve the metadata
(the place you got the artefact from
should tell you which format it's in).
If you have previously extracted an artefact,
you can re-read the metadata directly
using ExtractedArtefact::new()
.
First Example
extern crate rust_release_artefact as rra;
use std::error;
use std::fs;
use std::io;
use std::path;
fn install_from_tar_gz(
artefact_path: &path::Path,
stage: &path::Path,
component_name: &str,
dest_root: &path::Path,
) -> Result<(), Box<error::Error>> {
// Open the file containing the artefact.
let handle = fs::File::open(artefact_path)?;
// Extract it to the given staging path and read the metadata.
// We're assuming the staging path is already canonicalized, and
// the artefact is in .tar.gz format.
let extracted_artefact = rra::ExtractedArtefact::from_tar_gz(
io::BufReader::new(handle),
stage,
)?;
// Get the requested component from the artefact.
let component = extracted_artefact.components
.get(component_name)
.ok_or("Could not find component")?;
println!(
"Installing component {} version {} to {:?}",
component_name,
extracted_artefact.version,
dest_root,
);
// Install the component into the destination.
// We're also assuming dest_root is already canonicalized.
component.install_to(dest_root)?;
// All done!
Ok(())
}
Capabilities
Extract downloaded artefacts
Once you have downloaded a release artefact,
you can extract it into a staging area with
the ExtractedArtefact::from_tar_gz()
or ExtractedArtefact::from_tar_xz()
functions
(depending on the format).
extern crate rust_release_artefact as rra;
use std::fs;
use std::io;
use std::path;
# fn example() -> Result<(), Box<std::error::Error>> {
let handle = fs::File::open("path/to/artefact.tar.gz")?;
// Make sure the staging area exists.
let staging_area = path::Path::new("path/to/staging/area");
fs::create_dir_all(&staging_area)?;
// Canonicalize the staging area path, so Windows can handle long path
// names.
let staging_area = staging_area.canonicalize()?;
let extracted_artefact = rra::ExtractedArtefact::from_tar_gz(
io::BufReader::new(handle),
staging_area,
)?;
# Ok(())
# }
Read artefact metadata
An ExtractedArtefact
struct
represents the artefact's metadata,
including the components in this artefact
and the complete list of installable files in each component.
# extern crate rust_release_artefact as rra;
# fn example() -> Result<(), Box<std::error::Error>> {
# let extracted_artefact = rra::ExtractedArtefact::new("src")?;
println!("Version: {:?}", extracted_artefact.version);
println!("Git commit hash: {:?}", extracted_artefact.git_commit_hash);
for (name, component) in &extracted_artefact.components {
println!("Component: {:?} in {:?}", name, component.root);
for path in &component.files {
println!(" - {:?}", path);
}
}
# Ok(())
# }
Install components to a given destination
The Component
struct represents
an installable component of the artefact,
whose files are in the artefact's staging area,
ready to be installed to a target location.
The handy Component::install_to()
method
does exactly that.
# extern crate rust_release_artefact as rra;
# fn example() -> Result<(), Box<std::error::Error>> {
# let extracted_artefact = rra::ExtractedArtefact::new("src")?;
let component = extracted_artefact.components.get("my-component")
.ok_or("no such component?")?;
// Make sure the destination exists.
let destination = std::path::Path::new("path/to/install/destination");
std::fs::create_dir_all(&destination)?;
// Canonicalize the staging area path, so Windows can handle long path
// names.
let destination = destination.canonicalize()?;
component.install_to(destination)?;
# Ok(())
# }
Dependencies
~3–12MB
~152K SLoC