|
24 | 24 | //! - Extensible with metadata: The default inventory format covers a lot of common use cases,
|
25 | 25 | //! but if you need more, you can extend it by adding custom metadata to each artifact.
|
26 | 26 | //!
|
27 |
| -//! ## Example consumer |
| 27 | +//! ## Example usage |
28 | 28 | //!
|
29 |
| -//! This example uses the `inventory-semver` and `inventory-sha2` features to parse an existing |
30 |
| -//! inventory file, compare versions via semver logic: |
| 29 | +//! This example demonstrates: |
| 30 | +//! * Creating an artifact using the `inventory-sha2` and `inventory-semver` features. |
| 31 | +//! * Adding the artifact to an inventory. |
| 32 | +//! * Serializing and deserializing the inventory [to](Inventory#method.fmt) and [from](Inventory::from_str) TOML. |
| 33 | +//! * [Resolving an inventory artifact](Inventory::resolve) specifying relevant OS, architecture, and version requirements. |
| 34 | +//! * Using the resolved artifact's checksum value to verify "downloaded" data. |
31 | 35 | //!
|
32 |
| -//! ```no_run,rust |
33 |
| -//! use libherokubuildpack::inventory::{artifact::{Os, Arch}, Inventory, checksum::Checksum}; |
| 36 | +//! ```rust |
| 37 | +//! use libherokubuildpack::inventory::{artifact::{Arch, Artifact, Os}, Inventory, checksum::Checksum}; |
34 | 38 | //! use semver::{Version, VersionReq};
|
35 |
| -//! use libherokubuildpack::download::download_file; |
36 |
| -//! use std::path::Path; |
37 |
| -//! use std::str::FromStr; |
| 39 | +//! use sha2::{Sha256, Digest}; |
38 | 40 | //!
|
39 |
| -//! #[cfg(feature = "inventory-sha2")] |
40 |
| -//! #[cfg(feature = "inventory-semver")] |
41 |
| -//! use sha2::Sha256; |
| 41 | +//! // Create an artifact with a SHA256 checksum and `semver::Version` |
| 42 | +//! let new_artifact = Artifact { |
| 43 | +//! version: Version::new(1, 0, 0), |
| 44 | +//! os: Os::Linux, |
| 45 | +//! arch: Arch::Arm64, |
| 46 | +//! url: "https://example.com/foo.txt".to_string(), |
| 47 | +//! checksum: "sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae" |
| 48 | +//! .parse::<Checksum<Sha256>>() |
| 49 | +//! .unwrap(), |
| 50 | +//! metadata: None, |
| 51 | +//! }; |
42 | 52 | //!
|
43 |
| -//! let inventory: Inventory<Version, Sha256, Option<()>> = |
44 |
| -//! std::fs::read_to_string("inventory.toml") |
45 |
| -//! .unwrap() |
46 |
| -//! .parse() |
| 53 | +//! // Create an inventory and add the artifact |
| 54 | +//! let mut inventory = Inventory::<Version, Sha256, Option<()>>::new(); |
| 55 | +//! inventory.push(new_artifact.clone()); |
| 56 | +//! |
| 57 | +//! // Serialize the inventory to TOML |
| 58 | +//! let inventory_toml = inventory.to_string(); |
| 59 | +//! assert_eq!( |
| 60 | +//! r#"[[artifacts]] |
| 61 | +//! version = "1.0.0" |
| 62 | +//! os = "linux" |
| 63 | +//! arch = "arm64" |
| 64 | +//! url = "https://example.com/foo.txt" |
| 65 | +//! checksum = "sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae" |
| 66 | +//! "#, |
| 67 | +//! inventory_toml |
| 68 | +//! ); |
| 69 | +//! |
| 70 | +//! // Deserialize the inventory from TOML |
| 71 | +//! let parsed_inventory = inventory_toml |
| 72 | +//! .parse::<Inventory<Version, Sha256, Option<()>>>() |
47 | 73 | //! .unwrap();
|
48 |
| -//! let requirement = VersionReq::parse("= 1.0.0").unwrap(); |
49 |
| -//! if let Some(artifact) = inventory.resolve(Os::Linux, Arch::Amd64, &requirement) { |
50 |
| -//! // Downloading the artifact |
51 |
| -//! println!("Installing {requirement:?} from {}", artifact.url); |
52 |
| -//! let path = Path::new("path/to/binary"); |
53 |
| -//! download_file(&artifact.url, &path) |
54 |
| -//! .unwrap(); |
55 | 74 | //!
|
56 |
| -//! // Validating the checksum |
57 |
| -//! Checksum::<Sha256>::from_str(&std::fs::read_to_string(&path).unwrap()) |
58 |
| -//! .and_then(|downloaded_file_digest| { |
59 |
| -//! if downloaded_file_digest == artifact.checksum { |
60 |
| -//! Ok(()) |
61 |
| -//! } else { |
62 |
| -//! panic!( |
63 |
| -//! "Invalid checksum for download {url}: expected {expected:?}, got {actual:?}", |
64 |
| -//! url = artifact.url, |
65 |
| -//! expected = hex::encode(&artifact.checksum.value), |
66 |
| -//! actual = hex::encode(&downloaded_file_digest.value), |
67 |
| -//! ) |
68 |
| -//! } |
69 |
| -//! }).unwrap() |
70 |
| -//! } else { |
71 |
| -//! panic!("Could not install artifact {requirement:?} from inventory.toml"); |
72 |
| -//! } |
| 75 | +//! // Resolve the artifact by OS, architecture, and version requirement |
| 76 | +//! let version_req = VersionReq::parse("=1.0.0").unwrap(); |
| 77 | +//! let resolved_artifact = parsed_inventory.resolve(Os::Linux, Arch::Arm64, &version_req).unwrap(); |
| 78 | +//! |
| 79 | +//! assert_eq!(&new_artifact, resolved_artifact); |
| 80 | +//! |
| 81 | +//! // Verify checksum of the resolved artifact |
| 82 | +//! let downloaded_data = "foo"; // Example downloaded file content |
| 83 | +//! let downloaded_checksum = Sha256::digest(downloaded_data).to_vec(); |
| 84 | +//! assert_eq!(resolved_artifact.checksum.value, downloaded_checksum); |
73 | 85 | //! ```
|
74 | 86 | pub mod artifact;
|
75 | 87 | pub mod checksum;
|
|
0 commit comments