# Sortify ๐Ÿš€ [![Go](https://github.com/ahmedthebest31/sortify/actions/workflows/ci.yml/badge.svg)](https://github.com/ahmedthebest31/sortify/actions/workflows/ci.yml) [![Release](https://github.com/ahmedthebest31/sortify/actions/workflows/release.yml/badge.svg)](https://github.com/ahmedthebest31/sortify/actions/workflows/release.yml) [![Go Version](https://img.shields.io/github/go-mod/go-version/ahmedthebest31/sortify)](https://golang.org/) [![License](https://img.shields.io/github/license/ahmedthebest31/sortify)](LICENSE) [![Downloads](https://img.shields.io/github/downloads/ahmedthebest31/sortify/total)](https://github.com/ahmedthebest31/sortify/releases) **Sortify** ๐Ÿ—‚๏ธ is a fast, safety-first CLI tool that automatically organizes files in a directory into categorized folders (Images, Documents, Videos, Archives, Code, etc.). Written in Go, it compiles to a single static binary with no runtime dependencies. Supports dry-run previews, filename sanitization, real-time watch mode, and custom configuration. --- ## Features โœจ - **๐Ÿ“‚ Smart categorization** -- files are sorted by extension into logical folders - **๐Ÿ‘€ Watch mode** -- monitor a directory in real-time and organize files as they arrive (recursive) - **๐Ÿ›ก๏ธ Safety guards** -- prevents accidental organization of system roots, home, or Windows system directories - **๐Ÿ’ฌ Interactive mode** -- if you run without flags, you get a guided prompt - **๐Ÿ‘๏ธ Dry-run mode** -- preview all changes without moving a single file - **๐Ÿงน Filename sanitization** -- remove emojis, collapse spaces, normalize case - **๐Ÿ”ข Number patching** -- zero-pad numbers in filenames (lesson1 -> lesson001) - **โš™๏ธ Custom configuration** -- JSON-based config for categories, ignore patterns, and more - **๐Ÿ’ป Cross-platform** -- Windows, macOS, Linux (amd64 + arm64) - **๐Ÿ“ฆ Single binary** -- no dependencies, no runtime required --- ## Installation ๐Ÿ“ฅ ### Via Go (any platform) ๐Ÿน ```bash go install github.com/ahmedthebest31/sortify@latest ``` Make sure `$GOPATH/bin` is in your `PATH`. ### Via GitHub Releases โฌ‡๏ธ Download the pre-built binary for your platform from the [Releases page](https://github.com/ahmedthebest31/sortify/releases). - ๐Ÿง Linux: `sortify_Linux_x86_64.tar.gz` - ๐ŸŽ macOS: `sortify_Darwin_x86_64.tar.gz` or `sortify_Darwin_arm64.tar.gz` (Apple Silicon) - ๐ŸชŸ Windows: `sortify_Windows_x86_64.exe` ### Via Winget (Windows) ๐ŸชŸ ```powershell winget install AhmedSamy.Sortify ``` --- ## Usage ๐Ÿ› ๏ธ ``` sortify [flags] sortify --dir sortify watch --dir sortify --version sortify --help ``` ### Commands | Command | Description | |---------|-------------| | `sortify` | Run interactive mode (prompts for directory) | | `sortify --dir ./Downloads` | Organize a specific directory | | `sortify --dir ./Downloads --dry-run` | Preview changes without moving files | | `sortify watch --dir ./Downloads` | Watch a directory and organize files in real time | ### Global Flags | Flag | Description | |------|-------------| | `--dir` string | Target directory to organize | | `--dry-run` | Preview changes without moving files | | `--verbose` | Show detailed per-file logging | | `--config` string | Path to a custom `config.json` | | `--version` | Show version information | | `-h, --help` | Show help | ### Examples ```bash # Organize Downloads (interactive) sortify --dir ~/Downloads # Preview what would happen sortify --dir ~/Downloads --dry-run --verbose # Keep watching Desktop and auto-organize sortify watch --dir ~/Desktop # Use a custom config sortify --dir ~/Downloads --config ~/my-config.json ``` --- ## Configuration โš™๏ธ Sortify reads `config.json` from the current directory (or a custom path via `--config`). If no file is found, sensible defaults are used. ```json { "categories": { "images": [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp", ".svg"], "documents": [".pdf", ".docx", ".txt", ".xlsx", ".pptx", ".csv", ".md"], "code": [".go", ".py", ".js", ".ts", ".html", ".css", ".java", ".rs", ".cpp", ".h"] }, "ignore": [".tmp", ".DS_Store", "thumbs.db"], "sanitizeNames": true, "sanitizeOptions": { "removeEmojis": true, "collapseSpaces": true, "normalizeCase": "lower" }, "patchNumbers": false, "numberWidth": 3, "numberPatchingMode": "first", "dryRun": false, "logLevel": "info", "logPath": "organizer.log", "printSummary": true, "verboseOutput": false } ``` ### Configuration fields | Field | Type | Default | Description | |-------|------|---------|-------------| | `categories` | object | go, py, js, etc. | Map of folder names to file extension lists | | `ignore` | array | .tmp, .DS_Store | Filenames/patterns to skip | | `sanitizeNames` | bool | true | Clean up filenames (remove emojis, collapse spaces) | | `sanitizeOptions.removeEmojis` | bool | true | Strip emoji characters | | `sanitizeOptions.collapseSpaces` | bool | true | Replace multiple spaces with one | | `sanitizeOptions.normalizeCase` | string | "lower" | "lower", "upper", or "none" | | `patchNumbers` | bool | false | Zero-pad numbers in filenames | | `numberWidth` | int | 3 | Width for number patching (e.g. 3 -> 001) | | `numberPatchingMode` | string | "first" | "first", "all", or "none" | | `dryRun` | bool | false | Preview without moving | | `logLevel` | string | "info" | "silent", "info", or "debug" | | `logPath` | string | "organizer.log" | Path for the log file (relative to working dir) | | `printSummary` | bool | true | Print summary after organization | | `verboseOutput` | bool | false | Per-file output to stdout | --- ## Contributing ๐Ÿค Contributions are welcome. Open an issue or submit a pull request on [GitHub](https://github.com/ahmedthebest31/sortify). ## License ๐Ÿ“„ MIT License. See [LICENSE](LICENSE).