volta-cli / volta

Volta: JS Toolchains as Code. ⚡
https://volta.sh
Other
10.99k stars 232 forks source link

List installed packages with npm #1012

Open gperdomor opened 3 years ago

gperdomor commented 3 years ago

Hi

Running npm -g list not show the installed packages, but Volta list if it does...

Screen Shot 2021-08-06 at 4 46 15 PM
charlespierce commented 3 years ago

Hi @gperdomor, thanks for reporting! Volta manages packages in a custom layout that is different from what npm uses, so we'll have to investigate if we can set some flags to get npm to detect that layout. If not, we could probably intercept that command and show the volta list output, but that wouldn't be an ideal solution.

ljharb commented 3 years ago

You can set $NPM_CONFIG_PREFIX to override npm root -g.

bretonics commented 2 years ago

I've actually been meaning to report this as well and was just about to...then saw this.

I think the reason is that Volta sets up the npm config with the prefix value as prefix = "/Users/bretonics/.volta/tools/image/node/16.17.0" (run npm config ls -l).

I was surprised because when you do volta which <tool> it displays this path: /Users/bretonics/.volta/tools/image/packages/.

❯ volta which ng  
/Users/bretonics/.volta/tools/image/packages/@angular/cli/bin/ng

I could be wrong in my initial thought, but I was expecting the prefix to be that since that's were the tools (packages) are installed. However, I believe the reason they are in this location, is because of how package installs are sandboxed. Is this correct? What I don't understand is how such a global package is sandboxed and has its node version pinned when switching node versions still shows the same path....?

at 21:54:22 zsh ❯ volta install node@14
success: installed and set node@14.20.0 (with npm@6.14.17) as default

~ 
at 22:00:12 zsh ❯ volta list           
⚡️ Currently active tools:

    Node: v14.20.0 (default)
    Tool binaries available:
        ng (default)
         (default)

See options for more detailed reports by running `volta list --help`.

~ 
at 22:00:15 zsh ❯ volta which ng
/Users/bretonics/.volta/tools/image/packages/@angular/cli/bin/ng

However, it's confusing that npm list --global --depth 0 -p only lists corepack and npm, rather than all the globally installed packages as one would expect with a normal node/npm install, which is what volta list displays.

Here's a sequence of events:

~ 
at 18:40:44 zsh ❯ volta install node@16
success: installed and set node@16.17.0 (with npm@8.15.0) as default

~ 
at 21:33:11 zsh ❯ volta list
⚡️ Currently active tools:

    Node: v16.17.0 (default)
    Tool binaries available:
         (default)

See options for more detailed reports by running `volta list --help`.

~ 
at 21:33:16 zsh ❯ npm install --global @angular/cli

added 209 packages, and audited 210 packages in 9s

25 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
npm notice 
npm notice New minor version of npm available! 8.15.0 -> 8.19.2
npm notice Changelog: https://github.com/npm/cli/releases/tag/v8.19.2
npm notice Run npm install -g npm@8.19.2 to update!
npm notice 

~ took 10s 
at 21:33:50 zsh ❯ volta list
⚡️ Currently active tools:

    Node: v16.17.0 (default)
    Tool binaries available:
        ng (default)
         (default)

See options for more detailed reports by running `volta list --help`.

~ 
at 21:33:57 zsh ❯ volta which ng  
/Users/bretonics/.volta/tools/image/packages/@angular/cli/bin/ng

~ 
at 21:34:05 zsh ❯ npm list --global --depth 0 -p   
/Users/bretonics/.volta/tools/image/node/16.17.0/lib
/Users/bretonics/.volta/tools/image/node/16.17.0/lib/node_modules/corepack
/Users/bretonics/.volta/tools/image/node/16.17.0/lib/node_modules/npm

~ 
at 21:34:14 zsh ❯ npm config ls -l              
; "default" config from default values

