Skip to main content

bones_core/
lib.rs

1#![deny(unsafe_code)]
2//! bones-core library.
3
4pub mod cache;
5pub mod capabilities;
6pub mod clock;
7pub mod compact;
8pub mod config;
9pub mod crdt;
10pub mod dag;
11pub mod db;
12pub mod error;
13pub mod event;
14pub mod graph;
15pub mod lock;
16pub mod model;
17pub mod recovery;
18pub mod shard;
19pub mod sync;
20pub mod timing;
21pub mod undo;
22pub mod verify;
23
24use tracing::{info, instrument};
25
26/// # Conventions
27///
28/// - **Errors**: Use `anyhow::Result` for return types where appropriate.
29/// - **Logging**: Use `tracing` macros (`info!`, `warn!`, `error!`, `debug!`, `trace!`).
30
31#[instrument]
32pub fn init() {
33    info!("bones-core initialized");
34    // Ensure .bones/.gitattributes exists and has the union merge hint for events.
35    let bones_dir = std::path::Path::new(".bones");
36    if !bones_dir.is_dir() {
37        return;
38    }
39
40    let gitattributes_path = bones_dir.join(".gitattributes");
41    let attr_line = "events/** merge=union\n";
42    let legacy_attr = "events merge=union";
43
44    let mut content = if gitattributes_path.exists() {
45        std::fs::read_to_string(&gitattributes_path).unwrap_or_default()
46    } else {
47        String::new()
48    };
49
50    // Migrate old buggy pattern that only matched a file named `events`.
51    if content.contains(legacy_attr) && !content.contains("events/**") {
52        content = content.replace(legacy_attr, "events/** merge=union");
53        let _ = std::fs::write(&gitattributes_path, &content);
54    } else if !content.contains("events/** merge=union") {
55        if !content.is_empty() && !content.ends_with('\n') {
56            content.push('\n');
57        }
58        content.push_str(attr_line);
59        let _ = std::fs::write(gitattributes_path, content);
60    }
61}
62
63#[cfg(test)]
64mod tests {
65    #[test]
66    fn it_works() {
67        assert!(true);
68    }
69}