├── output_example.png ├── LICENSE ├── README.md └── dependency-cleaner.sh /output_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olegkron/dependency-cleaner/HEAD/output_example.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Oleg Kron 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 |

Dependency Cleaner

2 | 3 | A shell script to easily delete dependency folders in a given directory and its subdirectories. A great tool to free up disk space by removing unnecessary node_modules, .cache, pycache, target, venv, env, go/pkg folders. 4 | 5 | [![Stars](https://img.shields.io/github/stars/olegkron/dependency-cleaner.svg?style=social)](https://github.com/olegkron/dependency-cleaner/stargazers) [![Forks](https://img.shields.io/github/forks/olegkron/dependency-cleaner.svg?style=social)](https://github.com/olegkron/dependency-cleaner/network/members) [![Contributors](https://img.shields.io/github/contributors/olegkron/dependency-cleaner.svg)](https://github.com/olegkron/dependency-cleaner/graphs/contributors) [![Issues](https://img.shields.io/github/issues/olegkron/dependency-cleaner.svg)](https://github.com/olegkron/dependency-cleaner/issues) [![MIT License](https://img.shields.io/github/license/olegkron/dependency-cleaner.svg)](https://github.com/olegkron/dependency-cleaner/blob/main/LICENSE) 6 | 7 |
8 | 9 | ![Output example](https://raw.githubusercontent.com/olegkron/node_modules_remover/main/output_example.png) 10 | 11 | ## 🎉 Features 12 | 13 | - 🔎 Recursively searches for the following folders in the input directory: "node_modules", ".cache", "pycache". "target", "venv". "env", "go/pkg" (any of them can be added or removed) 14 | - 📊 Displays the total size of each folder 15 | - 💽 Calculates the total space saved 16 | - 🖥️ Works on Linux and MacOS 17 | 18 | ## 💻 Usage 19 | 20 | The script can be executed using the following command in the terminal: 21 | 22 | `./dependency-cleaner.sh [directory_path] [max_depth]` 23 | 24 | - `directory_path`: Required. The directory to search for node_modules folders. 25 | - `max_depth`: Optional. Sets maximum depth to search for node_modules folders. Default is 3. 26 | 27 | ## Star History 28 | 29 | [![Star History Chart](https://api.star-history.com/svg?repos=olegkron/dependency-cleaner&type=Date)](https://star-history.com/#olegkron/dependency-cleaner&Date) 30 | 31 | ## 🙌 Contributing 32 | 33 | If you have any suggestions for improvements or find any bugs, feel free to open a pull request or an issue. 34 | 35 | ## 👥 Authors 36 | 37 | - **Oleg Kron** - [olegkron](https://github.com/olegkron) 38 | 39 | ## 📄 License 40 | 41 | This project is licensed under the MIT License - see the [LICENSE](https://github.com/olegkron/node_modules_remover/blob/main/LICENSE) file for details. 42 | -------------------------------------------------------------------------------- /dependency-cleaner.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | RED='\033[0;31m' 4 | GREEN='\033[0;32m' 5 | YELLOW='\033[0;33m' 6 | NC='\033[0m' # No Color 7 | 8 | # Checks if the input directory exists 9 | if [ ! -d "$1" ]; then 10 | echo -e "${RED}Error: $1 is not a directory or does not exist${NC}" 11 | exit 1 12 | fi 13 | 14 | if [ -z "$2" ]; then 15 | depth=3 16 | else 17 | if ! [[ "$2" =~ ^[0-9]+$ ]]; then 18 | echo -e "${RED}Error: Invalid value for maximum depth: $2${NC}" 19 | exit 1 20 | fi 21 | depth=$2 22 | fi 23 | 24 | # List of folders to search for 25 | folders=("node_modules" ".cache" "__pycache__" "target" "venv" "env" "go/pkg") 26 | 27 | # Find folders 28 | found_folders=() 29 | for folder in "${folders[@]}"; do 30 | echo -e "${YELLOW}Searching for $folder folders in $1... (max depth: $depth)${NC}" 31 | current_found=$(find "$1" -mindepth 2 -maxdepth "$depth" -name "$folder" -type d 2>/dev/null) 32 | if [ $? -ne 0 ]; then 33 | echo -e "${RED}Error: Failed to search for $folder folders${NC}" 34 | continue 35 | fi 36 | found_folders+=($current_found) 37 | done 38 | 39 | if [ ${#found_folders[@]} -eq 0 ]; then 40 | echo -e "${RED}No target folders found in $1${NC}" 41 | exit 0 42 | fi 43 | 44 | # Calculate total size 45 | total_size=$(du -shc ${found_folders[@]} | tail -1 | awk '{print $1}') 46 | 47 | # Print summary 48 | echo -e "${GREEN}Found ${#found_folders[@]} target folders of total size $total_size in the following folders:${NC}" 49 | index=0 50 | for folder in "${found_folders[@]}"; do 51 | project_folder=$(dirname "$folder") 52 | project_name=$(basename "$project_folder") 53 | size=$(du -sh "$folder" | awk '{print $1}') 54 | echo "[$index] $project_name - $size" 55 | index=$((index+1)) 56 | done 57 | 58 | # Prompt user for deletion 59 | echo -e "\nEnter the index number(s) of the folders to delete (separated by a space).\nTo delete all, press enter. To quit, type 'q':" 60 | read -a folders_to_delete 61 | if [ "${folders_to_delete[0]}" == "q" ]; then 62 | echo "Aborted" 63 | exit 0 64 | elif [ ${#folders_to_delete[@]} -eq 0 ]; then 65 | folders_to_delete=($(seq 0 $((index-1)))) 66 | fi 67 | 68 | # Delete folders 69 | total_size_deleted=0 70 | for i in "${folders_to_delete[@]}"; do 71 | if [ $i -lt 0 ] || [ $i -ge $index ]; then 72 | echo "Error: Invalid index: $i" 73 | continue 74 | fi 75 | folder=${found_folders[$i]} 76 | project_folder=$(dirname "$folder") 77 | project_name=$(basename "$project_folder") 78 | size=$(du -sh "$folder" | awk '{print $1}') 79 | echo "Removing $folder for $project_name ($size)..." 80 | rm -rf "$folder" 81 | size_in_bytes=$(numfmt --from=iec $size) 82 | total_size_deleted=$(echo $total_size_deleted + $size_in_bytes | bc) 83 | done 84 | 85 | echo -e "${GREEN}Done, Total space saved: $(numfmt --to=iec-i --suffix=B $total_size_deleted)${NC}" 86 | --------------------------------------------------------------------------------