Git Product home page Git Product logo

kondo's Introduction

Kondo ๐Ÿงน

Cleans node_modules, target, build, and friends from your projects.

Excellent if

  • ๐Ÿ’พ You want to back up your code but don't want to include GBs of dependencies
  • ๐Ÿง‘โ€๐ŸŽจ You try out lots of projects but hate how much space they occupy
  • โšก๏ธ You like keeping your disks lean and zippy

20+ Supported Project Types

Cargo (Rust), CMake (C, C++), Composer (PHP), Elixir, Godot 4.x (C#, GDScript)

Gradle (Java) Jupyter Notebook (Python), Pixi (Python), Maven (Java), Node (JavaScript)

Pub (Dart), Python SBT (Scala), Stack (Haskell), Swift

Unity (C#), Unreal Engine (C++), Zig, .NET (C#, F#)

kondo cli cleaning projects

kondo gui displaying projects

CLI Video
kondo-cli-preview-clean.webm
GUI Video
kondo-ui.webm

Installation

Warning

Kondo is essentially rm -rf with a prompt. Use at your own discretion. Always have a backup of your projects.

Command Line

winget

winget install kondo

Homebrew

brew install kondo

Arch Linux

pacman -S kondo

Source

Requires rust.

git clone https://github.com/tbillington/kondo.git
cargo install --path kondo/kondo

Others

Binaries available on the releases page.

Packaging status

Graphic User Interface

Arch Linux

pacman -S kondo-ui

Source

Requires rust. You may need platform specific dependencies on linux.

git clone https://github.com/tbillington/kondo.git
cargo install --path kondo/kondo-ui

Binaries available on the releases page.

Packaging status

Usage

Warning

Kondo is essentially rm -rf with a prompt. Use at your own discretion. Always have a backup of your projects.

Command Line Interface

Running kondo without a directory specified will run in the current directory.

kondo

Supplying a path will tell kondo where to start. Multiple paths are supported.

kondo code/my_project code/my_project_2

Passing a time will filter projects to those that haven't been modified for at least the specified period. See kondo --help for the full list of options.

kondo --older 3M # only projects with last modified greater than 3 months
kondo -o3M # shorthand

More options such as quiet mode, following symlinks, and filesystem restriction are viewable with kondo --help.

Building/Development

To build the cli kondo you can run cargo build and cargo run from the projects root directory.

To build the gui kondo-ui you must first navigate into the kondo-ui directory, then you can run cargo build and cargo run.

The output binaries will be located in target/debug/ or target/release/ per Cargo defaults.

Similar Projects

kondo's People

Contributors

anosatsuk124 avatar aschiavon91 avatar aszecsei avatar aursen avatar br1ght0ne avatar colindean avatar dependabot[bot] avatar desdaemon avatar gabrielztk avatar gzsombor avatar janvhs avatar jwodder avatar licon4812 avatar lipen avatar mrivnak avatar nickymeuleman avatar orhun avatar pawamoy avatar pbevin avatar pilltime avatar s-aditya-k avatar sassman avatar striezel avatar stunkymonkey avatar tbillington avatar trag1c avatar vrmiguel avatar wesleyklop avatar xampprocky avatar ysndr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kondo's Issues

Publish kondo-ui

Kondo-ui doesn't seem to be published yet. At least cargo install kondo-ui fails. I can't find a way starting kondo-ui without downloading the binary directly or building it myself. Could you publish kondo-ui to crates.io so installing via cargo is straight forward?

Discovery Rework

The current project discovery logic of kondo fails in edge cases related to assumptions made during the initial implementation.

  • Directories represent at most one project type
  • Projects cannot "nest" in the filesystem
  • Users want to look for all types of projects at all times (no filtering)

While the assumptions work for the vast majority of users it would be nice to not be bound by them. By removing them from the code the project will support more users and scenarios.

Summary of edge cases

Users with a "root" directory that is being identified as a project, eg #29.

Projects with "sub-modules", eg #55 or tauri projects.

Directories that are more than a single project, eg a Cargo project that is also a Node project containing both Cargo.toml and package.json.

"Auxiliary projects" such as direnv raised in #101 that would almost always accompany a "regular" project in a directory, and may be too noisy to surface regularly.

Miscellaneous project structures that should be supported

Various Python project configurations, see #105 & #108.

Unity projects will have nested Node projects that should be ignored.

Rust workspace projects should ignore sub-crates that are in the workspace, but not ignore subdirectories that are not in the workspace.

Decide on if/how to handle git ignore.

Features that affect implementation

  • Option to filter search to certain project types
  • "Dry run" aka "listing" the directories
  • Support for 3rd party "clean" commands like Cargo clean/Makefile clean #122
  • To support "remembering" decision about using 3rd party "clean" or not (see above) kondo would need to store the users preferences on disk

Progress

Work is being done in https://github.com/tbillington/kondo/tree/discovery-rework.

App paniked on "Select Directory" button press

OS: Linux Kubuntu 18.04
Kernel: 4.15.0-128-generic
AppVersion: 0.1.0 (the last from Cargo)

Terminal output (verbose):

popov@popov ~> env RUST_BACKTRACE=1 RUST_BACKTRACE=full /home/popov/.cargo/bin/kondo-ui
DEBUG [druid::localization] available locales [], current en-US
DEBUG [druid::localization] resolved: [en-US]
WARN  [druid::menu] MenuDesc::platform_default is not implemented for this platform.
INFO  [druid_shell::platform::gtk::application] gtk: Activated application
thread 'main' panicked at 'already borrowed: BorrowMutError', /home/popov/.cargo/registry/src/github.com-1ecc6299db9ec823/druid-shell-0.5.0/src/platform/gtk/window.rs:345:22
stack backtrace:
   0:     0x558f6fa08355 - std::backtrace_rs::backtrace::libunwind::trace::h577ea05e9ca4629a
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/../../backtrace/src/backtrace/libunwind.rs:96
   1:     0x558f6fa08355 - std::backtrace_rs::backtrace::trace_unsynchronized::h50b9b72b84c7dd56
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/../../backtrace/src/backtrace/mod.rs:66
   2:     0x558f6fa08355 - std::sys_common::backtrace::_print_fmt::h6541cf9823837fac
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/sys_common/backtrace.rs:79
   3:     0x558f6fa08355 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hf64fbff071026df5
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/sys_common/backtrace.rs:58
   4:     0x558f6f9cfe9c - core::fmt::write::h9ddafa4860d8adff
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/core/src/fmt/mod.rs:1082
   5:     0x558f6fa079b6 - std::io::Write::write_fmt::h1d2ee292d2b65481
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/io/mod.rs:1514
   6:     0x558f6fa07340 - std::sys_common::backtrace::_print::ha25f9ff5080d886d
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/sys_common/backtrace.rs:61
   7:     0x558f6fa07340 - std::sys_common::backtrace::print::h213e8aa8dc5405c0
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/sys_common/backtrace.rs:48
   8:     0x558f6fa07340 - std::panicking::default_hook::{{closure}}::h6482fae49ef9d963
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/panicking.rs:200
   9:     0x558f6fa06a53 - std::panicking::default_hook::he30ad7589e0970f9
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/panicking.rs:219
  10:     0x558f6fa06a53 - std::panicking::rust_panic_with_hook::haa1ed36ada4ffb03
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/panicking.rs:569
  11:     0x558f6fa066f8 - std::panicking::begin_panic_handler::{{closure}}::h7001af1bb21aeaeb
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/panicking.rs:476
  12:     0x558f6fa066c4 - std::sys_common::backtrace::__rust_end_short_backtrace::h39910f557f5f2367
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/sys_common/backtrace.rs:153
  13:     0x558f6fa0667d - rust_begin_unwind
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/panicking.rs:475
  14:     0x558f6f9ce240 - core::panicking::panic_fmt::h4e2659771ebc78eb
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/core/src/panicking.rs:85
  15:     0x558f6f9d1082 - core::option::expect_none_failed::h448b58a024c2c33a
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/core/src/option.rs:1221
  16:     0x558f6f9e8253 - core::cell::RefCell<T>::borrow_mut::h3603befb390e1563
  17:     0x558f6f9e97b1 - <O as gtk::auto::widget::WidgetExt>::connect_leave_notify_event::leave_notify_event_trampoline::h75875ed0bb521cbe
  18:     0x7f6e198508f7 - <unknown>
  19:     0x7f6e18a29346 - <unknown>
  20:     0x7f6e18a443cd - g_signal_emit_valist
  21:     0x7f6e18a4512f - g_signal_emit
  22:     0x7f6e19998534 - <unknown>
  23:     0x7f6e1999883d - <unknown>
  24:     0x7f6e1999e707 - <unknown>
  25:     0x7f6e1984da30 - <unknown>
  26:     0x7f6e1984dd30 - <unknown>
  27:     0x7f6e1973f3d0 - <unknown>
  28:     0x7f6e1984dc01 - <unknown>
  29:     0x7f6e199ad4c9 - <unknown>
  30:     0x7f6e1984dc01 - <unknown>
  31:     0x7f6e1984dea7 - <unknown>
  32:     0x7f6e18a2910d - g_closure_invoke
  33:     0x7f6e18a3c12e - <unknown>
  34:     0x7f6e18a44715 - g_signal_emit_valist
  35:     0x7f6e18a4512f - g_signal_emit
  36:     0x7f6e199a10c6 - gtk_widget_show
  37:     0x7f6e19879e20 - gtk_native_dialog_show
  38:     0x7f6e1987a5fa - gtk_native_dialog_run
  39:     0x558f6f9ebd6f - druid_shell::platform::gtk::window::WindowHandle::file_dialog::h61890d67b1dfd6d5
  40:     0x558f6f9ba465 - druid::win_handler::AppState<T>::handle_cmd::hc2abc37aad9a458d
  41:     0x558f6f9bab2f - druid::win_handler::AppState<T>::process_commands::h088db73c09277ecc
  42:     0x558f6f9baa1e - druid::win_handler::AppState<T>::do_window_event::h72282a694bc2956c
  43:     0x558f6f9c5125 - <druid::win_handler::DruidHandler<T> as druid_shell::window::WinHandler>::mouse_up::h6dea4b8b5390d8cc
  44:     0x558f6f9e9a31 - <O as gtk::auto::widget::WidgetExt>::connect_button_release_event::button_release_event_trampoline::h50bb8aa8b40ec165
  45:     0x7f6e198507fb - <unknown>
  46:     0x7f6e18a2910d - g_closure_invoke
  47:     0x7f6e18a3c05e - <unknown>
  48:     0x7f6e18a440af - g_signal_emit_valist
  49:     0x7f6e18a4512f - g_signal_emit
  50:     0x7f6e19998534 - <unknown>
  51:     0x7f6e1984d86e - <unknown>
  52:     0x7f6e1984f948 - gtk_main_do_event
  53:     0x7f6e19360765 - <unknown>
  54:     0x7f6e19390f92 - <unknown>
  55:     0x7f6e1874e417 - g_main_context_dispatch
  56:     0x7f6e1874e650 - <unknown>
  57:     0x7f6e1874e6dc - g_main_context_iteration
  58:     0x7f6e18d0fefd - g_application_run
  59:     0x558f6f9cb2d0 - kondo_ui::main::h725d4d5bbde190fc
  60:     0x558f6f9b314c - std::sys_common::backtrace::__rust_begin_short_backtrace::h4fefc5af64538c72
  61:     0x558f6f9cca0b - main
  62:     0x7f6e17aefbf7 - __libc_start_main
  63:     0x558f6f9ad3ea - _start
  64:                0x0 - <unknown>

Support system level cleaning

Some languages & projects have system level caches/build artifacts.

For example the package cache for Unity, or the cargo cache for Rust.

Some kind of --system parameter could be added to instruct kondo to check known system level caches instead of the usual directory based mode.

Add progress indicator

Hi, thanks for this project!
It has been really useful for me, by showing me exactly how large those Rust target folders become :)

One nitpick: When I ran kondo on my home directory, it took a very long time. That's ok, you're working on parallelization ๐Ÿ‘. However, I'd have appreciated some kind of output to show me the process hasn't crashed :) Maybe add a --verbose flag and output the name folder that's currently being analyzed?

