-
Notifications
You must be signed in to change notification settings - Fork 29
Expand file tree
/
Copy pathcpcode
More file actions
executable file
·166 lines (147 loc) · 6.75 KB
/
cpcode
File metadata and controls
executable file
·166 lines (147 loc) · 6.75 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
165
166
#!/bin/bash
########################################################################
# cpcode — Regroupe des fichiers par extension dans le presse-papiers
#
# Usage : cpcode [--json] [--maxfilesize N] <extension1> [ext2 ...] <dossier>
#
# Options :
# --json Sortie JSON compatible code_assistant / LLM tool
# --maxfilesize N Limite la taille par fichier en octets (défaut: illimité)
# Ex: --maxfilesize 102400 (100 Ko par fichier)
# --help Affiche cette aide
########################################################################
show_help() {
echo "Usage : $0 [--json] [--maxfilesize N] <ext1> [ext2 ...] <dossier>"
echo ""
echo "Options :"
echo " --json Sortie JSON (compatible code_assistant / LLM tool)"
echo " --maxfilesize N Limite par fichier en octets (P3)"
echo " --help Affiche cette aide."
exit 0
}
# ── Parsing des options ───────────────────────────────────────────────────
JSON_MODE=false
MAX_FILE_SIZE=0
POSITIONAL=()
while [[ $# -gt 0 ]]; do
case "$1" in
--help) show_help ;;
--json) JSON_MODE=true; shift ;;
--maxfilesize) MAX_FILE_SIZE="$2"; shift 2 ;;
--maxfilesize=*) MAX_FILE_SIZE="${1#--maxfilesize=}"; shift ;;
*) POSITIONAL+=("$1"); shift ;;
esac
done
if [ "${#POSITIONAL[@]}" -lt 2 ]; then
echo "Erreur : Arguments manquants."
show_help
exit 1
fi
# Séparer extensions (tout sauf dernier) et dossier (dernier)
EXTENSIONS=("${POSITIONAL[@]:0:${#POSITIONAL[@]}-1}")
SOURCE_DIR="${POSITIONAL[-1]}"
if [ ! -d "$SOURCE_DIR" ]; then
echo "Erreur : Le dossier source '$SOURCE_DIR' n'existe pas."
exit 1
fi
MOATS=$(date -u +"%Y%m%d%H%M%S%4N")
TEMP_FILE="/tmp/$MOATS.txt"
> "$TEMP_FILE"
NB_FILES=0
JSON_FILE_COUNT=0
# ── Traitement des fichiers ───────────────────────────────────────────────
for EXT in "${EXTENSIONS[@]}"; do
while IFS= read -r FILE; do
# Vérifier que c'est un fichier texte (grep -I échoue sur les binaires)
if ! grep -Iq . "$FILE" 2>/dev/null; then
echo " [IGNORÉ - binaire] $FILE"
continue
fi
RELATIVE_PATH=$(realpath --relative-to="$SOURCE_DIR" "$FILE")
FILENAME=$(basename "$FILE" | sed "s/\.$EXT$//")
echo "Ajout de : $FILE"
# Lire le contenu (avec limite optionnelle par fichier)
if [ "$MAX_FILE_SIZE" -gt 0 ]; then
CONTENT=$(head -c "$MAX_FILE_SIZE" "$FILE")
local FULL_SIZE
FULL_SIZE=$(wc -c < "$FILE" 2>/dev/null || echo 0)
if [ "$FULL_SIZE" -gt "$MAX_FILE_SIZE" ]; then
CONTENT="${CONTENT}"$'\n'"[... TRONQUÉ à ${MAX_FILE_SIZE} octets / ${FULL_SIZE} total ...]"
fi
else
CONTENT=$(cat "$FILE")
fi
if $JSON_MODE; then
# Sortie JSON : un objet par fichier
local COMMA=""
[ "$JSON_FILE_COUNT" -gt 0 ] && COMMA=","
local CONTENT_JSON
CONTENT_JSON=$(python3 -c "import json,sys; print(json.dumps(sys.stdin.read()))" <<< "$CONTENT" 2>/dev/null || echo '""')
{
echo "${COMMA}{"
printf ' "path": %s,\n' "$(python3 -c "import json; print(json.dumps('$RELATIVE_PATH'))" 2>/dev/null || echo '"'"$RELATIVE_PATH"'"')"
printf ' "filename": %s,\n' "$(python3 -c "import json; print(json.dumps('$FILENAME'))" 2>/dev/null || echo '"'"$FILENAME"'"')"
printf ' "extension": "%s",\n' "$EXT"
printf ' "content": %s\n' "$CONTENT_JSON"
echo "}"
} >> "$TEMP_FILE"
(( JSON_FILE_COUNT++ )) || true
else
# Sortie texte classique (écriture directe, pas de RESULT+= pour éviter corruption)
{
echo "Chemin : $RELATIVE_PATH"
echo "Titre : $FILENAME"
echo ""
echo "$CONTENT"
echo ""
} >> "$TEMP_FILE"
fi
(( NB_FILES++ )) || true
done < <(find "$SOURCE_DIR" -type f -name "*.$EXT" | grep -v '/\.')
done
# ── Enveloppe JSON finale ────────────────────────────────────────────────
if $JSON_MODE; then
TOTAL_CHARS=$(wc -c < "$TEMP_FILE" 2>/dev/null || echo 0)
TOTAL_TOKENS=$(( TOTAL_CHARS / 4 ))
JSON_FINAL="/tmp/${MOATS}.json"
{
echo "{"
printf ' "tool": "cpcode",\n'
printf ' "source_dir": %s,\n' "$(python3 -c "import json; print(json.dumps('$(realpath "$SOURCE_DIR")'))" 2>/dev/null)"
printf ' "extensions": %s,\n' "$(python3 -c "import json; print(json.dumps($(printf '[%s]' "$(printf '"%s",' "${EXTENSIONS[@]}" | sed 's/,$//')" )))" 2>/dev/null || echo "[]")"
printf ' "stats": { "files_count": %d, "total_chars": %d, "total_tokens": %d },\n' \
"$NB_FILES" "$TOTAL_CHARS" "$TOTAL_TOKENS"
echo ' "files": ['
cat "$TEMP_FILE"
echo ' ]'
echo "}"
} > "$JSON_FINAL"
mv "$JSON_FINAL" "$TEMP_FILE"
fi
# ── Validation ────────────────────────────────────────────────────────────
if [ ! -s "$TEMP_FILE" ]; then
echo "Erreur : Aucun fichier trouvé avec les extensions spécifiées dans '$SOURCE_DIR'."
rm -f "$TEMP_FILE"
exit 1
fi
TOTAL_CHARS=$(wc -c < "$TEMP_FILE" 2>/dev/null || echo 0)
TOTAL_TOKENS=$(( TOTAL_CHARS / 4 ))
echo ""
echo "=== $NB_FILES fichier(s) — ${TOTAL_CHARS} chars (~${TOTAL_TOKENS} tokens) ==="
# ── Presse-papiers ────────────────────────────────────────────────────────
COPIED=false
if [ -n "$DISPLAY" ] && command -v xclip &>/dev/null; then
if cat "$TEMP_FILE" | xclip -selection clipboard 2>/dev/null; then
COPIED=true; echo "Contenu copié dans le presse-papiers (xclip)."
fi
elif [ -n "$WAYLAND_DISPLAY" ] && command -v wl-copy &>/dev/null; then
if cat "$TEMP_FILE" | wl-copy 2>/dev/null; then
COPIED=true; echo "Contenu copié dans le presse-papiers (wl-copy)."
fi
elif command -v pbcopy &>/dev/null; then
if cat "$TEMP_FILE" | pbcopy 2>/dev/null; then
COPIED=true; echo "Contenu copié dans le presse-papiers (pbcopy)."
fi
fi
[ "$COPIED" = false ] && echo "Avertissement : Impossible de copier dans le presse-papiers."
echo "Résultat écrit dans : $TEMP_FILE"