Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add documentation about Build Extensibility #71

Merged
merged 1 commit into from
Dec 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,16 @@ resources:
configuration:
paths:
"src": "source"
builder:
customTasks:
- name: custom-task-name-1
beforeTask: standard-task-name
configuration:
configuration-key: value
- name: custom-task-name-2
afterTask: custom-task-name-1
configuration:
color: blue
server:
settings:
port: 8099
Expand All @@ -234,6 +244,12 @@ Some general information
+ For type `library` there can be a setting for mapping the virtual paths `src` and `test` to physical paths within the project
- `shims`: Can be used to define, extend or override UI5 configs of dependencies. Inner structure equals the general structure. It is a key-value map where the key equals the project ID as supplied by the translator.

##### builder (optional)
- `customTasks` (optional, list): in this block you can define additional custom build tasks. Please see [here](docs/BuildExtensibility.md) for a detailed explanation and examples of the build extensibility. Each entry in the `customTasks` list consists of the following options:
- `name` (mandatory): the name of the custom task
- `afterTask` or `beforeTask` (only one, mandatory): the name of the build task after or before which your custom task will be executed.
- `configuration` (optional): additional configuration that will be passed to the custom build task

##### server (optional)
- `settings` (not yet implemented)
- `port`: Project default server port. Can be overwritten via CLI parameters.
Expand Down
143 changes: 143 additions & 0 deletions docs/BuildExtensibility.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
![UI5 icon](https://raw.githubusercontent.com/SAP/ui5-tooling/master/docs/images/UI5_logo_wide.png)

# UI5 Build Extensibility

The UI5 Build Extensibility enables a developer to enhance the build process of any UI5 project. In addition to the [standard task list](https://github.com/SAP/ui5-builder/blob/master/README.md#tasks), custom tasks can be created.

## Configuration of the Custom Build Process

You can configure your build process with additional build task. The custom tasks can be defined in the project [configuration](https://github.com/SAP/ui5-project/blob/master/README.md#configuration) within the `ui5.yaml` file.

In the below example, when building the library `my.library` the `babel` task will be executed before the standard task `generateComponentPreload`. Another custom task called `generateMarkdownFiles` is then executed immediatly after the standard task `uglify`.

### Example: Configuration of project 'my.library'

````yaml
---
# In this example configuration two custom tasks are defined: 'babel' and 'generateMarkdownFiles'.
specVersion: "0.1"
type: library
metadata:
name: my.library
builder:
customTasks:
- name: babel
beforeTask: generateComponentPreload
- name: generateMarkdownFiles
afterTask: uglify
configuration:
color: blue
````

### Example: Connect multiple custom tasks

You can also connect multiple custom task with each other. Please be aware that the order of your definitions is important. You have to make sure that the task is defined before you reference it as `beforeTask` or `afterTask`.

````yaml
---
# In this example 'myCustomTask2' gets executed after 'myCustomTask1'.
specVersion: "0.1"
type: library
metadata:
name: my.library
builder:
customTasks:
- name: myCustomTask1
beforeTask: generateComponentPreload
- name: myCustomTask2
afterTask: myCustomTask1
````

## Custom Task Extension

A custom task extension consists of a `ui5.yaml` and a [task implementation](#task-implementation). It can be a standalone module or part of an existing UI5 project.

### Example: ui5.yaml

````yaml
---
specVersion: "0.1"
kind: extension
type: task
metadata:
name: generateMarkdownFiles
task:
path: lib/tasks/generateMarkdownFiles.js
````

Task extensions can be **standalone modules** which are handled as dependencies.

On the other hand you can implement a task extension as **part of your UI5 project**. In that case, the configuration of the extension is part of your project configuration inside the `ui5.yaml` as shown below.

The task extension will then be automatically collected and processed during the processing of the project.

### Example: Custom Task Extension defined in UI5 project

````yaml
# ui5.yaml configuration for the above example

specVersion: "0.1"
kind: project
type: library
metadata:
name: my.library
builder:
customTasks:
- name: generateMarkdownFiles
afterTask: uglify
configuration:
color: blue
---
# Task extension as part of your project
specVersion: "0.1"
kind: extension
type: task
metadata:
name: generateMarkdownFiles
task:
path: lib/tasks/generateMarkdownFiles.js
````

## Task Implementation

A custom task implementation needs to return a function with the following signature:

````javascript
/**
* Custom task example
*
* @param {Object} parameters Parameters
* @param {DuplexCollection} parameters.workspace DuplexCollection to read and write files
* @param {AbstractReader} parameters.dependencies Reader or Collection to read dependency files
* @param {Object} parameters.options Options
* @param {string} parameters.options.projectName Project name
* @param {string} [parameters.options.configuration] Task configuration if given in ui5.yaml
* @returns {Promise<undefined>} Promise resolving with undefined once data has been written
*/
module.exports = function({workspace, options}) {
// [...]
};
````

The following code snippets shows an example how a task implementation could look like:

### Example: lib/tasks/generateMarkdownFiles.js

````javascript
// Task implementation
const markdownGenerator = require("./markdownGenerator");

module.exports = function({workspace, options}) {
return workspace.byGlob("**/*.txt")
.then((textResources) => {
return markdownGenerator({
resources: textResources
});
})
.then((markdownResources) => {
return Promise.all(markdownResources.map((resource) => {
return workspace.write(resource);
}));
});
};
````