MCPcopy Create free account
hub / github.com/colbymchenry/codegraph / detectInstallMethod

Function detectInstallMethod

src/upgrade/index.ts:95–144  ·  view source on GitHub ↗
(input: DetectInput)

Source from the content-addressed store, hash-verified

93}
94
95export function detectInstallMethod(input: DetectInput): InstallMethod {
96 const exists = input.exists ?? fs.existsSync;
97 const isWin = input.platform === 'win32';
98 // Path math keyed on the TARGET platform so detection is host-independent
99 // (a Windows layout resolves correctly even when unit-tested on macOS/Linux).
100 const P = isWin ? path.win32 : path.posix;
101 const binDir = P.dirname(input.filename); // <…>/bin
102
103 const norm = toPosix(input.filename);
104
105 // Path-based checks come FIRST. The npm thin-installer's per-platform
106 // package (@colbymchenry/codegraph-<platform>-<arch>) is itself a complete
107 // bundle — vendored node + bin/ launcher — living inside node_modules, so
108 // the layout sniff below would misread every npm install as a standalone
109 // bundle. `upgrade` would then curl install.sh into ~/.codegraph: a SECOND
110 // install that never wins the PATH race against npm's shim, leaving
111 // `codegraph -v` permanently on the old version (the #1071 shadow,
112 // self-inflicted). A path under node_modules is authoritative about HOW the
113 // user installed, whatever the artifact inside looks like.
114
115 // npx cache: <…>/_npx/<hash>/node_modules/@colbymchenry/codegraph/…
116 // (checked before npm — the npx cache path also contains /node_modules/).
117 if (norm.includes('/_npx/')) {
118 return { kind: 'npx' };
119 }
120
121 // npm install (global or local): lives under a node_modules tree.
122 if (norm.includes('/node_modules/')) {
123 const underCwd = norm.startsWith(toPosix(P.resolve(input.cwd)) + '/');
124 return { kind: 'npm', scope: underCwd ? 'local' : 'global' };
125 }
126
127 // Bundle: <root>/lib/dist/bin/codegraph.js → <root> is up 3 from bin/.
128 // A bundle has a vendored node + a launcher script as siblings of lib/.
129 const bundleRoot = P.resolve(binDir, '..', '..', '..');
130 const vendoredNode = P.join(bundleRoot, isWin ? 'node.exe' : 'node');
131 const launcher = P.join(bundleRoot, 'bin', isWin ? 'codegraph.cmd' : 'codegraph');
132 if (exists(vendoredNode) && exists(launcher)) {
133 const os = isWin ? 'windows' : 'unix';
134 return { kind: 'bundle', os, bundleRoot, installDir: deriveInstallDir(bundleRoot, os, exists) };
135 }
136
137 // Source checkout: running <repo>/dist/bin/codegraph.js with a sibling .git.
138 const repoRoot = P.resolve(binDir, '..', '..');
139 if (exists(P.join(repoRoot, 'package.json')) && exists(P.join(repoRoot, '.git'))) {
140 return { kind: 'source', root: repoRoot };
141 }
142
143 return { kind: 'unknown', reason: `unrecognized install layout at ${input.filename}` };
144}
145
146// ---------------------------------------------------------------------------
147// Version helpers (pure)

Callers 3

installDirCandidatesFunction · 0.90
planBinaryRemovalFunction · 0.90
upgrade.test.tsFile · 0.90

Calls 4

toPosixFunction · 0.85
deriveInstallDirFunction · 0.85
resolveMethod · 0.80
joinMethod · 0.45

Tested by

no test coverage detected