@singhaman21/cleansweep 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +447 -0
- package/USAGE.md +81 -0
- package/delete.sh +489 -0
- package/dist/bin/cli.d.ts +7 -0
- package/dist/bin/cli.d.ts.map +1 -0
- package/dist/bin/cli.js +114 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/core/deletionEngine.d.ts +47 -0
- package/dist/core/deletionEngine.d.ts.map +1 -0
- package/dist/core/deletionEngine.js +184 -0
- package/dist/core/deletionEngine.js.map +1 -0
- package/dist/types.d.ts +26 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/fileUtils.d.ts +54 -0
- package/dist/utils/fileUtils.d.ts.map +1 -0
- package/dist/utils/fileUtils.js +232 -0
- package/dist/utils/fileUtils.js.map +1 -0
- package/dist/utils/logger.d.ts +31 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +110 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/prompts.d.ts +17 -0
- package/dist/utils/prompts.d.ts.map +1 -0
- package/dist/utils/prompts.js +86 -0
- package/dist/utils/prompts.js.map +1 -0
- package/package.json +49 -0
- package/src/bin/cli.ts +130 -0
- package/src/core/deletionEngine.ts +219 -0
- package/src/types.ts +30 -0
- package/src/utils/fileUtils.ts +218 -0
- package/src/utils/logger.ts +91 -0
- package/src/utils/prompts.ts +54 -0
- package/tsconfig.json +21 -0
package/delete.sh
ADDED
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
###############################################################################
|
|
4
|
+
# Enhanced Delete Script
|
|
5
|
+
#
|
|
6
|
+
# This script provides a comprehensive solution for deleting files and folders
|
|
7
|
+
# with multiple safety features, logging, and customization options.
|
|
8
|
+
###############################################################################
|
|
9
|
+
|
|
10
|
+
# Global variables
|
|
11
|
+
DRY_RUN=false
|
|
12
|
+
INTERACTIVE=false
|
|
13
|
+
FORCE=false
|
|
14
|
+
PREVIEW=false
|
|
15
|
+
LOG_FILE=""
|
|
16
|
+
OUTPUT_FORMAT="plain"
|
|
17
|
+
MAX_DEPTH=""
|
|
18
|
+
FILES_PATTERN=""
|
|
19
|
+
FOLDERS_PATTERN=""
|
|
20
|
+
TYPES_PATTERN=""
|
|
21
|
+
EXCLUDE_PATTERNS=()
|
|
22
|
+
ITEMS_TO_DELETE=()
|
|
23
|
+
DELETED_ITEMS=()
|
|
24
|
+
FAILED_DELETIONS=()
|
|
25
|
+
|
|
26
|
+
###############################################################################
|
|
27
|
+
# Function: print_usage
|
|
28
|
+
# Description: Displays the usage information and available options for the script
|
|
29
|
+
###############################################################################
|
|
30
|
+
print_usage() {
|
|
31
|
+
cat << EOF
|
|
32
|
+
Usage: $0 [OPTIONS]
|
|
33
|
+
|
|
34
|
+
Options:
|
|
35
|
+
--files | -fi PATTERN Specify file patterns to delete (e.g., "*.tmp", "*.log")
|
|
36
|
+
--folders | -fo PATTERN Specify folder patterns to delete (e.g., "temp", "cache")
|
|
37
|
+
--types | -ty PATTERN Specify multiple types of files/directories to delete
|
|
38
|
+
--exclude | -ex PATTERN Exclude patterns or folders from deletion (can be used multiple times)
|
|
39
|
+
--depth | -d NUMBER Limit the search depth in directory structure
|
|
40
|
+
--dry-run | -dr Simulate deletion without actually deleting anything
|
|
41
|
+
--interactive | -in Prompt for confirmation before each deletion
|
|
42
|
+
--preview | -pr Display list of items that will be deleted
|
|
43
|
+
--force | -f Bypass safety checks and interactive warnings
|
|
44
|
+
--log | -lg FILE Generate a log file with timestamps of deletions
|
|
45
|
+
--format | -fm FORMAT Output format: plain, json (default: plain)
|
|
46
|
+
-h, --help Display this help message
|
|
47
|
+
|
|
48
|
+
Examples:
|
|
49
|
+
$0 --files "*.tmp" --folders "temp" --exclude "important" --log deletion_log.txt --dry-run
|
|
50
|
+
$0 --types "*.log" --depth 2 --interactive
|
|
51
|
+
$0 --files "*.tmp" --preview
|
|
52
|
+
$0 --folders "cache" --force --log cleanup.log
|
|
53
|
+
|
|
54
|
+
EOF
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
###############################################################################
|
|
58
|
+
# Function: log_message
|
|
59
|
+
# Description: Logs a message with timestamp to both console and log file (if specified)
|
|
60
|
+
# Parameters:
|
|
61
|
+
# $1 - Message to log
|
|
62
|
+
# $2 - Log level (INFO, WARNING, ERROR)
|
|
63
|
+
###############################################################################
|
|
64
|
+
log_message() {
|
|
65
|
+
local message="$1"
|
|
66
|
+
local level="${2:-INFO}"
|
|
67
|
+
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
|
68
|
+
local formatted_message="[$timestamp] [$level] $message"
|
|
69
|
+
|
|
70
|
+
# Print to console
|
|
71
|
+
if [ "$OUTPUT_FORMAT" = "json" ]; then
|
|
72
|
+
echo "{\"timestamp\":\"$timestamp\",\"level\":\"$level\",\"message\":\"$message\"}"
|
|
73
|
+
else
|
|
74
|
+
echo "$formatted_message"
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# Write to log file if specified
|
|
78
|
+
if [ -n "$LOG_FILE" ]; then
|
|
79
|
+
echo "$formatted_message" >> "$LOG_FILE"
|
|
80
|
+
fi
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
###############################################################################
|
|
84
|
+
# Function: parse_arguments
|
|
85
|
+
# Description: Parses command-line arguments and sets global configuration variables
|
|
86
|
+
###############################################################################
|
|
87
|
+
parse_arguments() {
|
|
88
|
+
while [[ $# -gt 0 ]]; do
|
|
89
|
+
case $1 in
|
|
90
|
+
--files | -fi)
|
|
91
|
+
FILES_PATTERN="$2"
|
|
92
|
+
shift 2
|
|
93
|
+
;;
|
|
94
|
+
--folders | -fo)
|
|
95
|
+
FOLDERS_PATTERN="$2"
|
|
96
|
+
shift 2
|
|
97
|
+
;;
|
|
98
|
+
--types | -ty)
|
|
99
|
+
TYPES_PATTERN="$2"
|
|
100
|
+
shift 2
|
|
101
|
+
;;
|
|
102
|
+
--exclude | -ex)
|
|
103
|
+
EXCLUDE_PATTERNS+=("$2")
|
|
104
|
+
shift 2
|
|
105
|
+
;;
|
|
106
|
+
--depth | -d)
|
|
107
|
+
MAX_DEPTH="$2"
|
|
108
|
+
if ! [[ "$MAX_DEPTH" =~ ^[0-9]+$ ]]; then
|
|
109
|
+
log_message "Error: --depth must be a positive number" "ERROR"
|
|
110
|
+
exit 1
|
|
111
|
+
fi
|
|
112
|
+
shift 2
|
|
113
|
+
;;
|
|
114
|
+
--dry-run | -dr)
|
|
115
|
+
DRY_RUN=true
|
|
116
|
+
shift
|
|
117
|
+
;;
|
|
118
|
+
--interactive | -in)
|
|
119
|
+
INTERACTIVE=true
|
|
120
|
+
shift
|
|
121
|
+
;;
|
|
122
|
+
--preview | -pr)
|
|
123
|
+
PREVIEW=true
|
|
124
|
+
shift
|
|
125
|
+
;;
|
|
126
|
+
--force | -f)
|
|
127
|
+
FORCE=true
|
|
128
|
+
shift
|
|
129
|
+
;;
|
|
130
|
+
--log | -lg)
|
|
131
|
+
LOG_FILE="$2"
|
|
132
|
+
shift 2
|
|
133
|
+
;;
|
|
134
|
+
--format | -fm)
|
|
135
|
+
OUTPUT_FORMAT="$2"
|
|
136
|
+
if [[ ! "$OUTPUT_FORMAT" =~ ^(plain|json)$ ]]; then
|
|
137
|
+
log_message "Error: --format must be 'plain' or 'json'" "ERROR"
|
|
138
|
+
exit 1
|
|
139
|
+
fi
|
|
140
|
+
shift 2
|
|
141
|
+
;;
|
|
142
|
+
-h|--help)
|
|
143
|
+
print_usage
|
|
144
|
+
exit 0
|
|
145
|
+
;;
|
|
146
|
+
*)
|
|
147
|
+
log_message "Unknown option: $1" "ERROR"
|
|
148
|
+
print_usage
|
|
149
|
+
exit 1
|
|
150
|
+
;;
|
|
151
|
+
esac
|
|
152
|
+
done
|
|
153
|
+
|
|
154
|
+
# Validate that at least one pattern is specified
|
|
155
|
+
if [ -z "$FILES_PATTERN" ] && [ -z "$FOLDERS_PATTERN" ] && [ -z "$TYPES_PATTERN" ]; then
|
|
156
|
+
log_message "Error: At least one of --files, --folders, or --types must be specified" "ERROR"
|
|
157
|
+
print_usage
|
|
158
|
+
exit 1
|
|
159
|
+
fi
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
###############################################################################
|
|
163
|
+
# Function: should_exclude
|
|
164
|
+
# Description: Checks if a given path should be excluded based on exclusion patterns
|
|
165
|
+
# Parameters:
|
|
166
|
+
# $1 - Path to check
|
|
167
|
+
# Returns: 0 if should be excluded, 1 otherwise
|
|
168
|
+
###############################################################################
|
|
169
|
+
should_exclude() {
|
|
170
|
+
local path="$1"
|
|
171
|
+
|
|
172
|
+
for pattern in "${EXCLUDE_PATTERNS[@]}"; do
|
|
173
|
+
# Check if path matches the exclusion pattern
|
|
174
|
+
if [[ "$path" == *"$pattern"* ]] || [[ "$(basename "$path")" == "$pattern" ]]; then
|
|
175
|
+
return 0 # Should be excluded
|
|
176
|
+
fi
|
|
177
|
+
done
|
|
178
|
+
|
|
179
|
+
return 1 # Should not be excluded
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
###############################################################################
|
|
183
|
+
# Function: build_find_command
|
|
184
|
+
# Description: Constructs the find command with appropriate options based on patterns and depth
|
|
185
|
+
# Parameters:
|
|
186
|
+
# $1 - Type of item to find ("f" for files, "d" for directories)
|
|
187
|
+
# $2 - Pattern to match
|
|
188
|
+
# Returns: The constructed find command as a string
|
|
189
|
+
###############################################################################
|
|
190
|
+
build_find_command() {
|
|
191
|
+
local item_type="$1"
|
|
192
|
+
local pattern="$2"
|
|
193
|
+
local find_cmd="find ."
|
|
194
|
+
|
|
195
|
+
# Add depth limit if specified
|
|
196
|
+
if [ -n "$MAX_DEPTH" ]; then
|
|
197
|
+
find_cmd="$find_cmd -maxdepth $MAX_DEPTH"
|
|
198
|
+
fi
|
|
199
|
+
|
|
200
|
+
# Add type filter
|
|
201
|
+
find_cmd="$find_cmd -type $item_type"
|
|
202
|
+
|
|
203
|
+
# Add name pattern
|
|
204
|
+
find_cmd="$find_cmd -name \"$pattern\""
|
|
205
|
+
|
|
206
|
+
echo "$find_cmd"
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
###############################################################################
|
|
210
|
+
# Function: collect_items_to_delete
|
|
211
|
+
# Description: Collects all items (files/folders) that match the specified patterns
|
|
212
|
+
# and stores them in the ITEMS_TO_DELETE array
|
|
213
|
+
###############################################################################
|
|
214
|
+
collect_items_to_delete() {
|
|
215
|
+
ITEMS_TO_DELETE=()
|
|
216
|
+
|
|
217
|
+
# Process file patterns
|
|
218
|
+
if [ -n "$FILES_PATTERN" ]; then
|
|
219
|
+
while IFS= read -r -d '' item; do
|
|
220
|
+
if ! should_exclude "$item"; then
|
|
221
|
+
ITEMS_TO_DELETE+=("$item")
|
|
222
|
+
fi
|
|
223
|
+
done < <(eval "$(build_find_command "f" "$FILES_PATTERN")" -print0 2>/dev/null)
|
|
224
|
+
fi
|
|
225
|
+
|
|
226
|
+
# Process folder patterns
|
|
227
|
+
if [ -n "$FOLDERS_PATTERN" ]; then
|
|
228
|
+
while IFS= read -r -d '' item; do
|
|
229
|
+
if ! should_exclude "$item"; then
|
|
230
|
+
ITEMS_TO_DELETE+=("$item")
|
|
231
|
+
fi
|
|
232
|
+
done < <(eval "$(build_find_command "d" "$FOLDERS_PATTERN")" -print0 2>/dev/null)
|
|
233
|
+
fi
|
|
234
|
+
|
|
235
|
+
# Process types pattern (can match both files and directories)
|
|
236
|
+
if [ -n "$TYPES_PATTERN" ]; then
|
|
237
|
+
while IFS= read -r -d '' item; do
|
|
238
|
+
if ! should_exclude "$item"; then
|
|
239
|
+
ITEMS_TO_DELETE+=("$item")
|
|
240
|
+
fi
|
|
241
|
+
done < <(eval "find . ${MAX_DEPTH:+-maxdepth $MAX_DEPTH} -name \"$TYPES_PATTERN\"" -print0 2>/dev/null)
|
|
242
|
+
fi
|
|
243
|
+
|
|
244
|
+
# Remove duplicates
|
|
245
|
+
IFS=$'\n' ITEMS_TO_DELETE=($(printf '%s\n' "${ITEMS_TO_DELETE[@]}" | sort -u))
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
###############################################################################
|
|
249
|
+
# Function: display_preview
|
|
250
|
+
# Description: Displays a preview of all items that will be deleted
|
|
251
|
+
###############################################################################
|
|
252
|
+
display_preview() {
|
|
253
|
+
if [ ${#ITEMS_TO_DELETE[@]} -eq 0 ]; then
|
|
254
|
+
log_message "No items found matching the specified patterns." "INFO"
|
|
255
|
+
return
|
|
256
|
+
fi
|
|
257
|
+
|
|
258
|
+
log_message "Preview: Items that will be deleted (${#ITEMS_TO_DELETE[@]} items):" "INFO"
|
|
259
|
+
|
|
260
|
+
if [ "$OUTPUT_FORMAT" = "json" ]; then
|
|
261
|
+
echo -n "{\"items\":["
|
|
262
|
+
local first=true
|
|
263
|
+
for item in "${ITEMS_TO_DELETE[@]}"; do
|
|
264
|
+
if [ "$first" = true ]; then
|
|
265
|
+
first=false
|
|
266
|
+
else
|
|
267
|
+
echo -n ","
|
|
268
|
+
fi
|
|
269
|
+
echo -n "{\"path\":\"$item\"}"
|
|
270
|
+
done
|
|
271
|
+
echo "]}"
|
|
272
|
+
else
|
|
273
|
+
for item in "${ITEMS_TO_DELETE[@]}"; do
|
|
274
|
+
echo " - $item"
|
|
275
|
+
done
|
|
276
|
+
fi
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
###############################################################################
|
|
280
|
+
# Function: confirm_deletion
|
|
281
|
+
# Description: Prompts the user for confirmation before deleting an item
|
|
282
|
+
# Parameters:
|
|
283
|
+
# $1 - Path of the item to delete
|
|
284
|
+
# Returns: 0 if confirmed, 1 if not confirmed
|
|
285
|
+
###############################################################################
|
|
286
|
+
confirm_deletion() {
|
|
287
|
+
local item="$1"
|
|
288
|
+
|
|
289
|
+
if [ "$FORCE" = true ]; then
|
|
290
|
+
return 0 # Force mode, always confirm
|
|
291
|
+
fi
|
|
292
|
+
|
|
293
|
+
echo -n "Delete '$item'? [y/N]: "
|
|
294
|
+
read -r response
|
|
295
|
+
case "$response" in
|
|
296
|
+
[yY][eE][sS]|[yY])
|
|
297
|
+
return 0
|
|
298
|
+
;;
|
|
299
|
+
*)
|
|
300
|
+
return 1
|
|
301
|
+
;;
|
|
302
|
+
esac
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
###############################################################################
|
|
306
|
+
# Function: delete_item
|
|
307
|
+
# Description: Deletes a single item (file or directory) with appropriate logging
|
|
308
|
+
# Parameters:
|
|
309
|
+
# $1 - Path of the item to delete
|
|
310
|
+
###############################################################################
|
|
311
|
+
delete_item() {
|
|
312
|
+
local item="$1"
|
|
313
|
+
|
|
314
|
+
# Skip if dry run
|
|
315
|
+
if [ "$DRY_RUN" = true ]; then
|
|
316
|
+
log_message "Would delete: $item" "INFO"
|
|
317
|
+
DELETED_ITEMS+=("$item")
|
|
318
|
+
return 0
|
|
319
|
+
fi
|
|
320
|
+
|
|
321
|
+
# Interactive confirmation
|
|
322
|
+
if [ "$INTERACTIVE" = true ]; then
|
|
323
|
+
if ! confirm_deletion "$item"; then
|
|
324
|
+
log_message "Skipped: $item" "INFO"
|
|
325
|
+
return 0
|
|
326
|
+
fi
|
|
327
|
+
fi
|
|
328
|
+
|
|
329
|
+
# Perform deletion
|
|
330
|
+
if [ -d "$item" ]; then
|
|
331
|
+
if rm -rf "$item" 2>/dev/null; then
|
|
332
|
+
log_message "Deleted directory: $item" "INFO"
|
|
333
|
+
DELETED_ITEMS+=("$item")
|
|
334
|
+
else
|
|
335
|
+
log_message "Failed to delete directory: $item" "ERROR"
|
|
336
|
+
FAILED_DELETIONS+=("$item")
|
|
337
|
+
fi
|
|
338
|
+
elif [ -f "$item" ]; then
|
|
339
|
+
if rm -f "$item" 2>/dev/null; then
|
|
340
|
+
log_message "Deleted file: $item" "INFO"
|
|
341
|
+
DELETED_ITEMS+=("$item")
|
|
342
|
+
else
|
|
343
|
+
log_message "Failed to delete file: $item" "ERROR"
|
|
344
|
+
FAILED_DELETIONS+=("$item")
|
|
345
|
+
fi
|
|
346
|
+
else
|
|
347
|
+
log_message "Item not found or already deleted: $item" "WARNING"
|
|
348
|
+
fi
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
###############################################################################
|
|
352
|
+
# Function: process_deletions
|
|
353
|
+
# Description: Processes all collected items for deletion based on the current mode
|
|
354
|
+
###############################################################################
|
|
355
|
+
process_deletions() {
|
|
356
|
+
if [ ${#ITEMS_TO_DELETE[@]} -eq 0 ]; then
|
|
357
|
+
log_message "No items to delete." "INFO"
|
|
358
|
+
return
|
|
359
|
+
fi
|
|
360
|
+
|
|
361
|
+
# Show preview if requested
|
|
362
|
+
if [ "$PREVIEW" = true ]; then
|
|
363
|
+
display_preview
|
|
364
|
+
if [ "$DRY_RUN" = false ] && [ "$FORCE" = false ]; then
|
|
365
|
+
echo -n "Proceed with deletion? [y/N]: "
|
|
366
|
+
read -r response
|
|
367
|
+
case "$response" in
|
|
368
|
+
[yY][eE][sS]|[yY])
|
|
369
|
+
;;
|
|
370
|
+
*)
|
|
371
|
+
log_message "Deletion cancelled by user." "INFO"
|
|
372
|
+
exit 0
|
|
373
|
+
;;
|
|
374
|
+
esac
|
|
375
|
+
fi
|
|
376
|
+
fi
|
|
377
|
+
|
|
378
|
+
# Process each item
|
|
379
|
+
for item in "${ITEMS_TO_DELETE[@]}"; do
|
|
380
|
+
delete_item "$item"
|
|
381
|
+
done
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
###############################################################################
|
|
385
|
+
# Function: print_summary
|
|
386
|
+
# Description: Displays a summary of the deletion operation including statistics
|
|
387
|
+
###############################################################################
|
|
388
|
+
print_summary() {
|
|
389
|
+
local total_items=${#ITEMS_TO_DELETE[@]}
|
|
390
|
+
local deleted_count=${#DELETED_ITEMS[@]}
|
|
391
|
+
local failed_count=${#FAILED_DELETIONS[@]}
|
|
392
|
+
|
|
393
|
+
if [ "$OUTPUT_FORMAT" = "json" ]; then
|
|
394
|
+
echo "{"
|
|
395
|
+
echo " \"summary\": {"
|
|
396
|
+
echo " \"total_items\": $total_items,"
|
|
397
|
+
echo " \"deleted\": $deleted_count,"
|
|
398
|
+
echo " \"failed\": $failed_count,"
|
|
399
|
+
echo " \"dry_run\": $DRY_RUN"
|
|
400
|
+
echo " }"
|
|
401
|
+
if [ $failed_count -gt 0 ]; then
|
|
402
|
+
echo " \"failed_items\": ["
|
|
403
|
+
local first=true
|
|
404
|
+
for item in "${FAILED_DELETIONS[@]}"; do
|
|
405
|
+
if [ "$first" = true ]; then
|
|
406
|
+
first=false
|
|
407
|
+
else
|
|
408
|
+
echo ","
|
|
409
|
+
fi
|
|
410
|
+
echo -n " {\"path\":\"$item\"}"
|
|
411
|
+
done
|
|
412
|
+
echo ""
|
|
413
|
+
echo " ]"
|
|
414
|
+
fi
|
|
415
|
+
echo "}"
|
|
416
|
+
else
|
|
417
|
+
log_message "=== Deletion Summary ===" "INFO"
|
|
418
|
+
log_message "Total items found: $total_items" "INFO"
|
|
419
|
+
if [ "$DRY_RUN" = true ]; then
|
|
420
|
+
log_message "Items that would be deleted: $deleted_count" "INFO"
|
|
421
|
+
else
|
|
422
|
+
log_message "Items successfully deleted: $deleted_count" "INFO"
|
|
423
|
+
fi
|
|
424
|
+
if [ $failed_count -gt 0 ]; then
|
|
425
|
+
log_message "Failed deletions: $failed_count" "ERROR"
|
|
426
|
+
for item in "${FAILED_DELETIONS[@]}"; do
|
|
427
|
+
log_message " - $item" "ERROR"
|
|
428
|
+
done
|
|
429
|
+
fi
|
|
430
|
+
fi
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
###############################################################################
|
|
434
|
+
# Function: initialize_log_file
|
|
435
|
+
# Description: Initializes the log file if logging is enabled
|
|
436
|
+
###############################################################################
|
|
437
|
+
initialize_log_file() {
|
|
438
|
+
if [ -n "$LOG_FILE" ]; then
|
|
439
|
+
# Create log file with header
|
|
440
|
+
{
|
|
441
|
+
echo "=========================================="
|
|
442
|
+
echo "Deletion Log - $(date '+%Y-%m-%d %H:%M:%S')"
|
|
443
|
+
echo "=========================================="
|
|
444
|
+
echo "Dry Run: $DRY_RUN"
|
|
445
|
+
echo "Interactive: $INTERACTIVE"
|
|
446
|
+
echo "Force: $FORCE"
|
|
447
|
+
[ -n "$FILES_PATTERN" ] && echo "Files Pattern: $FILES_PATTERN"
|
|
448
|
+
[ -n "$FOLDERS_PATTERN" ] && echo "Folders Pattern: $FOLDERS_PATTERN"
|
|
449
|
+
[ -n "$TYPES_PATTERN" ] && echo "Types Pattern: $TYPES_PATTERN"
|
|
450
|
+
[ ${#EXCLUDE_PATTERNS[@]} -gt 0 ] && echo "Exclude Patterns: ${EXCLUDE_PATTERNS[*]}"
|
|
451
|
+
[ -n "$MAX_DEPTH" ] && echo "Max Depth: $MAX_DEPTH"
|
|
452
|
+
echo "=========================================="
|
|
453
|
+
echo ""
|
|
454
|
+
} > "$LOG_FILE"
|
|
455
|
+
fi
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
###############################################################################
|
|
459
|
+
# Main execution flow
|
|
460
|
+
###############################################################################
|
|
461
|
+
main() {
|
|
462
|
+
# Parse command-line arguments
|
|
463
|
+
parse_arguments "$@"
|
|
464
|
+
|
|
465
|
+
# Initialize log file
|
|
466
|
+
initialize_log_file
|
|
467
|
+
|
|
468
|
+
# Log start of operation
|
|
469
|
+
log_message "Starting deletion operation..." "INFO"
|
|
470
|
+
|
|
471
|
+
# Collect items to delete
|
|
472
|
+
collect_items_to_delete
|
|
473
|
+
|
|
474
|
+
# Process deletions
|
|
475
|
+
process_deletions
|
|
476
|
+
|
|
477
|
+
# Print summary
|
|
478
|
+
print_summary
|
|
479
|
+
|
|
480
|
+
# Exit with appropriate code
|
|
481
|
+
if [ ${#FAILED_DELETIONS[@]} -gt 0 ]; then
|
|
482
|
+
exit 1
|
|
483
|
+
else
|
|
484
|
+
exit 0
|
|
485
|
+
fi
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
# Run main function with all arguments
|
|
489
|
+
main "$@"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/bin/cli.ts"],"names":[],"mappings":";AAEA;;;GAGG"}
|
package/dist/bin/cli.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* cleansweep CLI Entry Point
|
|
5
|
+
* Command-line interface for the cleansweep deletion tool
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
const commander_1 = require("commander");
|
|
9
|
+
const logger_1 = require("../utils/logger");
|
|
10
|
+
const deletionEngine_1 = require("../core/deletionEngine");
|
|
11
|
+
/**
|
|
12
|
+
* Main function to run the CLI
|
|
13
|
+
*/
|
|
14
|
+
async function main() {
|
|
15
|
+
const program = new commander_1.Command();
|
|
16
|
+
program
|
|
17
|
+
.name('cleansweep')
|
|
18
|
+
.description('A powerful command-line tool for safely deleting files and folders')
|
|
19
|
+
.version('1.0.0')
|
|
20
|
+
.option('-fi, --files <pattern>', 'Specify file patterns to delete (e.g., "*.tmp", "*.log")')
|
|
21
|
+
.option('-fo, --folders <pattern>', 'Specify folder patterns to delete (e.g., "temp", "cache")')
|
|
22
|
+
.option('-ty, --types <pattern>', 'Specify multiple types of files/directories to delete')
|
|
23
|
+
.option('-ex, --exclude <pattern>', 'Exclude patterns or folders from deletion (can be used multiple times)', (val, prev) => {
|
|
24
|
+
prev.push(val);
|
|
25
|
+
return prev;
|
|
26
|
+
}, [])
|
|
27
|
+
.option('-d, --depth <number>', 'Limit the search depth in directory structure', parseInt)
|
|
28
|
+
.option('-dr, --dry-run', 'Simulate deletion without actually deleting anything', false)
|
|
29
|
+
.option('-in, --interactive', 'Prompt for confirmation before each deletion', false)
|
|
30
|
+
.option('-pr, --preview', 'Display list of items that will be deleted', false)
|
|
31
|
+
.option('-f, --force', 'Bypass safety checks and interactive warnings', false)
|
|
32
|
+
.option('-lg, --log <file>', 'Generate a log file with timestamps of deletions')
|
|
33
|
+
.option('-fm, --format <format>', 'Output format: plain, json (default: plain)', 'plain')
|
|
34
|
+
.addHelpText('after', `
|
|
35
|
+
Examples:
|
|
36
|
+
npx cleansweep --files "*.tmp" --folders "temp" --exclude "important" --log deletion_log.txt --dry-run
|
|
37
|
+
npx cleansweep -fi "*.tmp" -fo "temp" -ex "important" -lg deletion_log.txt -dr
|
|
38
|
+
npx cleansweep --types "*.log" --depth 2 --interactive
|
|
39
|
+
npx cleansweep -ty "*.log" -d 2 -in
|
|
40
|
+
npx cleansweep --files "*.tmp" --preview
|
|
41
|
+
npx cleansweep -fi "*.tmp" -pr
|
|
42
|
+
npx cleansweep --folders "cache" --force --log cleanup.log
|
|
43
|
+
npx cleansweep -fo "cache" -f -lg cleanup.log
|
|
44
|
+
`);
|
|
45
|
+
program.parse(process.argv);
|
|
46
|
+
const options = program.opts();
|
|
47
|
+
// Build configuration
|
|
48
|
+
const config = {
|
|
49
|
+
dryRun: options.dryRun || false,
|
|
50
|
+
interactive: options.interactive || false,
|
|
51
|
+
force: options.force || false,
|
|
52
|
+
preview: options.preview || false,
|
|
53
|
+
logFile: options.log,
|
|
54
|
+
outputFormat: options.format === 'json' ? 'json' : 'plain',
|
|
55
|
+
maxDepth: options.depth,
|
|
56
|
+
filesPattern: options.files,
|
|
57
|
+
foldersPattern: options.folders,
|
|
58
|
+
typesPattern: options.types,
|
|
59
|
+
excludePatterns: options.exclude || []
|
|
60
|
+
};
|
|
61
|
+
// Validate that at least one pattern is specified
|
|
62
|
+
if (!config.filesPattern && !config.foldersPattern && !config.typesPattern) {
|
|
63
|
+
console.error('Error: At least one of --files, --folders, or --types must be specified');
|
|
64
|
+
program.help();
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
// Validate output format
|
|
68
|
+
if (config.outputFormat !== 'plain' && config.outputFormat !== 'json') {
|
|
69
|
+
console.error("Error: --format must be 'plain' or 'json'");
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
// Validate depth if provided
|
|
73
|
+
if (config.maxDepth !== undefined && (isNaN(config.maxDepth) || config.maxDepth < 1)) {
|
|
74
|
+
console.error('Error: --depth must be a positive number');
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
// Initialize logger
|
|
78
|
+
const logger = new logger_1.Logger(config.logFile, config.outputFormat);
|
|
79
|
+
// Initialize log file
|
|
80
|
+
logger.initializeLogFile({
|
|
81
|
+
dryRun: config.dryRun,
|
|
82
|
+
interactive: config.interactive,
|
|
83
|
+
force: config.force,
|
|
84
|
+
filesPattern: config.filesPattern,
|
|
85
|
+
foldersPattern: config.foldersPattern,
|
|
86
|
+
typesPattern: config.typesPattern,
|
|
87
|
+
excludePatterns: config.excludePatterns,
|
|
88
|
+
maxDepth: config.maxDepth
|
|
89
|
+
});
|
|
90
|
+
// Log start of operation
|
|
91
|
+
logger.log('Starting deletion operation...', 'INFO');
|
|
92
|
+
try {
|
|
93
|
+
// Create deletion engine
|
|
94
|
+
const engine = new deletionEngine_1.DeletionEngine(config, logger);
|
|
95
|
+
// Collect items to delete
|
|
96
|
+
await engine.collectItemsToDelete();
|
|
97
|
+
// Process deletions
|
|
98
|
+
await engine.processDeletions();
|
|
99
|
+
// Print summary
|
|
100
|
+
engine.printSummary();
|
|
101
|
+
// Exit with appropriate code
|
|
102
|
+
process.exit(engine.getExitCode());
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
logger.log(`Error: ${error instanceof Error ? error.message : String(error)}`, 'ERROR');
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// Run main function
|
|
110
|
+
main().catch((error) => {
|
|
111
|
+
console.error('Fatal error:', error);
|
|
112
|
+
process.exit(1);
|
|
113
|
+
});
|
|
114
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/bin/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deletion Engine for cleansweep
|
|
3
|
+
* Core logic for collecting and processing deletions
|
|
4
|
+
*/
|
|
5
|
+
import { Config, DeletionResult } from '../types';
|
|
6
|
+
import { Logger } from '../utils/logger';
|
|
7
|
+
export declare class DeletionEngine {
|
|
8
|
+
private config;
|
|
9
|
+
private logger;
|
|
10
|
+
private itemsToDelete;
|
|
11
|
+
private deletedItems;
|
|
12
|
+
private failedDeletions;
|
|
13
|
+
constructor(config: Config, logger: Logger);
|
|
14
|
+
/**
|
|
15
|
+
* Collects all items (files/folders) that match the specified patterns
|
|
16
|
+
* and stores them in the itemsToDelete array
|
|
17
|
+
*/
|
|
18
|
+
collectItemsToDelete(): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Displays a preview of all items that will be deleted
|
|
21
|
+
*/
|
|
22
|
+
displayPreview(): void;
|
|
23
|
+
/**
|
|
24
|
+
* Deletes a single item (file or directory) with appropriate logging
|
|
25
|
+
* @param item - Path of the item to delete
|
|
26
|
+
*/
|
|
27
|
+
deleteItem(item: string): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Processes all collected items for deletion based on the current mode
|
|
30
|
+
*/
|
|
31
|
+
processDeletions(): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Gets the deletion summary
|
|
34
|
+
* @returns DeletionResult object with statistics
|
|
35
|
+
*/
|
|
36
|
+
getSummary(): DeletionResult;
|
|
37
|
+
/**
|
|
38
|
+
* Prints a summary of the deletion operation
|
|
39
|
+
*/
|
|
40
|
+
printSummary(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Gets the exit code based on deletion results
|
|
43
|
+
* @returns 0 for success, 1 for failures
|
|
44
|
+
*/
|
|
45
|
+
getExitCode(): number;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=deletionEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deletionEngine.d.ts","sourceRoot":"","sources":["../../src/core/deletionEngine.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAYzC,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,eAAe,CAAgB;gBAE3B,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAK1C;;;OAGG;IACG,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IA2C3C;;OAEG;IACH,cAAc,IAAI,IAAI;IAqBtB;;;OAGG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuC7C;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAwBvC;;;OAGG;IACH,UAAU,IAAI,cAAc;IAU5B;;OAEG;IACH,YAAY,IAAI,IAAI;IAsBpB;;;OAGG;IACH,WAAW,IAAI,MAAM;CAGtB"}
|