0
0
Fork 0

fix(postinstall): use script-location-vs-INIT_CWD to detect dev (npm 11)

The previous heuristic checked whether INIT_CWD's package.json had our
name -- but that triggers a false positive when the user runs
`npm install -g codesys-mcp-sp21-plus@latest` from a clone of the
repo (very common -- they're testing the new release). My install
ran from ~/Codesys-MCP and the banner stayed silent.

Right discriminator: does the script's __dirname LIVE INSIDE
INIT_CWD? If yes, this is the dev case (installing yourself into
yourself). If no -- even when INIT_CWD is a clone of this repo --
the script lives in the global prefix and the user is doing a real
install. Print the banner.

Verified:
- INIT_CWD == repo, __dirname == /tmp/...: banner prints
- INIT_CWD == repo, __dirname == repo/dist: silent (dev case)
This commit is contained in:
Karstein Phobic Nyvold Kvistad 2026-04-27 20:40:02 +02:00
parent 5c756147c1
commit 37050ce2b6

View file

@ -18,24 +18,24 @@ function shouldSkip(): boolean {
if (process.env.npm_config_ci === 'true') return true;
// Skip when running inside the package's own dev clone (developer ran
// `npm install` on a checkout of this repo). Detect by checking whether
// INIT_CWD (npm sets this to the user's invocation cwd) appears to be
// a checkout of THIS package, vs a global install or a downstream consumer.
// Heuristic: if INIT_CWD contains a package.json whose name matches ours,
// it's the dev clone.
// `npm install` on a checkout of this repo). The right discriminator is
// whether the script's own directory LIVES INSIDE INIT_CWD. If yes, the
// install is targeting our own checkout (dev). If no -- even if INIT_CWD
// happens to be a clone of this repo -- the script lives in the global
// prefix and should print the banner.
//
// INIT_CWD == npm's invocation cwd.
// __dirname == <install-prefix>/codesys-mcp-sp21-plus/dist for global
// installs, == <repo>/dist for the dev case.
if (process.env.INIT_CWD) {
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const fs = require('fs');
// eslint-disable-next-line @typescript-eslint/no-var-requires
const path = require('path');
const pkgPath = path.join(process.env.INIT_CWD, 'package.json');
if (fs.existsSync(pkgPath)) {
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
if (pkg.name === 'codesys-mcp-sp21-plus') return true;
}
const rel = path.relative(process.env.INIT_CWD, __dirname);
const livesUnderInitCwd = !rel.startsWith('..') && !path.isAbsolute(rel);
if (livesUnderInitCwd) return true;
} catch {
// Not a dev clone or unreadable -- fall through and print the banner.
// Fall through and print the banner.
}
}