devcontainers / devcontainers/spec
Proposal: More Consistent Configurations for Features, Options, and Customizations
- Dominant language
- No language data
- Stars
- 5.7k
- Forks
- 496
- PR merge metrics
- No merged PRs in 30d
Description
# More Consistent Configurations for Features, Options, and Customizations
The overall goal of this proposal is to allow more robust constraints and configurations for options and configurations and to make the supported configurations more consistant between `Features`, `options`, and `customizations`. This set of new properties is intended to be fully backwards compatable. Only new properties are listed for ease of review.
It originated based on the way we use (and would like to be able to use) dev containers at [Salesforce](https://www.salesforce.com/).
Happy to put up the full PR for these spec changes, but filing an issue first, as per [How to Contribute](https://github.com/devcontainers/spec/blob/main/contributing.md).
## Feature
Feature customizations is currently a completely open-ended structure. This is nice for flexibility but can make `customizations` very hard to consume as the way it is used may vary wildly from Feature to Feature. By associating the path to a customization with configurations for that customization, Features can better constrain and define their customizations.
When trying to use Dev Container Features, there was a strong tendancy for engineers to want to use `options` for everything, even if it wasn't used in initial set up of the Feature because of the convenience of the configurations that exist for `options` but not for `customizations`. This bridges that gap and allows both to be constrained and customized in the same way while maintaining backwards compatability. It's fully optional, so Features that don't want to apply configurations to their customizations do not need to.
| Property | Type | Description |
| ----------------------------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `customizationConfigurations` | Record | A map of customizations to its configuration. The JSON path should refer to the customization to be configured. This allows similar configurations on customizations as on options to allow clearer constraints and typing for customizations. |
### CustomizationConfigurations
The proposed configurations that can be mapped to any customization based on the customization's path. These configurations should match all the same configurations available for `options` (note: a number of new properies have been proposed for `options` which are described in detail in that section.)
| Property | Type | Description |
| ------------------ | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `name` | string | A 'human-friendly' display name for the customization. |
| `type` | string | Type of the customization. Can be any valid JSON data: "string" or "number" or "boolean" or "array" or "object" type. |
| `proposals` | array | A list of suggested string values for the customization. Free-form values are allowed. Omit when using enum. |
| `enums` | array | A strict list of allowed string values for the customization. Free-form values are not allowed. Omit when using proposals. |
| `default` | string or boolean | Default value for the customization. |
| `description` | string | Description for the customization. |
| `keywords` | array | List of strings relevant to a user that would search for this customization. |
| `documentationURL` | string | Link to relevant documentation for the customization. |
| `maxValues` | number | The maximum number of values a user can select for this customization. |
| `validationRegex` | string | Regular expression pattern to validate a provided customization value against. It is a schema violation if any values in proposals or enum do not pass the supplied validationRegex. |
| `valueMap` | Record | A map of values to their detailed descriptions and documentation for the customization. These values must be included in either enum or proposals. Not every value needs to be included, only the ones that have associated details. |
## FeatureOptions
There were a number of general human-friendly configurations that exist for `Features` but not for `options` such as `name`, `keywords`, and `documentationURL` that should be added for better consistency and experience.
There are also a few new propeties proposed here: `maxValues`, `delimiter`, and `validationRegex`. Given that options are limited to only `string` or `boolean`, there have been a number of Features we've seen internally that end up trying to use `string` options as a space-separated array. Instead of adding `array` which would make the spec no longer backwards compatible, these three properities can be used to constrain complex string options with known delimiters, a limit on how many values can be provided, and regex validation for values that are acceptable for that option.
Finally, `valueMap` allows human-friendly data to be associated with specific values in `enum` or `proposals`. This is useful for human-readable value names, or providing keywords, descriptions, or documentation for each value to better allow users to determine which value they want to supply to the option. Not ever value needs to be included in the `valueMap`, for example: if one of the values in the enum is in "beta" or on the path to becoming deprecated, a Feature might want to specify that description for just one value if the list of values is otherwise self-explanatory.
| Property | Type | Description |
| --------------------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `optionId.name` | string | A 'human-friendly' display name for the option. |
| `optionId.keywords` | array | List of strings relevant to a user that would search for this option. |
| `optionId.documentationURL` | string | Link to relevant documentation for the option. |
| `optionId.maxValues` | number | The maximum number of values a user can select for this option. |
| `optionId.delimiter` | string | If multiple values can be selected for this option, this is the delimiter that should be used to separate them when they are stored as a single string in the environment variable. |
| `optionId.validationRegex` | string | Regular expression pattern to validate a provided option value against. It is a schema violation if any values in proposals or enum do not pass the supplied validationRegex. |
| `optionId.valueMap` | Record | A map of values to their associated 'human-friendly' details. These values must be included in either enum or proposals. Not every value needs to be included, only the ones that have associated details. |
### ValueDetails
Used for both `Options` and `Customizations`, this provides standard human-friendly data to values (used in `enums` or `proposals`).
| Property | Type | Description |
| ------------------ | ------ | -------------------------------------------------------------------- |
| `name` | string | A 'human-friendly' display name for the option. |
| `description` | string | Detailed description of the value. |
| `documentationURL` | string | URL to additional documentation or resources about this value. |
| `keywords` | array | List of strings relevant to a user that would search for this value. |
Contributor guide
Assessment
This issue has not been assessed yet.