-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathresolve-package-manager.sh
More file actions
95 lines (85 loc) · 2.61 KB
/
Copy pathresolve-package-manager.sh
File metadata and controls
95 lines (85 loc) · 2.61 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
#!/usr/bin/env bash
#
# resolve-package-manager.sh — detect which JS package manager a project uses
# by inspecting lockfiles, and emit the binary name plus canonical command tail.
#
# Usage:
# resolve-package-manager.sh [path]
#
# Arguments:
# path (optional) — directory to inspect. When omitted, defaults to the
# repo root via `git rev-parse --show-toplevel`.
#
# Output contract (two lines on stdout):
# Line 1: package-manager binary token (`npm` | `pnpm` | `yarn` | `bun`)
# Line 2: canonical argv tail for running a dev script
# - npm: "run dev" (npm requires the `run` verb)
# - pnpm: "dev" (pnpm allows bare script names)
# - yarn: "dev" (yarn allows bare script names)
# - bun: "run dev" (bun requires the `run` verb)
#
# Lockfile priority order (first match wins):
# 1. pnpm-lock.yaml -> pnpm
# 2. yarn.lock -> yarn
# 3. bun.lock -> bun (text format, preferred — newer canonical)
# 4. bun.lockb -> bun (binary format, legacy)
# 5. package-lock.json -> npm
# When both bun.lock and bun.lockb are present, bun.lock (text) is checked
# first and wins because it is the newer canonical format.
#
# Sentinel (stdout, exit 0):
# __NO_PACKAGE_JSON__ — the target directory has no package.json
#
# Errors (stderr, exit 1):
# ERROR: <message> — path does not exist, is not a directory, or
# no positional arg and not inside a git repo
set -u
TARGET_PATH="${1:-}"
# Resolve target directory: positional arg or git repo root.
if [ -n "$TARGET_PATH" ]; then
if [ ! -d "$TARGET_PATH" ]; then
echo "ERROR: path does not exist or is not a directory: $TARGET_PATH" >&2
exit 1
fi
else
TARGET_PATH=$(git rev-parse --show-toplevel 2>/dev/null)
if [ -z "$TARGET_PATH" ]; then
echo "ERROR: not in a git repository and no path argument provided" >&2
exit 1
fi
fi
# Sentinel: no package.json means this is not a JS/TS project.
if [ ! -f "$TARGET_PATH/package.json" ]; then
echo "__NO_PACKAGE_JSON__"
exit 0
fi
# Check lockfiles in priority order.
if [ -f "$TARGET_PATH/pnpm-lock.yaml" ]; then
echo "pnpm"
echo "dev"
exit 0
fi
if [ -f "$TARGET_PATH/yarn.lock" ]; then
echo "yarn"
echo "dev"
exit 0
fi
if [ -f "$TARGET_PATH/bun.lock" ]; then
echo "bun"
echo "run dev"
exit 0
fi
if [ -f "$TARGET_PATH/bun.lockb" ]; then
echo "bun"
echo "run dev"
exit 0
fi
if [ -f "$TARGET_PATH/package-lock.json" ]; then
echo "npm"
echo "run dev"
exit 0
fi
# Fallback: package.json present but no recognized lockfile.
echo "npm"
echo "run dev"
exit 0