Commit 4997aae7 authored by Sarah White's avatar Sarah White Committed by Sarah White

improve playbook architecture guidebook

- move software, data, and functional details to correct sections
- remove example code
- add json format
- edit content for clarity
- add input and output items
- move future ideas to comment section
- move file into devdocs dir
parent 938b928a
= Playbook Component Guidebook
== Context
The documentation pipeline needs to be able to accept user input in the form of configuration options.
This configuration, which we call a [.term]_playbook_, tells the documentation pipeline what input to use, how the input should be processed, how the site should be generated, and where to publish the output.
== Functional Overview
The playbook needs to be loaded as the first step in the pipeline.
Numerous components in the documentation pipeline need to access configuration options that are provided by the playbook.
Therefore, the object that holds the data in the playbook needs to be transmittable.
The main configuration will be read from a file, which we call a [.term]_playbook spec_.
The user should be able to apply [.term]_audibles_, which are substitute options passed at usage time.
Audibles may be passed using either process arguments (i.e., command-line flags and switches), environment variables, or a combination of both.
(Future idea: Plugins should be able to participate in the process of building the playbook, either to modify the schema or modify the configuration data.)
== Software Architecture
The playbook functionality is provided by the playbook component.
The playbook component is composed of several object prototypes, including a playbook builder and the playbook data model.
All the details of loading the configuration, including the schema, the validation, the precedence of input methods, and the conversion to a transmittable model should be encapsulated in this component.
The playbook builder is the main coordinator, though it may delegate work to subordinate objects.
The playbook builder should accept two parameters, an array of arguments (populated from or simulating process arguments) and a hash of variables (populated from or simulating environment variables).
By accepting these two parameters, the playbook builder can be used and tested independently of the CLI runtime environment.
Within those parameters, a playbook spec file may be specified, which is a third (and the bulk) method of user input.
The playbook spec file may be composed in either YAML or CSON format.
(Future idea: The playbook builder should fire one event after the configuration schema is loaded and one event after the configuration data is populated.
This means that the playbook component has an implicit dependency on an event bus infrastructure.)
The playbook builder should return a well-defined, read-only data model called a playbook.
This model should not be coupled to any configuration-related technology used within the component.
Instead, it should be a pure model that can be easily reproduced by another means, such as an alternate implementation of the playbook component.
== Code
The playbook component is implemented as a dedicated node package (i.e., module).
It's APIs should be exported so that they can be required using the `require` keyword in the documentation pipeline.
Here's a rough sketch of how this component will be used in the pipeline:
[source,js]
----
const PlaybookBuilder = require('./packages/playbook/builder')
const playbook = PlaybookBuilder.load(process.argv, process.env)
----
The playbook builder should use https://github.com/mozilla/node-convict[convict] to process the user input.
If the `playbook` option is specified, it should be interpretted as a relative path to a playbook spec file (i.e., configuration file).
The playbook spec can be composed in either the YAML or CSON data format.
The format of the playbook spec file is determined by the file's extension.
If the path does not have a file extension, the builder should attempt to locate a file with the `.yml` extension or `.cson` extension, in that order.
If the playbook spec file is found, the configuration should be loaded again, this time loading the playbook spec file first followed by the audibles (environment variables then process arguments).
(Future idea: This component should use the global event emitter to fire events into the event bus.)
== Data
The playbook object produced by this component should have a well-defined data model.
Each section of configuration (site, content, ui) should be represented by a dedicated model type whose properties (name, location, and type) can be easily converted into API documentation (for example, using a tool like https://github.com/documentationjs/documentation[documentationjs]).
== Consequences
By introducing a dedicated playbook component that produces a pure data model, the configuration step is decoupled from the runtime environment (e.g., CLI environment).
This design will have an immediate impact on development by making the component easier to test in isolation.
This component also reserves room in the future for the documentation pipeline to accept configuration from other types of input, such as a database or web service.
(Future idea: By raising events at strategic points, the playbook component allows plugins to introduce flags and switches to the main application interface.)
= Playbook Component Architecture
== Context
The documentation pipeline needs to be able to accept user input in the form of configuration options.
This configuration, which we call a [.term]_playbook_, tells the documentation pipeline what input to use, how the input should be processed, how the site should be generated, and where to publish the output.
== Functional Overview
The playbook needs to be loaded as the first step in the Antora pipeline.
The playbook component is responsible for accessing, validating, and processing a user provided playbook.
Numerous components in the Antora pipeline will need to access the configuration options provided by the playbook.
Therefore, the object that holds the data in the playbook needs to be transmittable.
The playbook component requires a configuration file, which we call a [.term]_playbook spec_, as input.
A playbook spec can be created and used by anyone operating an Antora pipeline.
Using a playbook spec as an input, the component should carry out the following operations:
* Read the playbook spec file
* Accept and apply any substitute options passed by the user at usage time.
* Validate the playbook spec
* Convert the playbook spec file into a transmittable model that the other pipeline components can use
== Software Architecture
The playbook component functionality is provided by the playbook module.
All the details of loading the configuration, including the schema, the validation, the precedence of input methods, and the conversion to a transmittable model should be encapsulated in this component.
The playbook component should:
* Accept a playbook spec file composed in YAML, JSON, or CSON format.
* Accept two parameters, an array of arguments (populated from or simulating process arguments) and a hash of variables (populated from or simulating environment variables).
** By accepting these two parameters, the playbook builder can be used and tested independently of the CLI runtime environment.
// ** Within those parameters, a playbook spec file may be specified, which is a third (and the bulk) method of user input.
* Validate the playbook spec
* Convert a valid playbook spec into a transmittable, well-defined, read-only data model that other pipeline components can use
.Inputs
* Playbook spec (`site.yml`, `site.json`, or `site.cson`)
* Process arguments (i.e., command-line flags and switches)
* Environment variables
.Output
* Playbook (`playbook`)
== Code
The playbook component is implemented as a dedicated node package (i.e., module).
Its APIs should be exported so that they can be required using the `require` keyword in the documentation pipeline.
The playbook component is composed of several object prototypes, including a playbook builder and the playbook data model.
The playbook builder should:
* Be the main coordinator, though it may delegate work to subordinate objects
* Use https://github.com/mozilla/node-convict[convict] to process the user input
* Interpret the `playbook` option as a relative path to a playbook spec file
* Load a playbook spec composed in YAML, JSON, or CSON data format
** The format of the playbook spec file is determined by the file`'s extension
** If the path does not have a file extension, the builder should attempt to locate a file with the `.yml`, `.json`, or `.cson` extension, in that order
* Load any environment variables, then process arguments
== Data
The playbook object (`playbook`) produced by this component should be a well-defined, read-only data model.
This model should not be coupled to any configuration-related technology used within the component.
Instead, it should be a model that can be easily reproduced by another means, such as an alternate implementation of the playbook component.
Each section of configuration (site, content, ui) should be represented by a dedicated model type whose properties (name, location, and type) can be easily converted into API documentation (for example, using a tool like https://github.com/documentationjs/documentation[documentationjs]).
== Consequences
By introducing a dedicated playbook component that produces a data model, the configuration step is decoupled from the runtime environment (e.g., CLI environment).
This design will have an immediate impact on development by making the component easier to test in isolation.
This component also reserves room in the future for Antora to accept configuration from other input types, such as a database or web service.
// Audibles may be passed using either process arguments (i.e., command-line flags and switches), environment variables, or a combination of both.
//Future idea: Plugins should be able to participate in the process of building the playbook, either to modify the schema or modify the configuration data.
// Future idea: The playbook builder should fire one event after the configuration schema is loaded and one event after the configuration data is populated.
// This means that the playbook component has an implicit dependency on an event bus infrastructure.
// Future idea: This component should use the global event emitter to fire events into the event bus.
// Future idea: By raising events at strategic points, the playbook component allows plugins to introduce flags and switches to the main application interface.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment