@sap/cds-dk 6.2.3 → 6.3.0
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/CHANGELOG.md +27 -0
- package/bin/bind.js +4 -4
- package/bin/deploy/to-h2.js +4 -0
- package/bin/deploy/to-sqlite.js +6 -4
- package/bin/help.js +1 -1
- package/bin/login.js +1 -0
- package/bin/push.js +29 -7
- package/lib/bind/userCdsrcJsonStorageProvider.js +4 -4
- package/lib/client/activate.js +1 -1
- package/lib/client/base_command.js +10 -10
- package/lib/client/helper/dependency_helper.js +10 -1
- package/lib/client/helper/logging.js +6 -2
- package/lib/client/pull.js +6 -6
- package/lib/client/push.js +33 -14
- package/lib/client/settings_manager.js +52 -21
- package/lib/compile/openapi/csdl2openapi.js +1 -1
- package/lib/compile/to-xsuaa.js +1 -1
- package/lib/import/odata/v2parser.js +37 -1
- package/lib/import/odata/v4parser.js +101 -23
- package/lib/init/constants.js +1 -1
- package/lib/init/index.js +23 -45
- package/lib/init/template/approuter/index.js +44 -48
- package/lib/init/template/auditlog/index.js +14 -10
- package/lib/init/template/cf-manifest/index.js +9 -11
- package/lib/init/template/connectivity/index.js +10 -10
- package/lib/init/template/data/index.js +20 -19
- package/lib/init/template/destinations/index.js +14 -9
- package/lib/init/template/enterprise-messaging/index.js +14 -9
- package/lib/init/template/extensibility/index.js +14 -9
- package/lib/init/template/hana/index.js +51 -57
- package/lib/init/template/helm/index.js +27 -59
- package/lib/init/template/helm/subchart/templates/_helpers.tpl +38 -0
- package/lib/init/template/helm/subchart/templates/deployment.yaml +12 -12
- package/lib/init/template/helm/subchart/values.md +565 -194
- package/lib/init/template/helm/subchart/values.schema.json +163 -8
- package/lib/init/template/helm/subchart/values.yaml +17 -1
- package/lib/init/template/html5-repo/index.js +15 -11
- package/lib/init/template/java/index.js +15 -11
- package/lib/init/template/kibana-logging/index.js +30 -31
- package/lib/init/template/lint/index.js +17 -18
- package/lib/init/template/mta/index.js +18 -40
- package/lib/init/template/mtx/index.js +2 -3
- package/lib/init/template/multitenancy/index.js +27 -20
- package/lib/init/template/nodejs/index.js +18 -20
- package/lib/init/template/notebook/index.js +5 -434
- package/lib/init/template/pipeline/index.js +10 -10
- package/lib/init/template/samples/index.js +7 -16
- package/lib/init/template/templateBase.js +17 -18
- package/lib/init/template/toggles/files/cdsrc.json +5 -0
- package/lib/init/template/toggles/files/cdsrc.json.hbs +7 -0
- package/lib/init/template/toggles/index.js +12 -6
- package/lib/init/template/xsuaa/index.js +44 -41
- package/lib/init/types.d.ts +0 -59
- package/lib/init/util/commandUtil.js +6 -7
- package/lib/init/util/fsUtil.js +23 -109
- package/lib/init/util/merge.js +319 -0
- package/lib/init/util/mvnArchetypeUtil.js +6 -5
- package/lib/init/util/projectReader.js +125 -300
- package/lib/init/util/spinner.js +10 -8
- package/lib/init/util/templateUtil.js +25 -368
- package/lib/lint/Linter.js +2 -3
- package/lib/lint/checks.js +0 -1
- package/lib/lint/io.js +18 -34
- package/npm-shrinkwrap.json +102 -239
- package/package.json +3 -3
- package/lib/init/template/notebook/cap_magic.py +0 -118
- package/lib/init/template/notebook/files/{{{name}}}.ipynb.hbs +0 -90
- package/lib/init/template/notebook/files/{{{name}}}.json +0 -102
- package/lib/init/template/notebook/notebook.js +0 -394
- package/lib/init/util/logger.js +0 -42
|
@@ -1,24 +1,15 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
-
|
|
3
|
-
const TemplateBase = require('../templateBase');
|
|
4
|
-
|
|
2
|
+
const { copyFiles } = require('../../util/templateUtil')
|
|
5
3
|
const commandUtil = require('../../util/commandUtil');
|
|
6
4
|
const mvnArchetypes = require('../../util/mvnArchetypeUtil');
|
|
7
5
|
const term = require('../../../util/term');
|
|
8
|
-
|
|
9
6
|
const { PROJECT_TYPE, OPTION_JAVA, URLS } = require('../../constants');
|
|
10
7
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
module.exports = class SamplesTemplate extends TemplateBase {
|
|
8
|
+
module.exports = class SamplesTemplate extends require('../templateBase') {
|
|
14
9
|
constructor(projectPath, generator) {
|
|
15
10
|
super(projectPath, generator, __dirname);
|
|
16
11
|
}
|
|
17
12
|
|
|
18
|
-
async checkEnabled() {
|
|
19
|
-
return true;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
13
|
async run() {
|
|
23
14
|
switch (await this.getProjectType()) {
|
|
24
15
|
case PROJECT_TYPE.java:
|
|
@@ -35,19 +26,19 @@ module.exports = class SamplesTemplate extends TemplateBase {
|
|
|
35
26
|
|
|
36
27
|
async _addJavaSamples() {
|
|
37
28
|
// only execute if not add via cds init --add java, otherwise samples would be added twice
|
|
38
|
-
// do not check in
|
|
29
|
+
// do not check in canRun since log output "> adding samples" wouldn't appear
|
|
39
30
|
if (!this.options.add.has(OPTION_JAVA)) {
|
|
40
31
|
// keep sequence since plugin needs samples to generate test classes
|
|
41
32
|
const mvnAddSamplesArgs = mvnArchetypes.getAddSamplesCmdArgs(this.options);
|
|
42
33
|
try {
|
|
43
34
|
await commandUtil.spawnCommand('mvn', mvnAddSamplesArgs, {
|
|
44
35
|
cwd: this.projectPath
|
|
45
|
-
}
|
|
36
|
+
});
|
|
46
37
|
|
|
47
38
|
const mvnAddTestsArgs = mvnArchetypes.getAddTestsCmdArgs(this.options);
|
|
48
39
|
await commandUtil.spawnCommand('mvn', mvnAddTestsArgs, {
|
|
49
40
|
cwd: this.projectPath
|
|
50
|
-
}
|
|
41
|
+
});
|
|
51
42
|
} catch (err) {
|
|
52
43
|
if (err.code === 'ENOENT' && err.path === 'mvn') {
|
|
53
44
|
throw new Error(`Maven executable 'mvn' not found, follow ${term.info(URLS.MAVEN_INSTALL_HELP)} and install Maven on your machine.`);
|
|
@@ -60,10 +51,10 @@ module.exports = class SamplesTemplate extends TemplateBase {
|
|
|
60
51
|
async _addNodejsSamples() {
|
|
61
52
|
const folders = (await this.getEnv()).folders;
|
|
62
53
|
const dbFolder = path.join(this.projectPath, folders.db);
|
|
63
|
-
await
|
|
54
|
+
await copyFiles(path.join(__dirname, 'files', 'nodejs', 'db'), dbFolder, {}, this.options.force);
|
|
64
55
|
|
|
65
56
|
const srvFolder = path.join(this.projectPath, folders.srv);
|
|
66
|
-
await
|
|
57
|
+
await copyFiles(path.join(__dirname, 'files', 'nodejs', 'srv'), srvFolder, {
|
|
67
58
|
dbFolder: folders.db.replace(/[\\/]+$/, '')
|
|
68
59
|
}, this.options.force);
|
|
69
60
|
}
|
|
@@ -4,29 +4,25 @@ const path = require('path');
|
|
|
4
4
|
const TemplateUtil = require('../util/templateUtil');
|
|
5
5
|
|
|
6
6
|
const { PROJECT_TYPE } = require('../constants');
|
|
7
|
-
|
|
7
|
+
const { exists } = require('../../cds').utils;
|
|
8
8
|
|
|
9
9
|
module.exports = class TemplateBase {
|
|
10
10
|
/**
|
|
11
11
|
* @constructor
|
|
12
12
|
*/
|
|
13
|
-
constructor(projectPath, generator, dirName
|
|
13
|
+
constructor(projectPath, generator, dirName) {
|
|
14
14
|
if (generator.options && generator.options.for && typeof generator.options.for !== 'string') {
|
|
15
15
|
throw new Error('The --for argument must not be empty.')
|
|
16
16
|
}
|
|
17
17
|
this.projectPath = path.resolve(projectPath);
|
|
18
18
|
this.options = generator.options || {};
|
|
19
19
|
this.projectPath = path.resolve(projectPath);
|
|
20
|
-
this.fsUtil = generator.fsUtil;
|
|
21
|
-
this.logger = generator.logger;
|
|
22
20
|
this.generator = generator;
|
|
23
21
|
|
|
24
22
|
this.cwd = this.options.cwd || process.cwd();
|
|
25
23
|
this.name = (dirName ? path.basename(dirName) : this.constructor.name.replace(/template/i, '').toLowerCase());
|
|
26
|
-
this.dontAnnounce = dontAnnounce;
|
|
27
24
|
|
|
28
25
|
this.projectName = path.basename(this.projectPath);
|
|
29
|
-
this.templateUtil = new TemplateUtil(path.join(dirName, 'files'), this.fsUtil);
|
|
30
26
|
}
|
|
31
27
|
|
|
32
28
|
/**
|
|
@@ -42,24 +38,27 @@ module.exports = class TemplateBase {
|
|
|
42
38
|
* @returns true, if template should handle this request, false otherwise
|
|
43
39
|
* @throws Error, if request is invalid, e.g. a file exists already
|
|
44
40
|
*/
|
|
45
|
-
async
|
|
41
|
+
async canRun() {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// eslint-disable-next-line no-unused-vars
|
|
46
|
+
static hasFacet(env, projectPath, options) {
|
|
46
47
|
return true;
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
/**
|
|
50
51
|
* calls cds env and caches result
|
|
51
|
-
* @param {boolean} force, ignore cached value
|
|
52
52
|
* @returns {object} the current cds env
|
|
53
53
|
*/
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
async getEnv(profile = 'production') {
|
|
55
|
+
const cdsEnvVar = process.env.CDS_ENV
|
|
56
|
+
process.env.CDS_ENV = profile
|
|
57
|
+
try {
|
|
58
|
+
return cds.env.for('cds', exists(this.projectPath) ? this.projectPath : this.cwd);
|
|
59
|
+
} finally {
|
|
60
|
+
cdsEnvVar ? process.env.CDS_ENV = cdsEnvVar : delete process.env.CDS_ENV
|
|
60
61
|
}
|
|
61
|
-
|
|
62
|
-
return cds.env.for('cds', projectPath);
|
|
63
62
|
}
|
|
64
63
|
|
|
65
64
|
/**
|
|
@@ -98,11 +97,11 @@ module.exports = class TemplateBase {
|
|
|
98
97
|
* @returns PROJECT_TYPE for current project
|
|
99
98
|
*/
|
|
100
99
|
async getProjectType() {
|
|
101
|
-
if (
|
|
100
|
+
if (exists(path.join(this.projectPath, 'pom.xml'))) {
|
|
102
101
|
return PROJECT_TYPE.java;
|
|
103
102
|
}
|
|
104
103
|
|
|
105
|
-
if (
|
|
104
|
+
if (exists(path.join(this.projectPath, 'package.json'))) {
|
|
106
105
|
return PROJECT_TYPE.nodejs;
|
|
107
106
|
}
|
|
108
107
|
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
const cds = require('../../../cds'), { path } = cds.utils
|
|
2
|
-
const TemplateBase = require('../templateBase')
|
|
3
2
|
const ProjectReader = require('../../util/projectReader')
|
|
3
|
+
const { mergeJSON, sortDependencies } = require('../../util/merge')
|
|
4
4
|
|
|
5
|
-
module.exports = class TogglesTemplate extends
|
|
5
|
+
module.exports = class TogglesTemplate extends require('../templateBase') {
|
|
6
6
|
constructor(projectPath, generator) {
|
|
7
7
|
super(projectPath, generator, __dirname)
|
|
8
|
-
this.projectReader = new ProjectReader(
|
|
8
|
+
this.projectReader = new ProjectReader(projectPath)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
static hasFacet(env) {
|
|
12
|
+
return !!env.requires?.toggles
|
|
9
13
|
}
|
|
10
14
|
|
|
11
15
|
async run() {
|
|
@@ -14,10 +18,12 @@ module.exports = class TogglesTemplate extends TemplateBase {
|
|
|
14
18
|
if (isNodejs) {
|
|
15
19
|
const packageJSONPath = path.join(this.projectPath, 'package.json')
|
|
16
20
|
const cdsTemplateFile = forProfile ? 'cds.package.json.hbs' : 'cds.package.json'
|
|
17
|
-
await
|
|
18
|
-
await
|
|
21
|
+
await mergeJSON(packageJSONPath, path.join(__dirname, 'files', cdsTemplateFile), projectDescriptor)
|
|
22
|
+
await sortDependencies(packageJSONPath)
|
|
19
23
|
} else if (isJava) {
|
|
20
|
-
|
|
24
|
+
const cdsrcPath = path.join(this.projectPath, '.cdsrc.json')
|
|
25
|
+
const cdsTemplateFile = path.join(__dirname, 'files', forProfile ? 'cdsrc.json.hbs' : 'cdsrc.json')
|
|
26
|
+
await mergeJSON(cdsrcPath, cdsTemplateFile, projectDescriptor)
|
|
21
27
|
}
|
|
22
28
|
await this.runDependentMerging()
|
|
23
29
|
}
|
|
@@ -1,19 +1,48 @@
|
|
|
1
1
|
const path = require('path')
|
|
2
|
-
const cds = require('../../../cds')
|
|
3
|
-
const
|
|
2
|
+
const cds = require('../../../cds')
|
|
3
|
+
const { copy } = cds.utils
|
|
4
4
|
const ProjectReader = require('../../util/projectReader')
|
|
5
|
+
const { mergeJSON, mergeYAML } = require('../../util/merge')
|
|
5
6
|
const { srvNode, srvJava, xsuaa, mtxSidecar } = require('../_merging/registry-mta')
|
|
6
7
|
const { PROJECT_TYPE } = require('../../constants')
|
|
7
8
|
|
|
8
|
-
module.exports = class XsuaaTemplate extends
|
|
9
|
+
module.exports = class XsuaaTemplate extends require('../templateBase') {
|
|
9
10
|
constructor(projectPath, generator) {
|
|
10
11
|
super(projectPath, generator, __dirname)
|
|
11
|
-
this.projectReader = new ProjectReader(
|
|
12
|
+
this.projectReader = new ProjectReader(projectPath)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
static hasFacet(env) {
|
|
16
|
+
return env.requires?.auth?.kind === 'xsuaa'
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async run() {
|
|
20
|
+
const { projectPath } = this
|
|
21
|
+
const templatePath = path.join(__dirname, 'files')
|
|
22
|
+
const projectDescriptor = await this.projectReader.read(this.options)
|
|
23
|
+
const projectType = await this.getProjectType();
|
|
24
|
+
const { for: forProfile } = projectDescriptor.cap
|
|
25
|
+
|
|
26
|
+
if (projectType === PROJECT_TYPE.java) {
|
|
27
|
+
const cdsrcJSONPath = path.join(projectPath, '.cdsrc.json')
|
|
28
|
+
const cdsTemplateFile = forProfile ? 'cds.cdsrc.json.hbs' : 'cds.cdsrc.json'
|
|
29
|
+
const cdsTemplatePath = path.join(templatePath, cdsTemplateFile)
|
|
30
|
+
await mergeJSON(cdsrcJSONPath, cdsTemplatePath, projectDescriptor)
|
|
31
|
+
} else if (projectType === PROJECT_TYPE.nodejs) {
|
|
32
|
+
const packageJSONPath = path.join(projectPath, 'package.json')
|
|
33
|
+
const cdsTemplateFile = forProfile ? 'cds.package.json.hbs' : 'cds.package.json'
|
|
34
|
+
const cdsTemplatePath = path.join(templatePath, cdsTemplateFile)
|
|
35
|
+
await mergeJSON(packageJSONPath, cdsTemplatePath, projectDescriptor)
|
|
36
|
+
const dependenciesTemplatePath = path.join(templatePath, 'dependencies.package.json')
|
|
37
|
+
await mergeJSON(packageJSONPath, dependenciesTemplatePath)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
await this.runDependentMerging()
|
|
12
41
|
}
|
|
13
42
|
|
|
14
43
|
async runDependentMerging() {
|
|
15
44
|
const projectDescriptor = await this.projectReader.read(this.options)
|
|
16
|
-
const { isMultitenant, isExtensible,
|
|
45
|
+
const { isMultitenant, isExtensible, hasMta, hasHelm, isNodejs, isJava } = projectDescriptor.cap
|
|
17
46
|
|
|
18
47
|
const cds = require('../../../../lib/compile')
|
|
19
48
|
const xsSecurity = await (async () => { try {
|
|
@@ -30,9 +59,9 @@ module.exports = class XsuaaTemplate extends TemplateBase {
|
|
|
30
59
|
}],
|
|
31
60
|
}))}
|
|
32
61
|
const xsSecurityPath = path.join(this.projectPath, 'xs-security.json')
|
|
33
|
-
await
|
|
62
|
+
await mergeJSON(xsSecurityPath, xsSecurity, projectDescriptor, mergingSemantics)
|
|
34
63
|
|
|
35
|
-
if (
|
|
64
|
+
if (hasMta) {
|
|
36
65
|
const srv = isNodejs ? srvNode : srvJava
|
|
37
66
|
const additions = [srv, xsuaa]
|
|
38
67
|
if (isMultitenant && isJava) additions.push(mtxSidecar)
|
|
@@ -47,7 +76,7 @@ module.exports = class XsuaaTemplate extends TemplateBase {
|
|
|
47
76
|
into: [mtxSidecar, 'requires', 'name']
|
|
48
77
|
})
|
|
49
78
|
|
|
50
|
-
await
|
|
79
|
+
await mergeYAML(
|
|
51
80
|
mtaYAMLPath,
|
|
52
81
|
`${__dirname}/files/mta.yaml.hbs`,
|
|
53
82
|
projectDescriptor,
|
|
@@ -58,15 +87,18 @@ module.exports = class XsuaaTemplate extends TemplateBase {
|
|
|
58
87
|
)
|
|
59
88
|
}
|
|
60
89
|
|
|
61
|
-
if (
|
|
62
|
-
await
|
|
63
|
-
|
|
90
|
+
if (hasHelm) {
|
|
91
|
+
await copy(
|
|
92
|
+
path.join(__dirname, 'files', 'xsuaa.yaml'),
|
|
93
|
+
path.join(this.projectPath, 'chart', 'templates', 'xsuaa.yaml')
|
|
94
|
+
)
|
|
95
|
+
await mergeYAML(
|
|
64
96
|
path.join(this.projectPath, 'chart', 'values.yaml'),
|
|
65
97
|
path.join(__dirname, 'files', 'values.yaml.hbs'),
|
|
66
98
|
projectDescriptor, { forceOverwrite: true }
|
|
67
99
|
)
|
|
68
100
|
// REVISIT: Shared xs-security.json location for Helm and MTA?
|
|
69
|
-
await
|
|
101
|
+
await copy(
|
|
70
102
|
path.join(this.projectPath, 'xs-security.json'),
|
|
71
103
|
path.join(this.projectPath, 'chart', 'xs-security.json')
|
|
72
104
|
)
|
|
@@ -86,33 +118,4 @@ module.exports = class XsuaaTemplate extends TemplateBase {
|
|
|
86
118
|
await extensibilityTemplate.runDependentMerging()
|
|
87
119
|
}
|
|
88
120
|
}
|
|
89
|
-
|
|
90
|
-
async run() {
|
|
91
|
-
const { projectPath } = this
|
|
92
|
-
const templatePath = path.join(__dirname, 'files')
|
|
93
|
-
const projectDescriptor = await this.projectReader.read(this.options)
|
|
94
|
-
const { for: forProfile } = projectDescriptor.cap
|
|
95
|
-
|
|
96
|
-
const projectType = await this.getProjectType();
|
|
97
|
-
switch (projectType) {
|
|
98
|
-
case PROJECT_TYPE.java: {
|
|
99
|
-
const cdsrcJSONPath = path.join(projectPath, '.cdsrc.json')
|
|
100
|
-
const cdsTemplateFile = forProfile ? 'cds.cdsrc.json.hbs' : 'cds.cdsrc.json'
|
|
101
|
-
const cdsTemplatePath = path.join(templatePath, cdsTemplateFile)
|
|
102
|
-
await this.templateUtil.mergeJSON(cdsrcJSONPath, cdsTemplatePath, projectDescriptor)
|
|
103
|
-
break
|
|
104
|
-
}
|
|
105
|
-
case PROJECT_TYPE.nodejs: {
|
|
106
|
-
const packageJSONPath = path.join(projectPath, 'package.json')
|
|
107
|
-
const cdsTemplateFile = forProfile ? 'cds.package.json.hbs' : 'cds.package.json'
|
|
108
|
-
const cdsTemplatePath = path.join(templatePath, cdsTemplateFile)
|
|
109
|
-
await this.templateUtil.mergeJSON(packageJSONPath, cdsTemplatePath, projectDescriptor)
|
|
110
|
-
const dependenciesTemplatePath = path.join(templatePath, 'dependencies.package.json')
|
|
111
|
-
await this.templateUtil.mergeJSON(packageJSONPath, dependenciesTemplatePath)
|
|
112
|
-
break
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
await this.runDependentMerging()
|
|
117
|
-
}
|
|
118
121
|
}
|
package/lib/init/types.d.ts
CHANGED
|
@@ -28,41 +28,6 @@ export interface CDSGenerator {
|
|
|
28
28
|
uiConfig?: any;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* An interface providing logging functionality.
|
|
34
|
-
*/
|
|
35
|
-
export interface Logger {
|
|
36
|
-
/**
|
|
37
|
-
* True if logger is in debug mode
|
|
38
|
-
*/
|
|
39
|
-
isDebug: boolean;
|
|
40
|
-
/**
|
|
41
|
-
* Writes a debug message to log.
|
|
42
|
-
* @param message the message to write to log
|
|
43
|
-
*/
|
|
44
|
-
debug(message: string): void;
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Writes a message to log.
|
|
48
|
-
* @param message the message to write to log
|
|
49
|
-
*/
|
|
50
|
-
log(message: string): void;
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Writes a warning message to log.
|
|
54
|
-
* @param message the message to write to log
|
|
55
|
-
*/
|
|
56
|
-
warn(message: string): void;
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Writes an error to log.
|
|
60
|
-
* @param Error the error to write to log
|
|
61
|
-
*/
|
|
62
|
-
error(error: Error): void;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
|
|
66
31
|
/**
|
|
67
32
|
* This is a helper interface to provide support for different file system implementations.
|
|
68
33
|
* Depending on the scenario different file systems will be used, e.g. Yeoman vs. native FS.
|
|
@@ -129,30 +94,6 @@ export interface FsUtil {
|
|
|
129
94
|
* @param skipFileLog do not log files if true
|
|
130
95
|
*/
|
|
131
96
|
copy(source: string, destination: string, options?: any, skipFileLog?: boolean): Promise<void>;
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Checks if given path exists.
|
|
135
|
-
* @param filePath the absolute path
|
|
136
|
-
* @returns true if given path exists, otherwise false
|
|
137
|
-
*/
|
|
138
|
-
pathExists(filePath: string): Promise<boolean>;
|
|
139
|
-
|
|
140
|
-
/*
|
|
141
|
-
* Methods mapping to fs-extra
|
|
142
|
-
*/
|
|
143
|
-
readdir(filePath: string): Promise<string[]>;
|
|
144
|
-
|
|
145
|
-
mkdirp(folderPath: string): Promise<void>;
|
|
146
|
-
|
|
147
|
-
stat(filePath: string): Promise<any>;
|
|
148
|
-
|
|
149
|
-
/*
|
|
150
|
-
* Helper methods
|
|
151
|
-
*/
|
|
152
|
-
hasContent(folderPath: string): Promise<boolean>;
|
|
153
|
-
|
|
154
|
-
getTouchedFiles(): string[];
|
|
155
|
-
|
|
156
97
|
}
|
|
157
98
|
|
|
158
99
|
/**
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
const cp = require('child_process');
|
|
2
2
|
const os = require('os');
|
|
3
|
+
const cds = require('../../cds')
|
|
4
|
+
const LOG = cds.log('cds')
|
|
3
5
|
|
|
4
6
|
const { IS_WIN } = require('../constants');
|
|
5
7
|
|
|
6
|
-
const { nullLogger } = require('./logger');
|
|
7
|
-
|
|
8
8
|
class CommandUtil {
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -13,30 +13,29 @@ class CommandUtil {
|
|
|
13
13
|
* @param cmd command
|
|
14
14
|
* @param args command args
|
|
15
15
|
* @param options spawn options
|
|
16
|
-
* @param logger logger to use
|
|
17
16
|
* @param collectResult if true, return complete console output as promise resolve value
|
|
18
17
|
* this might result in a huge string!
|
|
19
18
|
*
|
|
20
19
|
* @returns Promise
|
|
21
20
|
*/
|
|
22
|
-
async spawnCommand(cmd, args, options = {},
|
|
21
|
+
async spawnCommand(cmd, args, options = {}, collectResult = false) {
|
|
23
22
|
args = this._sanitizeArgs(args);
|
|
24
23
|
return new Promise((resolve, reject) => {
|
|
25
|
-
|
|
24
|
+
LOG.debug(`[spawn] ${cmd} ${args.join(' ')}`);
|
|
26
25
|
|
|
27
26
|
options.env = options.env || process.env;
|
|
28
27
|
|
|
29
28
|
const child = this._getChildProcess(cmd, args, options);
|
|
30
29
|
|
|
31
30
|
// use inplace methods to ensure logger is called in context
|
|
32
|
-
const stdLogBuffer = new LogBuffer((chunk) =>
|
|
31
|
+
const stdLogBuffer = new LogBuffer((chunk) => LOG.info(chunk), collectResult);
|
|
33
32
|
child.stdout.on('data', (chunk) => {
|
|
34
33
|
stdLogBuffer.handleChunk(chunk);
|
|
35
34
|
});
|
|
36
35
|
|
|
37
36
|
// use inplace methods to ensure logger is called in context
|
|
38
37
|
// collect error log in case of Win to handle command not found (ENOENT),
|
|
39
|
-
const errLogBuffer = new LogBuffer((chunk) =>
|
|
38
|
+
const errLogBuffer = new LogBuffer((chunk) => LOG.error(chunk), (IS_WIN || collectResult));
|
|
40
39
|
child.stderr.on('data', (chunk) => {
|
|
41
40
|
errLogBuffer.handleChunk(chunk);
|
|
42
41
|
});
|
package/lib/init/util/fsUtil.js
CHANGED
|
@@ -1,127 +1,41 @@
|
|
|
1
|
-
const
|
|
2
|
-
const path = require('path');
|
|
3
|
-
|
|
4
|
-
const {yaml:YAML} = require('@sap/cds-foss')
|
|
1
|
+
const { yaml: YAML } = require('@sap/cds-foss')
|
|
5
2
|
const JSONC = require('../../util/jsonc');
|
|
3
|
+
const { read, write } = require('../../cds').utils;
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* this util implements FsUtil declared in ../types.d.ts
|
|
11
|
-
* the interface FsUtil is also used by @sap/generator-cap-project
|
|
12
|
-
*/
|
|
13
|
-
module.exports = class FsUtil {
|
|
14
|
-
|
|
15
|
-
constructor() {
|
|
16
|
-
this.touchedFiles = new Set();
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
async writeFile(filepath, content, skipFileLog = false) {
|
|
20
|
-
if (!skipFileLog) {
|
|
21
|
-
this._addTouchedFile(filepath);
|
|
22
|
-
}
|
|
23
|
-
await fs.mkdir(path.dirname(filepath), { recursive: true })
|
|
24
|
-
await fs.writeFile(filepath, content, UTF_8);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async writeJSON(filepath, object, options = { spaces: 2 }, skipFileLog = false) {
|
|
28
|
-
const content = JSON.stringify(object, null, options.spaces)
|
|
29
|
-
await this.writeFile(filepath, content, skipFileLog)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async writeYAML(filepath, yaml, skipFileLog = false) {
|
|
33
|
-
await this.writeFile(filepath, YAML.stringify(yaml, { collectionStyle: 'block' }), skipFileLog);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async readFile(src) {
|
|
37
|
-
return await fs.readFile(src, UTF_8);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async readJSON(src, projectDescriptor) {
|
|
41
|
-
const file = await this.readFile(src);
|
|
42
|
-
if (projectDescriptor) {
|
|
43
|
-
const Mustache = require('mustache');
|
|
44
|
-
const renderedFile = Mustache.render(file, projectDescriptor);
|
|
45
|
-
return JSON.parse(renderedFile);
|
|
46
|
-
}
|
|
47
|
-
return JSON.parse(file)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
async readJSONC(src) {
|
|
51
|
-
const fileContents = await this.readFile(src);
|
|
52
|
-
return JSONC.parse(fileContents);
|
|
53
|
-
}
|
|
5
|
+
module.exports = new class FsUtil {
|
|
54
6
|
|
|
55
7
|
async readYAML(src, projectDescriptor) {
|
|
56
|
-
let file
|
|
8
|
+
let file
|
|
57
9
|
try {
|
|
58
|
-
file = await
|
|
10
|
+
file = await read(src, 'utf8')
|
|
59
11
|
} catch (e) {
|
|
60
|
-
if (e.code === 'ENOENT') return undefined
|
|
61
|
-
throw e
|
|
12
|
+
if (e.code === 'ENOENT') return undefined
|
|
13
|
+
throw e
|
|
62
14
|
}
|
|
63
15
|
if (projectDescriptor) {
|
|
64
|
-
const Mustache = require('mustache')
|
|
65
|
-
const renderedFile = Mustache.render(file, projectDescriptor)
|
|
66
|
-
return YAML.parseDocument(renderedFile)
|
|
67
|
-
}
|
|
68
|
-
return YAML.parseDocument(file);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// eslint-disable-next-line no-unused-vars
|
|
72
|
-
async copy(source, destination, options = {}, skipFileLog = false) {
|
|
73
|
-
if (!skipFileLog) {
|
|
74
|
-
this._addTouchedFile(destination);
|
|
75
|
-
}
|
|
76
|
-
if (fs.cp) { // Node.js >= 16.7
|
|
77
|
-
await fs.cp(source, destination, { recursive: true })
|
|
78
|
-
} else {
|
|
79
|
-
await _copy(source, destination);
|
|
16
|
+
const Mustache = require('mustache')
|
|
17
|
+
const renderedFile = Mustache.render(file, projectDescriptor)
|
|
18
|
+
return YAML.parseDocument(renderedFile)
|
|
80
19
|
}
|
|
20
|
+
return YAML.parseDocument(file)
|
|
81
21
|
}
|
|
82
22
|
|
|
83
|
-
async
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
async readdir(filePath) {
|
|
88
|
-
return await fs.readdir(filePath);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
getTouchedFiles() {
|
|
92
|
-
return Array.from(this.touchedFiles.keys());
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
async mkdirp(folderPath) {
|
|
96
|
-
await fs.mkdir(folderPath, { recursive: true });
|
|
23
|
+
async writeYAML(filepath, yaml) {
|
|
24
|
+
const content = YAML.stringify(yaml, { collectionStyle: 'block' })
|
|
25
|
+
await write(filepath, content)
|
|
97
26
|
}
|
|
98
27
|
|
|
99
|
-
async
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const projectContent = await this.readdir(folderPath);
|
|
106
|
-
return projectContent.length > 0;
|
|
28
|
+
async readJSON(src, projectDescriptor) {
|
|
29
|
+
const file = await read(src, 'utf8')
|
|
30
|
+
if (projectDescriptor) {
|
|
31
|
+
const Mustache = require('mustache')
|
|
32
|
+
const renderedFile = Mustache.render(file, projectDescriptor)
|
|
33
|
+
return JSON.parse(renderedFile)
|
|
107
34
|
}
|
|
108
|
-
|
|
109
|
-
return false;
|
|
35
|
+
return JSON.parse(file)
|
|
110
36
|
}
|
|
111
37
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
this.touchedFiles.add(relativeFilepath);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Polyfill for Node.14: asynchronously copies the entire content from src to dest.
|
|
119
|
-
async function _copy(src, dest) {
|
|
120
|
-
if ((await fs.stat(src)).isDirectory()) {
|
|
121
|
-
const entries = await fs.readdir(src)
|
|
122
|
-
return Promise.all(entries.map(async each => _copy(path.join(src, each), path.join(dest, each))))
|
|
123
|
-
} else {
|
|
124
|
-
await fs.mkdir(path.dirname(dest), { recursive: true })
|
|
125
|
-
return fs.copyFile(src, dest)
|
|
38
|
+
async readJSONC(src) {
|
|
39
|
+
return JSONC.parse(await read(src, 'utf8'))
|
|
126
40
|
}
|
|
127
41
|
}
|