@sap/cds-dk 7.0.3 → 7.1.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/bind.js +5 -6
- package/bin/build.js +2 -7
- package/bin/cds.js +2 -5
- package/bin/subscribe.js +4 -4
- package/bin/unsubscribe.js +4 -4
- package/bin/upgrade.js +4 -4
- package/lib/bind/cfKeyProvider.js +9 -10
- package/lib/bind/index.js +1 -3
- package/lib/build/buildTaskEngine.js +10 -22
- package/lib/build/buildTaskFactory.js +18 -27
- package/lib/build/buildTaskHandler.js +4 -7
- package/lib/build/index.js +12 -3
- package/lib/build/provider/buildTaskProviderInternal.js +23 -15
- package/lib/build/provider/fiori/index.js +4 -3
- package/lib/build/provider/java/index.js +2 -2
- package/lib/build/provider/mtx/index.js +8 -2
- package/lib/build/util.js +13 -0
- package/lib/client/activate.js +7 -7
- package/lib/client/auth_manager.js +5 -5
- package/lib/client/base_command.js +5 -5
- package/lib/client/extend.js +2 -2
- package/lib/client/helper/logging.js +7 -2
- package/lib/client/params.js +2 -3
- package/lib/client/pull.js +3 -3
- package/lib/client/push.js +3 -3
- package/lib/client/settings_manager.js +7 -8
- package/lib/client/tenant_action.js +3 -3
- package/lib/deploy/to-hana/hana.js +1 -2
- package/lib/import/common.js +3 -0
- package/lib/import/message.js +8 -2
- package/lib/import/odata/metadataconverter/MetadataConverter.js +13 -9
- package/lib/import/odata/v4parser.js +111 -107
- package/lib/init/constants.js +1 -1
- package/lib/init/index.js +24 -11
- package/lib/init/template/cf-manifest/files/manifest.yml.hbs +1 -1
- package/lib/init/template/data/index.js +2 -3
- package/lib/init/template/lint/index.js +5 -6
- package/lib/init/template/nodejs/index.js +2 -3
- package/lib/init/template/pipeline/index.js +1 -2
- package/lib/init/util/indent.js +1 -1
- package/lib/init/util/merge.js +3 -3
- package/lib/init/util/mvn.js +17 -22
- package/lib/util/cfUtil.js +1 -2
- package/npm-shrinkwrap.json +51 -53
- package/package.json +3 -2
- package/lib/client/helper/errors.js +0 -26
- package/lib/util/version.js +0 -27
package/bin/bind.js
CHANGED
|
@@ -54,7 +54,6 @@ module.exports = Object.assign(cds_bind, {
|
|
|
54
54
|
const os = require('os');
|
|
55
55
|
const IS_WIN = os.platform() === 'win32';
|
|
56
56
|
|
|
57
|
-
const { CliError } = require('../lib/client/helper/errors');
|
|
58
57
|
const { bind, parseProfile } = require('../lib/bind');
|
|
59
58
|
|
|
60
59
|
|
|
@@ -70,26 +69,26 @@ async function cds_bind(args, options) {
|
|
|
70
69
|
|
|
71
70
|
// Check if cds command was bind. Don't abort in case of deploy
|
|
72
71
|
if (process.env.CDS_ENV && process.argv[2] === 'bind') {
|
|
73
|
-
throw
|
|
72
|
+
throw 'Option --profile is no longer supported. Use --for instead to specify the profile to use when storing connection settings.';
|
|
74
73
|
}
|
|
75
74
|
|
|
76
75
|
if (!options.to) {
|
|
77
|
-
throw
|
|
76
|
+
throw `Use option --to or -2 to specify the target instance, e.g. cds bind --to myInstance:myService`;
|
|
78
77
|
}
|
|
79
78
|
|
|
80
79
|
if (args.length > 1) {
|
|
81
|
-
throw
|
|
80
|
+
throw `Too many arguments: Please specify only one or no service.`;
|
|
82
81
|
}
|
|
83
82
|
|
|
84
83
|
options.serviceArg = args[0]
|
|
85
84
|
options.targets = options.to.split(/,/g);
|
|
86
85
|
|
|
87
86
|
if (options.targets.length >= 2 && options.serviceArg) {
|
|
88
|
-
throw
|
|
87
|
+
throw `Service argument cannot be specified together with multiple targets ('--to') services. Use one service per call or omit the service argument.`;
|
|
89
88
|
}
|
|
90
89
|
|
|
91
90
|
if (options.targets.length >= 2 && options.kind) {
|
|
92
|
-
throw
|
|
91
|
+
throw `The option '--kind' cannot be specified together with multiple targets ('--to') services. Use one service per call or omit the '--kind' option.`;
|
|
93
92
|
}
|
|
94
93
|
|
|
95
94
|
await bind({
|
package/bin/build.js
CHANGED
|
@@ -96,19 +96,14 @@ async function build([project], options = {}) {
|
|
|
96
96
|
cds.env = cds.env.for('cds', cds.root);
|
|
97
97
|
delete options.project // avoid that relative project paths are resolved twice
|
|
98
98
|
|
|
99
|
-
options.cli = true // avoid that errors are logged twice
|
|
100
|
-
|
|
101
|
-
const { CliError } = require('../lib/client/helper/errors')
|
|
102
99
|
const { build } = require('../lib/build')
|
|
103
|
-
|
|
104
100
|
const [major] = cds.version.split('.')
|
|
105
101
|
if (Number(major) < 6) {
|
|
106
|
-
throw
|
|
102
|
+
throw "This application uses @sap/cds version < 6, which is not compatible with the installed @sap/cds-dk version >= 7. Update @sap/cds to version >= 6."
|
|
107
103
|
}
|
|
108
104
|
if (options.clean === "false") {
|
|
109
|
-
throw
|
|
105
|
+
throw "cds build option '--clean' is deprecated - build output folders are always cleaned before build"
|
|
110
106
|
}
|
|
111
|
-
|
|
112
107
|
if (typeof options["options-model"] === "string") {
|
|
113
108
|
options.opts = "model=[" + options["options-model"].split(",").map((entry) => entry.trim()) + "]"
|
|
114
109
|
delete options["options-model"]
|
package/bin/cds.js
CHANGED
|
@@ -54,11 +54,7 @@ const cli = { //NOSONAR
|
|
|
54
54
|
return await task.apply(this, args)
|
|
55
55
|
}
|
|
56
56
|
} catch (e) {
|
|
57
|
-
const { BuildError } = require('../lib/build')
|
|
58
|
-
const { CliError } = require('../lib/client/helper/errors')
|
|
59
57
|
process.exitCode ??= 1
|
|
60
|
-
if (e.messages?.length) return cds._log(e.messages, { 'log-level': cds.env.log.levels.cli })
|
|
61
|
-
else if (e instanceof CliError || e instanceof BuildError) return console.error(e.message)
|
|
62
58
|
if (cds.watched) throw e // bin/watched.js handles errors
|
|
63
59
|
else return console.error(e)
|
|
64
60
|
}
|
|
@@ -106,7 +102,8 @@ const cli = { //NOSONAR
|
|
|
106
102
|
}
|
|
107
103
|
|
|
108
104
|
// if (env) require('../lib/cds').env.add (env) //> avoid loading env
|
|
109
|
-
|
|
105
|
+
// unless it has already explicitly been set by the user
|
|
106
|
+
process.env.CDS_CONFIG ??= JSON.stringify(env)
|
|
110
107
|
return [ args, options ]
|
|
111
108
|
},
|
|
112
109
|
|
package/bin/subscribe.js
CHANGED
|
@@ -46,19 +46,19 @@ module.exports = Object.assign(subscribe, {
|
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
async function subscribe([tenant], options = {}) {
|
|
49
|
-
const {
|
|
49
|
+
const { getMessage } = require('../lib/client/helper/logging');
|
|
50
50
|
if (!tenant) {
|
|
51
|
-
throw
|
|
51
|
+
throw getMessage('Tenant not given.', { command: 'subscribe' });
|
|
52
52
|
}
|
|
53
53
|
const libOptions = { tenant };
|
|
54
54
|
if (options.local) {
|
|
55
55
|
libOptions.local = true;
|
|
56
56
|
delete options.local;
|
|
57
57
|
if (options.user) {
|
|
58
|
-
throw
|
|
58
|
+
throw getMessage('Username cannot be specified when running @sap/cds-mtxs locally.', { command: 'subscribe' });
|
|
59
59
|
}
|
|
60
60
|
if (options.to) {
|
|
61
|
-
throw
|
|
61
|
+
throw getMessage('URL cannot be specified when running @sap/cds-mtxs locally.', { command: 'subscribe' });
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
const [username, password] = options.user?.split(':') ?? [];
|
package/bin/unsubscribe.js
CHANGED
|
@@ -47,19 +47,19 @@ module.exports = Object.assign(unsubscribe, {
|
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
async function unsubscribe([tenant], options = {}) {
|
|
50
|
-
const {
|
|
50
|
+
const { getMessage } = require('../lib/client/helper/logging');
|
|
51
51
|
if (!tenant) {
|
|
52
|
-
throw
|
|
52
|
+
throw getMessage('Tenant not given.', { command: 'unsubscribe' });
|
|
53
53
|
}
|
|
54
54
|
const libOptions = { tenant };
|
|
55
55
|
if (options.local) {
|
|
56
56
|
libOptions.local = true;
|
|
57
57
|
delete options.local;
|
|
58
58
|
if (options.user) {
|
|
59
|
-
throw
|
|
59
|
+
throw getMessage('Username cannot be specified when running @sap/cds-mtxs locally.', { command: 'subscribe' });
|
|
60
60
|
}
|
|
61
61
|
if (options.from) {
|
|
62
|
-
throw
|
|
62
|
+
throw getMessage('URL cannot be specified when running @sap/cds-mtxs locally.', { command: 'unsubscribe' });
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
const [username, password] = options.user?.split(':') ?? [];
|
package/bin/upgrade.js
CHANGED
|
@@ -47,19 +47,19 @@ module.exports = Object.assign(upgrade, {
|
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
async function upgrade([tenant], options = {}) {
|
|
50
|
-
const {
|
|
50
|
+
const { getMessage } = require('../lib/client/helper/logging');
|
|
51
51
|
if (!tenant) {
|
|
52
|
-
throw
|
|
52
|
+
throw getMessage('Tenant not given.', { command: 'upgrade' });
|
|
53
53
|
}
|
|
54
54
|
const libOptions = { tenant };
|
|
55
55
|
if (options.local) {
|
|
56
56
|
libOptions.local = true;
|
|
57
57
|
delete options.local;
|
|
58
58
|
if (options.user) {
|
|
59
|
-
throw
|
|
59
|
+
throw getMessage('Username cannot be specified when running @sap/cds-mtxs locally.', { command: 'upgrade' });
|
|
60
60
|
}
|
|
61
61
|
if (options.at) {
|
|
62
|
-
throw
|
|
62
|
+
throw getMessage('URL cannot be specified when running @sap/cds-mtxs locally.', { command: 'upgrade' });
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
const [username, password] = options.user?.split(':') ?? [];
|
|
@@ -7,7 +7,6 @@ const axios = require('axios');
|
|
|
7
7
|
require('../util/pruneAxiosErrors');
|
|
8
8
|
const { URL } = require('url');
|
|
9
9
|
const { bold, highlight } = require('../util/term');
|
|
10
|
-
const { CliError } = require('../client/helper/errors');
|
|
11
10
|
|
|
12
11
|
class CFKeyProvider {
|
|
13
12
|
async getCfSpaceInfo() {
|
|
@@ -21,13 +20,13 @@ class CFKeyProvider {
|
|
|
21
20
|
const { org, space } = target;
|
|
22
21
|
const orgs = await BatchRequest.req(targetWithAuth, `/v3/organizations?names=${encodeURIComponent(encodeURIComponent(org))}`);
|
|
23
22
|
if (!(orgs && orgs.resources.length === 1)) {
|
|
24
|
-
throw
|
|
23
|
+
throw `CF org ${org} not found!`;
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
const orgGuid = orgs.resources[0].guid;
|
|
28
27
|
const spaces = await BatchRequest.req(targetWithAuth, `/v3/spaces?names=${encodeURIComponent(encodeURIComponent(space))}&organization_guids=${encodeURIComponent(encodeURIComponent(orgGuid))}`)
|
|
29
28
|
if (!(spaces && spaces.resources.length === 1)) {
|
|
30
|
-
throw
|
|
29
|
+
throw `CF space ${space} not found in org ${org}!`;
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
const spaceGuid = spaces.resources[0].guid;
|
|
@@ -81,7 +80,7 @@ class CFKeyProvider {
|
|
|
81
80
|
try {
|
|
82
81
|
instanceObj = await this.getInstance({ names: instance, space_guids: spaceGuid });
|
|
83
82
|
} catch (error) {
|
|
84
|
-
throw
|
|
83
|
+
throw `Service instance "${instance}" not found.`;
|
|
85
84
|
}
|
|
86
85
|
switch (instanceObj.type) {
|
|
87
86
|
case 'managed':
|
|
@@ -89,7 +88,7 @@ class CFKeyProvider {
|
|
|
89
88
|
case 'user-provided':
|
|
90
89
|
return this._resolveUserProvidedService(instanceObj, instance, org, space);
|
|
91
90
|
default:
|
|
92
|
-
throw
|
|
91
|
+
throw `Service type ${instanceObj.type} not supported`;
|
|
93
92
|
}
|
|
94
93
|
}
|
|
95
94
|
|
|
@@ -100,7 +99,7 @@ class CFKeyProvider {
|
|
|
100
99
|
} catch (error) {
|
|
101
100
|
let message = `No service key ${highlight(key)} found for service instance ${highlight(instance)}.\n\n`;
|
|
102
101
|
message += `Use ${bold(`cf create-service-key ${instanceObj.name} ${key} [-c ...]`)} to create the required service key.`;
|
|
103
|
-
throw
|
|
102
|
+
throw message;
|
|
104
103
|
}
|
|
105
104
|
const planObj = await this.getPlans({ guids: instanceObj.relationships.service_plan.data.guid });
|
|
106
105
|
const offeringObj = await this.getOfferings({ guids: planObj.relationships.service_offering.data.guid });
|
|
@@ -151,10 +150,10 @@ class CFKeyProvider {
|
|
|
151
150
|
|
|
152
151
|
// if no api endpoint is configured the currently logged in endpoint will be used
|
|
153
152
|
if (apiEndpoint && apiEndpoint !== this.target.apiEndpoint) {
|
|
154
|
-
name = `${name || instance}:${key || instance + '-key'}
|
|
153
|
+
name = `${name || instance}:${key || instance + '-key'}`;
|
|
155
154
|
let message = `Current Cloud Foundry API endpoint ${highlight(this.target.apiEndpoint)} differs from API endpoint ${highlight(apiEndpoint)} for service binding ${highlight(name)}.\n\n`;
|
|
156
155
|
message += `Use ${bold(`cf login -a ${apiEndpoint}`)} to log in to the target API endpoint.`;
|
|
157
|
-
throw
|
|
156
|
+
throw message;
|
|
158
157
|
}
|
|
159
158
|
}
|
|
160
159
|
}
|
|
@@ -224,9 +223,9 @@ class BatchRequest {
|
|
|
224
223
|
if (filteredResources.length === 1) {
|
|
225
224
|
filter.resolve(filteredResources[0]);
|
|
226
225
|
} else if (filteredResources.length === 0) {
|
|
227
|
-
filter.reject(
|
|
226
|
+
filter.reject(`Couldn't find resource for url "${this.url}" with filter "${fmt(filter.filter)}"`);
|
|
228
227
|
} else {
|
|
229
|
-
filter.reject(
|
|
228
|
+
filter.reject(`Found more than one resources for url "${this.url}" with filter "${fmt(filter.filter)}"`);
|
|
230
229
|
}
|
|
231
230
|
}
|
|
232
231
|
}
|
package/lib/bind/index.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
const cds = require('../cds');
|
|
2
2
|
|
|
3
|
-
const { CliError } = require('../client/helper/errors');
|
|
4
|
-
|
|
5
3
|
const BindingResolver = require('./bindingResolver');
|
|
6
4
|
const { determineKinds, getRequiresNameFromKind, checkIsJavaProject, platformText, bindingText, logger } = require('./bindingUtil');
|
|
7
5
|
const { highlight, bold, info } = require('../util/term');
|
|
@@ -31,7 +29,7 @@ async function bind(options) {
|
|
|
31
29
|
on = 'cf';
|
|
32
30
|
break;
|
|
33
31
|
default:
|
|
34
|
-
throw
|
|
32
|
+
throw `Invalid value '${options.on}' for option --on.`;
|
|
35
33
|
}
|
|
36
34
|
|
|
37
35
|
const onText = { 'cf': 'Cloud Foundry', 'k8s': 'Kubernetes' }[on];
|
|
@@ -27,7 +27,6 @@ class BuildTaskEngine {
|
|
|
27
27
|
|
|
28
28
|
async processTasks(tasks) {
|
|
29
29
|
const startTime = Date.now()
|
|
30
|
-
const messages = []
|
|
31
30
|
|
|
32
31
|
this.logger.log(`building project [${cds.root}], clean [${this.buildOptions.clean}]`)
|
|
33
32
|
this.logger.log(`cds-dk [${require('../../package.json').version}], cds [${cds.version}], compiler [${cds.compiler.version()}], home [${cds.home}]\n`)
|
|
@@ -64,18 +63,12 @@ class BuildTaskEngine {
|
|
|
64
63
|
|
|
65
64
|
await this._writeGenerationLog(handlers)
|
|
66
65
|
this._logBuildOutput(handlers)
|
|
67
|
-
this._logMessages(
|
|
66
|
+
this._logMessages(BuildTaskEngine._getHandlerMessages(handlers))
|
|
68
67
|
this._logTimer(startTime, Date.now())
|
|
69
68
|
|
|
70
69
|
return buildResult
|
|
71
70
|
} catch (error) {
|
|
72
71
|
this._logBuildOutput(handlers)
|
|
73
|
-
|
|
74
|
-
// cds CLI layer logs in case of an exception if invoked from CLI
|
|
75
|
-
if (!this.buildOptions.cli) {
|
|
76
|
-
this._logMessages([...BuildTaskEngine._getErrorMessages([error]), ...messages])
|
|
77
|
-
}
|
|
78
|
-
|
|
79
72
|
throw error
|
|
80
73
|
}
|
|
81
74
|
}
|
|
@@ -215,22 +208,16 @@ class BuildTaskEngine {
|
|
|
215
208
|
}
|
|
216
209
|
|
|
217
210
|
_createHandler(task) {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
handler.init()
|
|
211
|
+
const handler = this.providerFactory.createHandler(task)
|
|
212
|
+
handler.init()
|
|
221
213
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
227
|
-
this._logTaskHandler(handler)
|
|
228
|
-
|
|
229
|
-
return handler
|
|
230
|
-
} catch (error) {
|
|
231
|
-
log(error, { log: this.logger.log })
|
|
232
|
-
throw error
|
|
214
|
+
if (!(handler instanceof BuildTaskHandlerInternal) && handler.priority !== 1) {
|
|
215
|
+
// Custom build handlers are executed before internal handlers to ensure
|
|
216
|
+
// that generated content cannot be overwritten by mistake
|
|
217
|
+
throw new Error(`Illegal priority for ${handler.constructor.name} encountered for custom handler - in this version only priority value '1' is allowed`)
|
|
233
218
|
}
|
|
219
|
+
this._logTaskHandler(handler)
|
|
220
|
+
return handler
|
|
234
221
|
}
|
|
235
222
|
|
|
236
223
|
_logBuildOutput(handlers) {
|
|
@@ -282,6 +269,7 @@ class BuildTaskEngine {
|
|
|
282
269
|
"log-level": this._getLogLevel() // ensures that for tests the correct cds.env is used
|
|
283
270
|
}
|
|
284
271
|
deduplicateMessages(messages)
|
|
272
|
+
sortMessagesSeverityAware(messages)
|
|
285
273
|
log(messages, options)
|
|
286
274
|
}
|
|
287
275
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
2
|
const path = require('path')
|
|
3
|
-
const cds = require('../cds')
|
|
3
|
+
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")
|
|
@@ -24,36 +24,27 @@ class BuildTaskFactory {
|
|
|
24
24
|
// 2. read using cds.env.build.tasks
|
|
25
25
|
// 3. create from cds.env.folders config data
|
|
26
26
|
async getTasks() {
|
|
27
|
-
|
|
28
|
-
const tasks = await this._createTasks()
|
|
27
|
+
const tasks = await this._createTasks()
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
// log build tasks
|
|
30
|
+
this.logger.log(`the following build tasks will be executed`)
|
|
31
|
+
let tasksOutput = " {\n \"build\": {\n \"target\": \"" + cds.env.build.target + "\",\n \"tasks\": ["
|
|
32
|
+
for (let i = 0; i < tasks.length; i++) {
|
|
33
|
+
tasksOutput += "\n " + BuildTaskFactory._stringifyTask(tasks[i]) + (i + 1 < tasks.length ? "," : "")
|
|
34
|
+
}
|
|
35
|
+
tasksOutput += "\n ]\n }\n }\n"
|
|
36
|
+
this.logger.log(tasksOutput)
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
// for testing purposes
|
|
39
|
+
this.logger.debug("cds.env used for build:")
|
|
40
|
+
this.logger._debug && this.logger.debug(redactCredentials(cds.env))
|
|
42
41
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
return tasks
|
|
49
|
-
} catch (e) {
|
|
50
|
-
this.logger.log('')
|
|
51
|
-
// cds CLI layer is doing the logging if invoked using CLI
|
|
52
|
-
if (!this.buildOptions.cli) {
|
|
53
|
-
log(e, { withStack: true, log: (message) => this.logger.log(message) })
|
|
54
|
-
}
|
|
55
|
-
throw e
|
|
42
|
+
// always resolve tasks for input validation
|
|
43
|
+
const resolvedTasks = this.providerFactory.resolveTasks(tasks)
|
|
44
|
+
if (this.buildOptions.resolve) {
|
|
45
|
+
return resolvedTasks
|
|
56
46
|
}
|
|
47
|
+
return tasks
|
|
57
48
|
}
|
|
58
49
|
|
|
59
50
|
async _createTasks() {
|
|
@@ -227,14 +227,11 @@ class BuildTaskHandler {
|
|
|
227
227
|
// Returns the value of the given build option defined for this build task.
|
|
228
228
|
_getBuildOption(qualifiedName) {
|
|
229
229
|
// build task options overwriting other settings
|
|
230
|
-
let value = getProperty(this.
|
|
231
|
-
if (value
|
|
232
|
-
|
|
233
|
-
}
|
|
234
|
-
value = getProperty(this.context.options, qualifiedName)
|
|
235
|
-
if (value !== undefined) {
|
|
236
|
-
return value
|
|
230
|
+
let value = getProperty(this.context.options, qualifiedName) // command line
|
|
231
|
+
if (value === undefined) {
|
|
232
|
+
value = getProperty(this.task.options, qualifiedName) // task options
|
|
237
233
|
}
|
|
234
|
+
return value
|
|
238
235
|
}
|
|
239
236
|
}
|
|
240
237
|
module.exports = BuildTaskHandler
|
package/lib/build/index.js
CHANGED
|
@@ -14,8 +14,17 @@ module.exports = { build, BuildTaskFactory, BuildTaskEngine, BuildTaskHandler, B
|
|
|
14
14
|
*/
|
|
15
15
|
async function build(options = {}) {
|
|
16
16
|
if (!fs.existsSync(cds.root) || !fs.lstatSync(cds.root).isDirectory()) {
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
throw `Project folder '${cds.root}' does not exist`
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
return await new BuildTaskEngine(options).processTasks()
|
|
21
|
+
} catch (e) {
|
|
22
|
+
if (e instanceof BuildError || e.constructor.name === 'CompilationError') {
|
|
23
|
+
cds._log(e.messages.length ? [...e.messages, ''] : e.message + '\n', { 'log-level': options['log-level'] || cds.env['log-level'] })
|
|
24
|
+
// CompilationError.message also includes the detail messages - do not log twice
|
|
25
|
+
const message = e.constructor.name === 'CompilationError' ? 'CDS compilation failed' : e.messages.length ? e.message : 'CDS build failed'
|
|
26
|
+
throw message
|
|
27
|
+
}
|
|
28
|
+
throw e
|
|
19
29
|
}
|
|
20
|
-
return await new BuildTaskEngine(options).processTasks()
|
|
21
30
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
2
|
const path = require('path')
|
|
3
3
|
const cds = require('../../cds')
|
|
4
|
-
const { hasJavaNature, getDefaultModelOptions, BuildError, hasOptionValue } = require('../util')
|
|
4
|
+
const { hasJavaNature, getDefaultModelOptions, BuildError, hasOptionValue, isClassicMtx } = require('../util')
|
|
5
5
|
const BuildTaskProvider = require('../buildTaskProvider')
|
|
6
6
|
|
|
7
7
|
const { FILE_EXT_CDS, BUILD_TASK_HANA, BUILD_TASK_FIORI, BUILD_TASK_JAVA, BUILD_TASK_JAVA_CF, BUILD_TASK_NODEJS, BUILD_TASK_NODE_CF, BUILD_TASK_MTX,
|
|
@@ -12,6 +12,11 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
|
|
|
12
12
|
constructor(logger) {
|
|
13
13
|
super()
|
|
14
14
|
this._logger = logger
|
|
15
|
+
// ensure that classic mtx is not used in combination with cds-dk@7
|
|
16
|
+
if (isClassicMtx()) {
|
|
17
|
+
throw new BuildError(`@sap/cds-mtx is deprecated and not supported by @sap/cds-dk >= 7.
|
|
18
|
+
Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/docs/guides/multitenancy/old-mtx-migration or install @sap/cds-dk version 6 instead.`)
|
|
19
|
+
}
|
|
15
20
|
}
|
|
16
21
|
get logger() {
|
|
17
22
|
return this._logger
|
|
@@ -65,7 +70,8 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
|
|
|
65
70
|
this.logger.debug("No service module found")
|
|
66
71
|
}
|
|
67
72
|
}
|
|
68
|
-
|
|
73
|
+
|
|
74
|
+
// order of creation is relevant
|
|
69
75
|
if (addRequiredTasks) {
|
|
70
76
|
const mtxTask = tasks.find(task => task.for === BUILD_TASK_MTX || task.for === BUILD_TASK_MTX_SIDECAR)
|
|
71
77
|
if (mtxTask) {
|
|
@@ -80,12 +86,15 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
|
|
|
80
86
|
let dbTask = tasks.find(task => task.for === BUILD_TASK_HANA)
|
|
81
87
|
if (!dbTask) {
|
|
82
88
|
// db task might be missing if mtx task is enforced by 'cds build --for mtx'
|
|
83
|
-
dbTask =
|
|
89
|
+
dbTask = cds.env.build.tasks?.find(task => task.for === BUILD_TASK_HANA)
|
|
90
|
+
if (!dbTask) {
|
|
91
|
+
dbTask = this._createDbTask(db, dbOptions)
|
|
92
|
+
}
|
|
84
93
|
if (dbTask) {
|
|
85
94
|
tasks.push(dbTask)
|
|
86
95
|
}
|
|
87
96
|
}
|
|
88
|
-
if (dbTask &&
|
|
97
|
+
if (dbTask && !mtxTask._uses?.map(use => use.task).includes(dbTask)) {
|
|
89
98
|
const use = { task: dbTask }
|
|
90
99
|
mtxTask._uses ? mtxTask._uses.push(use) : mtxTask._uses = [use]
|
|
91
100
|
}
|
|
@@ -106,7 +115,7 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
|
|
|
106
115
|
}
|
|
107
116
|
|
|
108
117
|
// create mtx build task
|
|
109
|
-
const mtxTask = this._createMtxTask(srv
|
|
118
|
+
const mtxTask = this._createMtxTask(srv)
|
|
110
119
|
if (mtxTask) {
|
|
111
120
|
tasks.push(mtxTask)
|
|
112
121
|
}
|
|
@@ -153,7 +162,7 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
|
|
|
153
162
|
return userEnv && (userEnv.data?.model || userEnv.service?.model)
|
|
154
163
|
}
|
|
155
164
|
|
|
156
|
-
_createMtxTask(src
|
|
165
|
+
_createMtxTask(src) {
|
|
157
166
|
this.logger.debug("determining MTX architecture")
|
|
158
167
|
|
|
159
168
|
// preserve order of creation
|
|
@@ -177,26 +186,26 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
|
|
|
177
186
|
throw new BuildError(`MTX sidecar directory '${sidecarPath}' not existing. Custom build task configuration required if the folder is named differently.`)
|
|
178
187
|
}
|
|
179
188
|
if (!sidecarEnv.requires["cds.xt.ModelProviderService"]?._in_sidecar) {
|
|
180
|
-
// correct profile might have been set, but couldn't be resolved
|
|
181
189
|
if (sidecarEnv.profiles?.includes('mtx-sidecar')) {
|
|
182
|
-
|
|
190
|
+
// profile has been set, but cannot be resolved
|
|
191
|
+
throw new BuildError('MTX configuration cannot be resolved. Make sure up-to-date versions of @sap/cds-mtxs and @sap/cds are installed.')
|
|
183
192
|
}
|
|
184
193
|
throw new BuildError(`Invalid MTX sidecar configuration - profile 'mtx-sidecar' not set.`)
|
|
185
194
|
}
|
|
186
195
|
return { for: BUILD_TASK_MTX_SIDECAR }
|
|
187
196
|
}
|
|
197
|
+
|
|
188
198
|
if (sidecarEnv?.requires["cds.xt.ModelProviderService"]?._in_sidecar || sidecarEnv?.profiles?.includes('mtx-sidecar')) {
|
|
189
199
|
throw new BuildError(`MTX sidecar requires profile 'with-mtx-sidecar' in project root configuration.`)
|
|
190
200
|
}
|
|
191
|
-
|
|
192
201
|
if (cds.env.requires["cds.xt.ModelProviderService"]?._in_sidecar || cds.env.profiles?.includes('mtx-sidecar')) {
|
|
193
202
|
// cds build is executed in sidecar folder
|
|
194
203
|
throw new BuildError(`Seems that you are executing 'cds build' in the 'mtx/sidecar' folder. Execute 'cds build' in the project root folder instead.`)
|
|
195
204
|
}
|
|
196
205
|
|
|
197
|
-
// mtxs
|
|
198
|
-
if (!
|
|
199
|
-
this.logger.debug("MTX app without sidecar")
|
|
206
|
+
// mtxs nodejs app without sidecar
|
|
207
|
+
if (!BuildTaskProviderInternal._hasJavaNature(src)) {
|
|
208
|
+
this.logger.debug("MTX Nodejs app without sidecar")
|
|
200
209
|
return {
|
|
201
210
|
for: BUILD_TASK_MTX,
|
|
202
211
|
src
|
|
@@ -278,7 +287,6 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
|
|
|
278
287
|
task.src = task.src || "."
|
|
279
288
|
break
|
|
280
289
|
case BUILD_TASK_MTX:
|
|
281
|
-
require('../../util/version').checkMtx(cds)
|
|
282
290
|
// mtxs with nodejs, but without sidecar
|
|
283
291
|
task.src = task.src || this._normalizePath(cds.env.folders.srv)
|
|
284
292
|
break
|
|
@@ -310,7 +318,7 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
|
|
|
310
318
|
}
|
|
311
319
|
|
|
312
320
|
// REVISIT: filter nodejs bootstrap service models for Java - issues/12770#issuecomment-1805719
|
|
313
|
-
if (this._hasJavaNature(
|
|
321
|
+
if (this._hasJavaNature()) {
|
|
314
322
|
defaultModelPaths = defaultModelPaths.filter(p => !NODEJS_MODEL_EXCLUDE_LIST.includes(p))
|
|
315
323
|
}
|
|
316
324
|
// also add built-in models to custom build tasks already containing model options
|
|
@@ -323,7 +331,7 @@ class BuildTaskProviderInternal extends BuildTaskProvider {
|
|
|
323
331
|
* Returns whether this project is a java project or not.
|
|
324
332
|
* @param {string} srv - the folder name of the service module
|
|
325
333
|
*/
|
|
326
|
-
static _hasJavaNature(srv) {
|
|
334
|
+
static _hasJavaNature(srv = cds.env.folders.srv) {
|
|
327
335
|
srv = this._getModuleFolder(Array.isArray(srv) ? srv : [srv])
|
|
328
336
|
return hasJavaNature([cds.root, srv && path.join(cds.root, srv)])
|
|
329
337
|
}
|
|
@@ -52,8 +52,9 @@ class FioriAppModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
52
52
|
appModelGroups.set(appFolder, appModels)
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
// ensure edmx is cached as build result
|
|
56
|
+
const buildOption = this.context.options[OUTPUT_MODE]
|
|
57
|
+
this.context.options[OUTPUT_MODE] |= OUTPUT_MODE_RESULT
|
|
57
58
|
|
|
58
59
|
try {
|
|
59
60
|
const edmxOptions = { version: cds.env.odata?.version }
|
|
@@ -76,7 +77,7 @@ class FioriAppModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
76
77
|
fioriBuildOptions.appEdmx.set(appFolder, this._result.edmx)
|
|
77
78
|
}
|
|
78
79
|
} finally {
|
|
79
|
-
|
|
80
|
+
this.context.options[OUTPUT_MODE] = buildOption
|
|
80
81
|
}
|
|
81
82
|
return false
|
|
82
83
|
}
|
|
@@ -2,7 +2,7 @@ const fs = require('fs')
|
|
|
2
2
|
const path = require('path')
|
|
3
3
|
const cds = require('../../../cds')
|
|
4
4
|
const BuildTaskHandlerEdmx = require('../buildTaskHandlerEdmx')
|
|
5
|
-
const { OUTPUT_MODE, OUTPUT_MODE_RESULT, FILE_EXT_CDS, CONTENT_LANGUAGE_BUNDLES, CONTENT_DEFAULT_CSN, DEFAULT_CSN_FILE_NAME } = require('../../constants')
|
|
5
|
+
const { OUTPUT_MODE, OUTPUT_MODE_RESULT, FILE_EXT_CDS, CONTENT_LANGUAGE_BUNDLES, CONTENT_DEFAULT_CSN, DEFAULT_CSN_FILE_NAME, OUTPUT_MODE_FILESYSTEM } = require('../../constants')
|
|
6
6
|
const { getI18nDefaultFolder } = require('../../util')
|
|
7
7
|
const DEFAULT_COMPILE_DEST_FOLDER = path.normalize('src/main/resources/edmx')
|
|
8
8
|
|
|
@@ -34,7 +34,7 @@ class JavaModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
34
34
|
this._result.languageBundles = i18n.bundles
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
-
if (this.isStagingBuild() && this.hasBuildOption(OUTPUT_MODE,
|
|
37
|
+
if (this.isStagingBuild() && this.hasBuildOption(OUTPUT_MODE, OUTPUT_MODE_FILESYSTEM)) {
|
|
38
38
|
await this._copyNativeContent(src, dest)
|
|
39
39
|
}
|
|
40
40
|
return this._result
|
|
@@ -5,6 +5,7 @@ const cds = require('../../../cds')
|
|
|
5
5
|
const BuildTaskHandlerEdmx = require('../buildTaskHandlerEdmx')
|
|
6
6
|
const ResourcesTarProvider = require('./resourcesTarBuilder')
|
|
7
7
|
const { FOLDER_GEN } = require('../../constants')
|
|
8
|
+
const { BuildError } = require('../../util')
|
|
8
9
|
|
|
9
10
|
class MtxModuleBuilder extends BuildTaskHandlerEdmx {
|
|
10
11
|
get priority() {
|
|
@@ -13,12 +14,17 @@ class MtxModuleBuilder extends BuildTaskHandlerEdmx {
|
|
|
13
14
|
}
|
|
14
15
|
init() {
|
|
15
16
|
super.init()
|
|
17
|
+
|
|
18
|
+
// this build task only supports nodejs mtxs apps without sidecar
|
|
19
|
+
if (cds.env['project-nature'] === 'java') {
|
|
20
|
+
throw new BuildError(`@sap/cds-mtx is deprecated and not supported by @sap/cds-dk >= 7. This also applies to the 'mtx' build task in Java projects.
|
|
21
|
+
Upgrade to @sap/cds-mtxs following the migration guide https://cap.cloud.sap/docs/guides/multitenancy/old-mtx-migration or install @sap/cds-dk version 6 instead.`)
|
|
22
|
+
}
|
|
16
23
|
}
|
|
17
24
|
|
|
18
25
|
async build() {
|
|
19
|
-
// Non-sidecar scenario: model-provider is implemented by the Nodejs app itself (default for Nodejs).
|
|
20
26
|
// Only create resources TAR, compiled CSN(s) are created by the Nodejs app build task.
|
|
21
|
-
const dest = cds.env.build.target !==
|
|
27
|
+
const dest = cds.env.build.target !== '.' ? this.task.dest : path.join(this.task.dest, FOLDER_GEN)
|
|
22
28
|
const model = await this.model()
|
|
23
29
|
if (!model) {
|
|
24
30
|
return
|
package/lib/build/util.js
CHANGED
|
@@ -177,6 +177,18 @@ function getI18nDefaultFolder() {
|
|
|
177
177
|
return cds.env.i18n.folders[0] ?? 'i18n'
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
+
function isClassicMtx() {
|
|
181
|
+
function _hasMtxDependency() {
|
|
182
|
+
try {
|
|
183
|
+
return !!require(path.join(cds.root, 'package.json'))?.dependencies?.['@sap/cds-mtx']
|
|
184
|
+
} catch (e) {
|
|
185
|
+
return false
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return /true/i.test(process.env.OLD_MTX) || _hasMtxDependency()
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
|
|
180
192
|
/**
|
|
181
193
|
* Return gnu-style error string for location `loc`:
|
|
182
194
|
* - 'File:Line:Col' without `loc.end`
|
|
@@ -266,6 +278,7 @@ module.exports = {
|
|
|
266
278
|
flatten,
|
|
267
279
|
copy,
|
|
268
280
|
getI18nDefaultFolder,
|
|
281
|
+
isClassicMtx,
|
|
269
282
|
BuildMessage,
|
|
270
283
|
BuildError
|
|
271
284
|
}
|