@slango.configs/scripts 1.1.0 → 1.2.1

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/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
+ ```
@@ -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,16 +1,25 @@
1
1
  {
2
2
  "name": "@slango.configs/scripts",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "private": false,
5
5
  "description": "Slango scripts",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/danilupion/slango",
9
+ "directory": "configs/scripts"
10
+ },
6
11
  "type": "module",
12
+ "files": [
13
+ "bin"
14
+ ],
7
15
  "bin": {
8
16
  "clean-node-modules": "bin/clean-node-modules.sh",
9
17
  "clean-build-artifacts": "bin/clean-build-artifacts.sh",
10
- "clean-cache-artifacts": "bin/clean-cache-artifacts.sh"
18
+ "clean-cache-artifacts": "bin/clean-cache-artifacts.sh",
19
+ "clean-docker-images": "bin/clean-docker-images.sh"
11
20
  },
12
21
  "devDependencies": {
13
- "@slango.configs/lint-staged": "1.1.2"
22
+ "@slango.configs/lint-staged": "1.1.30"
14
23
  },
15
24
  "scripts": {}
16
25
  }
package/CHANGELOG.md DELETED
@@ -1,13 +0,0 @@
1
- # @slango.configs/scripts
2
-
3
- ## 1.1.0
4
-
5
- ### Minor Changes
6
-
7
- - fe4fee1: Support for .nextjs build artifacts
8
-
9
- ## 1.0.0
10
-
11
- ### Major Changes
12
-
13
- - 26855a3: Initial release
@@ -1 +0,0 @@
1
- export { default } from '@slango.configs/lint-staged/default.js';