1mod document;
11mod metadata;
12
13pub use document::{
14 PackageMetadata, Release, ensure_releases_section, recent_releases, update_document,
15 update_document_with_releases, update_releases_section,
16};
17
18pub mod readme {
20 use bake::{Context, Error, Result};
21 use std::fs;
22 use std::io::Write;
23 use std::path::PathBuf;
24
25 use super::{metadata::read_project_package, recent_releases, update_document_with_releases};
26
27 #[bake::task]
29 pub fn update(
30 context: &mut Context,
31 #[bake(
32 default = "readme.md",
33 help = "readme file relative to the project root."
34 )]
35 path: PathBuf,
36 ) -> Result<()> {
37 let path = context.root().join(path).canonicalize()?;
38 let document = fs::read_to_string(&path)
39 .map_err(|error| Error::new(format!("{}: {error}", path.display())))?;
40 let package = read_project_package(context)?;
41 let release_path = context.root().join("releases.md");
42 let releases = if release_path.is_file() {
43 let release_document = fs::read_to_string(&release_path)
44 .map_err(|error| Error::new(format!("{}: {error}", release_path.display())))?;
45 recent_releases(&release_document)
46 } else {
47 Vec::new()
48 };
49 let updated = update_document_with_releases(&document, package.as_ref(), &releases);
50
51 if updated == document {
52 return Ok(());
53 }
54
55 let directory = path
56 .parent()
57 .ok_or_else(|| Error::new("readme file has no parent directory"))?;
58 let mut temporary = tempfile::NamedTempFile::new_in(directory)?;
59 temporary.write_all(updated.as_bytes())?;
60 temporary
61 .as_file()
62 .set_permissions(fs::metadata(&path)?.permissions())?;
63 temporary.as_file().sync_all()?;
64 temporary
65 .persist(&path)
66 .map_err(|error| Error::from(error.error))?;
67 Ok(())
68 }
69}