@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 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.4",
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",