Skip to content

Commit

Permalink
feat(CLI): Fallback to service local serverless installation by default
Browse files Browse the repository at this point in the history
BREAKING CHANGE:
When globally installed `serverless` CLI is invoked in a context of a service, which has locally installed (in its `node_modules`) `serverless`. The locally installed CLI will be (by default) run instead of a global one.
  • Loading branch information
medikoo committed Sep 10, 2020
1 parent 0597cfb commit dfc7839
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 23 deletions.
6 changes: 6 additions & 0 deletions docs/deprecations.md
Expand Up @@ -6,6 +6,12 @@ layout: Doc

# Serverless Framework Deprecations

<a name="DISABLE_LOCAL_INSTALLATION_FALLBACK_SETTING"><div>&nbsp;</div></a>

## Support for `enableLocalInstallationFallback` setting is to be removed

Starting with v3.0.0, framework will unconditionally run service local installation of `serverless` if its found.

<a name="LOCAL_INSTALLATION_FALLBACK"><div>&nbsp;</div></a>

## Fallback to a service local `serverless` installation
Expand Down
28 changes: 16 additions & 12 deletions lib/Serverless.js
Expand Up @@ -97,25 +97,29 @@ class Serverless {
});
}
eventuallyFallbackToLocal() {
if (
this.pluginManager.serverlessConfigFile &&
this.pluginManager.serverlessConfigFile.enableLocalInstallationFallback != null
) {
this._logDeprecation(
'DISABLE_LOCAL_INSTALLATION_FALLBACK_SETTING',
'Starting with next major version, "enableLocalInstallationFallback" setting will no longer be supported.' +
'CLI will unconditionally fallback to service local installation when its found.\n' +
'Remove this setting to clear this deprecation warning'
);
}
if (this.isLocallyInstalled) return null;
return resolve(process.cwd(), 'serverless').then(
({ realPath }) => {
if (realPath === __filename) {
this.isLocallyInstalled = true;
return null;
}
if (!this.pluginManager.serverlessConfigFile) return null;
if (this.pluginManager.serverlessConfigFile.enableLocalInstallationFallback == null) {
this._logDeprecation(
'LOCAL_INSTALLATION_FALLBACK',
'Local installation of Serverless detected. Starting with next major version, CLI ' +
'will run it instead of globally installed version.\n' +
'Set "enableLocalInstallationFallback" to "true" to switch to new behavior now, ' +
'set to "false" to keep current behavior and hide this message'
);
return null;
}
if (!this.pluginManager.serverlessConfigFile.enableLocalInstallationFallback) {
if (
this.pluginManager.serverlessConfigFile &&
this.pluginManager.serverlessConfigFile.enableLocalInstallationFallback != null &&
!this.pluginManager.serverlessConfigFile.enableLocalInstallationFallback
) {
return null;
}
this.cli.log('Running "serverless" installed locally (in service node_modules)');
Expand Down
29 changes: 19 additions & 10 deletions lib/Serverless.test.js
Expand Up @@ -288,41 +288,50 @@ describe('Serverless', () => {
describe('Serverless [new tests]', () => {
describe('When local version available', () => {
describe('When running global version', () => {
it('Should report deprecation notice when "enableLocalInstallationFallback" not set', () =>
it('Should fallback to local version when it is found and "enableLocalInstallationFallback" is not set', () =>
runServerless({ fixture: 'locallyInstalledServerless', cliArgs: ['-v'] }).then(
({ serverless }) => {
expect(Array.from(serverless.triggeredDeprecations)).to.deep.equal([
'LOCAL_INSTALLATION_FALLBACK',
]);
expect(serverless.isInvokedByGlobalInstallation).to.be.false;
expect(serverless.isLocallyInstalled).to.be.false;
expect(serverless.isLocalStub).to.not.exist;
expect(Array.from(serverless.triggeredDeprecations)).to.deep.equal([]);
expect(serverless.isInvokedByGlobalInstallation).to.be.true;
expect(serverless.isLocallyInstalled).to.be.true;
expect(serverless.isLocalStub).to.be.true;
}
));
it('Should run without notice when "enableLocalInstallationFallback" set to false', () =>

let serverlessWithDisabledLocalInstallationFallback;
it('Should report deprecation notice when "enableLocalInstallationFallback" is set', () =>
runServerless({
fixture: 'locallyInstalledServerless',
configExt: { enableLocalInstallationFallback: false },
cliArgs: ['-v'],
}).then(({ serverless }) => {
expect(Array.from(serverless.triggeredDeprecations)).to.deep.equal([]);
serverlessWithDisabledLocalInstallationFallback = serverless;
expect(Array.from(serverless.triggeredDeprecations)).to.deep.equal([
'DISABLE_LOCAL_INSTALLATION_FALLBACK_SETTING',
]);
expect(serverless.isInvokedByGlobalInstallation).to.be.false;
expect(serverless.isLocallyInstalled).to.be.false;
expect(serverless.isLocalStub).to.not.exist;
}));

it('Should not fallback to local when "enableLocalInstallationFallback" set to false', () =>
expect(serverlessWithDisabledLocalInstallationFallback.invokedInstance).to.not.exist);

it('Should fallback to local version when "enableLocalInstallationFallback" set to true', () =>
runServerless({
fixture: 'locallyInstalledServerless',
configExt: { enableLocalInstallationFallback: true },
cliArgs: ['-v'],
}).then(({ serverless }) => {
expect(Array.from(serverless.triggeredDeprecations)).to.deep.equal([]);
expect(Array.from(serverless.triggeredDeprecations)).to.deep.equal([
'DISABLE_LOCAL_INSTALLATION_FALLBACK_SETTING',
]);
expect(serverless.isInvokedByGlobalInstallation).to.be.true;
expect(serverless.isLocallyInstalled).to.be.true;
expect(serverless.isLocalStub).to.be.true;
}));
});

describe('When running local version', () => {
it('Should run without notice', () =>
fixtures.setup('locallyInstalledServerless').then(({ servicePath }) =>
Expand Down
1 change: 0 additions & 1 deletion lib/utils/analytics/generatePayload.test.js
Expand Up @@ -97,7 +97,6 @@ describe('lib/utils/analytics/generatePayload', () => {
it('Should recognize local fallback', () =>
runServerless({
fixture: 'locallyInstalledServerless',
configExt: { enableLocalInstallationFallback: true },
cliArgs: ['config'],
}).then(({ serverless }) => {
const payload = generatePayload(serverless);
Expand Down

0 comments on commit dfc7839

Please sign in to comment.