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
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `carwash scan --json` reports the disk's `available` bytes, and lists artifacts in `--sort`
order.
- `carwash clean --help` documents examples and exit codes.
- OS mode: `carwash os` lists the operating system's own space hogs on macOS, Linux and
Windows (app and browser caches, logs, crash reports, trash, temporary files,
package-manager caches, container data) with what cleaning each frees, in three tiers:
default (safe whenever), opt-in (a cost you choose) and report (never cleaned; instructions
to do it by hand). `carwash os clean` cleans the default tier, or areas named by id or
number. Directories are swept safely (contents only, no symlinks, one disk, recent and
in-use files kept, running apps' caches skipped); elevated tools are printed, or run through
sudo or UAC with `--escalate`. Areas can be added or overridden in `system.toml`.

### Changed
- In the TUI, marking a directory marks everything beneath it, including recently used and
Expand Down
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ every tab; in Reclaim, clicking selects a row and clicking it again expands it.
| `carwash outdated [PATH]` | Outdated and vulnerable dependencies. `--exit-code` for CI, `--no-vulns`, `--refresh` |
| `carwash caches` | Global caches and their sizes |
| `carwash caches clean ID...` | Clean caches; a parent id such as `rustup-toolchains` selects all its children |
| `carwash os` | The operating system's caches, logs, trash and temp files, with what cleaning frees |
| `carwash os clean [AREA...]` | Clean the default tier, or areas by id or number. `--escalate`, `--dry-run`, `--yes` |
| `carwash ecosystems` | Recognised ecosystems |
| `carwash history` | Space reclaimed so far |
| `carwash completions SHELL` | Shell completions |
Expand Down Expand Up @@ -153,6 +155,38 @@ reason), `removed`, `failed`, `bytes`, `free_before`, `free_after` and, with a g
do, 1 when a deletion failed, a pick was skipped or the goal could not be met, and 2 on
invalid usage or errors.

### OS mode

`carwash os` looks beyond your projects at the operating system's own space hogs on macOS,
Linux and Windows: app and browser caches, logs and crash reports, the trash, temporary
files, package-manager caches and container data. Each area is in one of three tiers:

- **default**: safe to clean whenever. It regenerates and holds nothing of yours, such as
app caches untouched for a week or a closed browser's cache. `carwash os clean` cleans these.
- **opt-in**: fine to clean, at a cost you choose: the trash (permanent), Spotify's cache
(re-downloads), `docker system prune`, or commands that need root. Name them to clean them.
- **report**: never cleaned by carwash, only measured, with instructions for doing it
yourself: iPhone backups, Messages attachments, Time Machine snapshots, the Windows
Installer cache, WSL disks.

```bash
carwash os # list areas, numbered, with what cleaning frees
carwash os clean # clean the default tier
carwash os clean 2,5-7 trash # clean areas by number or id
carwash os clean --escalate # also run commands that need root or administrator
```

Areas are swept or cleaned with the operating system's own tool (`journalctl --vacuum-time`,
`apt-get clean`, `qlmanage -r cache`, `Delete-DeliveryOptimizationCache`). Sweeping removes a
directory's contents and keeps the directory, never follows symlinks, junctions or other
links, stays on one disk, keeps recent entries where an age is shown, skips files in use,
cloud placeholders (OneDrive, iCloud) and the caches of apps that are running. carwash never
sweeps as root. Commands that need root or administrator rights are printed for you to run,
or run through `sudo` or a UAC prompt with `--escalate`. Areas in macOS privacy-protected
places (the Trash, Mail) need Full Disk Access for your terminal; listing never looks inside
them. Add or override areas in `~/.config/carwash/system.toml`, in the format of the built-in
[`system.toml`](crates/carwash-core/src/system.toml).

## Configuration

`~/.config/carwash/config.toml` (or `$CARWASH_CONFIG`). Every key is optional:
Expand Down
5 changes: 5 additions & 0 deletions crates/carwash-core/src/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ impl Dirs {
self.config.join("caches.toml")
}

/// User additions and overrides for OS mode areas.
pub fn system_file(&self) -> PathBuf {
self.config.join("system.toml")
}

pub fn size_cache_file(&self) -> PathBuf {
self.cache.join("sizes.json")
}
Expand Down
55 changes: 55 additions & 0 deletions crates/carwash/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ pub enum Command {
Outdated(OutdatedArgs),
/// List and clean per-user caches (package stores, toolchains, SDK and IDE caches).
Caches(CachesArgs),
/// List and clean the operating system's caches, logs, trash and temporary files.
#[command(after_long_help = OS_EXAMPLES)]
Os(OsArgs),
/// List the ecosystems carwash recognises.
Ecosystems(JsonArgs),
/// Show how much space carwash has reclaimed.
Expand Down Expand Up @@ -377,6 +380,58 @@ pub enum CachesAction {
},
}

#[derive(Debug, Args)]
pub struct OsArgs {
#[command(subcommand)]
pub action: Option<OsAction>,

/// Machine-readable output.
#[arg(long)]
pub json: bool,
}

#[derive(Debug, Subcommand)]
pub enum OsAction {
/// Clean areas by id or row number (default: every area in the default tier).
Clean {
/// Area ids or row numbers from `carwash os`, e.g. `app-caches` or `1,3-5`.
#[arg(value_name = "AREA", value_delimiter = ',')]
areas: Vec<String>,

/// Do not ask for confirmation.
#[arg(long, short = 'y')]
yes: bool,

/// Show what would be cleaned, then stop.
#[arg(long)]
dry_run: bool,

/// Run commands that need root or administrator rights, through sudo or a UAC
/// prompt (default: print them for you to run).
#[arg(long)]
escalate: bool,

/// Machine-readable output.
#[arg(long)]
json: bool,
},
}

const OS_EXAMPLES: &str = "\
Examples:
carwash os List areas on this machine with what cleaning frees
carwash os clean Clean every area in the default tier
carwash os clean 2,5-7 trash Clean rows 2, 5, 6 and 7 and the trash
carwash os clean --escalate Also run commands that need root or administrator

Tiers: default areas are safe to clean whenever; opt-in areas cost something (permanent,
re-downloads, privileged) and are cleaned only when named; report areas are never cleaned
by carwash, only measured, with instructions for doing it by hand.

Areas are swept (contents only, keeping recent entries where an age is shown, skipping
files in use and caches of running apps) or cleaned by the operating system's own tool.
carwash never sweeps as root; privileged tools run only with --escalate.";

#[derive(Debug, Args)]
pub struct JsonArgs {
/// Machine-readable output.
Expand Down
1 change: 1 addition & 0 deletions crates/carwash/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
pub mod caches;
pub mod clean;
pub mod info;
pub mod os;
pub mod outdated;
pub mod pick;
pub mod scan;
Expand Down
Loading
Loading