@slango.configs/scripts 1.0.0 → 1.2.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/CHANGELOG.md +12 -0
- package/README.md +25 -0
- package/bin/clean-build-artifacts.sh +3 -1
- package/bin/clean-cache-artifacts.sh +2 -1
- package/bin/clean-docker-images.sh +222 -0
- package/bin/clean-node-modules.sh +1 -1
- package/package.json +6 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @slango.configs/scripts
|
|
2
2
|
|
|
3
|
+
## 1.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 13f54b1: Add clean-docker-images script with scoped pruning based on the repo package name.
|
|
8
|
+
|
|
9
|
+
## 1.1.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- fe4fee1: Support for .nextjs build artifacts
|
|
14
|
+
|
|
3
15
|
## 1.0.0
|
|
4
16
|
|
|
5
17
|
### Major Changes
|
package/README.md
CHANGED
|
@@ -13,3 +13,28 @@ Removes all cache artifacts from the current directory and its subdirectories.
|
|
|
13
13
|
## clean-build-artifacts
|
|
14
14
|
|
|
15
15
|
Removes all build artifacts from the current directory and its subdirectories.
|
|
16
|
+
|
|
17
|
+
## clean-docker-images
|
|
18
|
+
|
|
19
|
+
Removes Docker images built from this repo, scoped by the `name` in the repo's `package.json`.
|
|
20
|
+
|
|
21
|
+
Usage:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
clean-docker-images [options]
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Options:
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
-a, --all Remove unused Docker images for this repo name
|
|
31
|
+
-i, --image <image:tag> Remove a specific image by name and tag (scoped)
|
|
32
|
+
-h, --help Show help
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Examples:
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
clean-docker-images --all
|
|
39
|
+
clean-docker-images --image myimage:1.0.11
|
|
40
|
+
```
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
#!/bin/
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
2
|
|
|
3
3
|
# This script removes all dist directories in the monorepo.
|
|
4
4
|
echo "Removing all dist directories..."
|
|
5
5
|
|
|
6
6
|
# Find and remove all dist folders
|
|
7
7
|
find . -name 'dist' -type d -prune -exec rm -rf '{}' +
|
|
8
|
+
# Find and remove all .next folders
|
|
9
|
+
find . -name '.next' -type d -prune -exec rm -rf '{}' +
|
|
8
10
|
# Find and remove all tsbuildinfo files
|
|
9
11
|
find . -name '*.tsbuildinfo' -type f -prune -exec rm -rf '{}' +
|
|
10
12
|
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
|
|
3
|
+
# This script removes Docker images from the local machine.
|
|
4
|
+
|
|
5
|
+
color_enabled=false
|
|
6
|
+
if [ -t 1 ] && [ -z "${NO_COLOR:-}" ]; then
|
|
7
|
+
color_enabled=true
|
|
8
|
+
fi
|
|
9
|
+
|
|
10
|
+
if [ "$color_enabled" = "true" ]; then
|
|
11
|
+
COLOR_RESET="$(printf '\033[0m')"
|
|
12
|
+
COLOR_BOLD="$(printf '\033[1m')"
|
|
13
|
+
COLOR_BLUE="$(printf '\033[34m')"
|
|
14
|
+
COLOR_GREEN="$(printf '\033[32m')"
|
|
15
|
+
COLOR_YELLOW="$(printf '\033[33m')"
|
|
16
|
+
COLOR_RED="$(printf '\033[31m')"
|
|
17
|
+
else
|
|
18
|
+
COLOR_RESET=""
|
|
19
|
+
COLOR_BOLD=""
|
|
20
|
+
COLOR_BLUE=""
|
|
21
|
+
COLOR_GREEN=""
|
|
22
|
+
COLOR_YELLOW=""
|
|
23
|
+
COLOR_RED=""
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
log_step() {
|
|
27
|
+
printf '%s==>%s %s\n' "${COLOR_BLUE}${COLOR_BOLD}" "$COLOR_RESET" "$*"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
log_info() {
|
|
31
|
+
printf '%s[info]%s %s\n' "$COLOR_BLUE" "$COLOR_RESET" "$*"
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
log_success() {
|
|
35
|
+
printf '%s[ok]%s %s\n' "$COLOR_GREEN" "$COLOR_RESET" "$*"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
log_warn() {
|
|
39
|
+
printf '%s[warn]%s %s\n' "$COLOR_YELLOW" "$COLOR_RESET" "$*"
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
log_error() {
|
|
43
|
+
printf '%s[error]%s %s\n' "$COLOR_RED" "$COLOR_RESET" "$*"
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
log_step "Docker image cleanup"
|
|
47
|
+
|
|
48
|
+
# Ensure Docker is available before attempting to prune.
|
|
49
|
+
if ! command -v docker >/dev/null 2>&1; then
|
|
50
|
+
log_warn "Docker CLI not found. Skipping."
|
|
51
|
+
exit 0
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
mode=""
|
|
55
|
+
image_name=""
|
|
56
|
+
|
|
57
|
+
usage() {
|
|
58
|
+
printf '%s\n' "Usage: clean-docker-images --all | --image <image:tag>"
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
repo_root() {
|
|
62
|
+
if command -v git >/dev/null 2>&1; then
|
|
63
|
+
git rev-parse --show-toplevel 2>/dev/null || pwd
|
|
64
|
+
else
|
|
65
|
+
pwd
|
|
66
|
+
fi
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
package_name() {
|
|
70
|
+
root="$(repo_root)"
|
|
71
|
+
pkg_file="$root/package.json"
|
|
72
|
+
if [ ! -f "$pkg_file" ]; then
|
|
73
|
+
return 1
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
if command -v node >/dev/null 2>&1; then
|
|
77
|
+
PKG_PATH="$pkg_file" node -p "require(process.env.PKG_PATH).name" 2>/dev/null || true
|
|
78
|
+
else
|
|
79
|
+
awk -F'"' '/"name"[[:space:]]*:/ { print $4; exit }' "$pkg_file"
|
|
80
|
+
fi
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
repo_in_scope() {
|
|
84
|
+
repo="${1:-}"
|
|
85
|
+
base="${2:-}"
|
|
86
|
+
repo="${repo%@*}"
|
|
87
|
+
last_segment="${repo##*/}"
|
|
88
|
+
case "$last_segment" in
|
|
89
|
+
*:*)
|
|
90
|
+
repo="${repo%:*}"
|
|
91
|
+
;;
|
|
92
|
+
esac
|
|
93
|
+
case "$repo" in
|
|
94
|
+
"$base" | "$base/"* | */"$base" | */"$base/"*)
|
|
95
|
+
return 0
|
|
96
|
+
;;
|
|
97
|
+
esac
|
|
98
|
+
return 1
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
while [ "$#" -gt 0 ]; do
|
|
102
|
+
case "$1" in
|
|
103
|
+
-a|--all)
|
|
104
|
+
mode="all"
|
|
105
|
+
shift
|
|
106
|
+
;;
|
|
107
|
+
-i|--image)
|
|
108
|
+
mode="image"
|
|
109
|
+
image_name="${2:-}"
|
|
110
|
+
shift 2
|
|
111
|
+
;;
|
|
112
|
+
-h|--help)
|
|
113
|
+
usage
|
|
114
|
+
exit 0
|
|
115
|
+
;;
|
|
116
|
+
*)
|
|
117
|
+
echo "Unknown option: $1"
|
|
118
|
+
usage
|
|
119
|
+
exit 1
|
|
120
|
+
;;
|
|
121
|
+
esac
|
|
122
|
+
done
|
|
123
|
+
|
|
124
|
+
if [ -z "$mode" ]; then
|
|
125
|
+
usage
|
|
126
|
+
exit 1
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
repo_name="$(package_name)"
|
|
130
|
+
if [ -z "$repo_name" ]; then
|
|
131
|
+
log_error "Unable to determine package.json name for this repo."
|
|
132
|
+
usage
|
|
133
|
+
exit 1
|
|
134
|
+
fi
|
|
135
|
+
|
|
136
|
+
if [ "$mode" = "all" ]; then
|
|
137
|
+
log_info "Scope: $repo_name"
|
|
138
|
+
log_info "Scanning local images..."
|
|
139
|
+
in_use_refs="$(docker ps -a --format '{{.Image}}' | sort -u)"
|
|
140
|
+
images_in_scope="$(docker images --format '{{.Repository}} {{.Tag}}' | while IFS=' ' read -r repo tag; do
|
|
141
|
+
[ -z "$repo" ] && continue
|
|
142
|
+
[ -z "$tag" ] && continue
|
|
143
|
+
[ "$repo" = "<none>" ] && continue
|
|
144
|
+
[ "$tag" = "<none>" ] && continue
|
|
145
|
+
if repo_in_scope "$repo" "$repo_name"; then
|
|
146
|
+
printf '%s:%s\n' "$repo" "$tag"
|
|
147
|
+
fi
|
|
148
|
+
done)"
|
|
149
|
+
|
|
150
|
+
if [ -z "$images_in_scope" ]; then
|
|
151
|
+
log_warn "No images found for repo: $repo_name"
|
|
152
|
+
exit 0
|
|
153
|
+
fi
|
|
154
|
+
|
|
155
|
+
removed_count=0
|
|
156
|
+
skipped_count=0
|
|
157
|
+
failed_count=0
|
|
158
|
+
total_count=0
|
|
159
|
+
|
|
160
|
+
while IFS= read -r ref; do
|
|
161
|
+
[ -z "$ref" ] && continue
|
|
162
|
+
total_count=$((total_count + 1))
|
|
163
|
+
if [ -n "$in_use_refs" ] && echo "$in_use_refs" | grep -Fxq "$ref"; then
|
|
164
|
+
skipped_count=$((skipped_count + 1))
|
|
165
|
+
log_warn "In use, skipping: $ref"
|
|
166
|
+
continue
|
|
167
|
+
fi
|
|
168
|
+
remove_output="$(docker rmi "$ref" 2>&1)"
|
|
169
|
+
if [ $? -eq 0 ]; then
|
|
170
|
+
removed_count=$((removed_count + 1))
|
|
171
|
+
log_success "Removed: $ref"
|
|
172
|
+
else
|
|
173
|
+
failed_count=$((failed_count + 1))
|
|
174
|
+
log_error "Failed: $ref"
|
|
175
|
+
if [ -n "$remove_output" ]; then
|
|
176
|
+
printf '%s\n' "$remove_output" | while IFS= read -r line; do
|
|
177
|
+
printf '%s %s%s\n' "$COLOR_RED" "$line" "$COLOR_RESET"
|
|
178
|
+
done
|
|
179
|
+
fi
|
|
180
|
+
fi
|
|
181
|
+
done <<EOF
|
|
182
|
+
$images_in_scope
|
|
183
|
+
EOF
|
|
184
|
+
|
|
185
|
+
log_step "Summary"
|
|
186
|
+
log_info "Images in scope: $total_count"
|
|
187
|
+
log_success "Removed: $removed_count"
|
|
188
|
+
log_warn "Skipped (in use): $skipped_count"
|
|
189
|
+
if [ "$failed_count" -gt 0 ]; then
|
|
190
|
+
log_error "Failed: $failed_count"
|
|
191
|
+
else
|
|
192
|
+
log_info "Failed: 0"
|
|
193
|
+
fi
|
|
194
|
+
exit 0
|
|
195
|
+
fi
|
|
196
|
+
|
|
197
|
+
if [ "$mode" = "image" ]; then
|
|
198
|
+
if [ -z "$image_name" ]; then
|
|
199
|
+
log_error "Missing image name."
|
|
200
|
+
usage
|
|
201
|
+
exit 1
|
|
202
|
+
fi
|
|
203
|
+
|
|
204
|
+
if ! docker image inspect "$image_name" >/dev/null 2>&1; then
|
|
205
|
+
log_warn "No image found for name: $image_name"
|
|
206
|
+
exit 0
|
|
207
|
+
fi
|
|
208
|
+
|
|
209
|
+
if ! repo_in_scope "$image_name" "$repo_name"; then
|
|
210
|
+
log_error "Image not in scope for repo: $repo_name"
|
|
211
|
+
exit 1
|
|
212
|
+
fi
|
|
213
|
+
|
|
214
|
+
log_info "Removing: $image_name"
|
|
215
|
+
docker rmi -f "$image_name"
|
|
216
|
+
|
|
217
|
+
log_success "Removed: $image_name"
|
|
218
|
+
exit 0
|
|
219
|
+
fi
|
|
220
|
+
|
|
221
|
+
usage
|
|
222
|
+
exit 1
|
package/package.json
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slango.configs/scripts",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Slango scripts",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
8
8
|
"clean-node-modules": "bin/clean-node-modules.sh",
|
|
9
9
|
"clean-build-artifacts": "bin/clean-build-artifacts.sh",
|
|
10
|
-
"clean-cache-artifacts": "bin/clean-cache-artifacts.sh"
|
|
10
|
+
"clean-cache-artifacts": "bin/clean-cache-artifacts.sh",
|
|
11
|
+
"clean-docker-images": "bin/clean-docker-images.sh"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"@slango.configs/lint-staged": "1.1.13"
|
|
11
15
|
},
|
|
12
|
-
"devDependencies": {},
|
|
13
16
|
"scripts": {}
|
|
14
17
|
}
|