Skip to content

Commit 5fac943

Browse files
chore: docs improvements
Signed-off-by: Andrew Lilley Brinker <[email protected]>
1 parent d8ef825 commit 5fac943

File tree

3 files changed

+198
-56
lines changed

3 files changed

+198
-56
lines changed

omnibor/src/artifact_id/identify.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{
88
ArtifactId, InputManifest,
99
};
1010
use std::{
11-
ffi::OsStr,
11+
ffi::{OsStr, OsString},
1212
fs::File,
1313
io::{BufReader, Cursor, Read, Seek},
1414
ops::Deref,
@@ -77,6 +77,18 @@ where
7777
}
7878
}
7979

80+
impl<H> Identify<H> for &String
81+
where
82+
H: HashAlgorithm,
83+
{
84+
fn identify<P>(self, provider: P) -> Result<ArtifactId<H>, ArtifactIdError>
85+
where
86+
P: HashProvider<H>,
87+
{
88+
Path::new(self).identify(provider)
89+
}
90+
}
91+
8092
impl<H> Identify<H> for &OsStr
8193
where
8294
H: HashAlgorithm,
@@ -89,6 +101,18 @@ where
89101
}
90102
}
91103

104+
impl<H> Identify<H> for &OsString
105+
where
106+
H: HashAlgorithm,
107+
{
108+
fn identify<P>(self, provider: P) -> Result<ArtifactId<H>, ArtifactIdError>
109+
where
110+
P: HashProvider<H>,
111+
{
112+
Path::new(self).identify(provider)
113+
}
114+
}
115+
92116
impl<H> Identify<H> for &Path
93117
where
94118
H: HashAlgorithm,
@@ -142,6 +166,18 @@ where
142166
}
143167
}
144168

169+
impl<H> Identify<H> for Box<File>
170+
where
171+
H: HashAlgorithm,
172+
{
173+
fn identify<P>(self, provider: P) -> Result<ArtifactId<H>, ArtifactIdError>
174+
where
175+
P: HashProvider<H>,
176+
{
177+
self.deref().identify(provider)
178+
}
179+
}
180+
145181
impl<H> Identify<H> for Rc<File>
146182
where
147183
H: HashAlgorithm,

omnibor/src/artifact_id/identify_async.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ use crate::{
33
hash_algorithm::HashAlgorithm, hash_provider::HashProvider, object_type::Blob,
44
util::clone_as_boxstr::CloneAsBoxstr, ArtifactId,
55
};
6-
use std::{ffi::OsStr, path::Path};
6+
use std::{
7+
ffi::{OsStr, OsString},
8+
ops::Deref,
9+
path::{Path, PathBuf},
10+
};
711
use tokio::{
812
fs::File,
913
io::{AsyncRead, AsyncSeek, BufReader},
@@ -36,6 +40,18 @@ where
3640
}
3741
}
3842

43+
impl<H> IdentifyAsync<H> for &String
44+
where
45+
H: HashAlgorithm,
46+
{
47+
async fn identify_async<P>(self, provider: P) -> Result<ArtifactId<H>, ArtifactIdError>
48+
where
49+
P: HashProvider<H>,
50+
{
51+
Path::new(self).identify_async(provider).await
52+
}
53+
}
54+
3955
impl<H> IdentifyAsync<H> for &OsStr
4056
where
4157
H: HashAlgorithm,
@@ -48,6 +64,18 @@ where
4864
}
4965
}
5066

67+
impl<H> IdentifyAsync<H> for &OsString
68+
where
69+
H: HashAlgorithm,
70+
{
71+
async fn identify_async<P>(self, provider: P) -> Result<ArtifactId<H>, ArtifactIdError>
72+
where
73+
P: HashProvider<H>,
74+
{
75+
Path::new(self).identify_async(provider).await
76+
}
77+
}
78+
5179
impl<H> IdentifyAsync<H> for &Path
5280
where
5381
H: HashAlgorithm,
@@ -67,6 +95,18 @@ where
6795
}
6896
}
6997

98+
impl<H> IdentifyAsync<H> for &PathBuf
99+
where
100+
H: HashAlgorithm,
101+
{
102+
async fn identify_async<P>(self, provider: P) -> Result<ArtifactId<H>, ArtifactIdError>
103+
where
104+
P: HashProvider<H>,
105+
{
106+
self.deref().identify_async(provider).await
107+
}
108+
}
109+
70110
impl<H> IdentifyAsync<H> for &mut File
71111
where
72112
H: HashAlgorithm,

omnibor/src/lib.rs

