-
Notifications
You must be signed in to change notification settings - Fork 250
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(init): use user configured npm registry (#4937)
Query your configured npm registry for Stryker plugins instead of the default one. If no registry is configured, fall back on the default.
- Loading branch information
Showing
7 changed files
with
146 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { execaCommandSync } from 'execa'; | ||
import { RestClient } from 'typed-rest-client'; | ||
import * as initializerTokens from './initializer-tokens.js'; | ||
import { coreTokens } from '../di/index.js'; | ||
import { errorToString } from '@stryker-mutator/util'; | ||
import { Logger } from '@stryker-mutator/api/logging'; | ||
import { commonTokens } from '@stryker-mutator/api/plugin'; | ||
|
||
const DEFAULT_NPM_REGISTRY = 'https://registry.npmjs.com'; | ||
|
||
function getRegistry(logger: Logger, execaSync: typeof execaCommandSync): string { | ||
if (process.env.npm_config_registry) { | ||
return process.env.npm_config_registry; | ||
} else if (process.env.npm_command) { | ||
// if running inside npm and not having the registry than it's the default one | ||
return DEFAULT_NPM_REGISTRY; | ||
} else { | ||
// Using global as when trying to get the registry inside npm workspace it would fail | ||
try { | ||
const registry = execaSync('npm config get --global registry', { | ||
stdout: 'pipe', | ||
timeout: 20000, | ||
}); | ||
|
||
return registry.stdout.trim(); | ||
} catch (e) { | ||
logger.warn('Could not run `npm config get --global registry` falling back to default npm registry.', errorToString(e)); | ||
|
||
return DEFAULT_NPM_REGISTRY; | ||
} | ||
} | ||
} | ||
|
||
getRegistry.inject = [commonTokens.logger, coreTokens.execaSync] as const; | ||
|
||
function createNpmRegistryClient(npmRegistry: string): RestClient { | ||
return new RestClient('npm', npmRegistry); | ||
} | ||
|
||
createNpmRegistryClient.inject = [initializerTokens.npmRegistry] as const; | ||
|
||
export { createNpmRegistryClient, getRegistry }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { getRegistry } from '../../../src/initializer/npm-registry.js'; | ||
import { expect } from 'chai'; | ||
import { testInjector } from '@stryker-mutator/test-helpers'; | ||
import sinon from 'sinon'; | ||
import { execaCommandSync } from 'execa'; | ||
|
||
const DEFAULT_REGISTRY = 'https://registry.npmjs.com'; | ||
|
||
describe('npm registry', () => { | ||
describe('get registry', () => { | ||
let oldNpmConfigRegistry: string | undefined; | ||
let oldNpmCommand: string | undefined; | ||
|
||
beforeEach(() => { | ||
oldNpmConfigRegistry = process.env.npm_config_registry; | ||
oldNpmCommand = process.env.npm_command; | ||
}); | ||
|
||
afterEach(() => { | ||
process.env.npm_config_registry = oldNpmConfigRegistry; | ||
process.env.npm_command = oldNpmCommand; | ||
}); | ||
|
||
it('should return default repository when run with npm command with no custom repository', () => { | ||
const execaCommandSyncMock = sinon.spy(); | ||
|
||
process.env.npm_config_registry = ''; | ||
process.env.npm_command = 'value'; | ||
|
||
const registry = getRegistry(testInjector.logger, execaCommandSyncMock); | ||
|
||
expect(registry).to.equal(DEFAULT_REGISTRY); | ||
sinon.assert.callCount(execaCommandSyncMock, 0); | ||
}); | ||
|
||
it('should return default repository when run with npm command with custom repository', () => { | ||
const execaCommandSyncMock = sinon.spy(); | ||
process.env.npm_config_registry = 'foo'; | ||
process.env.npm_command = 'value'; | ||
|
||
const registry = getRegistry(testInjector.logger, execaCommandSyncMock); | ||
|
||
expect(registry).to.equal('foo'); | ||
sinon.assert.callCount(execaCommandSyncMock, 0); | ||
}); | ||
|
||
it('should return globally configured npm registry when run with node command', () => { | ||
const expectedRegistry = 'http://my.custom.npm.registry.stryker'; | ||
const execaCommandSyncMock = sinon.spy((_command, _options) => ({ stdout: expectedRegistry })); | ||
process.env.npm_config_registry = ''; | ||
process.env.npm_command = ''; | ||
|
||
const registry = getRegistry(testInjector.logger, execaCommandSyncMock as unknown as typeof execaCommandSync); | ||
|
||
sinon.assert.calledOnceWithExactly(execaCommandSyncMock, 'npm config get --global registry', { | ||
stdout: 'pipe', | ||
timeout: 20000, | ||
}); | ||
|
||
expect(registry).to.equal(expectedRegistry); | ||
}); | ||
|
||
it('should return default repository and warn the user if run with node command and execa command failed', () => { | ||
const execaCommandSyncMock = sinon.spy((_command, _options) => { | ||
throw new Error(); | ||
}); | ||
|
||
process.env.npm_config_registry = ''; | ||
process.env.npm_command = ''; | ||
|
||
const registry = getRegistry(testInjector.logger, execaCommandSyncMock as unknown as typeof execaCommandSync); | ||
|
||
sinon.assert.calledOnceWithExactly(execaCommandSyncMock, 'npm config get --global registry', { | ||
stdout: 'pipe', | ||
timeout: 20000, | ||
}); | ||
|
||
expect(registry).to.equal(DEFAULT_REGISTRY); | ||
sinon.assert.calledOnceWithMatch( | ||
testInjector.logger.warn, | ||
'Could not run `npm config get --global registry` falling back to default npm registry.', | ||
); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters