pub struct ReleaseId(/* private fields */);Expand description
A validated opaque release identifier owned by the consumer.
Implementations§
Source§impl ReleaseId
impl ReleaseId
Sourcepub fn new(value: impl Into<String>) -> Result<Self>
pub fn new(value: impl Into<String>) -> Result<Self>
Creates a release identifier after rejecting empty or unsafe control-character input.
Examples found in repository?
examples/receipts.rs (line 53)
35fn build(
36 new: &[u8],
37 old: Option<&[u8]>,
38) -> Result<(PathBuf, InstallPlan), Box<dyn std::error::Error>> {
39 let base = temp_root("eggup-receipts");
40 let inputs = base.join("inputs");
41 let root = base.join("install");
42 fs::create_dir_all(&inputs)?;
43 fs::create_dir_all(root.join("bin"))?;
44 fs::write(inputs.join("app"), new)?;
45 if let Some(old) = old {
46 fs::write(root.join("bin/app"), old)?;
47 }
48 let digest = eggup_core::hash_file(&inputs.join("app"))?;
49 let member = ArtifactMember::new(MemberId::new("main")?, inputs.join("app"), "bin/app")?
50 .with_integrity(IntegrityRequirement::Sha256(digest));
51 let plan = InstallPlan::new(
52 ProductId::new("demo")?,
53 ReleaseId::new("5.0.0")?,
54 &root,
55 ArtifactSet::single(member)?,
56 )?;
57 // Leak the base via the plan's root; caller cleans `root.parent()`.
58 Ok((base, plan))
59}More examples
examples/one_member.rs (line 37)
25fn main() -> Result<(), Box<dyn std::error::Error>> {
26 let base = temp_root("eggup-one-member");
27 let inputs = base.join("inputs");
28 let root = base.join("install");
29 fs::create_dir_all(inputs.join("bin"))?;
30 fs::create_dir_all(root.join("bin"))?;
31 fs::write(inputs.join("app"), b"new-app")?;
32 let digest = eggup_core::hash_file(&inputs.join("app"))?;
33 let member = ArtifactMember::new(MemberId::new("main")?, inputs.join("app"), "bin/app")?
34 .with_integrity(IntegrityRequirement::Sha256(digest));
35 let plan = InstallPlan::new(
36 ProductId::new("demo")?,
37 ReleaseId::new("1.0.0")?,
38 &root,
39 ArtifactSet::single(member)?,
40 )?;
41 let receipt = plan
42 .prepare()?
43 .verify_integrity()?
44 .validate(&AllValidators::new())?
45 .commit(CommitOwnership::new(
46 &ExistingAsOwnedVerifier,
47 AbsentPolicy::AllowCreate,
48 ))?;
49 assert_eq!(receipt.disposition(), TransactionDisposition::Committed);
50 assert_eq!(fs::read(root.join("bin/app"))?, b"new-app");
51 let _ = fs::remove_dir_all(&base);
52 println!("one-member commit: {:?}", receipt.disposition());
53 Ok(())
54}examples/custom_validator.rs (line 58)
46fn main() -> Result<(), Box<dyn std::error::Error>> {
47 let base = temp_root("eggup-custom-validator");
48 let inputs = base.join("inputs");
49 let root = base.join("install");
50 fs::create_dir_all(&inputs)?;
51 fs::create_dir_all(root.join("bin"))?;
52 fs::write(inputs.join("app"), b"release-marker-42")?;
53 let digest = eggup_core::hash_file(&inputs.join("app"))?;
54 let member = ArtifactMember::new(MemberId::new("main")?, inputs.join("app"), "bin/app")?
55 .with_integrity(IntegrityRequirement::Sha256(digest));
56 let plan = InstallPlan::new(
57 ProductId::new("demo")?,
58 ReleaseId::new("3.0.0")?,
59 &root,
60 ArtifactSet::single(member)?,
61 )?;
62 let validator = ContainsMarker {
63 member: MemberId::new("main")?,
64 marker: b"marker-42".to_vec(),
65 };
66 let receipt = plan
67 .prepare()?
68 .verify_integrity()?
69 .validate(&validator)?
70 .commit(CommitOwnership::new(
71 &ExistingAsOwnedVerifier,
72 AbsentPolicy::AllowCreate,
73 ))?;
74 assert_eq!(receipt.disposition(), TransactionDisposition::Committed);
75 let _ = fs::remove_dir_all(&base);
76 println!("custom validator commit: {:?}", receipt.disposition());
77 Ok(())
78}examples/ownership.rs (line 38)
24fn main() -> Result<(), Box<dyn std::error::Error>> {
25 let base = temp_root("eggup-ownership");
26 let inputs = base.join("inputs");
27 let root = base.join("install");
28 fs::create_dir_all(&inputs)?;
29 fs::create_dir_all(root.join("bin"))?;
30 fs::write(inputs.join("app"), b"new-app")?;
31 fs::write(root.join("bin/app"), b"old-app")?;
32 let new_digest = eggup_core::hash_file(&inputs.join("app"))?;
33 let old_digest = eggup_core::hash_file(&root.join("bin/app"))?;
34 let member = ArtifactMember::new(MemberId::new("main")?, inputs.join("app"), "bin/app")?
35 .with_integrity(IntegrityRequirement::Sha256(new_digest));
36 let plan = InstallPlan::new(
37 ProductId::new("demo")?,
38 ReleaseId::new("4.0.0")?,
39 &root,
40 ArtifactSet::single(member)?,
41 )?;
42 // Prove the live file is the expected old deployment; deny creation of
43 // absent destinations (replacement-only policy).
44 let verifier = ExactDigestVerifier::new(vec![(MemberId::new("main")?, old_digest)]);
45 let receipt = plan
46 .prepare()?
47 .verify_integrity()?
48 .validate(&AllValidators::new())?
49 .commit(CommitOwnership::new(&verifier, AbsentPolicy::DenyCreate))?;
50 assert_eq!(receipt.disposition(), TransactionDisposition::Committed);
51 assert_eq!(fs::read(root.join("bin/app"))?, b"new-app");
52 let _ = fs::remove_dir_all(&base);
53 println!("ownership-verified commit: {:?}", receipt.disposition());
54 Ok(())
55}examples/multi_member.rs (line 48)
24fn main() -> Result<(), Box<dyn std::error::Error>> {
25 let base = temp_root("eggup-multi-member");
26 let inputs = base.join("inputs");
27 let root = base.join("install");
28 fs::create_dir_all(&inputs)?;
29 fs::create_dir_all(root.join("bin"))?;
30 fs::write(inputs.join("main"), b"new-main")?;
31 fs::write(inputs.join("helper"), b"new-helper")?;
32 fs::write(root.join("bin/main"), b"old-main")?;
33 fs::write(root.join("bin/helper"), b"old-helper")?;
34 let main_digest = eggup_core::hash_file(&inputs.join("main"))?;
35 let helper_digest = eggup_core::hash_file(&inputs.join("helper"))?;
36 let members = ArtifactSet::new(vec![
37 ArtifactMember::new(MemberId::new("main")?, inputs.join("main"), "bin/main")?
38 .with_integrity(IntegrityRequirement::Sha256(main_digest)),
39 ArtifactMember::new(
40 MemberId::new("helper")?,
41 inputs.join("helper"),
42 "bin/helper",
43 )?
44 .with_integrity(IntegrityRequirement::Sha256(helper_digest)),
45 ])?;
46 let plan = InstallPlan::new(
47 ProductId::new("bundle")?,
48 ReleaseId::new("2.0.0")?,
49 &root,
50 members,
51 )?;
52 let receipt = plan
53 .prepare()?
54 .verify_integrity()?
55 .validate(&AllValidators::new())?
56 .commit(CommitOwnership::new(
57 &ExistingAsOwnedVerifier,
58 AbsentPolicy::AllowCreate,
59 ))?;
60 assert_eq!(receipt.disposition(), TransactionDisposition::Committed);
61 assert_eq!(fs::read(root.join("bin/main"))?, b"new-main");
62 assert_eq!(fs::read(root.join("bin/helper"))?, b"new-helper");
63 let _ = fs::remove_dir_all(&base);
64 println!("multi-member commit: {:?}", receipt.disposition());
65 Ok(())
66}Trait Implementations§
impl Eq for ReleaseId
impl StructuralPartialEq for ReleaseId
Auto Trait Implementations§
impl Freeze for ReleaseId
impl RefUnwindSafe for ReleaseId
impl Send for ReleaseId
impl Sync for ReleaseId
impl Unpin for ReleaseId
impl UnsafeUnpin for ReleaseId
impl UnwindSafe for ReleaseId
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more