Add logDeprecation and tests#7741
Conversation
medikoo
left a comment
There was a problem hiding this comment.
Thank you @AhmedFat7y looks promising! See my suggestions
|
|
||
| function logDeprecation(code, message, docURL, serviceConfig) { | ||
| const disabledCodes = prepareCodes( | ||
| serviceConfig && serviceConfig.disabledCodes, |
There was a problem hiding this comment.
I would create one dedicated function to resolve deprecated codes from serviceConfig. I wouldn't mix it with resolution from process.env as it's different, and settings from process.env can be resolved upfront in module body
There was a problem hiding this comment.
The idea was to keep the codes preparation separate and explicit so you know what was prepared for this call explicitly. The env codes and serviceCodes (if they exist) were extracted in single call to make it easier to trace what was extracted
I assume serviceConfig.disabledCodes will always return either an empty Set or a Set with codes to disable. So I can use it without taking too much care about it being sent or not.
I separated them, but why do you want to keep the serviceConfig codes resolution and checking that separate?
There was a problem hiding this comment.
The env codes and serviceCodes (if they exist) were extracted in single call to make it easier to trace what was extracted
I understand the intention, still both values are provided at different points in time, and format of both differs. So resolving both with one function, doesn't seem clean to me.
I believe that process.env can be resolved upfront in module body, so we have upfront (for function processing) ready set of codes deprecated by env settings. I think it'll make further processing of that cleaner.
process.env format is in all cases a string, which eventually may contain multiple coma separated values. While in case of serviceConfig, it can be either string (singular value) or array. So resolution of both should in any case be done with different logic (different function)
There was a problem hiding this comment.
While in case of serviceConfig, it can be either string (singular value) or array
So it will be provided like this?
provider: aws
disabledCodes:
- code1
- code2I thought it will be comma separated values like the env var
provider: aws
disabledCodes: code1,code2,code3Or it will be processed by service initialisation? Because I assumed it should match how it's provided to the Env var
There was a problem hiding this comment.
In #7422 I've proposed to name it disabledDeprecations, and concerning format we should respect convention in how single and multiple valuas are configured in YAML (which translates to JSON).
Still I think it's fine to support just one format (an array), at least singular string will look confusing by disabledDeprecations which suggests plural.
So let's support just:
disabledDeprecations:
- CODE1
- CODE2There was a problem hiding this comment.
And for disabledDeprecations let's make a one test that is configured viarunServerless (only that way we should test input coming via serviceConfig)
There was a problem hiding this comment.
In #7422 I've proposed to name it disabledDeprecations, and concerning format we should respect convention in how single and multiple valuas are configured in YAML (which translates to JSON).
Sorry for that, I was trying to get sth submitted to discuss before finalizing the implementation
Still I think it's fine to support just one format (an array), at least singular string will look confusing by disabledDeprecations which suggests plural.
You always get the request to support '*' as a single value instead of a single array item. It doesn't matter here?
There was a problem hiding this comment.
You always get the request to support '*' as a single value instead of a single array item. It doesn't matter here?
Good point! I forgot about that. In that case let's support also single value notation where a string is assigned to disabledDeprecations directly.
Also I wonder, maybe more correct name would be disabledDeprecationNotifications (at least disabledDeprecations suggest we disable deprecations which is not perfectly correct). What do you think?
There was a problem hiding this comment.
I added the support for single value either way until you reply
5b3312a to
23a50a5
Compare
Codecov Report
@@ Coverage Diff @@
## master #7741 +/- ##
=========================================
Coverage ? 88.02%
=========================================
Files ? 245
Lines ? 9234
Branches ? 0
=========================================
Hits ? 8128
Misses ? 1106
Partials ? 0
Continue to review full report at Codecov.
|
|
@medikoo I added support for
|
No, any validation will be in hands of schema based config validation (handled in #6562). Here I imagine setup as: const schemaDeprecations = new Set([
typeof serviceConfig.disabledDeprecations === 'string'
? serviceConfig.disabledDeprecations
: ...(serviceConfig.disabledDeprecations || [])
]); |
So it's better to handle that support in the |
d5dcb3b to
330c1d1
Compare
medikoo
left a comment
There was a problem hiding this comment.
@AhmedFat7y looks great! I'm pretty excited to have that in soon, as it'll open a new great way towards new major releases.
Please see my final and rather minor remarks.
| frameworkVersion: '>=1.0.0 <2.0.0' | ||
|
|
||
| disabledDeprecations: # Disable deprecation logs by their codes. Default is empty. | ||
| - code1 # Deprecation code to disable |
There was a problem hiding this comment.
Let's use DEP_CODE_1 instead of code1, it'll be more similar to deprecation code format
| if (typeof serviceConfig.disabledDeprecations === 'string') { | ||
| disabledDeprecations = [serviceConfig.disabledDeprecations]; | ||
| } else { | ||
| disabledDeprecations = serviceConfig.disabledDeprecations || []; |
There was a problem hiding this comment.
To be on safer side, let's do Array.from(serviceConfig.disabledDeprecations || [])
Otherwise if e.g. a plain object is assigned to disabledDeprecations, it'll crash when it's passed to new Set, and we don't want crashes here
There was a problem hiding this comment.
I was planning to ask about that in a comment, but I think I didn't press the comment button.
Should we display a warning in case an object is passed for some reason? Or we ignore it for now until the schema validation is done?
There was a problem hiding this comment.
Should we display a warning in case an object is passed for some reason? Or we ignore it for now until the schema validation is done?
Ignore it. It's also per JS convention to accept objects as empty arrays when array was expected.
| return new Set(codesStr.split(',')); | ||
| } | ||
|
|
||
| const resolveDeprecatedByService = memoizee((serviceConfig = {}) => { |
There was a problem hiding this comment.
In this case serviceConfig should be treated as required argument (not default).
Note that configured as above, memoization will ignore serviceConfig argument, and will memoize function as if takes no arguments (only first invocation will be a cache miss, all others no matter what service config is passed will result with cache hit).
There was a problem hiding this comment.
When I try this simple demo
const memoize = require('memoizee');
const func = memoize(function (obj) { return Object.keys(obj); });
console.log(func({e: 1}))
console.log(func({y: 1}))This will print [ 'e' ] & [ 'y' ] respectively
There was a problem hiding this comment.
But this demo doesn't reflect what you've configured. Try below instead :)
const memoize = require('memoizee');
const func = memoize(function (obj = {}) { return Object.keys(obj); });
console.log(func({e: 1}))
console.log(func({y: 1}))| @@ -0,0 +1,51 @@ | |||
| 'use strict'; | |||
| const chalk = require('chalk'); | |||
| const memoizee = require('memoizee'); | |||
There was a problem hiding this comment.
It'll be cleaner to use memoizee/weak, then memoization will no lock service objects in a memory
| `More Info: https://www.serverless.com/framework/docs/deprecations/#${code}` | ||
| )}}`, | ||
| ].join('\n') | ||
| ); |
There was a problem hiding this comment.
Let's also add new line at the end (in case of process.stdout.write they're not added as it's with console.log
| const serviceDisabledCodes = resolveDeprecatedByService(serviceConfig); | ||
| if (serviceDisabledCodes.has(code) || serviceDisabledCodes.has('*')) { | ||
| return; | ||
| } |
There was a problem hiding this comment.
Let's wrap it into if (serviceConfig) conditional
7227afc to
601fa5c
Compare
|
Codecov ReportAll modified and coverable lines are covered by tests ✅
❗ Your organization needs to install the Codecov GitHub app to enable full functionality. Additional details and impacted files@@ Coverage Diff @@
## master #7741 +/- ##
==========================================
+ Coverage 88.00% 88.03% +0.03%
==========================================
Files 245 246 +1
Lines 9254 9279 +25
==========================================
+ Hits 8144 8169 +25
Misses 1110 1110 ☔ View full report in Codecov by Sentry. |
Resolve env codes in module body Re-require inside test body for env override Use stdout.write Change format to match provided in comments
Use Array.from to avoid errors in case the codes were an object Write new line as stdout.write doesn't print one by default Wrap serviceConfig resolution in if condition
Add new test to check silent failure in case of codes are an object
601fa5c to
22af615
Compare
|
@AhmedFat7y Thank you, looks really good! Before I merge it, I want to be sure we have website page towards deprecations configured. I'll get back to it shortly once that's setup |
medikoo
left a comment
There was a problem hiding this comment.
Thank you @AhmedFat7y !
I've added some minor tweaks, and fixed documentation page so it builds properly with our Gatsby setup.
I'll follow with simple PR that configures first depracation, it'll give an example on how deprecations should be configured
Closes: #7422
I'm not sure if this is what you're expecting, but wanted to push this so we can discuss the code better than just a theory