npm / npm/cli

[BUG] project config still loaded if userconfig sets global=true

Open
#5,797 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug Needs Triage
Dominant language
JavaScript
Stars
10.1k
Forks
4.7k
Avg merge
2d 2h
Merged PRs (30d)
19

Description

What / Why

https://github.com/npm/config/pull/23 will make npm not load the project config if global=true in cli or env.

However, if global=true is set in the userconfig, then the project config is still loaded.

If this is an unsupported case, then it should be documented. If not, then... I guess project config would have to be unloaded, since it can change the location of the userconfig? So, you could have a project config that sets userconfig=/path/to/userconfig/a, and then /path/to/userconfig/a contains global=true, which means we shouldn't load the project config, so now we loaded the wrong userconfig?

Maybe project config shouldn't be able to set the userconfig/globalconfig options?

Failing test showing the issue (but really, this just highlights that it's a weird paradox loop, not that this test should be made to pass, necessarily)

diff --git a/test/index.js b/test/index.js
index 17f0879..7d9ff5c 100644
--- a/test/index.js
+++ b/test/index.js
@@ -122,7 +122,11 @@ prefix = ${path}/global
 user-config-from-builtin = true
 foo = from-custom-userconfig
 globalconfig = ${path}/global/etc/npmrc
-`
+`,
+      '.npmrc-userconfig-sets-global-true': `
+globalconfig = ${path}/global/etc/npmrc
+global = true
+`,
     },
     project: {
       node_modules: {},
@@ -190,6 +194,22 @@ loglevel = yolo
     t.equal(config.sources.get(source), 'project', 'sources has project')
   })
 
+  t.test('dont load project config if global set by user config', async t => {
+    const config = new Config({
+      npmPath: `${path}/npm`,
+      env: {},
+      argv: [process.execPath, __filename, `--userconfig=${path}/user/.npmrc-userconfig-sets-global-true`],
+      cwd: `${path}/project`,
+      shorthands,
+      definitions,
+    })
+
+    await config.load()
+    const source = config.data.get('project').source
+    t.equal(source, '(global mode enabled, ignored)', 'data has placeholder')
+    t.equal(config.sources.get(source), 'project', 'sources has project')
+  })
+
   t.test('dont load project config if location is global', async t => {
     const config = new Config({
       npmPath: `${path}/npm`,

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in test/index.js with the shown Config load test and the userconfig fixture that sets global=true. Trace how Config.load() selects the project and user configuration sources, then run the relevant test to reproduce the paradox. Done requires an agreed behavior for this case, with regression coverage or documentation matching that decision.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, nodejs
Domain
cli, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.