بِسْمِ ٱللَّهِ ٱلرَّحْمَـٰنِ ٱلرَّحِيمِ
Build Guide
How to build refac from source, keep the installed binary current, and set up a local development loop.
This page will inshallah take you from a checkout to a development loop that stays current.
Build
The crate requires Rust 1.99 or newer. rust-toolchain.toml pins development to Rust 1.99.0 with rustfmt and rust-analyzer. Use Cargo in the normal way:
cargo build # debug build
cargo build --release # release buildOutputs:
target/debug/refactarget/release/refactarget/debug/create_testbed, the generator for sample projects
Install and keep it current
The expected setup is that refac is reachable as ~/.local/bin/refac. The preferred way is the script, which builds, links, and verifies:
scripts/install.shRun it after every pull, checkout, or source change. It is idempotent and takes seconds when nothing changed. It runs cargo build --release, points ~/.local/bin/refac at target/release/refac, and then checks three things. It stops with exit code 1 and the reason when one of them fails:
- A
refacis found on thePATH. If not,~/.local/binis missing from it. - That
refacis this checkout'starget/release/refacand not another copy that shadows it. refac --versionnames the commit that is checked out.
installed and current: refac 0.1.4 (55b157a, built 2026-10-09 20:09 UTC)The stamp comes from build.rs and exists in the release profile only, so debug and test builds do not recompile after every commit. They print dev build. +dirty after the commit means a file under src/, Cargo.toml, Cargo.lock, or build.rs differs from that commit. The helper scripts in scripts/ are read from the checkout at run time and are not compiled in. To check without building, compare refac --version with git rev-parse --short HEAD.
By hand, the same is a symlink, which follows every rebuild, or a copy, which is a fixed snapshot:
mkdir -p ~/.local/bin
ln -sf "$(pwd)/target/release/refac" ~/.local/bin/refac
cp target/release/refac ~/.local/bin/refacDisk
The installed binary is one file of about 36 MB. The 1.5 GB around it in target/release is build cache, mostly the embedded rust-analyzer, and it is what makes a repeat build take a fraction of a second, so keep it. Deleting target/release also deletes the binary that the link points to, and scripts/install.sh brings it back in about 4 minutes. The much larger debug and test programs are a by-product of cargo test and collect stale copies after toolchain or dependency changes.
CLI during development
Show help without installing:
cargo run -- --help
cargo run -- move --helpRun a move directly:
cargo run -- move \
--project-path /absolute/path/to/project \
--source-path src/old_file.ts \
--target-path src/new_file.tsRun a semantic Rust module move:
cargo run -- move-module \
--project-path /absolute/path/to/cargo-workspace \
crate::engine::matching \
crate::domain::matchingSet REFAC_PROJECT_PATH to avoid repeating --project-path. For move, point it at the concrete package root. Repeat --source-path and --target-path to run several moves in one call, and add --json for machine-readable output.
Testbed generator
create_testbed generates sample projects for manual verification:
cargo run --bin create_testbedIt recreates Trials/0_Refac_Tree/ with sample projects for TypeScript, Python, Rust, Go, and Dart. Each project has internal references, so a move can be checked against real imports and module declarations.
Basic development workflow
scripts/install.shbuilds, links, and verifies the release binary.- Run
cargo testafter a behavior change. cargo run --bin create_testbedregenerates the samples when you need them.- Run
refac move ...against a concrete project. - Verify the project still builds with its native toolchain (
cargo check,go build ./..., and so on). It should inshallah build without an edit by hand.