refolder 0.2.0

A CLI tool that redistributes files matching a pattern into evenly sized subfolders.
Documentation
# refolder

`refolder` is a small Rust CLI that moves files matching a glob pattern into an equal number of subfolders.

## Install

You can install from a git repo with:

```bash
cargo install --git https://github.com/trentzz/refolder.git
```

Or once published:

```bash
cargo install refolder
```

## Usage

```bash
refolder "/path/to/files" --matching "*.txt" --subfolders 3 --prefix "example"
```

```text
Move matching files into equally-sized subfolders

Usage: refolder [OPTIONS] --subfolders <SUBFOLDERS> <PATH>

Arguments:
  <PATH>  Path to the directory to search

Options:
  -m, --matching <MATCHING>        Glob pattern for matching files (shell-style) [default: *]
  -s, --subfolders <SUBFOLDERS>    Number of subfolders to split into
  -p, --prefix <PREFIX>            Prefix for created subfolders [default: group]
      --suffix <SUFFIX>            Suffix style: numbers | letters | none [default: numbers]
  -o, --output-dir <PATH>          Directory where subfolders are created. Defaults to the source path
      --sort <MODE>                Sort order before distribution: name | none | size | size-desc [default: name]
  -r, --recursive                  Recurse into subdirectories
      --dry-run                    Print actions without performing them
  -f, --force                      Overwrite existing files/folders in destination
  -v, --verbose                    Print each file move to stderr as it happens
      --no-color                   Suppress all ANSI colour codes in output
  -h, --help                       Print help
  -V, --version                    Print version
```

> [!NOTE]
> `--force` will overwrite files in the destination if necessary. Without `--force`, an existing destination file causes an error.

## Examples

### Simple usage

```bash
refolder "/path/to/files" --matching "*.txt" --subfolders 4 --prefix "example"
```

Resulting folders:

```text
.
├── example-1
│   ├── file10.txt
│   ├── file11.txt
│   └── file1.txt
├── example-2
│   ├── file12.txt
│   ├── file2.txt
│   └── file3.txt
├── example-3
│   ├── file4.txt
│   ├── file5.txt
│   └── file6.txt
└── example-4
    ├── file7.txt
    ├── file8.txt
    └── file9.txt
```

Files are distributed as evenly as possible.

### Dry run

```bash
$ refolder . --matching '*.txt' --prefix example --subfolders 4 --recursive --suffix letters --dry-run
.
├── example-a
│   ├── file1.txt
│   ├── file10.txt
│   └── file11.txt
├── example-b
│   ├── file12.txt
│   ├── file2.txt
│   └── file3.txt
├── example-c
│   ├── file4.txt
│   ├── file5.txt
│   └── file6.txt
└── example-d
    ├── file7.txt
    ├── file8.txt
    └── file9.txt

Summary:
  Total folders: 4
  Total files:   12
  Mode:          dry-run (no changes made)
```

### Output to a different directory

```bash
refolder /data/raw --matching "*.csv" --subfolders 3 --output-dir /data/sorted
```

Subfolders are created inside `/data/sorted` rather than `/data/raw`. The output directory must already exist.

### Sorting files before distribution

```bash
refolder /data/raw --matching "*.bin" --subfolders 4 --sort size
```

Files are sorted smallest-first before being distributed. Use `size-desc` for largest-first, `name` for alphabetical (the default), or `none` to use filesystem order.

## Behaviour notes

- After a successful run, a summary is printed: e.g. `Moved 42 files into 5 folders (5 created).`
- Dry-run mode prints the planned folder tree and a summary without moving any files.
- If files already sit in subfolders that match the prefix and suffix pattern (e.g. `example-1`), refolder treats those as sources and collects their files before redistributing. This lets you re-run with a different `--subfolders` count.
- The distribution ensures any two target folders differ in file count by at most 1.
- Moves use `fs::rename` and fall back to copy-and-remove if the source and destination are on different filesystems.
- Colour output is enabled when stdout is a TTY. Pass `--no-color` or set the `NO_COLOR` environment variable to suppress it.
- `--suffix none` with `--subfolders` greater than 1 returns an error, since all files would land in a single folder with no way to distinguish them.