@zendero/runctl 0.1.4 → 0.1.6
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 +1 -0
- package/bin/runctl +19 -0
- package/lib/run-lib.sh +58 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -136,6 +136,7 @@ Add scripts to your `package.json`:
|
|
|
136
136
|
| `runctl start` \| `runctl dev` | Start dev server (same command; picks free port, backgrounds) |
|
|
137
137
|
| `runctl stop [dir]` | Stop daemons & release ports |
|
|
138
138
|
| `runctl status [dir]` | Show `.run` state for this package |
|
|
139
|
+
| `runctl ps` | List running programs with PID, port, service, project |
|
|
139
140
|
| `runctl logs [dir] [service]` | Tail `.run/logs/<service>.log` (default service: `web`) |
|
|
140
141
|
| `runctl ports` | List user-wide port registry (`~/.run`) |
|
|
141
142
|
| `runctl ports gc` | Clean up stale port claims |
|
package/bin/runctl
CHANGED
|
@@ -20,6 +20,7 @@ ${_y}Commands${_r}
|
|
|
20
20
|
${_c}open${_r} [dir] Open running dev server in browser
|
|
21
21
|
${_c}stop${_r} [dir] Stop daemons & release ports
|
|
22
22
|
${_c}status${_r} [dir] Show running state
|
|
23
|
+
${_c}ps${_r} List running programs with ports/projects
|
|
23
24
|
${_c}logs${_r} [dir] [service] Tail .run/logs/<service>.log ${_d}(default service: web)${_r}
|
|
24
25
|
${_c}ports${_r} List user-wide port registry (~/.run)
|
|
25
26
|
${_c}ports gc${_r} Clean up stale port claims
|
|
@@ -156,6 +157,23 @@ cmd_ports() {
|
|
|
156
157
|
esac
|
|
157
158
|
}
|
|
158
159
|
|
|
160
|
+
cmd_ps() {
|
|
161
|
+
# shellcheck source=../lib/run-lib.sh
|
|
162
|
+
source "$RUNCTL_PKG_ROOT/lib/run-lib.sh"
|
|
163
|
+
run_global_list_running
|
|
164
|
+
local stale="${RUN_LAST_STALE_COUNT:-0}"
|
|
165
|
+
if [[ "$stale" =~ ^[0-9]+$ ]] && (( stale > 0 )); then
|
|
166
|
+
echo ""
|
|
167
|
+
echo "runctl ps: found $stale stale registry entr$( (( stale == 1 )) && echo "y" || echo "ies" ); cleaning..."
|
|
168
|
+
(run_global_gc >/dev/null 2>&1) &
|
|
169
|
+
local gc_pid=$!
|
|
170
|
+
wait "$gc_pid" || true
|
|
171
|
+
echo "runctl ps: refreshed"
|
|
172
|
+
echo ""
|
|
173
|
+
run_global_list_running
|
|
174
|
+
fi
|
|
175
|
+
}
|
|
176
|
+
|
|
159
177
|
cmd_env() {
|
|
160
178
|
local sub="${1:-}"
|
|
161
179
|
shift || true
|
|
@@ -449,6 +467,7 @@ main() {
|
|
|
449
467
|
open) cmd_open "$@" ;;
|
|
450
468
|
stop) cmd_stop "$@" ;;
|
|
451
469
|
status) cmd_status "$@" ;;
|
|
470
|
+
ps) cmd_ps "$@" ;;
|
|
452
471
|
logs) cmd_logs "$@" ;;
|
|
453
472
|
ports) cmd_ports "$@" ;;
|
|
454
473
|
env) cmd_env "$@" ;;
|
package/lib/run-lib.sh
CHANGED
|
@@ -501,6 +501,64 @@ run_global_list_ports() {
|
|
|
501
501
|
rm -f "$tmp"
|
|
502
502
|
}
|
|
503
503
|
|
|
504
|
+
run_pid_program_name() {
|
|
505
|
+
local pid="$1"
|
|
506
|
+
[[ -n "$pid" ]] || return 1
|
|
507
|
+
ps -p "$pid" -o comm= 2>/dev/null | awk '{$1=$1; print}'
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
run_global_list_running() {
|
|
511
|
+
mkdir -p "$RUN_GLOBAL_STATE/ports"
|
|
512
|
+
local f port tmp pid svc proot _line _k _v prog stale_count
|
|
513
|
+
stale_count=0
|
|
514
|
+
tmp="$(mktemp "${TMPDIR:-/tmp}/runlib-running.XXXXXX")"
|
|
515
|
+
shopt -s nullglob
|
|
516
|
+
for f in "$RUN_GLOBAL_STATE/ports"/*; do
|
|
517
|
+
[[ -f "$f" ]] || continue
|
|
518
|
+
port="$(basename "$f")"
|
|
519
|
+
[[ "$port" =~ ^[0-9]+$ ]] || continue
|
|
520
|
+
pid="" svc="" proot="" prog=""
|
|
521
|
+
while IFS= read -r _line; do
|
|
522
|
+
[[ -z "$_line" ]] && continue
|
|
523
|
+
_k="${_line%%=*}"
|
|
524
|
+
_v="${_line#*=}"
|
|
525
|
+
case "$_k" in
|
|
526
|
+
pid) pid="$_v" ;;
|
|
527
|
+
service) svc="$_v" ;;
|
|
528
|
+
project_root) proot="$_v" ;;
|
|
529
|
+
esac
|
|
530
|
+
done <"$f"
|
|
531
|
+
if [[ -z "$pid" ]]; then
|
|
532
|
+
stale_count=$((stale_count + 1))
|
|
533
|
+
continue
|
|
534
|
+
fi
|
|
535
|
+
if ! run_pid_alive "$pid"; then
|
|
536
|
+
stale_count=$((stale_count + 1))
|
|
537
|
+
continue
|
|
538
|
+
fi
|
|
539
|
+
if ! run_pid_listens_on_port "$pid" "$port"; then
|
|
540
|
+
stale_count=$((stale_count + 1))
|
|
541
|
+
continue
|
|
542
|
+
fi
|
|
543
|
+
prog="$(run_pid_program_name "$pid" || true)"
|
|
544
|
+
[[ -n "$prog" ]] || prog="(unknown)"
|
|
545
|
+
printf '%s\t%s\t%s\t%s\t%s\n' "$pid" "$prog" "$port" "${svc:--}" "${proot:--}" >>"$tmp"
|
|
546
|
+
done
|
|
547
|
+
shopt -u nullglob
|
|
548
|
+
printf '%-8s %-20s %-6s %-10s %s\n' "PID" "PROGRAM" "PORT" "SERVICE" "PROJECT"
|
|
549
|
+
printf '%-8s %-20s %-6s %-10s %s\n' "--------" "--------------------" "------" "----------" "-------"
|
|
550
|
+
if [[ -s "$tmp" ]]; then
|
|
551
|
+
sort -n -k1,1 "$tmp" | while IFS=$'\t' read -r pid prog port svc proot; do
|
|
552
|
+
printf '%-8s %-20s %-6s %-10s %s\n' "$pid" "$prog" "$port" "$svc" "$proot"
|
|
553
|
+
done
|
|
554
|
+
else
|
|
555
|
+
printf '%s\n' "(no running programs)"
|
|
556
|
+
fi
|
|
557
|
+
rm -f "$tmp"
|
|
558
|
+
RUN_LAST_STALE_COUNT="$stale_count"
|
|
559
|
+
export RUN_LAST_STALE_COUNT
|
|
560
|
+
}
|
|
561
|
+
|
|
504
562
|
run_local_status() {
|
|
505
563
|
printf 'runctl status\n'
|
|
506
564
|
printf ' %-10s %s\n' "project:" "$RUN_PROJECT_ROOT"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zendero/runctl",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Picks a free port, runs your dev server in the background, and keeps PID + port state in .run/ so projects don't collide.",
|
|
5
5
|
"author": "DoctorKhan",
|
|
6
6
|
"homepage": "https://github.com/DoctorKhan/runctl#readme",
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
],
|
|
38
38
|
"scripts": {
|
|
39
39
|
"run": "bash ./run.sh",
|
|
40
|
+
"test": "bash ./tests/runctl-ps.test.sh",
|
|
40
41
|
"doctor": "bash ./run.sh doctor",
|
|
41
42
|
"release-check": "bash ./run.sh release-check",
|
|
42
43
|
"promote": "bash ./run.sh promote",
|