@sap/cds-dk 7.2.0 → 7.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/activate.js +2 -2
- package/bin/add.js +1 -1
- package/bin/build.js +6 -3
- package/bin/compile/index.js +9 -5
- package/bin/env.js +0 -3
- package/bin/extend.js +29 -3
- package/bin/import.js +7 -3
- package/bin/init.js +31 -37
- package/bin/push.js +10 -6
- package/bin/repl.js +23 -43
- package/bin/watch.js +5 -9
- package/lib/bind/bindingResolver.js +2 -1
- package/lib/bind/index.js +1 -1
- package/lib/build/{buildTaskHandler.js → buildPlugin.js} +40 -27
- package/lib/build/buildTaskEngine.js +75 -74
- package/lib/build/buildTaskFactory.js +39 -32
- package/lib/build/buildTaskProvider.js +24 -19
- package/lib/build/buildTaskProviderFactory.js +125 -58
- package/lib/build/constants.js +6 -4
- package/lib/build/index.js +7 -3
- package/lib/build/plugins.js +35 -0
- package/lib/build/provider/{buildTaskHandlerEdmx.js → edmxBuildPlugin.js} +11 -7
- package/lib/build/provider/{buildTaskHandlerFeatureToggles.js → featureToggleBuildPlugin.js} +5 -5
- package/lib/build/provider/fiori/index.js +5 -6
- package/lib/build/provider/hana/index.js +54 -30
- package/lib/build/provider/{buildTaskHandlerInternal.js → internalBuildPlugin.js} +14 -10
- package/lib/build/provider/{buildTaskProviderInternal.js → internalBuildTaskProvider.js} +27 -28
- package/lib/build/provider/java/index.js +30 -24
- package/lib/build/provider/mtx/index.js +4 -4
- package/lib/build/provider/mtx/resourcesTarBuilder.js +8 -8
- package/lib/build/provider/mtx-extension/index.js +17 -9
- package/lib/build/provider/mtx-sidecar/index.js +17 -11
- package/lib/build/provider/nodejs/index.js +14 -13
- package/lib/build/util.js +5 -0
- package/lib/client/auth_manager.js +6 -12
- package/lib/client/base_command.js +1 -1
- package/lib/client/download_legacy.js +43 -0
- package/lib/client/params.js +6 -0
- package/lib/client/push.js +41 -1
- package/lib/client/settings_manager.js +28 -17
- package/lib/compile/openapi/csdl2openapi.js +1 -1
- package/lib/env/schema.js +36 -0
- package/lib/env/schemas/cds-rc.json +101 -0
- package/lib/import/common.js +23 -10
- package/lib/import/importapi.js +2 -2
- package/lib/import/message.js +3 -1
- package/lib/import/odata/v4parser.js +23 -7
- package/lib/index.js +11 -0
- package/lib/init/constants.js +5 -2
- package/lib/init/index.js +2 -3
- package/lib/init/template/_merging/registry-mta.js +33 -0
- package/lib/init/template/approuter/files/mta.yaml.hbs +1 -1
- package/lib/init/template/approuter/index.js +9 -9
- package/lib/init/template/connectivity/index.js +5 -4
- package/lib/init/template/destination/index.js +2 -5
- package/lib/init/template/helm/subcharts/content-deployment/Chart.yaml +4 -4
- package/lib/init/template/helm/subcharts/content-deployment/templates/_helpers.tpl +4 -2
- package/lib/init/template/helm/subcharts/content-deployment/templates/job.yaml +4 -3
- package/lib/init/template/helm/subcharts/content-deployment/values.schema.json +9 -83
- package/lib/init/template/helm/subcharts/content-deployment/values.yaml +54 -15
- package/lib/init/template/helm/subcharts/service-instance/Chart.yaml +4 -4
- package/lib/init/template/helm/subcharts/service-instance/templates/serviceinstance.yaml +1 -1
- package/lib/init/template/helm/subcharts/service-instance/values.schema.json +0 -17
- package/lib/init/template/helm/subcharts/service-instance/values.yaml +28 -0
- package/lib/init/template/helm/subcharts/web-application/Chart.yaml +5 -5
- package/lib/init/template/helm/subcharts/web-application/templates/_api.tpl +60 -0
- package/lib/init/template/helm/subcharts/web-application/templates/_helpers.tpl +34 -73
- package/lib/init/template/helm/subcharts/web-application/templates/api-rule.yaml +4 -4
- package/lib/init/template/helm/subcharts/web-application/templates/deployment.yaml +96 -17
- package/lib/init/template/helm/subcharts/web-application/templates/network-policy.yaml +19 -3
- package/lib/init/template/helm/subcharts/web-application/templates/pod-disruption-budget.yaml +3 -3
- package/lib/init/template/helm/subcharts/web-application/templates/rbac.yaml +26 -0
- package/lib/init/template/helm/subcharts/web-application/templates/secret.yaml +1 -1
- package/lib/init/template/helm/subcharts/web-application/templates/service-account.yaml +1 -1
- package/lib/init/template/helm/subcharts/web-application/templates/service-binding.yaml +1 -1
- package/lib/init/template/helm/subcharts/web-application/templates/service.yaml +21 -3
- package/lib/init/template/helm/subcharts/web-application/templates/virtual-service.yaml +36 -0
- package/lib/init/template/helm/subcharts/web-application/values.schema.json +535 -142
- package/lib/init/template/helm/subcharts/web-application/values.yaml +168 -44
- package/lib/init/template/html5-repo/index.js +27 -3
- package/lib/init/template/mta/index.js +9 -3
- package/lib/init/template/nodejs/files/.vscode/launch.json +0 -3
- package/lib/init/template/notifications/files/mta.yaml.hbs +17 -0
- package/lib/init/template/notifications/files/notificationtypes.json.hbs +16 -0
- package/lib/init/template/notifications/files/package.json.hbs +14 -0
- package/lib/init/template/notifications/index.js +52 -0
- package/lib/init/template/postgres/files/mta.yaml.hbs +27 -0
- package/lib/init/template/postgres/files/package.json.hbs +5 -0
- package/lib/init/template/postgres/index.js +52 -0
- package/lib/init/util/projectReader.js +0 -1
- package/lib/util/pruneAxiosErrors.js +25 -8
- package/lib/util/term.js +1 -2
- package/lib/watch/livereload-server.js +38 -2
- package/lib/watch/node-watch.js +3 -2
- package/npm-shrinkwrap.json +334 -335
- package/package.json +2 -2
- package/lib/init/template/helm/subcharts/content-deployment/templating.md +0 -37
- package/lib/init/template/helm/subcharts/content-deployment/values-lint.yaml +0 -5
- package/lib/init/template/helm/subcharts/content-deployment/values.md +0 -1011
- package/lib/init/template/helm/subcharts/service-instance/templating.md +0 -18
- package/lib/init/template/helm/subcharts/service-instance/values-lint.yaml +0 -2
- package/lib/init/template/helm/subcharts/service-instance/values.md +0 -186
- package/lib/init/template/helm/subcharts/web-application/templating.md +0 -51
- package/lib/init/template/helm/subcharts/web-application/values-lint.yaml +0 -8
- package/lib/init/template/helm/subcharts/web-application/values.md +0 -1363
|
@@ -2,13 +2,13 @@ const path = require('path')
|
|
|
2
2
|
const fs = require('fs').promises
|
|
3
3
|
const cds = require('../cds')
|
|
4
4
|
|
|
5
|
-
const { OUTPUT_MODE, OUTPUT_MODE_FILESYSTEM, SEVERITY_INFO, SEVERITY_WARNING, SEVERITY_ERROR
|
|
6
|
-
const { hasOptionValue, getProperty, relativePaths, BuildMessage } = require('./util')
|
|
5
|
+
const { OUTPUT_MODE, OUTPUT_MODE_FILESYSTEM, SEVERITY_INFO, SEVERITY_WARNING, SEVERITY_ERROR } = require('./constants')
|
|
6
|
+
const { hasOptionValue, getProperty, relativePaths, BuildMessage, pathExists } = require('./util')
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* The build
|
|
10
|
-
* by the build task's <code>use</code>
|
|
11
|
-
* of the build
|
|
9
|
+
* The build plugin creates the build output for a dedicated build task. It is uniquely identified
|
|
10
|
+
* by the build task's <code>for</code> or <code>use</code>property. The <code>use</code> property represents
|
|
11
|
+
* the fully qualified node module path of the build plugin implementation.
|
|
12
12
|
* <p>
|
|
13
13
|
* The build task engine defines the following protocol. The methods are invoked in descending order:
|
|
14
14
|
* <ul>
|
|
@@ -19,17 +19,17 @@ const { hasOptionValue, getProperty, relativePaths, BuildMessage } = require('./
|
|
|
19
19
|
* </ul>
|
|
20
20
|
* The reflected CSN can be accessed using the async method <code>model()</code>.
|
|
21
21
|
*/
|
|
22
|
-
class
|
|
22
|
+
class BuildPlugin {
|
|
23
23
|
/**
|
|
24
|
-
* @
|
|
24
|
+
* @constructor
|
|
25
25
|
*/
|
|
26
26
|
constructor() {
|
|
27
|
-
if (new.target === BuildTaskHandler) {
|
|
28
|
-
throw new TypeError("Cannot construct BuildTaskHandler instances directly");
|
|
29
|
-
}
|
|
30
27
|
this._written = new Set()
|
|
31
28
|
this._messages = []
|
|
32
29
|
}
|
|
30
|
+
static hasTask() {
|
|
31
|
+
return true
|
|
32
|
+
}
|
|
33
33
|
static get INFO() {
|
|
34
34
|
return SEVERITY_INFO
|
|
35
35
|
}
|
|
@@ -47,7 +47,7 @@ class BuildTaskHandler {
|
|
|
47
47
|
return this._context
|
|
48
48
|
}
|
|
49
49
|
/**
|
|
50
|
-
* Returns the build task executed by this build
|
|
50
|
+
* Returns the build task executed by this build plugin.
|
|
51
51
|
* @return {object}
|
|
52
52
|
*/
|
|
53
53
|
get task() {
|
|
@@ -56,7 +56,8 @@ class BuildTaskHandler {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
|
-
* Returns
|
|
59
|
+
* Returns a list of build and compiler messages created by this build plugin.
|
|
60
|
+
* Supported message severities are 'Info', 'Warning', and 'Error'.
|
|
60
61
|
* @return {Array}
|
|
61
62
|
*/
|
|
62
63
|
get messages() {
|
|
@@ -64,7 +65,7 @@ class BuildTaskHandler {
|
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
/**
|
|
67
|
-
* Returns the list of files written by this build
|
|
68
|
+
* Returns the list of files written by this build plugin.
|
|
68
69
|
* @return {Array}
|
|
69
70
|
*/
|
|
70
71
|
get files() {
|
|
@@ -72,14 +73,14 @@ class BuildTaskHandler {
|
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
/**
|
|
75
|
-
* Returns the priority of this
|
|
76
|
+
* Returns the priority of this plugin as number, where 0 represents the minimum value and
|
|
76
77
|
* Number.MAX_SAFE_INTEGER the maximum value.
|
|
77
|
-
* Positive numbers mean higher and negative numbers lower priority. Build
|
|
78
|
-
* with higher priority value are executed before
|
|
78
|
+
* Positive numbers mean higher and negative numbers lower priority. Build plugins
|
|
79
|
+
* with higher priority value are executed before plugins with lower priority.
|
|
79
80
|
* <br>
|
|
80
|
-
* Note: Currently not supported for custom build
|
|
81
|
-
* before the built-in
|
|
82
|
-
* @return {number} the priority for this
|
|
81
|
+
* Note: Currently not supported for custom build plugins as they are always executed
|
|
82
|
+
* before the built-in plugins.
|
|
83
|
+
* @return {number} the priority for this plugin as integer.
|
|
83
84
|
*/
|
|
84
85
|
get priority() {
|
|
85
86
|
return 1
|
|
@@ -88,29 +89,41 @@ class BuildTaskHandler {
|
|
|
88
89
|
* Called by the framework immediately after this instance has been created.
|
|
89
90
|
* The instance has already been fully initialized.
|
|
90
91
|
*/
|
|
91
|
-
init() {
|
|
92
|
+
init() {
|
|
93
|
+
if (cds.env.build.target === '.') {
|
|
94
|
+
this.task.dest = path.join(this.task.dest, 'gen')
|
|
95
|
+
}
|
|
96
|
+
}
|
|
92
97
|
|
|
93
98
|
/**
|
|
94
|
-
*
|
|
99
|
+
* @abstract
|
|
100
|
+
* Called by the framework to create the artifacts of this build plugin.
|
|
95
101
|
*/
|
|
96
102
|
async build() {
|
|
97
|
-
throw new TypeError(OVERRIDE_METHOD_MSG)
|
|
98
103
|
}
|
|
99
104
|
|
|
100
105
|
/**
|
|
101
|
-
* Called by the framework immediately before 'build' to delete any output created by this build
|
|
106
|
+
* Called by the framework immediately before 'build' to delete any output created by this build plugin.
|
|
102
107
|
* <p>
|
|
103
108
|
* Note: The <code>BuildTaskEngine</code> is cleaning the common generation target folder if the build is
|
|
104
109
|
* executed in staging mode, e.g. build.target: "gen".
|
|
105
110
|
*/
|
|
106
111
|
async clean() {
|
|
107
|
-
|
|
112
|
+
function isSubDirectory(parent, child) {
|
|
113
|
+
return !path.relative(parent, child).startsWith('..')
|
|
114
|
+
}
|
|
115
|
+
if (cds.env.build.target === '.'
|
|
116
|
+
&& this.task.src !== this.task.dest
|
|
117
|
+
&& !isSubDirectory(this.task.dest, this.task.src)
|
|
118
|
+
&& await pathExists(this.task.dest)) {
|
|
119
|
+
return fs.rm(this.task.dest, { force: true, recursive: true })
|
|
120
|
+
}
|
|
108
121
|
}
|
|
109
122
|
|
|
110
123
|
/**
|
|
111
124
|
* Asynchronously write the given content to a given file path.
|
|
112
125
|
* If the file exists the content is replaced. If the file does not exist, a new file will be created.
|
|
113
|
-
* The file name is stored in the list of files written by this build
|
|
126
|
+
* The file name is stored in the list of files written by this build plugin.
|
|
114
127
|
* @param {string} dest - absolute or relative file path. Relative paths will be resolved to this task's destination path.
|
|
115
128
|
* @param {any} data - If data is of type object the JSON-stringified version is written.
|
|
116
129
|
*/
|
|
@@ -135,7 +148,7 @@ class BuildTaskHandler {
|
|
|
135
148
|
* Copy a file or directory if the build task option 'outputMode' does not have the value 'resultOnly'.
|
|
136
149
|
* The directory can have contents.
|
|
137
150
|
* <p>
|
|
138
|
-
* Note: The file name is stored in the list of files written by this build
|
|
151
|
+
* Note: The file name is stored in the list of files written by this build plugin.
|
|
139
152
|
* </p>
|
|
140
153
|
* @param {string} src The absolute or relative source path of the file or directory to copy.
|
|
141
154
|
* Relative paths will be resolved to this task's source path.
|
|
@@ -231,4 +244,4 @@ class BuildTaskHandler {
|
|
|
231
244
|
return value
|
|
232
245
|
}
|
|
233
246
|
}
|
|
234
|
-
module.exports =
|
|
247
|
+
module.exports = BuildPlugin
|
|
@@ -5,7 +5,7 @@ const { sortMessagesSeverityAware, deduplicateMessages, CompilationError } = cds
|
|
|
5
5
|
const { relativePaths, BuildError, resolveRequiredSapModels } = require('./util')
|
|
6
6
|
const { SEVERITIES, LOG_LEVELS } = require('./constants')
|
|
7
7
|
const BuildTaskFactory = require('./buildTaskFactory')
|
|
8
|
-
const
|
|
8
|
+
const InternalBuildPlugin = require('./provider/internalBuildPlugin')
|
|
9
9
|
|
|
10
10
|
const COMPILATION_ERROR = 'CompilationError'
|
|
11
11
|
const COMPILE_MESSAGE = 'CompileMessage'
|
|
@@ -40,66 +40,66 @@ class BuildTaskEngine {
|
|
|
40
40
|
throw new BuildError(`Required CDS models [${unresolved.join(', ')}] cannot be resolved. Make sure up-to-date versions of the missing modules are installed.`)
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
// create build
|
|
44
|
-
const
|
|
43
|
+
// create build plugins
|
|
44
|
+
const plugins = []
|
|
45
45
|
tasks.forEach((task) => {
|
|
46
46
|
if (task) {
|
|
47
|
-
const
|
|
48
|
-
|
|
47
|
+
const plugin = this._createPlugin(task)
|
|
48
|
+
plugins.push(plugin)
|
|
49
49
|
}
|
|
50
50
|
})
|
|
51
51
|
|
|
52
52
|
try {
|
|
53
|
-
await this._executePrepare(
|
|
54
|
-
await this._executeCleanBuildTasks(
|
|
53
|
+
await this._executePrepare(plugins)
|
|
54
|
+
await this._executeCleanBuildTasks(plugins)
|
|
55
55
|
|
|
56
56
|
// throwing Exception in case of compilation errors
|
|
57
|
-
const buildResult = await this._executeBuildTasks(
|
|
57
|
+
const buildResult = await this._executeBuildTasks(plugins)
|
|
58
58
|
|
|
59
|
-
await this._writeGenerationLog(
|
|
60
|
-
this.
|
|
61
|
-
this._logMessages(BuildTaskEngine.
|
|
59
|
+
await this._writeGenerationLog(plugins)
|
|
60
|
+
this._logOutput(plugins)
|
|
61
|
+
this._logMessages(BuildTaskEngine._getMessages(plugins))
|
|
62
62
|
this._logTimer(startTime, Date.now())
|
|
63
63
|
|
|
64
64
|
return buildResult
|
|
65
65
|
} catch (error) {
|
|
66
|
-
this.
|
|
66
|
+
this._logOutput(plugins)
|
|
67
67
|
throw error
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
/**
|
|
72
|
-
*
|
|
73
|
-
* Currently only used by internal
|
|
72
|
+
* BuildPlugin#prepare has been deprecated and was never part of the public API.
|
|
73
|
+
* Currently only used by internal FioriBuildPlugin.
|
|
74
74
|
* @deprecated
|
|
75
|
-
* @param {*}
|
|
75
|
+
* @param {*} plugins
|
|
76
76
|
* @returns
|
|
77
77
|
*/
|
|
78
|
-
async _executePrepare(
|
|
79
|
-
const
|
|
78
|
+
async _executePrepare(plugins) {
|
|
79
|
+
const pluginGroups = new Map()
|
|
80
80
|
|
|
81
|
-
// group
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
// group plugins by type
|
|
82
|
+
plugins.forEach(plugin => {
|
|
83
|
+
pluginGroups.has(plugin.task.for) ? pluginGroups.get(plugin.task.for).push(plugin) : pluginGroups.set(plugin.task.for, [plugin])
|
|
84
84
|
})
|
|
85
85
|
|
|
86
86
|
const promises = []
|
|
87
|
-
for (let
|
|
88
|
-
promises.push(this._doPrepare(
|
|
87
|
+
for (let pluginGroup of pluginGroups.values()) {
|
|
88
|
+
promises.push(this._doPrepare(pluginGroup))
|
|
89
89
|
}
|
|
90
90
|
return Promise.all(promises)
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
/**
|
|
94
94
|
* @deprecated
|
|
95
|
-
* @param {*}
|
|
95
|
+
* @param {*} pluginGroup
|
|
96
96
|
*/
|
|
97
|
-
async _doPrepare(
|
|
98
|
-
for (let
|
|
97
|
+
async _doPrepare(pluginGroup) {
|
|
98
|
+
for (let plugin of pluginGroup) {
|
|
99
99
|
// prepare has been deprecated
|
|
100
|
-
if (
|
|
101
|
-
this.logger._debug && this.logger.debug(`preparing,
|
|
102
|
-
const result = await
|
|
100
|
+
if (plugin instanceof InternalBuildPlugin) {
|
|
101
|
+
this.logger._debug && this.logger.debug(`preparing, plugin [${plugin.constructor.name}], src [${relativePaths(cds.root, plugin.task.src)}]`)
|
|
102
|
+
const result = await plugin.prepare()
|
|
103
103
|
if (result === false) {
|
|
104
104
|
break
|
|
105
105
|
}
|
|
@@ -107,7 +107,7 @@ class BuildTaskEngine {
|
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
async _executeCleanBuildTasks(
|
|
110
|
+
async _executeCleanBuildTasks(plugins) {
|
|
111
111
|
if (this.options.clean) {
|
|
112
112
|
// clean entire build staging folder once
|
|
113
113
|
if (cds.env.build.target !== '.') {
|
|
@@ -116,30 +116,30 @@ class BuildTaskEngine {
|
|
|
116
116
|
await fs.promises.rm(target, { force: true, recursive: true })
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
const results = await Promise.allSettled(
|
|
120
|
-
this.logger._debug && this.logger.debug(`cleaning,
|
|
121
|
-
return
|
|
119
|
+
const results = await Promise.allSettled(plugins.map((plugin) => {
|
|
120
|
+
this.logger._debug && this.logger.debug(`cleaning, plugin [${plugin.constructor.name}], src [${relativePaths(cds.root, plugin.task.src)}]`)
|
|
121
|
+
return plugin.clean()
|
|
122
122
|
}))
|
|
123
123
|
// check for errors and throw exception
|
|
124
124
|
this._resolveHandlerResponse(results)
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
async _executeBuildTasks(
|
|
129
|
-
// sort
|
|
130
|
-
|
|
128
|
+
async _executeBuildTasks(plugins) {
|
|
129
|
+
// sort plugins based on priority in
|
|
130
|
+
plugins = plugins.sort((a, b) => {
|
|
131
131
|
return a.priority === b.priority ? 0 : a.priority > b.priority ? -1 : 1
|
|
132
132
|
})
|
|
133
|
-
// group
|
|
134
|
-
const buildPipeline =
|
|
133
|
+
// group plugins with same priority in order to execute in parallel
|
|
134
|
+
const buildPipeline = plugins.reduce((acc, plugin) => {
|
|
135
135
|
if (acc.length === 0) {
|
|
136
|
-
acc.push([
|
|
136
|
+
acc.push([plugin])
|
|
137
137
|
} else {
|
|
138
138
|
const currGroup = acc[acc.length - 1]
|
|
139
|
-
if (currGroup[0].priority ===
|
|
140
|
-
currGroup.push(
|
|
139
|
+
if (currGroup[0].priority === plugin.priority) {
|
|
140
|
+
currGroup.push(plugin)
|
|
141
141
|
} else {
|
|
142
|
-
acc.push([
|
|
142
|
+
acc.push([plugin])
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
return acc
|
|
@@ -148,20 +148,20 @@ class BuildTaskEngine {
|
|
|
148
148
|
const results = await this._executePipeline(buildPipeline)
|
|
149
149
|
|
|
150
150
|
// check for errors and throw exception - return results otherwise including any compiler and build status messages
|
|
151
|
-
return this._resolveHandlerResponse(results, BuildTaskEngine.
|
|
151
|
+
return this._resolveHandlerResponse(results, BuildTaskEngine._getMessages(plugins))
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
async _executePipeline(pipeline) {
|
|
155
155
|
let allResults = []
|
|
156
156
|
for (const group of pipeline) {
|
|
157
|
-
const results = await Promise.allSettled(group.map((
|
|
158
|
-
this.logger._debug && this.logger.debug(`building,
|
|
159
|
-
return
|
|
160
|
-
.then(
|
|
157
|
+
const results = await Promise.allSettled(group.map((plugin) => {
|
|
158
|
+
this.logger._debug && this.logger.debug(`building, plugin [${plugin.constructor.name}], src [${relativePaths(cds.root, plugin.task.src)}]`)
|
|
159
|
+
return plugin.build()
|
|
160
|
+
.then(pluginResult => {
|
|
161
161
|
return Promise.resolve({
|
|
162
|
-
task:
|
|
163
|
-
result:
|
|
164
|
-
messages: this._sortMessagesUnique(
|
|
162
|
+
task: plugin.task,
|
|
163
|
+
result: pluginResult,
|
|
164
|
+
messages: this._sortMessagesUnique(plugin.messages)
|
|
165
165
|
})
|
|
166
166
|
})
|
|
167
167
|
}))
|
|
@@ -170,7 +170,7 @@ class BuildTaskEngine {
|
|
|
170
170
|
return allResults
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
_resolveHandlerResponse(results,
|
|
173
|
+
_resolveHandlerResponse(results, pluginMessages = []) {
|
|
174
174
|
const errors = []
|
|
175
175
|
const resolvedResults = results.reduce((acc, r) => {
|
|
176
176
|
if (r.status === 'fulfilled') {
|
|
@@ -192,9 +192,9 @@ class BuildTaskEngine {
|
|
|
192
192
|
|
|
193
193
|
// propagate existing CompilationErrors
|
|
194
194
|
// merge all existing compilation messages into a single CompilationError
|
|
195
|
-
// compiler warning and info messages are returned as
|
|
195
|
+
// compiler warning and info messages are returned as plugin messages
|
|
196
196
|
const compileErrors = errors.filter(e => e.constructor.name === COMPILATION_ERROR)
|
|
197
|
-
const compileMessages =
|
|
197
|
+
const compileMessages = pluginMessages.filter(message => message.constructor.name === COMPILE_MESSAGE)
|
|
198
198
|
if (compileErrors.length) {
|
|
199
199
|
throw new CompilationError(this._sortMessagesUnique(BuildTaskEngine._getErrorMessages(compileErrors), compileMessages))
|
|
200
200
|
}
|
|
@@ -202,31 +202,32 @@ class BuildTaskEngine {
|
|
|
202
202
|
return resolvedResults
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
-
|
|
206
|
-
const
|
|
207
|
-
|
|
205
|
+
_createPlugin(task) {
|
|
206
|
+
const plugin = this.taskFactory.createPlugin(task)
|
|
207
|
+
plugin.init()
|
|
208
208
|
|
|
209
|
-
if (!(
|
|
210
|
-
// Custom build
|
|
209
|
+
if (!(plugin instanceof InternalBuildPlugin) && plugin.priority !== 1) {
|
|
210
|
+
// Custom build plugins are executed before internal plugins to ensure
|
|
211
211
|
// that generated content cannot be overwritten by mistake
|
|
212
|
-
throw new Error(`Illegal priority for ${
|
|
212
|
+
throw new Error(`Illegal priority for ${plugin.constructor.name} encountered for custom plugin - in this version only priority value '1' is allowed`)
|
|
213
213
|
}
|
|
214
|
-
this._logTaskHandler(
|
|
215
|
-
return
|
|
214
|
+
this._logTaskHandler(plugin)
|
|
215
|
+
return plugin
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
-
|
|
218
|
+
_logOutput(plugins) {
|
|
219
219
|
// log all generated files
|
|
220
|
-
const files = BuildTaskEngine.
|
|
220
|
+
const files = BuildTaskEngine._getOutput(plugins)
|
|
221
221
|
if (files.length > 0) {
|
|
222
|
-
|
|
222
|
+
const term = require('../util/term')
|
|
223
|
+
this.logger.log(`done > wrote output to:\n ${term.secondary(files.join("\n "))}\n`)
|
|
223
224
|
}
|
|
224
225
|
}
|
|
225
226
|
|
|
226
|
-
async _writeGenerationLog(
|
|
227
|
+
async _writeGenerationLog(plugins) {
|
|
227
228
|
const outputFile = cds.env.build.outputfile || process.env.GENERATION_LOG
|
|
228
229
|
if (outputFile) {
|
|
229
|
-
const files = BuildTaskEngine.
|
|
230
|
+
const files = BuildTaskEngine._getOutput(plugins)
|
|
230
231
|
this.logger.log(`writing generation log to [${outputFile}]\n`)
|
|
231
232
|
try {
|
|
232
233
|
await fs.promises.mkdir(path.dirname(outputFile), { recursive: true })
|
|
@@ -238,8 +239,8 @@ class BuildTaskEngine {
|
|
|
238
239
|
}
|
|
239
240
|
}
|
|
240
241
|
|
|
241
|
-
static
|
|
242
|
-
const files =
|
|
242
|
+
static _getOutput(plugins) {
|
|
243
|
+
const files = plugins.reduce((acc, plugin) => acc.concat(plugin.files), []).sort()
|
|
243
244
|
return files.map(file => {
|
|
244
245
|
if (path.isAbsolute(cds.env.build.target)) {
|
|
245
246
|
return file
|
|
@@ -252,9 +253,9 @@ class BuildTaskEngine {
|
|
|
252
253
|
this.logger.log(`build completed in ${end - start} ms\n`)
|
|
253
254
|
}
|
|
254
255
|
|
|
255
|
-
_logTaskHandler(
|
|
256
|
-
this.logger._debug && this.logger.debug(`
|
|
257
|
-
this.logger._debug && this.logger.debug(`details src [${relativePaths(cds.root,
|
|
256
|
+
_logTaskHandler(plugin) {
|
|
257
|
+
this.logger._debug && this.logger.debug(`plugin ${plugin.constructor.name}`)
|
|
258
|
+
this.logger._debug && this.logger.debug(`details src [${relativePaths(cds.root, plugin.task.src)}], dest [${relativePaths(cds.root, plugin.task.dest)}], use [${plugin.task.use}], options [${JSON.stringify(plugin.task.options)}]`) //NOSONAR
|
|
258
259
|
}
|
|
259
260
|
|
|
260
261
|
_logMessages(messages) {
|
|
@@ -303,11 +304,11 @@ class BuildTaskEngine {
|
|
|
303
304
|
}
|
|
304
305
|
|
|
305
306
|
/**
|
|
306
|
-
* Returns compiler messages and validation messages issued by
|
|
307
|
-
* @param {Array<
|
|
307
|
+
* Returns compiler messages and validation messages issued by plugins.
|
|
308
|
+
* @param {Array<BuildPlugin>} plugins
|
|
308
309
|
*/
|
|
309
|
-
static
|
|
310
|
-
return
|
|
310
|
+
static _getMessages(plugins) {
|
|
311
|
+
return plugins.reduce((acc, plugin) => acc.concat(plugin.messages), [])
|
|
311
312
|
}
|
|
312
313
|
|
|
313
314
|
/**
|
|
@@ -4,6 +4,7 @@ const cds = require('../cds')
|
|
|
4
4
|
const BuildTaskProviderFactory = require('./buildTaskProviderFactory')
|
|
5
5
|
const { hasJavaNature, getProperty, redactCredentials, flatten, getDefaultModelOptions } = require('./util')
|
|
6
6
|
const { FILE_EXT_CDS, BUILD_TASK_JAVA_CF, BUILD_TASK_JAVA } = require("./constants")
|
|
7
|
+
const term = require('../util/term')
|
|
7
8
|
|
|
8
9
|
class BuildTaskFactory {
|
|
9
10
|
constructor(options) {
|
|
@@ -27,12 +28,11 @@ class BuildTaskFactory {
|
|
|
27
28
|
const tasks = await this._createTasks()
|
|
28
29
|
|
|
29
30
|
// log build tasks
|
|
30
|
-
|
|
31
|
-
let tasksOutput = " {\n \"build\": {\n \"target\": \"" + cds.env.build.target + "\",\n \"tasks\": ["
|
|
31
|
+
let tasksOutput = "{\n build: {\n target: " + term.info("'" + cds.env.build.target + "'") + ",\n tasks: [\n"
|
|
32
32
|
for (let i = 0; i < tasks.length; i++) {
|
|
33
|
-
tasksOutput += "
|
|
33
|
+
tasksOutput += " " + BuildTaskFactory._stringifyTask(tasks[i]) + (i + 1 < tasks.length ? ",\n" : "\n")
|
|
34
34
|
}
|
|
35
|
-
tasksOutput += "
|
|
35
|
+
tasksOutput += " ]\n }\n}\n"
|
|
36
36
|
this.logger.log(tasksOutput)
|
|
37
37
|
|
|
38
38
|
// for testing purposes
|
|
@@ -47,8 +47,8 @@ class BuildTaskFactory {
|
|
|
47
47
|
return tasks
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
return this.providerFactory.
|
|
50
|
+
createPlugin(task) {
|
|
51
|
+
return this.providerFactory.createPlugin(task)
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
async _createTasks() {
|
|
@@ -65,7 +65,7 @@ class BuildTaskFactory {
|
|
|
65
65
|
// 1. apply default values including task.for and task.use and ensure that for all tasks a provider exists - throwing error otherwise
|
|
66
66
|
await this.providerFactory.applyTaskDefaults(tasks)
|
|
67
67
|
// ensure that dependencies get wired up before filtering
|
|
68
|
-
await this.providerFactory.lookupTasks(tasks)
|
|
68
|
+
await this.providerFactory.lookupTasks(tasks, true)
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
// 3. filters the list of build tasks and adapts according to given CLI options
|
|
@@ -83,7 +83,7 @@ class BuildTaskFactory {
|
|
|
83
83
|
|
|
84
84
|
// 2. add dependencies
|
|
85
85
|
existingTasks = [...tasks]
|
|
86
|
-
await this.providerFactory.lookupTasks(tasks)
|
|
86
|
+
await this.providerFactory.lookupTasks(tasks, true)
|
|
87
87
|
if (tasks.length > existingTasks.length) {
|
|
88
88
|
const newTasks = tasks.filter(task => !existingTasks.includes(task))
|
|
89
89
|
// a dependant task was added
|
|
@@ -93,9 +93,6 @@ class BuildTaskFactory {
|
|
|
93
93
|
// obligatory task defaults shared by all tasks
|
|
94
94
|
BuildTaskFactory._applyCommonTaskDefaults(tasks)
|
|
95
95
|
|
|
96
|
-
// ensure correct values for optional build task properties, error for missing mandatory properties
|
|
97
|
-
BuildTaskFactory._validateBuildTasks(tasks)
|
|
98
|
-
|
|
99
96
|
this._setDefaultBuildTargetFolder(tasks)
|
|
100
97
|
return tasks
|
|
101
98
|
}
|
|
@@ -115,14 +112,6 @@ class BuildTaskFactory {
|
|
|
115
112
|
})
|
|
116
113
|
}
|
|
117
114
|
|
|
118
|
-
static _validateBuildTasks(tasks) {
|
|
119
|
-
tasks.forEach(task => {
|
|
120
|
-
if (!task.src) {
|
|
121
|
-
throw new Error(`Invalid build task definition - value of property 'src' is missing in [${task.for || task.use}].`)
|
|
122
|
-
}
|
|
123
|
-
})
|
|
124
|
-
}
|
|
125
|
-
|
|
126
115
|
_setDefaultBuildTargetFolder(tasks) {
|
|
127
116
|
const task = tasks.find(task => task.for === BUILD_TASK_JAVA_CF || task.for === BUILD_TASK_JAVA)
|
|
128
117
|
const srv = task ? task.src : BuildTaskFactory._getModuleFolder(flatten([cds.env.folders.srv])) || "srv"
|
|
@@ -161,19 +150,13 @@ class BuildTaskFactory {
|
|
|
161
150
|
})
|
|
162
151
|
if (resultTasks.length === 0) {
|
|
163
152
|
if (options.for || options.use) {
|
|
164
|
-
const task = {}
|
|
165
|
-
if ((options.for)) {
|
|
166
|
-
task.for = options.for
|
|
167
|
-
}
|
|
168
|
-
if ((options.use)) {
|
|
169
|
-
task.use = options.use
|
|
170
|
-
}
|
|
153
|
+
const task = this.providerFactory.getTask(options.for ? { for: options.for } : { use: options.use })
|
|
171
154
|
if (options.src) {
|
|
172
155
|
task.src = options.src
|
|
173
156
|
}
|
|
174
157
|
resultTasks.push(task)
|
|
175
158
|
}
|
|
176
|
-
} else if (resultTasks.length
|
|
159
|
+
} else if (resultTasks.length <= tasks.length) {
|
|
177
160
|
// return the same array as long as it contains a subset of the given tasks
|
|
178
161
|
tasks.length = 0
|
|
179
162
|
resultTasks.forEach(task => tasks.push(task))
|
|
@@ -213,12 +196,36 @@ class BuildTaskFactory {
|
|
|
213
196
|
static _stringifyTask(task) {
|
|
214
197
|
// ensures identical order of properties
|
|
215
198
|
const order = ["for", "use", "src", "dest", "options"]
|
|
216
|
-
const keys = Object.keys(task).sort((a, b) => order.indexOf(a) - order.indexOf(b))
|
|
199
|
+
const keys = Object.keys(task).filter(key => order.includes(key)).sort((a, b) => order.indexOf(a) - order.indexOf(b))
|
|
217
200
|
|
|
218
|
-
return keys.reduce((acc, key,
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
201
|
+
return keys.reduce((acc, key, i) => {
|
|
202
|
+
const prefix = acc !== '{' ? ', ' : (i === 0 ? ' ' : '')
|
|
203
|
+
if (!key.startsWith('_')) {
|
|
204
|
+
// render either "for" OR "use" value
|
|
205
|
+
if (key in { src: 1, for: 1 } || (!task.for && key === 'use')) {
|
|
206
|
+
return `${acc}${prefix}${key}: ${term.info(`'${task[key]}'`)}`
|
|
207
|
+
} else if (key === 'options') {
|
|
208
|
+
const options = Object.entries(task.options)
|
|
209
|
+
.map(([key, value]) => {
|
|
210
|
+
if (Array.isArray(value)) {
|
|
211
|
+
return `${key}: [${value.map(v => term.info(`'${v}'`)).join(', ')}]`
|
|
212
|
+
} else if (typeof value === 'object') {
|
|
213
|
+
const nested = Object.entries(value)
|
|
214
|
+
.map(([key, value]) => `${key}: ${term.info(`'${value}'`)}`)
|
|
215
|
+
.join(', ')
|
|
216
|
+
return `${key}: { ${nested} }`
|
|
217
|
+
} else {
|
|
218
|
+
return `${key}: ${term.info(`'${value}'`)}`
|
|
219
|
+
}
|
|
220
|
+
})
|
|
221
|
+
.join(', ')
|
|
222
|
+
return `${acc}${prefix}${key}: { ${options} }`
|
|
223
|
+
} else if (key !== 'use') {
|
|
224
|
+
return `${acc}${prefix}${key}: ${term.info(`'${task[key]}'`)}`
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return acc
|
|
228
|
+
}, '{') + '}'
|
|
222
229
|
}
|
|
223
230
|
|
|
224
231
|
static _scanTaskOptionParams(optsParams) {
|
|
@@ -1,22 +1,27 @@
|
|
|
1
1
|
/* eslint-disable no-unused-vars */
|
|
2
|
+
/**
|
|
3
|
+
* @abstract
|
|
4
|
+
*/
|
|
2
5
|
module.exports = class BuildTaskProvider {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
6
|
+
/**
|
|
7
|
+
* @param {object} task
|
|
8
|
+
*/
|
|
9
|
+
providesTask(key) { }
|
|
10
|
+
/**
|
|
11
|
+
* @returns {object} task
|
|
12
|
+
*/
|
|
13
|
+
getTask(key) { return key }
|
|
14
|
+
/**
|
|
15
|
+
* @param {object} task
|
|
16
|
+
*/
|
|
17
|
+
getPluginClass(task) { }
|
|
18
|
+
/**
|
|
19
|
+
* @param {Array} tasks
|
|
20
|
+
* @param {boolean} dependencies
|
|
21
|
+
*/
|
|
22
|
+
async lookupTasks(tasks, dependencies) { }
|
|
23
|
+
/**
|
|
24
|
+
* @param {object} task
|
|
25
|
+
*/
|
|
26
|
+
async applyTaskDefaults(task) { }
|
|
22
27
|
}
|