_auth = (protected) 
access = null 
all = false 
allow-same-version = false 
also = null 
audit = true 
audit-level = null 
auth-type = "legacy" 
before = null 
bin-links = true 
browser = null 
ca = null 
cache = "/Users/bretonics/.npm" 
cache-max = null 
cache-min = 0 
cafile = null 
call = "" 
cert = null 
ci-name = null 
cidr = null 
color = true 
commit-hooks = true 
depth = null 
description = true 
dev = false 
diff = [] 
diff-dst-prefix = "b/" 
diff-ignore-all-space = false 
diff-name-only = false 
diff-no-prefix = false 
diff-src-prefix = "a/" 
diff-text = false 
diff-unified = 3 
dry-run = false 
editor = "vi" 
engine-strict = false 
fetch-retries = 2 
fetch-retry-factor = 10 
fetch-retry-maxtimeout = 60000 
fetch-retry-mintimeout = 10000 
fetch-timeout = 300000 
force = false 
foreground-scripts = false 
format-package-lock = true 
fund = true 
git = "git" 
git-tag-version = true 
global = false 
global-style = false 
globalconfig = "/Users/bretonics/.volta/tools/image/node/16.17.0/etc/npmrc" 
heading = "npm" 
https-proxy = null 
if-present = false 
ignore-scripts = false 
include = [] 
include-staged = false 
include-workspace-root = false 
init-author-email = "" 
init-author-name = "" 
init-author-url = "" 
init-license = "ISC" 
init-module = "/Users/bretonics/.npm-init.js" 
init-version = "1.0.0" 
init.author.email = "" 
init.author.name = "" 
init.author.url = "" 
init.license = "ISC" 
init.module = "/Users/bretonics/.npm-init.js" 
init.version = "1.0.0" 
install-links = false 
json = false 
key = null 
legacy-bundling = false 
legacy-peer-deps = false 
link = false 
local-address = null 
location = "user" 
lockfile-version = null 
loglevel = "notice" 
logs-dir = null 
logs-max = 10 
; long = false ; overridden by cli
maxsockets = 15 
message = "%s" 
metrics-registry = "https://registry.npmjs.org/" 
node-options = null 
node-version = "v16.17.0" 
noproxy = [""] 
npm-version = "8.15.0" 
offline = false 
omit = [] 
omit-lockfile-registry-resolved = false 
only = null 
optional = null 
otp = null 
pack-destination = "." 
package = [] 
package-lock = true 
package-lock-only = false 
parseable = false 
prefer-offline = false 
prefer-online = false 
prefix = "/Users/bretonics/.volta/tools/image/node/16.17.0" 
preid = "" 
production = null 
progress = true 
proxy = null 
read-only = false 
rebuild-bundle = true 
registry = "https://registry.npmjs.org/" 
save = true 
save-bundle = false 
save-dev = false 
save-exact = false 
save-optional = false 
save-peer = false 
save-prefix = "^" 
save-prod = false 
scope = "" 
script-shell = null 
searchexclude = "" 
searchlimit = 20 
searchopts = "" 
searchstaleness = 900 
shell = "/bin/zsh" 
shrinkwrap = true 
sign-git-commit = false 
sign-git-tag = false 
sso-poll-frequency = 500 
sso-type = "oauth" 
strict-peer-deps = false 
strict-ssl = true 
tag = "latest" 
tag-version-prefix = "v" 
timing = false 
tmp = "/var/folders/hw/3lf8_5fs6kv07xffnzd3h81r0000gp/T" 
umask = 0 
unicode = true 
update-notifier = true 
usage = false 
user-agent = "npm/{npm-version} node/{node-version} {platform} {arch} workspaces/{workspaces} {ci}" 
userconfig = "/Users/bretonics/.npmrc" 
version = false 
versions = false 
viewer = "man" 
which = null 
workspace = [] 
workspaces = null 
workspaces-update = true 
yes = null 

; "cli" config from command line options

long = true

~ 
at 21:37:00 zsh ❯ volta --version
1.0.8

A normal node/npm install would have prefix=/usr/local and stubbing this --if you previously had node/npm installed other than Volta of NVM, e.g. brew install node-- shows the expected globally installed packages:

at 21:55:44 zsh ❯ npm list --prefix '/usr/local' --global --depth 0 -p 
/usr/local/lib
/usr/local/lib/node_modules/@angular-devkit/schematics-cli
/usr/local/lib/node_modules/@angular/cli
/usr/local/lib/node_modules/@nestjs/cli
/usr/local/lib/node_modules/@nrwl/cli
/usr/local/lib/node_modules/auto-changelog
/usr/local/lib/node_modules/chalk
/usr/local/lib/node_modules/eslint
/usr/local/lib/node_modules/npm-check-updates
/usr/local/lib/node_modules/npm

All in all, I would expect npm list --global --depth 0 -p to show me the globally installed packages.

This is actually the behavior using nvm:

# Fresh `nvm` install with `npm install --global ng`
~ 
at 22:45:16 zsh ❯ npm list --global --depth 0 -p
/Users/abreton/.nvm/versions/node/v14.20.0/lib
/Users/abreton/.nvm/versions/node/v14.20.0/lib/node_modules/corepack
/Users/abreton/.nvm/versions/node/v14.20.0/lib/node_modules/npm
/Users/abreton/.nvm/versions/node/v14.20.0/lib/node_modules/ng
chriskrycho commented 9 months ago

It is indeed the result of sandboxing, as @bretonics identifies. The nvm approach has the upside of just having the prefix, while we have more complexity here to support the sandboxing from installed versions.

(It strikes me, a few years on, that this is actually one reason that npm install --global is less preferable than volta install. The latter gives a “more correct” mental model for the fact that we actually do have different behavior than npm install --global does.)