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
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@ What changed between versions of weft that you need to know about when you
update. To update, run `weft maintenance on`, pull and run `./setup.sh` again,
then run `weft maintenance off`.

## 2026-10-28 (341192de)

**The folders weft compiles in stop growing with every update.** Each
program weft compiles for a project now notes which compiled pieces and
source crates it used, and after every build weft keeps in its compile
folders (`~/.local/share/weft/worker-target/` and
`~/.local/share/weft/worker-crates/`) only what a program still on the
machine was built from. Before, every update left a full copy of weft's
libraries behind in each of them. The first project build after you update
clears out what older versions left, which can free tens of gigabytes. If
you build weft from source, `./setup.sh` now also removes from the
checkout's `target/` every compiled piece a newer build of it replaced, and
`WEFT_TARGET_CAP_GB` is gone.

## 2026-10-28 (0.2.277)

**If a project has its own nodes, or its own copy of the standard nodes, it
Expand Down
22 changes: 9 additions & 13 deletions crates/weft-cli/src/commands/runs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -634,9 +634,9 @@ pub async fn clean_build_plane() -> anyhow::Result<()> {
/// The files host builds leave on the machine that nothing uses any more:
/// the worker programs no install holds or names as its standard worker
/// (the standard worker of a weft an update replaced, a removed install's
/// programs), and the shared crates no build staged for
/// `WORKER_CACHE_RETENTION_DAYS` (the sources of a package since edited,
/// the workspace of a weft since updated). Needs no running install.
/// programs), and the shared crates no program left on the machine was
/// built from (the sources of a package since edited, the workspace of a
/// weft since updated). Needs no running install.
fn unused_worker_files(machine: &weft_platform_local::MachineLayout) -> anyhow::Result<()> {
let installs: Vec<String> = super::daemon::Install::every_on(machine.root())?.iter().map(|i| i.id.label_value().to_string()).collect();
let workers = weft_platform_local::images::reclaim_workers(&machine.workers(), &installs)?;
Expand All @@ -645,12 +645,10 @@ fn unused_worker_files(machine: &weft_platform_local::MachineLayout) -> anyhow::
} else {
println!("removed {} unused worker program(s)", workers.len());
}
let days = weft_compiler::worker_image::WORKER_CACHE_RETENTION_DAYS;
let crates = weft_compiler::build::reclaim_shared_crates(&machine.shared_crates(), std::time::Duration::from_secs(u64::from(days) * 24 * 3600))?;
if crates.is_empty() {
println!("no shared build crates unused for {days} days");
} else {
println!("removed {} shared build crate(s) unused for {days} days", crates.len());
match weft_platform_local::host_build::reclaim_shared_crates(machine)? {
None => println!("a build is staging its shared crates; they are left for the next clean"),
Some(crates) if crates.is_empty() => println!("no shared build crates unused"),
Some(crates) => println!("removed {} shared build crate(s) no program on this machine uses", crates.len()),
}
Ok(())
}
Expand Down Expand Up @@ -763,14 +761,12 @@ async fn report_compile_cache_size() -> anyhow::Result<()> {
let lanes = dir_size(&machine.compile_caches())?;
let crates = dir_size(&machine.shared_crates())?;
println!(
"worker compile caches: {:.1}GB in {} (every lane and the seed), and {:.1}GB of shared crates in {}; a build drops the \
per-project crates no build on this machine has linked for {} days, `weft clean --images --all` (the last step of \
`setup.sh`) the shared crates no build staged for as long, `weft clean --build-cache` drops everything now",
"worker compile caches: {:.1}GB in {} (every lane and the seed), and {:.1}GB of shared crates in {}; a build keeps \
in both only what a program on this machine was built from, `weft clean --build-cache` drops everything now",
gb(lanes),
machine.compile_caches().display(),
gb(crates),
machine.shared_crates().display(),
weft_compiler::worker_image::WORKER_CACHE_RETENTION_DAYS
);
match super::test_node::cache_size_bytes()? {
None => println!("node-test cache: nothing built on this host"),
Expand Down
19 changes: 14 additions & 5 deletions crates/weft-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ enum Cmd {
#[arg(long)]
out: std::path::PathBuf,
},
/// For setup.sh: remove from a cargo build folder (a checkout's
/// `target/`) every compiled piece a newer build of the same piece
/// replaced, keeping one copy of each way it is built (tests, clippy,
/// release), so the next build of any of them compiles nothing more.
#[command(name = "trim-cargo-target", hide = true)]
TrimCargoTarget { dir: std::path::PathBuf },
/// Make every image the release publishes exist locally: the runtime
/// image (every role weft has, in one), and for the cloud the worker
/// builder base and the full-library worker image, each under its
Expand Down Expand Up @@ -953,9 +959,9 @@ enum Cmd {
/// behind)
/// --images --build-plane
/// the worker programs no install on this machine
/// uses, the shared build crates no build staged
/// for 30 days, and the builder bases and node-test
/// images an older weft left
/// uses, the shared build crates no program on it
/// was built from, and the builder bases and
/// node-test images an older weft left
/// --build-cache drop the docker buildkit cache, the node-test cache
/// and the worker compile caches
/// --all with the journal subject: nuke every run
Expand Down Expand Up @@ -1006,8 +1012,8 @@ enum Cmd {
#[arg(long, default_value_t = false)]
images: bool,
/// With --images: only the build plane, the worker programs no
/// install on this machine uses, the shared build crates no build
/// staged for 30 days, and the builder bases and node-test images
/// install on this machine uses, the shared build crates no program
/// on it was built from, and the builder bases and node-test images
/// an older weft left that no install uses (kept whole while an
/// install has not recorded its own). Needs no running install;
/// setup.sh runs it after every start.
Expand Down Expand Up @@ -2089,6 +2095,9 @@ async fn run(cli: Cli, wanted: Result<weft_core::infra::Wanted, String>) -> anyh
Cmd::Ci { action: CiCmd::Add { cloud } } => commands::ci::add(ctx, cloud).await,
Cmd::Build { referenced } => commands::build::run(ctx, node_set(referenced)).await,
Cmd::BuildStandardWorker { out } => host_programs::pack_standard_program(&out).await,
Cmd::TrimCargoTarget { dir } => weft_platform_local::cargo_cache::drop_superseded(&dir).map(|swept| {
println!("removed {} superseded compiled pieces ({:.1}GB)", swept.units, swept.bytes as f64 / 1e9);
}),
Cmd::BuildImages { push, push_suffix, print, runtime_binary } => {
commands::build::run_build_images(push, push_suffix, print, runtime_binary.as_deref()).await
}
Expand Down
Loading
Loading