Skip to content

Commit

Permalink
feat(CLI): Deprecations logger (#7741)
Browse files Browse the repository at this point in the history
Co-authored-by: Ahmed Abdelwahab <ahmed.abdelwahab@prophecylabs.com>
Co-authored-by: Mariusz Nowak <medyk@medikoo.com>
  • Loading branch information
3 people committed May 21, 2020
1 parent aa48f0a commit 6f32f23
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 0 deletions.
7 changes: 7 additions & 0 deletions docs/deprecations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<!--
title: Serverless Framework Deprecations
menuText: Deprecations
layout: Doc
-->

# Serverless Framework Deprecations
4 changes: 4 additions & 0 deletions docs/providers/aws/guide/serverless.yml.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ service:

frameworkVersion: '>=1.0.0 <2.0.0'

disabledDeprecations: # Disable deprecation logs by their codes. Default is empty.
- DEP_CODE_1 # Deprecation code to disable
- '*' # Disable all deprecation messages

provider:
name: aws
runtime: nodejs12.x
Expand Down
2 changes: 2 additions & 0 deletions lib/classes/Service.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Service {
this.functions = {};
this.resources = {};
this.package = {};
this.disabledDeprecations = [];

if (data) this.update(data);
}
Expand Down Expand Up @@ -110,6 +111,7 @@ class Service {
that.plugins = serverlessFile.plugins;
that.resources = serverlessFile.resources;
that.functions = serverlessFile.functions || {};
that.disabledDeprecations = serverlessFile.disabledDeprecations;

// merge so that the default settings are still in place and
// won't be overwritten
Expand Down
48 changes: 48 additions & 0 deletions lib/utils/logDeprecation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use strict';

const chalk = require('chalk');
const weakMemoizee = require('memoizee/weak');

const disabledCodesByEnv = extractCodes(process.env.SLS_DEPRECATION_DISABLE);

const loggedDeprecations = new Set();

function extractCodes(codesStr) {
if (!codesStr) {
return new Set();
}
return new Set(codesStr.split(','));
}

const resolveDeprecatedByService = weakMemoizee(serviceConfig => {
let disabledDeprecations = [];
if (typeof serviceConfig.disabledDeprecations === 'string') {
disabledDeprecations = [serviceConfig.disabledDeprecations];
} else {
disabledDeprecations = Array.from(serviceConfig.disabledDeprecations || []);
}
return new Set(disabledDeprecations);
});

function writeDeprecation(code, message) {
process.stdout.write(
`Serverless: ${chalk.redBright(`Deprecation Notice: ${message}`)}\n ${chalk.dim(
`More Info: https://www.serverless.com/framework/docs/deprecations/#${code}`
)}\n`
);
}

module.exports = (code, message, { serviceConfig } = {}) => {
if (loggedDeprecations.has(code) || disabledCodesByEnv.has(code) || disabledCodesByEnv.has('*')) {
return;
}
if (serviceConfig) {
const serviceDisabledCodes = resolveDeprecatedByService(serviceConfig);
if (serviceDisabledCodes.has(code) || serviceDisabledCodes.has('*')) {
return;
}
}

loggedDeprecations.add(code);
writeDeprecation(code, message);
};
100 changes: 100 additions & 0 deletions lib/utils/logDeprecation.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
'use strict';
const sandbox = require('sinon');
const expect = require('chai').expect;
const mockRequire = require('mock-require');
const overrideEnv = require('process-utils/override-env');
const runServerless = require('../../tests/utils/run-serverless');
const fixtures = require('../../tests/fixtures');

describe('#logDeprecation()', () => {
let stdoutWriteSpy;
let restoreEnv;
let originalEnv;
let logDeprecation;

beforeEach(() => {
logDeprecation = mockRequire.reRequire('./logDeprecation');
stdoutWriteSpy = sandbox.spy(process.stdout, 'write');
({ originalEnv, restoreEnv } = overrideEnv());
});

afterEach(() => {
sandbox.restore();
restoreEnv();
});

it('Should log deprecation message if not disabled and first time', () => {
logDeprecation('code1', 'Start using depreication log');
const message = stdoutWriteSpy.args.join('\n');
expect(stdoutWriteSpy.called).to.equal(true);
expect(message).to.have.string('Deprecation Notice');
expect(message).to.have.string('https://www.serverless.com/framework/docs/deprecations/#code1');
});

it('Should not log deprecation if disabled in env.SLS_DEPRECATION_DISABLE', () => {
process.env.SLS_DEPRECATION_DISABLE = 'code1';
logDeprecation = mockRequire.reRequire('./logDeprecation');
logDeprecation('code1', 'Start using depreication log');
expect(stdoutWriteSpy.called).to.equal(false);
});

it('Should not log deprecation if disabled in serviceConfig', () => {
// We need original process env variables for npm-conf
Object.assign(process.env, originalEnv);
return fixtures
.extend('function', { disabledDeprecations: ['code1'] })
.then(fixturePath => runServerless({ cwd: fixturePath, cliArgs: ['package'] }))
.then(serverless => {
stdoutWriteSpy.clear;
const serviceConfig = serverless.service;
stdoutWriteSpy.resetHistory();
logDeprecation('code1', 'Start using depreication log', { serviceConfig });
expect(stdoutWriteSpy.called).to.equal(false);
});
});

it('Should not log deprecation if disabled by wildcard in env', () => {
process.env.SLS_DEPRECATION_DISABLE = '*';
logDeprecation = mockRequire.reRequire('./logDeprecation');
logDeprecation('code1', 'Start using depreication log');
expect(stdoutWriteSpy.called).to.equal(false);
});

it('Should not log deprecation if disabled by wildcard in service config', () => {
Object.assign(process.env, originalEnv);
return fixtures
.extend('function', { disabledDeprecations: '*' })
.then(fixturePath => runServerless({ cwd: fixturePath, cliArgs: ['package'] }))
.then(serverless => {
stdoutWriteSpy.clear;
const serviceConfig = serverless.service;
stdoutWriteSpy.resetHistory();
logDeprecation('code1', 'Start using depreication log', { serviceConfig });
expect(stdoutWriteSpy.called).to.equal(false);
});
});

it('Should not log deprecation twice', () => {
logDeprecation('code1', 'Start using depreication log');
logDeprecation('code1', 'Start using depreication log');
expect(stdoutWriteSpy.callCount).to.equal(1);
});

it('Should ignore serviceConfig.disabledDeprecations if it is an object without an error', () => {
Object.assign(process.env, originalEnv);
return fixtures
.extend('function', {
disabledDeprecations: {
code1: true,
},
})
.then(fixturePath => runServerless({ cwd: fixturePath, cliArgs: ['package'] }))
.then(serverless => {
stdoutWriteSpy.clear;
const serviceConfig = serverless.service;
stdoutWriteSpy.resetHistory();
logDeprecation('code1', 'Start using depreication log', { serviceConfig });
expect(stdoutWriteSpy.called).to.equal(true);
});
});
});

0 comments on commit 6f32f23

Please sign in to comment.