Skip to content

Commit

Permalink
feat(Plugins): Announce "type" requirement in CLI option definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
medikoo committed Apr 2, 2021
1 parent c9be9bc commit 959da67
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 3 deletions.
14 changes: 14 additions & 0 deletions docs/deprecations.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,20 @@ disabledDeprecations:
- '*' # To disable all deprecation messages
```

<a name="CLI_OPTIONS_SCHEMA'"><div>&nbsp;</div></a>

## CLI Options extensions, `type` requirement

Deprecation code: `CLI_OPTIONS_SCHEMA'`

Internal handling of CLI arguments was improved with type awareness for options. Now each option definition is expected have `type` defined in its settings.

Possible values are `string`, `boolean` and `multiple`. Check [Defining options](/framework/docs/providers/aws/guide/plugins#defining-options) documentation for more info.

If you rely on a plugin which does not set types (yet) please report the issue at its issue tracker.

Starting with v3.0.0 any option extensions which does not have `type` defined will be communicated with a thrown error

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

## New way to define packaging patterns
Expand Down
4 changes: 4 additions & 0 deletions docs/providers/aws/guide/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,8 @@ The `options` object will be passed in as the second parameter to the constructo

In it, you can optionally add a `shortcut` property, as well as a `required` property. The Framework will return an error if a `required` Option is not included. You can also set a `default` property if your option is not required.

Additionally `type` for each option should be set. Supported types are `string`, `boolean` and `multiple` (multiple strings).

**Note:** At this time, the Serverless Framework does not use parameters.

```javascript
Expand All @@ -291,6 +293,7 @@ class MyPlugin {
usage: 'Specify the function you want to handle (e.g. "--function myFunction")',
shortcut: 'f',
required: true,
type: 'string', // Possible options: "string", "boolean", "multiple"
},
},
},
Expand Down Expand Up @@ -335,6 +338,7 @@ class ProviderX {
function: {
usage: 'Specify the function you want to handle (e.g. "--function myFunction")',
required: true,
type: 'string', // Possible options: "string", "boolean", "multiple"
},
},
},
Expand Down
30 changes: 28 additions & 2 deletions lib/cli/commands-schema/resolve-final.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ const serviceCommands = require('./service');
const awsServiceCommands = require('./aws-service');
const serviceOptions = require('./common-options/service');
const awsServiceOptions = require('./common-options/aws-service');
const logDeprecation = require('../../utils/logDeprecation');

const deprecatedEventPattern = /^deprecated#(.*?)(?:->(.*?))?$/;

module.exports = (loadedPlugins, { providerName }) => {
module.exports = (loadedPlugins, { providerName, configuration }) => {
const commands = new Map(providerName === 'aws' ? awsServiceCommands : serviceCommands);

if (providerName !== 'aws') {
Expand Down Expand Up @@ -63,6 +64,7 @@ module.exports = (loadedPlugins, { providerName }) => {
}
}

const missingOptionTypes = new Map();
const resolveCommands = (loadedPlugin, config, commandPrefix = '') => {
if (!config.commands) return;
for (const [commandName, commandConfig] of Object.entries(config.commands)) {
Expand All @@ -83,7 +85,15 @@ module.exports = (loadedPlugins, { providerName }) => {
if (commandConfig.lifecycleEvents) schema.lifecycleEvents = commandConfig.lifecycleEvents;
if (commandConfig.options) {
for (const [optionName, optionConfig] of Object.entries(commandConfig.options)) {
if (!schema.options[optionName]) schema.options[optionName] = optionConfig;
if (!schema.options[optionName]) {
schema.options[optionName] = optionConfig;
if (!optionConfig.type) {
if (!missingOptionTypes.has(loadedPlugin)) {
missingOptionTypes.set(loadedPlugin, new Set());
}
missingOptionTypes.get(loadedPlugin).add(optionName);
}
}
}
}

Expand All @@ -101,5 +111,21 @@ module.exports = (loadedPlugins, { providerName }) => {

for (const loadedPlugin of loadedPlugins) resolveCommands(loadedPlugin, loadedPlugin);

if (missingOptionTypes.size) {
logDeprecation(
'CLI_OPTIONS_SCHEMA',
'CLI options definitions were upgraded with "type" property (which could be one of "string", "boolean", "multiple"). ' +
'Below listed plugins do not predefine type for introduced options:\n' +
` - ${Array.from(
missingOptionTypes,
([plugin, optionNames]) =>
`${plugin.constructor.name} for "${Array.from(optionNames).join('", "')}"`
).join('\n - ')}\n` +
'Please report this issue in plugin issue tracker.\n' +
'Starting with next major release, this will be communicated with a thrown error.',
{ serviceConfig: configuration }
);
}

return commands;
};
2 changes: 1 addition & 1 deletion scripts/serverless.js
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ const processSpanPromise = (async () => {
// might have defined extra commands and options
const commandsSchema = require('../lib/cli/commands-schema/resolve-final')(
serverless.pluginManager.externalPlugins,
{ providerName: providerName || 'aws' }
{ providerName: providerName || 'aws', configuration }
);
resolveInput.clear();
({ command, commands, options, isHelpRequest, commandSchema } = resolveInput(
Expand Down

0 comments on commit 959da67

Please sign in to comment.