Lines changed: 120 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! This crate implements the [OmniBOR][omnibor] specification, so you can
22
//! __identify artifacts__ like binaries and source code files and __track
3-
//! build dependencies__ in compilers and other build tools.
3+
//! build dependencies__ used to create them.
44
//!
55
//! You can identify a file like so:
66
//!
@@ -48,9 +48,9 @@
4848
//! Artifact ID in the "target artifact" whose build input it's describing.
4949
//!
5050
//! With Input Manifests, you get a [Merkle tree]-like record of build inputs,
51-
//! describing the full Artifact Dependency Graph (ADG)—every input used to build
52-
//! the final artifact. Any time a build input changes, all the Artifact IDs
53-
//! of anything derived from it change too! This enables easy detection of
51+
//! describing the full Artifact Dependency Graph (ADG)—every input used to
52+
//! build the final artifact. Any time a build input changes, all the Artifact
53+
//! IDs of anything derived from it change too! This enables easy detection of
5454
//! build differences, arbitrarily deep in an ADG.
5555
//!
5656
//! There are three ways to use the Rust OmniBOR implementation:
@@ -59,58 +59,95 @@
5959
//! - The [`omnibor` crate Foreign Function Interface (FFI)][ffi]
6060
//! - The [OmniBOR CLI][cli]
6161
//!
62-
//! # Creating Artifact IDs
62+
//! # Concepts
63+
//!
64+
//! In addition to [`ArtifactId`], [`InputManifest`], and
65+
//! [`InputManifestBuilder`], there are some key traits and types to know:
66+
//!
67+
//! - __[Identify and IdentifyAsync](#identify-and-identifyasync)__: Traits for
68+
//! types that can produce an [`ArtifactId`], synchronously or asynchronously.
69+
//! - __[Hash Algorithms](#hash-algorithms)__: Types implementing
70+
//! [`HashAlgorithm`](crate::hash_algorithm::HashAlgorithm), currently only
71+
//! [`Sha256`](crate::hash_algorithm::Sha256).
72+
//! - __[Hash Providers](#hash-providers)__: Types implementing
73+
//! [`HashProvider`](crate::hash_provider::HashProvider), currently
74+
//! [`RustCrypto`](crate::hash_provider::RustCrypto),
75+
//! [`OpenSsl`](crate::hash_provider::OpenSsl), and
76+
//! [`BoringSsl`](crate::hash_provider::BoringSsl).
77+
//! - __[Storage](#storage)__: Types implementing
78+
//! [`Storage`](crate::storage::Storage), currently
79+
//! [`FileSystemStorage`](crate::storage::FileSystemStorage) or
80+
//! [`InMemoryStorage`](crate::storage::InMemoryStorage).
81+
//! - __[Embedding](#embedding)__: Types implementing
82+
//! [`Embed`](crate::embed::Embed), currently
83+
//! [`NoEmbed`](crate::embed::NoEmbed),
84+
//! [`AutoEmbed`](crate::embed::AutoEmbed),
85+
//! and [`CustomEmbed`](crate::embed::CustomEmbed).
86+
//!
87+
//! ## Identify and IdentifyAsync
88+
//!
89+
//! There are two traits for types that can produce an [`ArtifactId`]:
90+
//!
91+
//! - [`Identify`]: Can produce an Artifact ID synchronously.
92+
//! - [`IdentifyAsync`]: Can produce an Artifact ID asynchronously.
93+
//!
94+
//! These traits are used as bounds on functions throughout the crate that
95+
//! expect an [`ArtifactId`].
96+
//!
97+
//! The full list of "identifiable" types, with an explanation of how they're
98+
//! processed, is as follows:
99+
//!
100+
//! | Type | `impl Identify` | `impl IdentifyAsync` | Explanation |
101+
//! |:-----------------------------------------------------------------|:----------------|:---------------------|:-------------------------------------------------------------|
102+
//! | `&[u8]` | ✅ | | Hash the bytes. |
103+
//! | `[u8; N]` | ✅ | | Hash the bytes. |
104+
//! | `&[u8; N]` | ✅ | | Hash the bytes. |
105+
//! | `&str` | ✅ | ✅ | Treat as a path, hash the contents of the file at that path. |
106+
//! | `&String` | ✅ | ✅ | Treat as a path, hash the contents of the file at that path. |
107+
//! | `&OsStr` | ✅ | ✅ | Treat as a path, hash the contents of the file at that path. |
108+
//! | `&OsString` | ✅ | ✅ | Treat as a path, hash the contents of the file at that path. |
109+
//! | `&Path` | ✅ | ✅ | Hash the contents of the file at that path. |
110+
//! | `&PathBuf` | ✅ | ✅ | Hash the contents of the file at that path. |
111+
//! | `File` | ✅ | | Hash the contents of the file. |
112+
//! | `&File` | ✅ | | Hash the contents of the file. |
113+
//! | `Box<File>` | ✅ | | Hash the contents of the file. |
114+
//! | `Rc<File>` | ✅ | | Hash the contents of the file. |
115+
//! | `Arc<File>` | ✅ | | Hash the contents of the file. |
116+
//! | `&mut tokio::fs::File` | | ✅ | Hash the contents of the file. |
117+
//! | `tokio::fs::File` | | ✅ | Hash the contents of the file. |
118+
//! | `BufReader<R> where R: Read + Seek` | ✅ | | Hash the bytes read off the reader. |
119+
//! | `tokio::io::BufReader<R> where R: AsyncRead + AsyncSync + Unpin` | | ✅ | Hash the bytes read off the reader. |
120+
//! | `&mut R where R: Read + Seek` | ✅ | | Hash the bytes read off the reader. |
121+
//! | `Cursor<T> where T: AsRef<[u8]>` | ✅ | | Hash the bytes read off the cursor. |
122+
//! | `InputManifest<H>` | ✅ | | Hash the on-disk representation of the manifest. |
123+
//! | `&InputManifest<H>` | ✅ | | Hash the on-disk representation of the manifest. |
124+
//! | `ArtifactId<H>` | ✅ | | Copy the Artifact ID. |
125+
//! | `&ArtifactId<H>` | ✅ | | Copy the Artifact ID. |
126+
//!
127+
//! ## Hash Algorithms
128+
//!
129+
//! Artifact IDs and Input Manifests are based on a hash algorithm.
130+
//! Today, OmniBOR only supports SHA-256, though alternatives may be added in
131+
//! the future if SHA-256's cryptographic properties are broken.
63132
//!
64-
//! Artifact IDs can be made from many different kinds of input types, and
65-
//! both synchronously and asynchronously, using the
66-
//! [`ArtifactId::new`] and [`ArtifactId::new_async`]
67-
//! methods, which take types that implement the [`Identify`] and
68-
//! [`IdentifyAsync`] traits, respectively.
133+
//! The [`HashAlgorithm`](crate::hash_algorithm::HashAlgorithm) trait is
134+
//! implemented by the [`Sha256`](crate::hash_algorithm::Sha256) type, and most
135+
//! types in this crate are parameterized over the hash algorithm.
69136
//!
70-
//! # Creating Input Manifests
137+
//! ## Hash Providers
71138
//!
72-
//! [`InputManifest`]s are created with an [`InputManifestBuilder`]. This type
73-
//! is parameterized over three things: the hash algorithm to use, the hash
74-
//! provider to use, and the storage to use. The usual flow of constructing
75-
//! an [`InputManifest`] is to create a new [`InputManifestBuilder`], add
76-
//! entries with [`InputManifestBuilder::add_relation`], and complete
77-
//! the build with [`InputManifestBuilder::build_for_target`].
139+
//! Hashes are produced by "hash providers," which implement the
140+
//! [`HashProvider`](crate::hash_provider::HashProvider) trait. Today we
141+
//! support [RustCrypto], [OpenSSL], and [BoringSSL], which you can turn on or
142+
//! off at compile time using features:
78143
//!
79-
//! # Hash Algorithms and Hash Providers
144+
//! | Feature | Provider | Type |
145+
//! |:----------------------|:-----------|:-------------------------------------------------|
146+
//! | `provider-rustcrypto` | RustCrypto | [`RustCrypto`](crate::hash_provider::RustCrypto) |
147+
//! | `provider-openssl` | OpenSSL | [`OpenSsl`](crate::hash_provider::OpenSsl) |
148+
//! | `provider-boringssl` | BoringSSL | [`BoringSsl`](crate::hash_provider::BoringSsl) |
80149
//!
81-
//! Artifact IDs and Input Manifests are based on a chosen hash algorithm.
82-
//! Today, OmniBOR only supports SHA-256, though alternatives may be added in
83-
//! the future if SHA-256's cryptographic properties are broken.
84-
//!
85-
//! The [`HashAlgorithm`](crate::hash_algorithm::HashAlgorithm) trait is
86-
//! implemented by the [`Sha256`](crate::hash_algorithm::Sha256) type, and
87-
//! both [`ArtifactId`]s and [`InputManifest`]s
88-
//! are parameterized over their [`HashAlgorithm`](crate::hash_algorithm::HashAlgorithm).
89-
//!
90-
//! We also support plugging in arbitrary "hash providers," libraries which
91-
//! provide implementations of cryptographic hashes. Today, we support
92-
//! [RustCrypto](https://github.com/rustcrypto), [OpenSSL](https://www.openssl.org/),
93-
//! and [BoringSSL](https://boringssl.googlesource.com/boringssl).
94-
//!
95-
//! All hash providers are represented by a type implementing the
96-
//! [`HashProvider`](crate::hash_provider::HashProvider) trait; so we have
97-
//! [`RustCrypto`](crate::hash_provider::RustCrypto),
98-
//! [`OpenSsl`](crate::hash_provider::OpenSsl), and
99-
//! [`BoringSsl`](crate::hash_provider::BoringSsl), respectively.
100-
//! All APIs in the crate for creating [`ArtifactId`]s or
101-
//! [`InputManifest`]s are
102-
//! parameterized over the [`HashProvider`](crate::hash_provider::HashProvider).
103-
//! We also provide convenience methods to choose one of the built-in providers.
104-
//!
105-
//! Providers are conditionally compiled in based on crate features. By default,
106-
//! only the `provider-rustcrypto` feature is turned on. Any combination of
107-
//! these may be included. In all cases, they are vendored in and do not link
108-
//! to any system instances of these libraries.
109-
//!
110-
//! In the future we plan to support linking to system instances of OpenSSL and
111-
//! BoringSSL.
112-
//!
113-
//! # Storing Input Manifests
150+
//! ## Storage
114151
//!
115152
//! We expose a [`Storage`](crate::storage::Storage) trait, representing the
116153
//! abstract interface needed for interacting with Input Manifests in memory or
@@ -126,7 +163,31 @@
126163
//! If you do not need to persist Input Manifests, use
127164
//! [`InMemoryStorage`](crate::storage::InMemoryStorage).
128165
//!
129-
//! # Specification Compliance
166+
//! ## Embedding
167+
//!
168+
//! When [`InputManifest`]s are built with [`InputManifestBuilder`], you pass
169+
//! in an embedding choice to select whether and how to embed the Artifact ID
170+
//! of the Input Manifest into the target artifact the manifest is describing.
171+
//!
172+
//! If you _do_ embed the manifest's Artifact ID, you ensure changes to the
173+
//! build inputs are reflected in the Artifact ID of the target artifact.
174+
//!
175+
//! There are currently three options, all implementing the
176+
//! [`Embed`](crate::embed::Embed) trait:
177+
//!
178+
//! - [`NoEmbed`](crate::embed::NoEmbed): Do not do embedding. The resulting
179+
//! manifest is considered "detached."
180+
//! - [`AutoEmbed`](crate::embed::AutoEmbed): Do embedding, with the `omnibor`
181+
//! crate inferring the filetype of the target artifact to determine how to
182+
//! embed in it. Requires the `infer-filetypes` feature is on.
183+
//! - [`CustomEmbed`](crate::embed::CustomEmbed): Do embedding, providing your
184+
//! own embedding function which takes the path to the target artifact, and
185+
//! an [`EmbedProvider`](crate::embed::EmbedProvider) which gives a hex string
186+
//! or bytes to embed, as appropriate.
187+
//!
188+
//! # Meta
189+
//!
190+
//! ## Specification Compliance
130191
//!
131192
//! OmniBOR is a [draft specification][omnibor_spec], and this implementation
132193
//! is the primary implementation of it.
@@ -140,7 +201,7 @@
140201
//! All differences from the specification and this library are in the process
141202
//! of being resolved through specification updates.
142203
//!
143-
//! # Comparison with other Software Identifiers
204+
//! ## Comparison with other Software Identifiers
144205
//!
145206
//! OmniBOR Artifact IDs are just one scheme for identifying software. Others
146207
//! include the [Common Platform Enumeration (CPE)][cpe],
@@ -222,7 +283,7 @@
222283
//! same inputs is not guaranteed, and will not be detectable by Derivation
223284
//! Store Path alone).
224285
//!
225-
//! # Contribute
286+
//! ## Contribute
226287
//!
227288
//! The following items are things we'd want to complete before committing to
228289
//! stability in this crate with a 1.0.0 release:
@@ -231,6 +292,8 @@
231292
//! - [ ] Support for auto-embedding in ELF files
232293
//! - [ ] Support for auto-embedding in Mach-O binary files
233294
//! - [ ] Support for auto-embedding in Portable Executable files
295+
//! - [ ] ADG Support
296+
//! - [ ] Support creating an Artifact Dependency Graph
234297
//! - [ ] FFI Support
235298
//! - [ ] Exposing the `InputManifestBuilder` API over FFI
236299
//! - [ ] Exposing the `InputManifest` API over FFI
@@ -264,6 +327,9 @@
264327
//! [swhid]: https://www.swhid.org/
265328
//! [Issue Tracker]: https://github.com/omnibor/omnibor-rs/issues
266329
//! [Contributor Guide]: https://github.com/omnibor/omnibor-rs/blob/main/CONTRIBUTING.md
330+
//! [RustCrypto]: https://github.com/rustcrypto
331+
//! [OpenSSL]: https://www.openssl.org/
332+
//! [BoringSSL]: https://boringssl.googlesource.com/boringssl
267333
268334
/*===============================================================================================
269335
* Lint Configuration

0 commit comments

Comments
 (0)