Makefile support

kondo should inspect Makefiles and run their respective clean command (make clean)

`--ignored-dirs` argument ignores the project itself

I'm not sure if this is the expected behavior but I came across this issue while I was working on #92

To reproduce:

$ cargo new repro
$ cargo build
# target directory is created
$ kondo
Projects cleaned: 0, Bytes deleted: 0.0B
# nothing is cleaned

I think this is due to:

kondo/kondo/src/main.rs

Lines 57 to 61 in 51828a1

fn prepare_directories(dirs: Vec<PathBuf>) -> Result<Vec<PathBuf>, Box<dyn Error>> {
let cd = current_dir()?;
if dirs.is_empty() {
return Ok(vec![cd]);
}

might be regression in #90

Issues deleting directories. Error: "Directory not empty"

Kondo is successfully detecting my cargo projects. And it is successfully deleting some of them. However, some of them are erroring out with error removing directory "/path/to/directory": Os { code: 66, kind: DirectoryNotEmpty, message: "Directory not empty" }. The directory is always the top-level target directory. And it seems that kondo is trying to delete this directory before it is deleted the entire contents.

For context, some of these directories are very large (the largest being ~170GB). Not sure if that could be part of the cause.

Use a CLI helper

User Svenstaro on reddit mentioned StructOpt as a nice way to handle CLI arguments, especially as the supported options/flags grows.

Keep looking inside project

For example, the target dir at <rust_project>/examples/<example>/target is ignored, only <rust_project>/target is removed.
And if all examples were built for test purposes, the sum of those targets can often exceed the crate's main target

Fails to detect Python projects that don't have a `.py` file in their root

It appears that kondo (as of commit 69c153b) detects Python projects by looking for a file with a .py extension, at which point the directory in which this file is located is taken as the project root. However, this easily results in false negatives for modern Python packages, in which directories that need cleaning can be located above the directory of .py files.

Note the following about Python projects:

  • If a Python project is intended for distribution on PyPI, it will have a setup.py file (historical and now somewhat discouraged, but there's a lot of history), setup.cfg (declarative form of setup.py that was recommended for a while), and/or pyproject.toml file (new standard) in the project root.
  • If a Python project is not intended for distribution, it may or may not have any of setup.py/setup.cfg/pyproject.toml. If all are absent, the most reliable marker for a project root is probably a requirements.txt file, but this is purely conventional.
    • Some other reliable markers of Python project roots are configuration files for Python tools, such as tox.ini or noxfile.py.
  • Except in very simple or very messy projects, .py files tend to be organized under a directory with the same or similar name to that of the project. This directory is either located in the project root or nested inside a src/ directory in the project root (though, in the latter case, I'd expect such projects to also be the kind to have a setup.py, setup.cfg, or pyproject.toml file).
  • Due to how namespace packages are implemented, it is technically possible for the directory containing the .py files to be located inside one or more levels of otherwise-empty non-src/ directories, though I think it'd be highly unusual to do this if you weren't planning on distributing the project.

Support deleting the Zig cache

Hey, thanks for this tool! ๐Ÿป

I realized kondo doesn't delete the Zig cache folder which is usually zig-cache.

If appropriate, I would like to submit a PR for this!

CMake build directories with "unconventional" names are undiscovered

Currently kondo hardcodes a list of possible CMake build directories. This often works well enough, but since the name of a CMake build directory is merely convention it can fail for directories with other names.

A more reliable way to discover CMake build directories would be to search for subdirectories with a generated file CMakeCache.txt, but this cannot be supported in the current impl. Most of the infrastructure around artifact dirs assumes a static list of directories where instead a possible approach to address this would be to e.g., compute a (set of) globs for artifact_dirs and then have consumers of that API dynamically check for glob matches in the file system (e.g., here). It might make sense to also centralize glob matching to reduce slow repeated and identical hits of the filesystem.

.gitignore

Would deleting things that fall under explicit .gitignore globs (as opposed to plain untracked files, which is wildly dangerous) be a useful thing for most people?

Optimise directory walk code

Currently the code that walks directories will traverse into child directories even if the current directory is identified as one of the known project types. This is unnecessary for the default case, and is pure overhead.

It also means we need to perform the CPU intensive step of removing everything found inside that projects artifacts, eg the node_modules of packages inside the top level node_modules of a node project.

72 years ago

I am getting time information like "72 years ago", which is both unlikely and most importantly, not actually true. :)

For example, for a node_modules directory with the date Jan 19 2018 I'm getting "72 years ago". I can't explain it through a confusion with months; that's more like 67 months ago.

For items months ago, I am getting plausible time periods.

I'm on Fedora 38. I installed the tool through cargo install after cloning from git.

Could not compile kondo-ui

Compiling kondo-ui fails with the following error messages:

error[E0061]: this function takes 2 arguments but 1 argument was supplied
   --> src/main.rs:187:21
    |
187 |                     scan(&p).filter_map(|p| p.ok()).for_each(|project| {
    |                     ^^^^---- an argument of type `&ScanOptions` is missing
    |
note: function defined here
   --> /tmp/kondo/kondo-lib/src/lib.rs:349:8
    |
349 | pub fn scan<P: AsRef<path::Path>>(
    |        ^^^^
help: provide the argument
    |
187 |                     scan(&p, /* &ScanOptions */).filter_map(|p| p.ok()).for_each(|project| {
    |                         ~~~~~~~~~~~~~~~~~~~~~~~~

error[E0061]: this function takes 1 argument but 0 arguments were supplied
   --> src/main.rs:189:52
    |
189 |                         let project_size = project.size_dirs();
    |                                                    ^^^^^^^^^-- an argument of type `&ScanOptions` is missing
    |
note: associated function defined here
   --> /tmp/kondo/kondo-lib/src/lib.rs:146:12
    |
146 |     pub fn size_dirs(&self, options: &ScanOptions) -> ProjectSize {
    |            ^^^^^^^^^
help: provide the argument
    |
189 |                         let project_size = project.size_dirs(/* &ScanOptions */);
    |                                                             ~~~~~~~~~~~~~~~~~~~~

For more information about this error, try `rustc --explain E0061`.
error: could not compile `kondo-ui` due to 2 previous errors

How to ignore some directory?

Hi.

I want to ignore some directories because I tend to run kondo $HOME.

~ took 20s
โฏ kondo $(\ls --ignore=opt/nodebin)
/var/home/azzamsa/opt/nodebin Node project (5 minutes ago)
  โ””โ”€ node_modules (177.8MiB)
  delete above artifact directories? ([y]es, [n]o, [a]ll, [q]uit): ^C
  
โฏ kondo $(exa --ignore-glob ~/opt/nodebin)
/var/home/azzamsa/opt/nodebin Node project (6 minutes ago)
  โ””โ”€ node_modules (177.8MiB)
  delete above artifact directories? ([y]es, [n]o, [a]ll, [q]uit): n
Projects cleaned: 0, Bytes deleted: 0.0B

Nothing works.

Any suggestions?

Thanks! โค๏ธ

Option for non-interactive mode

Hi, this is a question more than an issue. Sorry if this is not the right place for this.

I was wondering if there is an option to run kondo in non-interactive and maybe quiet mode? Something like kondo -a ~/code to remove all artifacts in one command without manual input.

Thanks for all the work put into this helpful tool!

Only delete old project (skip active project)

Hi.

When I use kondo in my directory project, it deletes all the build artifacts in all directories. Including the active one.
woubuc/sweep: Reduce the disk usage of your projects by removing dependencies & builds on the other hand, only delete inactive directory: old projects that haven't been changed in more than a month.

Sweep (swp) finds old projects that haven't been changed in more than a month.

I thought I was missing some options. But I don't find any clue with kondo --help.

Kondo crash on `PermissionDenied`

Hi!

At the moment kondo crashes if it hits something it can't open. Maybe show some warning that folder/file x can not be analyzed and continue scanning.

I use version 0.2; build from git hash c2307fa.

$ kondo -V
kondo 0.2.0

$ RUST_BACKTRACE=1 kondo
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 13, kind: PermissionDenied, message: "Permission denied" }', src/libcore/result.rs:1188:5
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:84
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:61
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1025
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1426
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:65
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:50
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:193
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:210
  10: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:471
  11: rust_begin_unwind
             at src/libstd/panicking.rs:375
  12: core::panicking::panic_fmt
             at src/libcore/panicking.rs:84
  13: core::result::unwrap_failed
             at src/libcore/result.rs:1188
  14: kondo::check_file_exists
  15: <core::iter::adapters::FilterMap<I,F> as core::iter::traits::iterator::Iterator>::next
  16: <core::iter::adapters::flatten::FlatMap<I,U,F> as core::iter::traits::iterator::Iterator>::next
  17: kondo::main
  18: std::rt::lang_start::{{closure}}
  19: main
  20: __libc_start_main
  21: _start
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Does not delete all `__pycache__` directories

It seems that, currently, kondo only deletes __pycache__ directories located in the root of a Python project, but this is not the only place they can occur (and often there isn't even one in the root). A __pycache__ directory can be created in any directory containing a .py file, and .py files can be organized in any arbitrary assortment of directories with any depth.

kondo doesn't build on FreeBSD

... because many sections in the code are conditioned on target_os = "linux".

Conditions should include target_os = "freebsd".

No icons in UI (actually, just one). Font needed?

Hey there,
I went to check out the UI on linux (Pop_os 22.04, installed via cargo) but unfortunately, the icons in the main UI did not show up (strangely, the one in the title bar did, though).

Is a specific font required on the system for them to be displayed? I didn't see any mention of it, or any other font related issue posts, so I am not sure what is going on.

I just noticed that this particular icon did end up showing up once the search completed, but thats all?

Following symlinks is a questionable default

I tried kondo in my home directory, and it ended up scanning everything due to a symlink:

'Steam/steamapps/common/Proton 7.0/dist/share/default_pfx/dosdevices/z:' -> /

It was taking a really long time, so I ran strace and found that it was lost somewhere in .../z:/proc. I know there are symlink loops in procfs, and I think walkdir is supposed to detect loops, so maybe it would have figured that out eventually. Still, I don't think it's a good default to follow links, and other tools I know like fd-find and dua-cli do not.

Semi-related, you might also want an option for same_file_system, but that's less clear as a default.

"kondo ." does not work inside $HOME

When cwd is the root of my home directory (~) and I run kondo or kondo ., it just displays Total bytes deleted: 0.0B and does not even start searching through any directories it looks like.

kondo 0.4.0

edit: same with kondo @ 71d7539

Overview for CLI version

It looks like the GUI has a list of all the projects Kondo detected. Would it be possible to bring something like this to the CLI?

Npkill's TUI has a pretty cool way of doing this for reference (first GIF at https://github.com/voidcosmos/npkill shows it), though that exact interface would need something like ratatui which would be more complex than necessary.

(if you do replicate the npkill interface, please consider using space to stage changes then something like D and confirm with y to delete all staged deletions. Hitting space to instantly make a folder go poof is easy to mess up).

Awesome project with a great name, thank you for creating it!

Defer to 3rd party for removing artifacts

Some 3rd party project management tools include commands, or users add them by convention, that clean their workspace.

Eg Cargo will remove target, and users of Makefiles and other scripting tools may create their own "clean" command.

Should kondo defer to these tools?

I'm inclined to say yes, however there may be situations where kondo knows more about the artifacts than the specific tool. There also may be situations where the user has implemented a clean command that performs some specific actions that kondo can't reasonably mimic.

It's not obvious to me which path kondo should take. I am erring on the side of not depending on the 3rd party tools because:

  • We don't have control over what they're doing
  • They may have different behaviours between versions
  • We don't know the semantics of "clean" that users have implemented, it may not mean the same thing we assume it to

That being said, it does make sense to defer to tools like Cargos clean command, since it is the standard for projects of that nature.

Moving build dir to another directory

Here's some weird thing I do: I have a directory outside home where I put my target, node_modules etc, and I put symlinks on the project dirs. Those "shadow" directories are arranged in the same directory tree as the home directory. When I delete such build artifacts, I don't delete the directory that contains it (so I do not break the symlink). I do this to keep backups small.

I think your tool can help automate this workflow. I could pass a directory to it and it would move build dirs and set up symlinks. I may send a PR if you wish.

Anyway, thanks for this tool!

Does not recurse through directories with python scripts present

I have a project where I use python to script some misc tasks like testing. It seems that once a .py file is detected it'll stop searching any other subdirectories since it marks the project as Python. This might have to get filed under the discovery rework since it might need project types to be non-exclusive which could take some extra refactoring.

Example: since the project root has a run.py file, the cargo and nodejs projects aren't detected

project/
โ”œโ”€โ”€ api/
โ”‚   โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ target/
โ”‚   โ”œโ”€โ”€ tests/
โ”‚   โ”œโ”€โ”€ Cargo.toml
โ”‚   โ””โ”€โ”€ test.py
โ”œโ”€โ”€ web/
โ”‚   โ”œโ”€โ”€ node_modules/
โ”‚   โ”œโ”€โ”€ src/
โ”‚   โ””โ”€โ”€ package.json
โ””โ”€โ”€ run.py

Directories you can delete for Python projects

Virtual environments are often named .venv. For example, this is the name used by Poetry when creating the venv inside the project folder. They are also often named venv, though maybe sometimes such a directory could contain things the user wants to keep (never met this, but who knows). I guess the leading dot of .venv makes it safer to assume this is a virtualenv and that it can be removed.

Links:

Additionally, PEP582, which is used by some projects managers like PDM, says Python packages can be installed in a __pypackages__ directory.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.