-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcopy_project
More file actions
executable file
·164 lines (141 loc) · 4.37 KB
/
copy_project
File metadata and controls
executable file
·164 lines (141 loc) · 4.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#!/bin/bash
output_file="project_summary.txt"
show_help() {
echo "Usage: $0 PROJECT_ROOT [--exclude PATTERNS] [-h]"
echo "Generate a summary of the project structure and file contents."
echo ""
echo "Arguments:"
echo " PROJECT_ROOT Path to the project directory"
echo "Options:"
echo " --exclude PATTERNS Comma or space-separated patterns to exclude"
echo " (supports: folder names, file names, extensions like *.ext)"
echo " -h Show this help message"
echo ""
echo "Example:"
echo " $0 /path/to/project --exclude .git,node_modules,*.log,output.txt"
}
is_excluded() {
local path="$1"
local filename=$(basename "$path")
# Always exclude the output file
if [[ "$filename" == "$output_file" ]]; then
return 0
fi
for pattern in "${exclude[@]}"; do
# Check if pattern matches the full path
if [[ "$path" == *"$pattern"* ]]; then
return 0
fi
# Check if pattern is an extension (starts with *. and filename matches)
if [[ "$pattern" == *.* && "$pattern" == \*.* ]]; then
if [[ "$filename" == *"${pattern#\*}" ]]; then
return 0
fi
fi
# Check exact filename match
if [[ "$filename" == "$pattern" ]]; then
return 0
fi
done
return 1
}
process_file() {
local file="$1"
local relative_path="$2"
local filename=$(basename "$file")
if is_excluded "$relative_path"; then
echo "[Excluded: $relative_path]" > /dev/null # Silent exclusion
return
fi
if file -b --mime-type "$file" | grep -q 'text/'; then
lines=$(wc -l < "$file")
echo -e "\n$filename (lines: $lines):" >> "$output_file"
cat "$file" >> "$output_file"
echo >> "$output_file"
else
echo -e "\n$filename [Binary or non-text file skipped]" >> "$output_file"
fi
}
process_directory() {
local dir="$1"
local relative_dir="$2"
if is_excluded "$relative_dir"; then
echo "[Excluded directory: $relative_dir]" > /dev/null
return
fi
if [[ "$relative_dir" == "." ]]; then
echo "Project Root" >> "$output_file"
else
echo "${relative_dir} folder" >> "$output_file"
fi
shopt -s nullglob
for file in "$dir"/*; do
if [[ -f "$file" ]]; then
local filename=$(basename "$file")
local file_relative_path="${relative_dir}/${filename}"
process_file "$file" "$file_relative_path"
fi
done
for subdir in "$dir"/*; do
if [[ -d "$subdir" && ! -L "$subdir" ]]; then
local subdir_name=$(basename "$subdir")
local subdir_relative_path="${relative_dir}/${subdir_name}"
process_directory "$subdir" "$subdir_relative_path"
fi
done
shopt -u nullglob
}
# Parse arguments
project_root=""
exclude=()
# Always exclude the output file by default
exclude+=("$output_file")
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
show_help
exit 0
;;
--exclude)
shift
IFS=', ' read -ra patterns <<< "$1"
for pattern in "${patterns[@]}"; do
# Remove leading/trailing whitespace and quotes
pattern=$(echo "$pattern" | xargs)
pattern="${pattern%\'}"
pattern="${pattern#\'}"
pattern="${pattern%\"}"
pattern="${pattern#\"}"
if [[ -n "$pattern" ]]; then
exclude+=("$pattern")
fi
done
shift
;;
*)
if [[ -z "$project_root" ]]; then
project_root="$1"
shift
else
echo "Error: Unexpected argument $1" >&2
show_help
exit 1
fi
;;
esac
done
if [[ -z "$project_root" ]]; then
echo "Error: Project root directory is required" >&2
show_help
exit 1
fi
project_root=$(realpath "$project_root")
if [[ ! -d "$project_root" ]]; then
echo "Error: $project_root is not a valid directory" >&2
exit 1
fi
shopt -s dotglob
: > "$output_file"
process_directory "$project_root" "."
shopt -u dotglob
echo "Project structure and content have been written to $output_file"