├── .github └── workflows │ └── rust.yaml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENCE ├── README.md ├── src ├── config.toml └── main.rs └── topclean.json /.github/workflows/rust.yaml: -------------------------------------------------------------------------------- 1 | name: Rust 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | 11 | ci: 12 | name: CI 13 | strategy: 14 | matrix: 15 | os: [ubuntu-latest, macos-latest, windows-latest] 16 | runs-on: ${{ matrix.os }} 17 | steps: 18 | - uses: actions/checkout@v4 19 | - name: Format 20 | run: cargo fmt --all -- --check 21 | - name: Clippy 22 | run: cargo clippy 23 | - name: Test 24 | run: cargo test 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | debug/ 4 | target/ 5 | 6 | # These are backup files generated by rustfmt 7 | **/*.rs.bk 8 | 9 | # MSVC Windows builds of rustc generate these, which store debugging information 10 | *.pdb 11 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "atty" 7 | version = "0.2.14" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 10 | dependencies = [ 11 | "hermit-abi", 12 | "libc", 13 | "winapi", 14 | ] 15 | 16 | [[package]] 17 | name = "autocfg" 18 | version = "1.4.0" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 21 | 22 | [[package]] 23 | name = "bitflags" 24 | version = "1.3.2" 25 | source = "registry+https://github.com/rust-lang/crates.io-index" 26 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 27 | 28 | [[package]] 29 | name = "bitflags" 30 | version = "2.6.0" 31 | source = "registry+https://github.com/rust-lang/crates.io-index" 32 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 33 | 34 | [[package]] 35 | name = "clap" 36 | version = "3.2.25" 37 | source = "registry+https://github.com/rust-lang/crates.io-index" 38 | checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" 39 | dependencies = [ 40 | "atty", 41 | "bitflags 1.3.2", 42 | "clap_derive", 43 | "clap_lex", 44 | "indexmap 1.9.3", 45 | "once_cell", 46 | "strsim", 47 | "termcolor", 48 | "textwrap", 49 | ] 50 | 51 | [[package]] 52 | name = "clap_derive" 53 | version = "3.2.25" 54 | source = "registry+https://github.com/rust-lang/crates.io-index" 55 | checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" 56 | dependencies = [ 57 | "heck", 58 | "proc-macro-error", 59 | "proc-macro2", 60 | "quote", 61 | "syn 1.0.109", 62 | ] 63 | 64 | [[package]] 65 | name = "clap_lex" 66 | version = "0.2.4" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" 69 | dependencies = [ 70 | "os_str_bytes", 71 | ] 72 | 73 | [[package]] 74 | name = "either" 75 | version = "1.13.0" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" 78 | 79 | [[package]] 80 | name = "equivalent" 81 | version = "1.0.1" 82 | source = "registry+https://github.com/rust-lang/crates.io-index" 83 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 84 | 85 | [[package]] 86 | name = "errno" 87 | version = "0.3.9" 88 | source = "registry+https://github.com/rust-lang/crates.io-index" 89 | checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" 90 | dependencies = [ 91 | "libc", 92 | "windows-sys 0.52.0", 93 | ] 94 | 95 | [[package]] 96 | name = "hashbrown" 97 | version = "0.12.3" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 100 | 101 | [[package]] 102 | name = "hashbrown" 103 | version = "0.15.1" 104 | source = "registry+https://github.com/rust-lang/crates.io-index" 105 | checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" 106 | 107 | [[package]] 108 | name = "heck" 109 | version = "0.4.1" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 112 | 113 | [[package]] 114 | name = "hermit-abi" 115 | version = "0.1.19" 116 | source = "registry+https://github.com/rust-lang/crates.io-index" 117 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 118 | dependencies = [ 119 | "libc", 120 | ] 121 | 122 | [[package]] 123 | name = "home" 124 | version = "0.5.9" 125 | source = "registry+https://github.com/rust-lang/crates.io-index" 126 | checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" 127 | dependencies = [ 128 | "windows-sys 0.52.0", 129 | ] 130 | 131 | [[package]] 132 | name = "indexmap" 133 | version = "1.9.3" 134 | source = "registry+https://github.com/rust-lang/crates.io-index" 135 | checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" 136 | dependencies = [ 137 | "autocfg", 138 | "hashbrown 0.12.3", 139 | ] 140 | 141 | [[package]] 142 | name = "indexmap" 143 | version = "2.6.0" 144 | source = "registry+https://github.com/rust-lang/crates.io-index" 145 | checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" 146 | dependencies = [ 147 | "equivalent", 148 | "hashbrown 0.15.1", 149 | ] 150 | 151 | [[package]] 152 | name = "libc" 153 | version = "0.2.162" 154 | source = "registry+https://github.com/rust-lang/crates.io-index" 155 | checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" 156 | 157 | [[package]] 158 | name = "linux-raw-sys" 159 | version = "0.4.14" 160 | source = "registry+https://github.com/rust-lang/crates.io-index" 161 | checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" 162 | 163 | [[package]] 164 | name = "memchr" 165 | version = "2.7.4" 166 | source = "registry+https://github.com/rust-lang/crates.io-index" 167 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 168 | 169 | [[package]] 170 | name = "once_cell" 171 | version = "1.20.2" 172 | source = "registry+https://github.com/rust-lang/crates.io-index" 173 | checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" 174 | 175 | [[package]] 176 | name = "os_str_bytes" 177 | version = "6.6.1" 178 | source = "registry+https://github.com/rust-lang/crates.io-index" 179 | checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" 180 | 181 | [[package]] 182 | name = "proc-macro-error" 183 | version = "1.0.4" 184 | source = "registry+https://github.com/rust-lang/crates.io-index" 185 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 186 | dependencies = [ 187 | "proc-macro-error-attr", 188 | "proc-macro2", 189 | "quote", 190 | "syn 1.0.109", 191 | "version_check", 192 | ] 193 | 194 | [[package]] 195 | name = "proc-macro-error-attr" 196 | version = "1.0.4" 197 | source = "registry+https://github.com/rust-lang/crates.io-index" 198 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 199 | dependencies = [ 200 | "proc-macro2", 201 | "quote", 202 | "version_check", 203 | ] 204 | 205 | [[package]] 206 | name = "proc-macro2" 207 | version = "1.0.89" 208 | source = "registry+https://github.com/rust-lang/crates.io-index" 209 | checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" 210 | dependencies = [ 211 | "unicode-ident", 212 | ] 213 | 214 | [[package]] 215 | name = "quote" 216 | version = "1.0.37" 217 | source = "registry+https://github.com/rust-lang/crates.io-index" 218 | checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" 219 | dependencies = [ 220 | "proc-macro2", 221 | ] 222 | 223 | [[package]] 224 | name = "rustix" 225 | version = "0.38.39" 226 | source = "registry+https://github.com/rust-lang/crates.io-index" 227 | checksum = "375116bee2be9ed569afe2154ea6a99dfdffd257f533f187498c2a8f5feaf4ee" 228 | dependencies = [ 229 | "bitflags 2.6.0", 230 | "errno", 231 | "libc", 232 | "linux-raw-sys", 233 | "windows-sys 0.52.0", 234 | ] 235 | 236 | [[package]] 237 | name = "serde" 238 | version = "1.0.214" 239 | source = "registry+https://github.com/rust-lang/crates.io-index" 240 | checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" 241 | dependencies = [ 242 | "serde_derive", 243 | ] 244 | 245 | [[package]] 246 | name = "serde_derive" 247 | version = "1.0.214" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" 250 | dependencies = [ 251 | "proc-macro2", 252 | "quote", 253 | "syn 2.0.87", 254 | ] 255 | 256 | [[package]] 257 | name = "serde_spanned" 258 | version = "0.6.8" 259 | source = "registry+https://github.com/rust-lang/crates.io-index" 260 | checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" 261 | dependencies = [ 262 | "serde", 263 | ] 264 | 265 | [[package]] 266 | name = "strsim" 267 | version = "0.10.0" 268 | source = "registry+https://github.com/rust-lang/crates.io-index" 269 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 270 | 271 | [[package]] 272 | name = "syn" 273 | version = "1.0.109" 274 | source = "registry+https://github.com/rust-lang/crates.io-index" 275 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 276 | dependencies = [ 277 | "proc-macro2", 278 | "quote", 279 | "unicode-ident", 280 | ] 281 | 282 | [[package]] 283 | name = "syn" 284 | version = "2.0.87" 285 | source = "registry+https://github.com/rust-lang/crates.io-index" 286 | checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" 287 | dependencies = [ 288 | "proc-macro2", 289 | "quote", 290 | "unicode-ident", 291 | ] 292 | 293 | [[package]] 294 | name = "termcolor" 295 | version = "1.4.1" 296 | source = "registry+https://github.com/rust-lang/crates.io-index" 297 | checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" 298 | dependencies = [ 299 | "winapi-util", 300 | ] 301 | 302 | [[package]] 303 | name = "textwrap" 304 | version = "0.16.1" 305 | source = "registry+https://github.com/rust-lang/crates.io-index" 306 | checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" 307 | 308 | [[package]] 309 | name = "toml" 310 | version = "0.8.19" 311 | source = "registry+https://github.com/rust-lang/crates.io-index" 312 | checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" 313 | dependencies = [ 314 | "serde", 315 | "serde_spanned", 316 | "toml_datetime", 317 | "toml_edit", 318 | ] 319 | 320 | [[package]] 321 | name = "toml_datetime" 322 | version = "0.6.8" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" 325 | dependencies = [ 326 | "serde", 327 | ] 328 | 329 | [[package]] 330 | name = "toml_edit" 331 | version = "0.22.22" 332 | source = "registry+https://github.com/rust-lang/crates.io-index" 333 | checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" 334 | dependencies = [ 335 | "indexmap 2.6.0", 336 | "serde", 337 | "serde_spanned", 338 | "toml_datetime", 339 | "winnow", 340 | ] 341 | 342 | [[package]] 343 | name = "topclean" 344 | version = "0.5.0" 345 | dependencies = [ 346 | "clap", 347 | "serde", 348 | "serde_derive", 349 | "toml", 350 | "which", 351 | ] 352 | 353 | [[package]] 354 | name = "unicode-ident" 355 | version = "1.0.13" 356 | source = "registry+https://github.com/rust-lang/crates.io-index" 357 | checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" 358 | 359 | [[package]] 360 | name = "version_check" 361 | version = "0.9.5" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 364 | 365 | [[package]] 366 | name = "which" 367 | version = "7.0.0" 368 | source = "registry+https://github.com/rust-lang/crates.io-index" 369 | checksum = "c9cad3279ade7346b96e38731a641d7343dd6a53d55083dd54eadfa5a1b38c6b" 370 | dependencies = [ 371 | "either", 372 | "home", 373 | "rustix", 374 | "winsafe", 375 | ] 376 | 377 | [[package]] 378 | name = "winapi" 379 | version = "0.3.9" 380 | source = "registry+https://github.com/rust-lang/crates.io-index" 381 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 382 | dependencies = [ 383 | "winapi-i686-pc-windows-gnu", 384 | "winapi-x86_64-pc-windows-gnu", 385 | ] 386 | 387 | [[package]] 388 | name = "winapi-i686-pc-windows-gnu" 389 | version = "0.4.0" 390 | source = "registry+https://github.com/rust-lang/crates.io-index" 391 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 392 | 393 | [[package]] 394 | name = "winapi-util" 395 | version = "0.1.9" 396 | source = "registry+https://github.com/rust-lang/crates.io-index" 397 | checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" 398 | dependencies = [ 399 | "windows-sys 0.59.0", 400 | ] 401 | 402 | [[package]] 403 | name = "winapi-x86_64-pc-windows-gnu" 404 | version = "0.4.0" 405 | source = "registry+https://github.com/rust-lang/crates.io-index" 406 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 407 | 408 | [[package]] 409 | name = "windows-sys" 410 | version = "0.52.0" 411 | source = "registry+https://github.com/rust-lang/crates.io-index" 412 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 413 | dependencies = [ 414 | "windows-targets", 415 | ] 416 | 417 | [[package]] 418 | name = "windows-sys" 419 | version = "0.59.0" 420 | source = "registry+https://github.com/rust-lang/crates.io-index" 421 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 422 | dependencies = [ 423 | "windows-targets", 424 | ] 425 | 426 | [[package]] 427 | name = "windows-targets" 428 | version = "0.52.6" 429 | source = "registry+https://github.com/rust-lang/crates.io-index" 430 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 431 | dependencies = [ 432 | "windows_aarch64_gnullvm", 433 | "windows_aarch64_msvc", 434 | "windows_i686_gnu", 435 | "windows_i686_gnullvm", 436 | "windows_i686_msvc", 437 | "windows_x86_64_gnu", 438 | "windows_x86_64_gnullvm", 439 | "windows_x86_64_msvc", 440 | ] 441 | 442 | [[package]] 443 | name = "windows_aarch64_gnullvm" 444 | version = "0.52.6" 445 | source = "registry+https://github.com/rust-lang/crates.io-index" 446 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 447 | 448 | [[package]] 449 | name = "windows_aarch64_msvc" 450 | version = "0.52.6" 451 | source = "registry+https://github.com/rust-lang/crates.io-index" 452 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 453 | 454 | [[package]] 455 | name = "windows_i686_gnu" 456 | version = "0.52.6" 457 | source = "registry+https://github.com/rust-lang/crates.io-index" 458 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 459 | 460 | [[package]] 461 | name = "windows_i686_gnullvm" 462 | version = "0.52.6" 463 | source = "registry+https://github.com/rust-lang/crates.io-index" 464 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 465 | 466 | [[package]] 467 | name = "windows_i686_msvc" 468 | version = "0.52.6" 469 | source = "registry+https://github.com/rust-lang/crates.io-index" 470 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 471 | 472 | [[package]] 473 | name = "windows_x86_64_gnu" 474 | version = "0.52.6" 475 | source = "registry+https://github.com/rust-lang/crates.io-index" 476 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 477 | 478 | [[package]] 479 | name = "windows_x86_64_gnullvm" 480 | version = "0.52.6" 481 | source = "registry+https://github.com/rust-lang/crates.io-index" 482 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 483 | 484 | [[package]] 485 | name = "windows_x86_64_msvc" 486 | version = "0.52.6" 487 | source = "registry+https://github.com/rust-lang/crates.io-index" 488 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 489 | 490 | [[package]] 491 | name = "winnow" 492 | version = "0.6.20" 493 | source = "registry+https://github.com/rust-lang/crates.io-index" 494 | checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" 495 | dependencies = [ 496 | "memchr", 497 | ] 498 | 499 | [[package]] 500 | name = "winsafe" 501 | version = "0.0.19" 502 | source = "registry+https://github.com/rust-lang/crates.io-index" 503 | checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" 504 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "topclean" 3 | version = "0.5.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | clap = { version = "3", features = ["derive"] } 8 | serde = "1" 9 | serde_derive = "1" 10 | toml = "0.8" 11 | which = "7" 12 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Mert Demir 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # topclean 2 | 3 | > Free up disk space with one command 4 | 5 | `topclean` is intended to be used when you are running low on disk space and you are sure that deleting temporary files, caches, files marked for deletion (e.g. recycle bin) etc. is safe. 6 | 7 | ## Motivation and Inspiration 8 | 9 | `topclean` has been inspired by these projects: 10 | - [BleachBit](https://github.com/bleachbit/bleachbit) 11 | - [topgrade](https://github.com/r-darwish/topgrade) 12 | 13 | The goal is to provide disk cleaning functionality like BleachBit, but in a zero/low config way like topgrade offers for software upgrades. Another similarity to the latter is a focus on development tools. 14 | 15 | Also, I wanted to try out Rust. 16 | 17 | ## Install and Run 18 | 19 | ### Windows 20 | 21 | You can install topclean using scoop as below, or the same way as for other OS. 22 | 23 | ```ps1 24 | # Add custom bucket 25 | scoop bucket add topclean https://github.com/mertd/topclean 26 | # Install 27 | scoop install topclean 28 | # Run 29 | topclean 30 | ``` 31 | 32 | ### Generic 33 | 34 | Use this for all other OS. 35 | 36 | Check out the repository and execute `cargo run` within the directory. 37 | 38 | ## Licence 39 | 40 | [MIT](LICENCE) -------------------------------------------------------------------------------- /src/config.toml: -------------------------------------------------------------------------------- 1 | [[apps]] 2 | name = "scoop versions" 3 | cmd = "scoop" 4 | args = ["cleanup", "*"] 5 | interactive = false 6 | 7 | [[apps]] 8 | name = "scoop cache" 9 | cmd = "scoop" 10 | args = ["cache", "rm", "*"] 11 | interactive = false 12 | 13 | [[apps]] 14 | name = "npm" 15 | cmd = "npm" 16 | args = ["cache", "clean", "--force"] 17 | interactive = false 18 | 19 | [[apps]] 20 | name = "yarn" 21 | cmd = "yarn" 22 | args = ["cache", "clean"] 23 | interactive = false 24 | 25 | [[apps]] 26 | name = "cleanmgr" 27 | cmd = "cleanmgr" 28 | args = ["/d", "/c", "/verylowdisk"] 29 | interactive = true 30 | 31 | [[apps]] 32 | name = "brew" 33 | cmd = "brew" 34 | args = ["cleanup"] 35 | interactive = false 36 | 37 | [[apps]] 38 | name = "apt" 39 | cmd = "apt" 40 | args = ["clean"] 41 | interactive = false 42 | 43 | [[apps]] 44 | name = "pacman" 45 | cmd = "pacman" 46 | args = ["-Scc"] 47 | interactive = false 48 | 49 | [[apps]] 50 | name = "yum" 51 | cmd = "yum" 52 | args = ["clean", "all"] 53 | interactive = false 54 | 55 | [[apps]] 56 | name = "apk" 57 | cmd = "apk" 58 | args = ["cache", "clean"] 59 | interactive = false 60 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | use serde_derive::Deserialize; 3 | use std::io::{self, Write}; 4 | use std::process::{Command, Output}; 5 | use which::which; 6 | 7 | const PREFIX: &str = "[topclean]"; 8 | 9 | /// Free up disk space by cleaning caches and temporary files 10 | #[derive(Parser, Debug)] 11 | #[clap(author, version, about, long_about = None)] 12 | struct Args { 13 | /// Include apps that require user input to exit even if there were no errors 14 | #[clap(short, long)] 15 | interactive: bool, 16 | } 17 | 18 | #[derive(Deserialize)] 19 | struct Config { 20 | apps: Vec, 21 | } 22 | 23 | #[derive(Deserialize)] 24 | struct App { 25 | /// App Name 26 | name: String, 27 | /// Executable 28 | cmd: String, 29 | /// Arguments 30 | args: Vec, 31 | /// App requires user input to exit even if there were no errors 32 | interactive: bool, 33 | } 34 | 35 | impl App { 36 | fn clean(&self) -> Output { 37 | let mut command: Command; 38 | // choose shell-appropriate syntax 39 | if cfg!(target_os = "windows") { 40 | command = Command::new("cmd"); 41 | command.arg("/c"); 42 | } else { 43 | command = Command::new("sh"); 44 | command.arg("-c"); 45 | } 46 | // construct command with arguments 47 | command.arg(format!("{} {}", &self.cmd, &self.args.join(" "))); 48 | // execute 49 | let output = command 50 | .output() 51 | .unwrap_or_else(|_| panic!("{} cleaning failed", &self.name)); 52 | // print app output 53 | io::stdout() 54 | .write_all(&output.stdout) 55 | .expect("Writing to stdout failed"); 56 | io::stderr() 57 | .write_all(&output.stderr) 58 | .expect("Writing to stderr failed"); 59 | output 60 | } 61 | } 62 | 63 | /// Process apps according to configuration 64 | fn run(interactive: bool) -> bool { 65 | println!("{} Starting!", PREFIX); 66 | // read supported app configurations at build time 67 | let config: Config = 68 | toml::from_str(include_str!("config.toml")).expect("configuration is invalid"); 69 | for app in config.apps { 70 | let installed = which(&app.cmd).is_ok(); 71 | if !installed || (!interactive && app.interactive) { 72 | println!("{} Skipping {}", PREFIX, app.name); 73 | } else { 74 | println!("{} Cleaning {}", PREFIX, app.name); 75 | app.clean(); 76 | } 77 | } 78 | println!("{} Done!", PREFIX); 79 | true 80 | } 81 | 82 | fn main() { 83 | let args = Args::parse(); 84 | if args.interactive { 85 | println!("{} Including interactive commands", PREFIX); 86 | } 87 | run(args.interactive); 88 | } 89 | 90 | #[cfg(test)] 91 | mod tests { 92 | use super::*; 93 | #[test] 94 | fn runs() { 95 | // Skip interactive commands as they will never exit in a CI pipeline 96 | let result = run(false); 97 | assert!(result); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /topclean.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.5.0", 3 | "description": "Free up disk space with one command and zero config. Inspired by topgrade and BleachBit.", 4 | "homepage": "https://github.com/mertd/topclean", 5 | "license": "MIT", 6 | "url": "https://github.com/mertd/topclean/releases/download/0.5.0/topclean.exe", 7 | "hash": "7624c4442ca6ae824e795f3732905129460b77fbcfaf25d168466b93db28a43b", 8 | "bin": "topclean.exe", 9 | "checkver": "github", 10 | "autoupdate": { 11 | "url": "https://github.com/mertd/topclean/releases/download/$version/topclean.exe" 12 | } 13 | } 14 | --------------------------------------------------------------------------------