@@ -122,54 +122,41 @@ class Gyp extends EventEmitter {
122122 }
123123
124124 // support for inheriting config env variables from npm
125+ // npm will set environment variables in the following forms:
126+ // - `npm_config_<key>` for values from npm's own config. Setting arbitrary
127+ // options on npm's config was deprecated in npm v11 but node-gyp still
128+ // supports it for backwards compatibility.
129+ // See https://github.com/nodejs/node-gyp/issues/3156
130+ // - `npm_package_config_node_gyp_<key>` for values from the `config` object
131+ // in package.json. This is the preferred way to set options for node-gyp
132+ // since npm v11. The `node_gyp_` prefix is used to avoid conflicts with
133+ // other tools.
134+ // The `npm_package_config_node_gyp_` prefix will take precedence over
135+ // `npm_config_` keys.
125136 const npmConfigPrefix = 'npm_config_'
126- Object . keys ( process . env ) . forEach ( ( name ) => {
127- if ( name . indexOf ( npmConfigPrefix ) !== 0 ) {
128- return
129- }
130- const val = process . env [ name ]
131- if ( name === npmConfigPrefix + 'loglevel' ) {
132- log . logger . level = val
133- } else {
134- // add the user-defined options to the config
135- name = name . substring ( npmConfigPrefix . length )
136- // gyp@741b7f1 enters an infinite loop when it encounters
137- // zero-length options so ensure those don't get through.
138- if ( name ) {
139- // convert names like force_process_config to force-process-config
140- if ( name . includes ( '_' ) ) {
141- name = name . replace ( / _ / g, '-' )
142- }
143- this . opts [ name ] = val
144- }
145- }
146- } )
147-
148- // Read values that npm sets based on the `config` object in package.json.
149- // These take precendence over the npm_config_ prefixed values which
150- // are deprecated in npm@11.
151- // These can also be set directly in the environment, if setting in
152- // package.json is not desired.
153137 const npmPackageConfigPrefix = 'npm_package_config_node_gyp_'
154- Object . keys ( process . env ) . forEach ( ( name ) => {
155- if ( name . indexOf ( npmPackageConfigPrefix ) !== 0 ) {
156- return
157- }
158- const val = process . env [ name ]
159- name = name . substring ( npmPackageConfigPrefix . length )
138+
139+ const configEnvKeys = Object . keys ( process . env )
140+ . filter ( ( k ) => k . startsWith ( npmConfigPrefix ) || k . startsWith ( npmPackageConfigPrefix ) )
141+ // sort so that npm_package_config_node_gyp_ keys come last and will override
142+ . sort ( ( a ) => a . startsWith ( npmConfigPrefix ) ? - 1 : 1 )
143+
144+ for ( const key of configEnvKeys ) {
145+ // add the user-defined options to the config
146+ const name = key . startsWith ( npmConfigPrefix )
147+ ? key . substring ( npmConfigPrefix . length )
148+ : key . substring ( npmPackageConfigPrefix . length )
160149 // gyp@741b7f1 enters an infinite loop when it encounters
161150 // zero-length options so ensure those don't get through.
162151 if ( name ) {
163152 // convert names like force_process_config to force-process-config
164- if ( name . includes ( '_' ) ) {
165- name = name . replace ( / _ / g, '-' )
166- }
167- this . opts [ name ] = val
153+ this . opts [ name . replaceAll ( '_' , '-' ) ] = process . env [ key ]
168154 }
169- } )
155+ }
170156
171157 if ( this . opts . loglevel ) {
172158 log . logger . level = this . opts . loglevel
159+ delete this . opts . loglevel
173160 }
174161 log . resume ( )
175162 }
0 commit comments