Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions crates/weave-cli/src/commands/apply.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use colored::Colorize;
use weave_core::git::find_repo_root;
use weave_crdt::{reconstruct_file_from_crdt, EntityStateDoc};

/// Materialize entity edits from the CRDT back onto the working files.
///
/// This is weave's write side: the CRDT is the authoritative source of an
/// entity's content, and this projects that content onto disk, reassembling
/// the file from its entities plus the interstitial text between them. It is
/// the counterpart to editing entities in the CRDT (via the MCP tools or
/// `weave claim` flows): edit entities, then `weave apply` to write the files.
pub fn run(files: &[String]) -> Result<(), Box<dyn std::error::Error>> {
if files.is_empty() {
return Err("Specify one or more files to apply, e.g. `weave apply src/lib.rs`".into());
}

let repo_root = find_repo_root()?;
let state_path = repo_root.join(".weave").join("state.automerge");
let state = EntityStateDoc::open(&state_path)?;

let mut applied = 0usize;
for file in files {
let reconstructed = reconstruct_file_from_crdt(&state, file)?;
if reconstructed.is_empty() {
println!(
" {} {} — no entities tracked in the CRDT, skipping",
"!".yellow().bold(),
file
);
continue;
}

let target = repo_root.join(file);
let before = std::fs::read_to_string(&target).unwrap_or_default();
if before == reconstructed {
println!(" {} {} — already up to date", "·".dimmed(), file);
continue;
}

std::fs::write(&target, &reconstructed)?;
applied += 1;
println!(" {} {} — materialized from CRDT", "✓".green().bold(), file);
}

println!(
"{} {} file(s) written from the CRDT.",
"weave apply:".bold(),
applied
);
Ok(())
}
1 change: 1 addition & 0 deletions crates/weave-cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod apply;
pub mod bench;
pub mod bench_repo;
pub mod claim;
Expand Down
6 changes: 6 additions & 0 deletions crates/weave-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ enum Commands {
},
/// Remove weave merge driver from the current Git repo
Unsetup,
/// Materialize entity edits from the CRDT back onto the working files
Apply {
/// One or more files to write from the CRDT
files: Vec<String>,
},
/// Preview what a merge between branches would look like
Preview {
/// The branch to merge into HEAD
Expand Down Expand Up @@ -99,6 +104,7 @@ fn main() {
global,
} => commands::setup::run(driver.as_deref(), local, global),
Commands::Unsetup => commands::setup::unsetup(),
Commands::Apply { ref files } => commands::apply::run(files),
Commands::Preview {
ref branch,
ref file,
Expand Down